diff options
Diffstat (limited to 'WebCore/rendering/InlineFlowBox.cpp')
| -rw-r--r-- | WebCore/rendering/InlineFlowBox.cpp | 131 |
1 files changed, 47 insertions, 84 deletions
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp index 0432a4c..543c190 100644 --- a/WebCore/rendering/InlineFlowBox.cpp +++ b/WebCore/rendering/InlineFlowBox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -253,12 +253,10 @@ int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& righ // Set our x position. setX(xPos); - int boxShadowLeft = 0; - int boxShadowRight = 0; - for (ShadowData* boxShadow = renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - boxShadowLeft = min(boxShadow->x - boxShadow->blur, boxShadowLeft); - boxShadowRight = max(boxShadow->x + boxShadow->blur, boxShadowRight); - } + int boxShadowLeft; + int boxShadowRight; + renderer()->style(m_firstLine)->getBoxShadowHorizontalExtent(boxShadowLeft, boxShadowRight); + leftPosition = min(xPos + boxShadowLeft, leftPosition); int startX = xPos; @@ -311,7 +309,7 @@ int InlineFlowBox::placeBoxesHorizontally(int xPos, int& leftPosition, int& righ xPos += flow->marginLeft(); xPos = flow->placeBoxesHorizontally(xPos, leftPosition, rightPosition, needsWordSpacing); xPos += flow->marginRight(); - } else if (!curr->renderer()->isListMarker() || static_cast<RenderListMarker*>(curr->renderer())->isInside()) { + } else if (!curr->renderer()->isListMarker() || toRenderListMarker(curr->renderer())->isInside()) { xPos += curr->boxModelObject()->marginLeft(); curr->setX(xPos); leftPosition = min(xPos + toRenderBox(curr->renderer())->overflowLeft(false), leftPosition); @@ -371,7 +369,7 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, if (curr->renderer()->isPositioned()) continue; // Positioned placeholders don't affect calculations. if (curr->y() == PositionTop || curr->y() == PositionBottom) { - int lineHeight = curr->renderer()->lineHeight(m_firstLine); + int lineHeight = curr->lineHeight(false); if (curr->y() == PositionTop) { if (maxAscent + maxDescent < lineHeight) maxDescent = lineHeight - maxAscent; @@ -404,11 +402,11 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi { if (isRootInlineBox()) { // Examine our root box. - int lineHeight = renderer()->lineHeight(m_firstLine, true); - int baseline = renderer()->baselinePosition(m_firstLine, true); + int height = lineHeight(true); + int baseline = baselinePosition(true); if (hasTextChildren() || strictMode) { int ascent = baseline; - int descent = lineHeight - ascent; + int descent = height - ascent; if (maxAscent < ascent) maxAscent = ascent; if (maxDescent < descent) @@ -456,8 +454,8 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi } } } else { - lineHeight = curr->renderer()->lineHeight(m_firstLine); - baseline = curr->renderer()->baselinePosition(m_firstLine); + lineHeight = curr->lineHeight(false); + baseline = curr->baselinePosition(false); } curr->setY(verticalPositionForBox(curr, m_firstLine)); @@ -485,8 +483,8 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, int& topPosition, int& bottomPosition, int& selectionTop, int& selectionBottom) { if (isRootInlineBox()) - setY(yPos + max(0, maxAscent - renderer()->baselinePosition(m_firstLine, true))); // Place our root box. - + setY(yPos + max(0, maxAscent - baselinePosition(true))); // Place our root box. + for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { if (curr->renderer()->isPositioned()) continue; // Positioned placeholders don't affect calculations. @@ -501,11 +499,11 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, if (curr->y() == PositionTop) curr->setY(yPos); else if (curr->y() == PositionBottom) - curr->setY(yPos + maxHeight - curr->renderer()->lineHeight(m_firstLine)); + curr->setY(yPos + maxHeight - curr->lineHeight(false)); else { if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasHorizontalBordersOrPadding() && !strictMode) childAffectsTopBottomPos = false; - int posAdjust = maxAscent - curr->renderer()->baselinePosition(m_firstLine); + int posAdjust = maxAscent - curr->baselinePosition(false); if (!childAffectsTopBottomPos) posAdjust = max(0, posAdjust); curr->setY(curr->y() + yPos + posAdjust); @@ -521,16 +519,9 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, int overflowBottom = 0; if (curr->isText() || curr->isInlineFlowBox()) { const Font& font = curr->renderer()->style(m_firstLine)->font(); - newY += curr->renderer()->baselinePosition(m_firstLine) - font.ascent(); - for (ShadowData* shadow = curr->renderer()->style()->textShadow(); shadow; shadow = shadow->next) { - overflowTop = min(overflowTop, shadow->y - shadow->blur); - overflowBottom = max(overflowBottom, shadow->y + shadow->blur); - } + newY += curr->baselinePosition(false) - font.ascent(); - for (ShadowData* boxShadow = curr->renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - overflowTop = min(overflowTop, boxShadow->y - boxShadow->blur); - overflowBottom = max(overflowBottom, boxShadow->y + boxShadow->blur); - } + curr->renderer()->style(m_firstLine)->getBoxShadowVerticalExtent(overflowTop, overflowBottom); for (ShadowData* textShadow = curr->renderer()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) { overflowTop = min(overflowTop, textShadow->y - textShadow->blur); @@ -565,7 +556,7 @@ void InlineFlowBox::placeBoxesVertically(int yPos, int maxHeight, int maxAscent, if (isRootInlineBox()) { const Font& font = renderer()->style(m_firstLine)->font(); - setY(y() + renderer()->baselinePosition(m_firstLine, true) - font.ascent()); + setY(y() + baselinePosition(true) - font.ascent()); if (hasTextChildren() || strictMode) { selectionTop = min(selectionTop, y()); selectionBottom = max(selectionBottom, y() + height()); @@ -597,16 +588,16 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) { int xPos = tx + m_x - renderer()->maximalOutlineSize(paintInfo.phase); int w = width() + 2 * renderer()->maximalOutlineSize(paintInfo.phase); - int shadowLeft = 0; - int shadowRight = 0; - for (ShadowData* boxShadow = renderer()->style(m_firstLine)->boxShadow(); boxShadow; boxShadow = boxShadow->next) { - shadowLeft = min(boxShadow->x - boxShadow->blur, shadowLeft); - shadowRight = max(boxShadow->x + boxShadow->blur, shadowRight); - } + int shadowLeft; + int shadowRight; + + renderer()->style(m_firstLine)->getBoxShadowHorizontalExtent(shadowLeft, shadowRight); + for (ShadowData* textShadow = renderer()->style(m_firstLine)->textShadow(); textShadow; textShadow = textShadow->next) { shadowLeft = min(textShadow->x - textShadow->blur, shadowLeft); shadowRight = max(textShadow->x + textShadow->blur, shadowRight); } + xPos += shadowLeft; w += -shadowLeft + shadowRight; bool intersectsDamageRect = xPos < paintInfo.rect.right() && xPos + w > paintInfo.rect.x(); @@ -658,22 +649,20 @@ void InlineFlowBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty) paintTextDecorations(paintInfo, tx, ty, true); } -void InlineFlowBox::paintFillLayers(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, - int my, int mh, int _tx, int _ty, int w, int h, CompositeOperator op) +void InlineFlowBox::paintFillLayers(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int _tx, int _ty, int w, int h, CompositeOperator op) { if (!fillLayer) return; - paintFillLayers(paintInfo, c, fillLayer->next(), my, mh, _tx, _ty, w, h, op); - paintFillLayer(paintInfo, c, fillLayer, my, mh, _tx, _ty, w, h, op); + paintFillLayers(paintInfo, c, fillLayer->next(), _tx, _ty, w, h, op); + paintFillLayer(paintInfo, c, fillLayer, _tx, _ty, w, h, op); } -void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, - int my, int mh, int tx, int ty, int w, int h, CompositeOperator op) +void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, int tx, int ty, int w, int h, CompositeOperator op) { StyleImage* img = fillLayer->image(); bool hasFillImage = img && img->canRender(renderer()->style()->effectiveZoom()); if ((!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent()) - boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, tx, ty, w, h, this, op); + boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, tx, ty, w, h, this, op); else { // We have a fill image that spans multiple lines. // We need to adjust _tx and _ty by the width of all previous lines. @@ -692,19 +681,19 @@ void InlineFlowBox::paintFillLayer(const RenderObject::PaintInfo& paintInfo, con totalWidth += curr->width(); paintInfo.context->save(); paintInfo.context->clip(IntRect(tx, ty, width(), height())); - boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, my, mh, startX, ty, totalWidth, h, this, op); + boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, startX, ty, totalWidth, h, this, op); paintInfo.context->restore(); } } -void InlineFlowBox::paintBoxShadow(GraphicsContext* context, RenderStyle* s, int tx, int ty, int w, int h) +void InlineFlowBox::paintBoxShadow(GraphicsContext* context, RenderStyle* s, ShadowStyle shadowStyle, int tx, int ty, int w, int h) { if ((!prevLineBox() && !nextLineBox()) || !parent()) - boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s); + boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, shadowStyle); else { // FIXME: We can do better here in the multi-line case. We want to push a clip so that the shadow doesn't // protrude incorrectly at the edges, and we want to possibly include shadows cast from the previous/following lines - boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, includeLeftEdge(), includeRightEdge()); + boxModelObject()->paintBoxShadow(context, tx, ty, w, h, s, shadowStyle, includeLeftEdge(), includeRightEdge()); } } @@ -720,13 +709,6 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int int w = width(); int h = height(); - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - GraphicsContext* context = paintInfo.context; // You can use p::first-line to specify a background. If so, the root line boxes for @@ -735,10 +717,13 @@ void InlineFlowBox::paintBoxDecorations(RenderObject::PaintInfo& paintInfo, int if ((!parent() && m_firstLine && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) { // Shadow comes first and is behind the background and border. if (styleToUse->boxShadow()) - paintBoxShadow(context, styleToUse, tx, ty, w, h); + paintBoxShadow(context, styleToUse, Normal, tx, ty, w, h); Color c = styleToUse->backgroundColor(); - paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), my, mh, tx, ty, w, h); + paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), tx, ty, w, h); + + if (styleToUse->boxShadow()) + paintBoxShadow(context, styleToUse, Inset, tx, ty, w, h); // :first-line cannot be used to put borders on a line. Always paint borders with our // non-first-line style. @@ -789,14 +774,6 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty int w = width(); int h = height(); - int my = max(ty, paintInfo.rect.y()); - int mh; - if (ty < paintInfo.rect.y()) - mh = max(0, h - (paintInfo.rect.y() - ty)); - else - mh = min(paintInfo.rect.height(), h); - - // Figure out if we need to push a transparency layer to render our mask. bool pushTransparencyLayer = false; const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage(); @@ -811,7 +788,7 @@ void InlineFlowBox::paintMask(RenderObject::PaintInfo& paintInfo, int tx, int ty compositeOp = CompositeSourceOver; } - paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), my, mh, tx, ty, w, h, compositeOp); + paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), tx, ty, w, h, compositeOp); bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer()->style()->effectiveZoom()); if (!hasBoxImage || !maskBoxImage->isLoaded()) @@ -997,33 +974,19 @@ void InlineFlowBox::paintTextDecorations(RenderObject::PaintInfo& paintInfo, int } } -InlineBox* InlineFlowBox::firstLeafChild() -{ - return firstLeafChildAfterBox(); -} - -InlineBox* InlineFlowBox::lastLeafChild() -{ - return lastLeafChildBeforeBox(); -} - -InlineBox* InlineFlowBox::firstLeafChildAfterBox(InlineBox* start) +InlineBox* InlineFlowBox::firstLeafChild() const { InlineBox* leaf = 0; - for (InlineBox* box = start ? start->nextOnLine() : firstChild(); box && !leaf; box = box->nextOnLine()) - leaf = box->firstLeafChild(); - if (start && !leaf && parent()) - return parent()->firstLeafChildAfterBox(this); + for (InlineBox* child = firstChild(); child && !leaf; child = child->nextOnLine()) + leaf = child->isLeaf() ? child : static_cast<InlineFlowBox*>(child)->firstLeafChild(); return leaf; } -InlineBox* InlineFlowBox::lastLeafChildBeforeBox(InlineBox* start) +InlineBox* InlineFlowBox::lastLeafChild() const { InlineBox* leaf = 0; - for (InlineBox* box = start ? start->prevOnLine() : lastChild(); box && !leaf; box = box->prevOnLine()) - leaf = box->lastLeafChild(); - if (start && !leaf && parent()) - return parent()->lastLeafChildBeforeBox(this); + for (InlineBox* child = lastChild(); child && !leaf; child = child->prevOnLine()) + leaf = child->isLeaf() ? child : static_cast<InlineFlowBox*>(child)->lastLeafChild(); return leaf; } @@ -1054,7 +1017,7 @@ int InlineFlowBox::placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightE int visibleLeftEdge = blockLeftEdge; int visibleRightEdge = blockRightEdge; - while(box) { + while (box) { int currResult = box->placeEllipsisBox(ltr, visibleLeftEdge, visibleRightEdge, ellipsisWidth, foundBox); if (currResult != -1 && result == -1) result = currResult; |
