| 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 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 else | 1019 else |
| 1020 childInfo.updatePaintingRootForChildren(&renderer()); | 1020 childInfo.updatePaintingRootForChildren(&renderer()); |
| 1021 | 1021 |
| 1022 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 1022 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
| 1023 if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPai
ntingLayer()) | 1023 if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPai
ntingLayer()) |
| 1024 curr->paint(childInfo, paintOffset, lineTop, lineBottom); | 1024 curr->paint(childInfo, paintOffset, lineTop, lineBottom); |
| 1025 } | 1025 } |
| 1026 } | 1026 } |
| 1027 } | 1027 } |
| 1028 | 1028 |
| 1029 void InlineFlowBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c,
const FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op) | 1029 void InlineFlowBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c,
const FillLayer& fillLayer, const LayoutRect& rect) |
| 1030 { | 1030 { |
| 1031 if (fillLayer.next()) | 1031 if (fillLayer.next()) |
| 1032 paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op); | 1032 paintFillLayers(paintInfo, c, *fillLayer.next(), rect); |
| 1033 paintFillLayer(paintInfo, c, fillLayer, rect, op); | 1033 paintFillLayer(paintInfo, c, fillLayer, rect); |
| 1034 } | 1034 } |
| 1035 | 1035 |
| 1036 bool InlineFlowBox::boxShadowCanBeAppliedToBackground(const FillLayer& lastBackg
roundLayer) const | 1036 bool InlineFlowBox::boxShadowCanBeAppliedToBackground(const FillLayer& lastBackg
roundLayer) const |
| 1037 { | 1037 { |
| 1038 // The checks here match how paintFillLayer() decides whether to clip (if it
does, the shadow | 1038 // The checks here match how paintFillLayer() decides whether to clip (if it
does, the shadow |
| 1039 // would be clipped out, so it has to be drawn separately). | 1039 // would be clipped out, so it has to be drawn separately). |
| 1040 StyleImage* image = lastBackgroundLayer.image(); | 1040 StyleImage* image = lastBackgroundLayer.image(); |
| 1041 bool hasFillImage = image && image->canRender(renderer()); | 1041 bool hasFillImage = image && image->canRender(renderer()); |
| 1042 return (!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLi
neBox() && !nextLineBox()) || !parent(); | 1042 return (!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLi
neBox() && !nextLineBox()) || !parent(); |
| 1043 } | 1043 } |
| 1044 | 1044 |
| 1045 void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, c
onst FillLayer& fillLayer, const LayoutRect& rect, CompositeOperator op) | 1045 void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, c
onst FillLayer& fillLayer, const LayoutRect& rect) |
| 1046 { | 1046 { |
| 1047 StyleImage* img = fillLayer.image(); | 1047 StyleImage* img = fillLayer.image(); |
| 1048 bool hasFillImage = img && img->canRender(renderer()); | 1048 bool hasFillImage = img && img->canRender(renderer()); |
| 1049 if ((!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLineB
ox() && !nextLineBox()) || !parent()) { | 1049 if ((!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLineB
ox() && !nextLineBox()) || !parent()) { |
| 1050 boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect,
BackgroundBleedNone, this, rect.size(), op); | 1050 boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect,
BackgroundBleedNone, this, rect.size()); |
| 1051 } else if (renderer().style()->boxDecorationBreak() == DCLONE) { | 1051 } else if (renderer().style()->boxDecorationBreak() == DCLONE) { |
| 1052 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 1052 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 1053 paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), width(), height()
)); | 1053 paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), width(), height()
)); |
| 1054 boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect,
BackgroundBleedNone, this, rect.size(), op); | 1054 boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect,
BackgroundBleedNone, this, rect.size()); |
| 1055 } else { | 1055 } else { |
| 1056 // We have a fill image that spans multiple lines. | 1056 // We have a fill image that spans multiple lines. |
| 1057 // We need to adjust tx and ty by the width of all previous lines. | 1057 // We need to adjust tx and ty by the width of all previous lines. |
| 1058 // Think of background painting on inlines as though you had one long li
ne, a single continuous | 1058 // Think of background painting on inlines as though you had one long li
ne, a single continuous |
| 1059 // strip. Even though that strip has been broken up across multiple lin
es, you still paint it | 1059 // strip. Even though that strip has been broken up across multiple lin
es, you still paint it |
| 1060 // as though you had one single line. This means each line has to pick
up the background where | 1060 // as though you had one single line. This means each line has to pick
up the background where |
| 1061 // the previous line left off. | 1061 // the previous line left off. |
| 1062 LayoutUnit logicalOffsetOnLine = 0; | 1062 LayoutUnit logicalOffsetOnLine = 0; |
| 1063 LayoutUnit totalLogicalWidth; | 1063 LayoutUnit totalLogicalWidth; |
| 1064 if (renderer().style()->direction() == LTR) { | 1064 if (renderer().style()->direction() == LTR) { |
| 1065 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLin
eBox()) | 1065 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLin
eBox()) |
| 1066 logicalOffsetOnLine += curr->logicalWidth(); | 1066 logicalOffsetOnLine += curr->logicalWidth(); |
| 1067 totalLogicalWidth = logicalOffsetOnLine; | 1067 totalLogicalWidth = logicalOffsetOnLine; |
| 1068 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) | 1068 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) |
| 1069 totalLogicalWidth += curr->logicalWidth(); | 1069 totalLogicalWidth += curr->logicalWidth(); |
| 1070 } else { | 1070 } else { |
| 1071 for (InlineFlowBox* curr = nextLineBox(); curr; curr = curr->nextLin
eBox()) | 1071 for (InlineFlowBox* curr = nextLineBox(); curr; curr = curr->nextLin
eBox()) |
| 1072 logicalOffsetOnLine += curr->logicalWidth(); | 1072 logicalOffsetOnLine += curr->logicalWidth(); |
| 1073 totalLogicalWidth = logicalOffsetOnLine; | 1073 totalLogicalWidth = logicalOffsetOnLine; |
| 1074 for (InlineFlowBox* curr = this; curr; curr = curr->prevLineBox()) | 1074 for (InlineFlowBox* curr = this; curr; curr = curr->prevLineBox()) |
| 1075 totalLogicalWidth += curr->logicalWidth(); | 1075 totalLogicalWidth += curr->logicalWidth(); |
| 1076 } | 1076 } |
| 1077 LayoutUnit stripX = rect.x() - logicalOffsetOnLine; | 1077 LayoutUnit stripX = rect.x() - logicalOffsetOnLine; |
| 1078 LayoutUnit stripY = rect.y(); | 1078 LayoutUnit stripY = rect.y(); |
| 1079 LayoutUnit stripWidth = totalLogicalWidth; | 1079 LayoutUnit stripWidth = totalLogicalWidth; |
| 1080 LayoutUnit stripHeight = static_cast<LayoutUnit>(height()); | 1080 LayoutUnit stripHeight = static_cast<LayoutUnit>(height()); |
| 1081 | 1081 |
| 1082 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 1082 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 1083 paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), width(), height()
)); | 1083 paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), width(), height()
)); |
| 1084 boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, Layout
Rect(stripX, stripY, stripWidth, stripHeight), BackgroundBleedNone, this, rect.s
ize(), op); | 1084 boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, Layout
Rect(stripX, stripY, stripWidth, stripHeight), BackgroundBleedNone, this, rect.s
ize()); |
| 1085 } | 1085 } |
| 1086 } | 1086 } |
| 1087 | 1087 |
| 1088 void InlineFlowBox::paintBoxShadow(const PaintInfo& info, RenderStyle* s, Shadow
Style shadowStyle, const LayoutRect& paintRect) | 1088 void InlineFlowBox::paintBoxShadow(const PaintInfo& info, RenderStyle* s, Shadow
Style shadowStyle, const LayoutRect& paintRect) |
| 1089 { | 1089 { |
| 1090 if ((!prevLineBox() && !nextLineBox()) || !parent()) | 1090 if ((!prevLineBox() && !nextLineBox()) || !parent()) |
| 1091 boxModelObject()->paintBoxShadow(info, paintRect, s, shadowStyle); | 1091 boxModelObject()->paintBoxShadow(info, paintRect, s, shadowStyle); |
| 1092 else { | 1092 else { |
| 1093 // FIXME: We can do better here in the multi-line case. We want to push
a clip so that the shadow doesn't | 1093 // FIXME: We can do better here in the multi-line case. We want to push
a clip so that the shadow doesn't |
| 1094 // protrude incorrectly at the edges, and we want to possibly include sh
adows cast from the previous/following lines | 1094 // protrude incorrectly at the edges, and we want to possibly include sh
adows cast from the previous/following lines |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 // Pixel snap mask painting. | 1196 // Pixel snap mask painting. |
| 1197 LayoutRect frameRect = roundedFrameRect(); | 1197 LayoutRect frameRect = roundedFrameRect(); |
| 1198 | 1198 |
| 1199 // Move x/y to our coordinates. | 1199 // Move x/y to our coordinates. |
| 1200 LayoutRect localRect(frameRect); | 1200 LayoutRect localRect(frameRect); |
| 1201 LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); | 1201 LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); |
| 1202 | 1202 |
| 1203 const NinePieceImage& maskNinePieceImage = renderer().style()->maskBoxImage(
); | 1203 const NinePieceImage& maskNinePieceImage = renderer().style()->maskBoxImage(
); |
| 1204 StyleImage* maskBoxImage = renderer().style()->maskBoxImage().image(); | 1204 StyleImage* maskBoxImage = renderer().style()->maskBoxImage().image(); |
| 1205 | 1205 |
| 1206 // Figure out if we need to push a transparency layer to render our mask. | |
| 1207 bool pushTransparencyLayer = false; | |
| 1208 bool flattenCompositingLayers = renderer().view()->frameView() && renderer()
.view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers; | |
| 1209 CompositeOperator compositeOp = CompositeSourceOver; | |
| 1210 if (flattenCompositingLayers) { | |
| 1211 if ((maskBoxImage && renderer().style()->maskLayers().hasImage()) || ren
derer().style()->maskLayers().next()) | |
| 1212 pushTransparencyLayer = true; | |
| 1213 | |
| 1214 compositeOp = CompositeDestinationIn; | |
| 1215 if (pushTransparencyLayer) { | |
| 1216 paintInfo.context->setCompositeOperation(CompositeDestinationIn); | |
| 1217 paintInfo.context->beginTransparencyLayer(1.0f); | |
| 1218 compositeOp = CompositeSourceOver; | |
| 1219 } | |
| 1220 } | |
| 1221 | |
| 1222 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); | 1206 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); |
| 1223 paintFillLayers(paintInfo, Color::transparent, renderer().style()->maskLayer
s(), paintRect, compositeOp); | 1207 paintFillLayers(paintInfo, Color::transparent, renderer().style()->maskLayer
s(), paintRect); |
| 1224 | 1208 |
| 1225 bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer()); | 1209 bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer()); |
| 1226 if (!hasBoxImage || !maskBoxImage->isLoaded()) { | 1210 if (!hasBoxImage || !maskBoxImage->isLoaded()) { |
| 1227 if (pushTransparencyLayer) | |
| 1228 paintInfo.context->endLayer(); | |
| 1229 return; // Don't paint anything while we wait for the image to load. | 1211 return; // Don't paint anything while we wait for the image to load. |
| 1230 } | 1212 } |
| 1231 | 1213 |
| 1232 // The simple case is where we are the only box for this object. In those | 1214 // The simple case is where we are the only box for this object. In those |
| 1233 // cases only a single call to draw is required. | 1215 // cases only a single call to draw is required. |
| 1234 if (!prevLineBox() && !nextLineBox()) { | 1216 if (!prevLineBox() && !nextLineBox()) { |
| 1235 boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(adju
stedPaintOffset, frameRect.size()), renderer().style(), maskNinePieceImage, comp
ositeOp); | 1217 boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(adju
stedPaintOffset, frameRect.size()), renderer().style(), maskNinePieceImage); |
| 1236 } else { | 1218 } else { |
| 1237 // We have a mask image that spans multiple lines. | 1219 // We have a mask image that spans multiple lines. |
| 1238 // We need to adjust _tx and _ty by the width of all previous lines. | 1220 // We need to adjust _tx and _ty by the width of all previous lines. |
| 1239 LayoutUnit logicalOffsetOnLine = 0; | 1221 LayoutUnit logicalOffsetOnLine = 0; |
| 1240 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox
()) | 1222 for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox
()) |
| 1241 logicalOffsetOnLine += curr->logicalWidth(); | 1223 logicalOffsetOnLine += curr->logicalWidth(); |
| 1242 LayoutUnit totalLogicalWidth = logicalOffsetOnLine; | 1224 LayoutUnit totalLogicalWidth = logicalOffsetOnLine; |
| 1243 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) | 1225 for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox()) |
| 1244 totalLogicalWidth += curr->logicalWidth(); | 1226 totalLogicalWidth += curr->logicalWidth(); |
| 1245 LayoutUnit stripX = adjustedPaintOffset.x() - logicalOffsetOnLine; | 1227 LayoutUnit stripX = adjustedPaintOffset.x() - logicalOffsetOnLine; |
| 1246 LayoutUnit stripY = adjustedPaintOffset.y(); | 1228 LayoutUnit stripY = adjustedPaintOffset.y(); |
| 1247 LayoutUnit stripWidth = totalLogicalWidth; | 1229 LayoutUnit stripWidth = totalLogicalWidth; |
| 1248 LayoutUnit stripHeight = frameRect.height(); | 1230 LayoutUnit stripHeight = frameRect.height(); |
| 1249 | 1231 |
| 1250 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, maskNinePiece
Image, paintRect); | 1232 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, maskNinePiece
Image, paintRect); |
| 1251 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 1233 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 1252 paintInfo.context->clip(clipRect); | 1234 paintInfo.context->clip(clipRect); |
| 1253 boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(stri
pX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage, co
mpositeOp); | 1235 boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(stri
pX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage); |
| 1254 } | 1236 } |
| 1255 | |
| 1256 if (pushTransparencyLayer) | |
| 1257 paintInfo.context->endLayer(); | |
| 1258 } | 1237 } |
| 1259 | 1238 |
| 1260 InlineBox* InlineFlowBox::firstLeafChild() const | 1239 InlineBox* InlineFlowBox::firstLeafChild() const |
| 1261 { | 1240 { |
| 1262 InlineBox* leaf = 0; | 1241 InlineBox* leaf = 0; |
| 1263 for (InlineBox* child = firstChild(); child && !leaf; child = child->nextOnL
ine()) | 1242 for (InlineBox* child = firstChild(); child && !leaf; child = child->nextOnL
ine()) |
| 1264 leaf = child->isLeaf() ? child : toInlineFlowBox(child)->firstLeafChild(
); | 1243 leaf = child->isLeaf() ? child : toInlineFlowBox(child)->firstLeafChild(
); |
| 1265 return leaf; | 1244 return leaf; |
| 1266 } | 1245 } |
| 1267 | 1246 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1446 ASSERT(child->prevOnLine() == prev); | 1425 ASSERT(child->prevOnLine() == prev); |
| 1447 prev = child; | 1426 prev = child; |
| 1448 } | 1427 } |
| 1449 ASSERT(prev == m_lastChild); | 1428 ASSERT(prev == m_lastChild); |
| 1450 #endif | 1429 #endif |
| 1451 } | 1430 } |
| 1452 | 1431 |
| 1453 #endif | 1432 #endif |
| 1454 | 1433 |
| 1455 } // namespace blink | 1434 } // namespace blink |
| OLD | NEW |