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 |