| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 | 1088 |
| 1089 void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
LayoutUnit lineTop, LayoutUnit lineBottom) | 1089 void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
LayoutUnit lineTop, LayoutUnit lineBottom) |
| 1090 { | 1090 { |
| 1091 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); | 1091 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); |
| 1092 flipForWritingMode(overflowRect); | 1092 flipForWritingMode(overflowRect); |
| 1093 overflowRect.moveBy(paintOffset); | 1093 overflowRect.moveBy(paintOffset); |
| 1094 | 1094 |
| 1095 if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect))) | 1095 if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect))) |
| 1096 return; | 1096 return; |
| 1097 | 1097 |
| 1098 if (paintInfo.phase != PaintPhaseChildOutlines) { | 1098 if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSel
fOutline) { |
| 1099 if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhas
eSelfOutline) { | 1099 // Add ourselves to the paint info struct's list of inlines that need to
paint their |
| 1100 // Add ourselves to the paint info struct's list of inlines that nee
d to paint their | 1100 // outlines. |
| 1101 // outlines. | 1101 if (renderer().style()->visibility() == VISIBLE && renderer().hasOutline
() && !isRootInlineBox()) { |
| 1102 if (renderer().style()->visibility() == VISIBLE && renderer().hasOut
line() && !isRootInlineBox()) { | 1102 RenderInline& inlineFlow = toRenderInline(renderer()); |
| 1103 RenderInline& inlineFlow = toRenderInline(renderer()); | |
| 1104 | 1103 |
| 1105 RenderBlock* cb = 0; | 1104 RenderBlock* cb = 0; |
| 1106 bool containingBlockPaintsContinuationOutline = inlineFlow.conti
nuation() || inlineFlow.isInlineElementContinuation(); | 1105 bool containingBlockPaintsContinuationOutline = inlineFlow.continuat
ion() || inlineFlow.isInlineElementContinuation(); |
| 1107 if (containingBlockPaintsContinuationOutline) { | 1106 if (containingBlockPaintsContinuationOutline) { |
| 1108 // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690.
We currently don't reconnect inline continuations | 1107 // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We
currently don't reconnect inline continuations |
| 1109 // after a child removal. As a result, those merged inlines
do not get seperated and hence not get enclosed by | 1108 // after a child removal. As a result, those merged inlines do n
ot get seperated and hence not get enclosed by |
| 1110 // anonymous blocks. In this case, it is better to bail out
and paint it ourself. | 1109 // anonymous blocks. In this case, it is better to bail out and
paint it ourself. |
| 1111 RenderBlock* enclosingAnonymousBlock = renderer().containing
Block(); | 1110 RenderBlock* enclosingAnonymousBlock = renderer().containingBloc
k(); |
| 1112 if (!enclosingAnonymousBlock->isAnonymousBlock()) | 1111 if (!enclosingAnonymousBlock->isAnonymousBlock()) { |
| 1113 containingBlockPaintsContinuationOutline = false; | 1112 containingBlockPaintsContinuationOutline = false; |
| 1114 else { | 1113 } else { |
| 1115 cb = enclosingAnonymousBlock->containingBlock(); | 1114 cb = enclosingAnonymousBlock->containingBlock(); |
| 1116 for (RenderBoxModelObject* box = boxModelObject(); box !
= cb; box = box->parent()->enclosingBoxModelObject()) { | 1115 for (RenderBoxModelObject* box = boxModelObject(); box != cb
; box = box->parent()->enclosingBoxModelObject()) { |
| 1117 if (box->hasSelfPaintingLayer()) { | 1116 if (box->hasSelfPaintingLayer()) { |
| 1118 containingBlockPaintsContinuationOutline = false
; | 1117 containingBlockPaintsContinuationOutline = false; |
| 1119 break; | 1118 break; |
| 1120 } | |
| 1121 } | 1119 } |
| 1122 } | 1120 } |
| 1123 } | 1121 } |
| 1122 } |
| 1124 | 1123 |
| 1125 if (containingBlockPaintsContinuationOutline) { | 1124 if (containingBlockPaintsContinuationOutline) { |
| 1126 // Add ourselves to the containing block of the entire conti
nuation so that it can | 1125 // Add ourselves to the containing block of the entire continuat
ion so that it can |
| 1127 // paint us atomically. | 1126 // paint us atomically. |
| 1128 cb->addContinuationWithOutline(toRenderInline(renderer().nod
e()->renderer())); | 1127 cb->addContinuationWithOutline(toRenderInline(renderer().node()-
>renderer())); |
| 1129 } else if (!inlineFlow.isInlineElementContinuation()) { | 1128 } else if (!inlineFlow.isInlineElementContinuation()) { |
| 1130 paintInfo.outlineObjects()->add(&inlineFlow); | 1129 paintInfo.outlineObjects()->add(&inlineFlow); |
| 1131 } | |
| 1132 } | 1130 } |
| 1133 } else if (paintInfo.phase == PaintPhaseMask) { | |
| 1134 paintMask(paintInfo, paintOffset); | |
| 1135 return; | |
| 1136 } else { | |
| 1137 // Paint our background, border and box-shadow. | |
| 1138 paintBoxDecorations(paintInfo, paintOffset); | |
| 1139 } | 1131 } |
| 1132 } else if (paintInfo.phase == PaintPhaseMask) { |
| 1133 paintMask(paintInfo, paintOffset); |
| 1134 return; |
| 1135 } else if (paintInfo.phase == PaintPhaseForeground) { |
| 1136 // Paint our background, border and box-shadow. |
| 1137 paintBoxDecorations(paintInfo, paintOffset); |
| 1140 } | 1138 } |
| 1141 | 1139 |
| 1142 if (paintInfo.phase == PaintPhaseMask) | |
| 1143 return; | |
| 1144 | |
| 1145 PaintPhase paintPhase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPh
aseOutline : paintInfo.phase; | |
| 1146 | |
| 1147 // Paint our children. | 1140 // Paint our children. |
| 1148 if (paintPhase != PaintPhaseSelfOutline) { | 1141 if (paintInfo.phase != PaintPhaseSelfOutline) { |
| 1149 PaintInfo childInfo(paintInfo); | 1142 PaintInfo childInfo(paintInfo); |
| 1150 childInfo.phase = paintPhase; | 1143 childInfo.phase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhas
eOutline : paintInfo.phase; |
| 1151 | 1144 |
| 1152 if (childInfo.paintingRoot && childInfo.paintingRoot->isDescendantOf(&re
nderer())) | 1145 if (childInfo.paintingRoot && childInfo.paintingRoot->isDescendantOf(&re
nderer())) |
| 1153 childInfo.paintingRoot = 0; | 1146 childInfo.paintingRoot = 0; |
| 1154 else | 1147 else |
| 1155 childInfo.updatePaintingRootForChildren(&renderer()); | 1148 childInfo.updatePaintingRootForChildren(&renderer()); |
| 1156 | 1149 |
| 1157 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 1150 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
| 1158 if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPai
ntingLayer()) | 1151 if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPai
ntingLayer()) |
| 1159 curr->paint(childInfo, paintOffset, lineTop, lineBottom); | 1152 curr->paint(childInfo, paintOffset, lineTop, lineBottom); |
| 1160 } | 1153 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 clipRect.setHeight(paintRect.height() + outsets.top()); | 1267 clipRect.setHeight(paintRect.height() + outsets.top()); |
| 1275 } | 1268 } |
| 1276 if (box->includeLogicalRightEdge()) | 1269 if (box->includeLogicalRightEdge()) |
| 1277 clipRect.setHeight(clipRect.height() + outsets.bottom()); | 1270 clipRect.setHeight(clipRect.height() + outsets.bottom()); |
| 1278 } | 1271 } |
| 1279 return clipRect; | 1272 return clipRect; |
| 1280 } | 1273 } |
| 1281 | 1274 |
| 1282 void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
paintOffset) | 1275 void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
paintOffset) |
| 1283 { | 1276 { |
| 1284 if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->vis
ibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground) | 1277 ASSERT(paintInfo.phase == PaintPhaseForeground); |
| 1278 if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->vis
ibility() != VISIBLE) |
| 1279 return; |
| 1280 |
| 1281 // You can use p::first-line to specify a background. If so, the root line b
oxes for |
| 1282 // a line may actually have to paint a background. |
| 1283 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); |
| 1284 bool shouldPaintBoxDecorations; |
| 1285 if (parent()) |
| 1286 shouldPaintBoxDecorations = renderer().hasBoxDecorations(); |
| 1287 else |
| 1288 shouldPaintBoxDecorations = isFirstLineStyle() && styleToUse != renderer
().style(); |
| 1289 |
| 1290 if (!shouldPaintBoxDecorations) |
| 1285 return; | 1291 return; |
| 1286 | 1292 |
| 1287 // Pixel snap background/border painting. | 1293 // Pixel snap background/border painting. |
| 1288 LayoutRect frameRect = roundedFrameRect(); | 1294 LayoutRect frameRect = roundedFrameRect(); |
| 1289 | |
| 1290 constrainToLineTopAndBottomIfNeeded(frameRect); | 1295 constrainToLineTopAndBottomIfNeeded(frameRect); |
| 1291 | 1296 |
| 1292 // Move x/y to our coordinates. | 1297 // Move x/y to our coordinates. |
| 1293 LayoutRect localRect(frameRect); | 1298 LayoutRect localRect(frameRect); |
| 1294 flipForWritingMode(localRect); | 1299 flipForWritingMode(localRect); |
| 1295 LayoutPoint adjustedPaintoffset = paintOffset + localRect.location(); | 1300 LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); |
| 1296 | 1301 |
| 1297 GraphicsContext* context = paintInfo.context; | 1302 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); |
| 1298 | 1303 |
| 1299 // You can use p::first-line to specify a background. If so, the root line b
oxes for | 1304 // Shadow comes first and is behind the background and border. |
| 1300 // a line may actually have to paint a background. | 1305 if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedN
one, this)) |
| 1301 RenderStyle* styleToUse = renderer().style(isFirstLineStyle()); | 1306 paintBoxShadow(paintInfo, styleToUse, Normal, paintRect); |
| 1302 if ((!parent() && isFirstLineStyle() && styleToUse != renderer().style()) ||
(parent() && renderer().hasBoxDecorations())) { | |
| 1303 LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size())
; | |
| 1304 // Shadow comes first and is behind the background and border. | |
| 1305 if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBl
eedNone, this)) | |
| 1306 paintBoxShadow(paintInfo, styleToUse, Normal, paintRect); | |
| 1307 | 1307 |
| 1308 Color c = renderer().resolveColor(styleToUse, CSSPropertyBackgroundColor
); | 1308 Color backgroundColor = renderer().resolveColor(styleToUse, CSSPropertyBackg
roundColor); |
| 1309 paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), paintRect)
; | 1309 paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(),
paintRect); |
| 1310 paintBoxShadow(paintInfo, styleToUse, Inset, paintRect); | 1310 paintBoxShadow(paintInfo, styleToUse, Inset, paintRect); |
| 1311 | 1311 |
| 1312 // :first-line cannot be used to put borders on a line. Always paint bor
ders with our | 1312 // :first-line cannot be used to put borders on a line. Always paint borders
with our |
| 1313 // non-first-line style. | 1313 // non-first-line style. |
| 1314 if (parent() && renderer().style()->hasBorder()) { | 1314 if (parent() && renderer().style()->hasBorder()) { |
| 1315 const NinePieceImage& borderImage = renderer().style()->borderImage(
); | 1315 const NinePieceImage& borderImage = renderer().style()->borderImage(); |
| 1316 StyleImage* borderImageSource = borderImage.image(); | 1316 StyleImage* borderImageSource = borderImage.image(); |
| 1317 bool hasBorderImage = borderImageSource && borderImageSource->canRen
der(renderer(), styleToUse->effectiveZoom()); | 1317 bool hasBorderImage = borderImageSource && borderImageSource->canRender(
renderer(), styleToUse->effectiveZoom()); |
| 1318 if (hasBorderImage && !borderImageSource->isLoaded()) | 1318 if (hasBorderImage && !borderImageSource->isLoaded()) |
| 1319 return; // Don't paint anything while we wait for the image to l
oad. | 1319 return; // Don't paint anything while we wait for the image to load. |
| 1320 | 1320 |
| 1321 // The simple case is where we either have no border image or we are
the only box for this object. In those | 1321 // The simple case is where we either have no border image or we are the
only box for this object. |
| 1322 // cases only a single call to draw is required. | 1322 // In those cases only a single call to draw is required. |
| 1323 if (!hasBorderImage || (!prevLineBox() && !nextLineBox())) | 1323 if (!hasBorderImage || (!prevLineBox() && !nextLineBox())) { |
| 1324 boxModelObject()->paintBorder(paintInfo, paintRect, renderer().s
tyle(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), include
LogicalRightEdge()); | 1324 boxModelObject()->paintBorder(paintInfo, paintRect, renderer().style
(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogi
calRightEdge()); |
| 1325 else { | 1325 } else { |
| 1326 // We have a border image that spans multiple lines. | 1326 // We have a border image that spans multiple lines. |
| 1327 // We need to adjust tx and ty by the width of all previous line
s. | 1327 // We need to adjust tx and ty by the width of all previous lines. |
| 1328 // Think of border image painting on inlines as though you had o
ne long line, a single continuous | 1328 // Think of border image painting on inlines as though you had one l
ong line, a single continuous |
| 1329 // strip. Even though that strip has been broken up across mult
iple lines, you still paint it | 1329 // strip. Even though that strip has been broken up across multiple
lines, you still paint it |
| 1330 // as though you had one single line. This means each line has
to pick up the image where | 1330 // as though you had one single line. This means each line has to pi
ck up the image where |
| 1331 // the previous line left off. | 1331 // the previous line left off. |
| 1332 // FIXME: What the heck do we do with RTL here? The math we're u
sing is obviously not right, | 1332 // FIXME: What the heck do we do with RTL here? The math we're using
is obviously not right, |
| 1333 // but it isn't even clear how this should work at all. | 1333 // but it isn't even clear how this should work at all. |
| 1334 LayoutUnit logicalOffsetOnLine = 0; | 1334 LayoutUnit logicalOffsetOnLine = 0; |
| 1335 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->pre
vLineBox()) | 1335 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLin
eBox()) |
| 1336 logicalOffsetOnLine += curr->logicalWidth(); | 1336 logicalOffsetOnLine += curr->logicalWidth(); |
| 1337 LayoutUnit totalLogicalWidth = logicalOffsetOnLine; | 1337 LayoutUnit totalLogicalWidth = logicalOffsetOnLine; |
| 1338 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox(
)) | 1338 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) |
| 1339 totalLogicalWidth += curr->logicalWidth(); | 1339 totalLogicalWidth += curr->logicalWidth(); |
| 1340 LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ?
logicalOffsetOnLine : LayoutUnit()); | 1340 LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logi
calOffsetOnLine : LayoutUnit()); |
| 1341 LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ?
LayoutUnit() : logicalOffsetOnLine); | 1341 LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? Layo
utUnit() : logicalOffsetOnLine); |
| 1342 LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : fra
meRect.width(); | 1342 LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRe
ct.width(); |
| 1343 LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : t
otalLogicalWidth; | 1343 LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : total
LogicalWidth; |
| 1344 | 1344 |
| 1345 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borde
rImage, paintRect); | 1345 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderIma
ge, paintRect); |
| 1346 GraphicsContextStateSaver stateSaver(*context); | 1346 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 1347 context->clip(clipRect); | 1347 paintInfo.context->clip(clipRect); |
| 1348 boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stri
pY, stripWidth, stripHeight), renderer().style(isFirstLineStyle())); | 1348 boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY,
stripWidth, stripHeight), renderer().style(isFirstLineStyle())); |
| 1349 } | |
| 1350 } | 1349 } |
| 1351 } | 1350 } |
| 1352 } | 1351 } |
| 1353 | 1352 |
| 1354 void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
et) | 1353 void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
et) |
| 1355 { | 1354 { |
| 1356 if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->vis
ibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) | 1355 if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->vis
ibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) |
| 1357 return; | 1356 return; |
| 1358 | 1357 |
| 1359 // Pixel snap mask painting. | 1358 // Pixel snap mask painting. |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1662 ASSERT(child->prevOnLine() == prev); | 1661 ASSERT(child->prevOnLine() == prev); |
| 1663 prev = child; | 1662 prev = child; |
| 1664 } | 1663 } |
| 1665 ASSERT(prev == m_lastChild); | 1664 ASSERT(prev == m_lastChild); |
| 1666 #endif | 1665 #endif |
| 1667 } | 1666 } |
| 1668 | 1667 |
| 1669 #endif | 1668 #endif |
| 1670 | 1669 |
| 1671 } // namespace WebCore | 1670 } // namespace WebCore |
| OLD | NEW |