summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/InlineFlowBox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/InlineFlowBox.cpp')
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp131
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;