OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/paint/InlineFlowBoxPainter.h" | 5 #include "core/paint/InlineFlowBoxPainter.h" |
6 | 6 |
7 #include "core/layout/LayoutBlock.h" | 7 #include "core/layout/LayoutBlock.h" |
8 #include "core/layout/LayoutInline.h" | 8 #include "core/layout/LayoutInline.h" |
9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
10 #include "core/layout/api/LineLayoutAPIShim.h" | 10 #include "core/layout/api/LineLayoutAPIShim.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 | 40 |
41 if (paintInfo.phase == PaintPhaseForeground) { | 41 if (paintInfo.phase == PaintPhaseForeground) { |
42 // Paint our background, border and box-shadow. | 42 // Paint our background, border and box-shadow. |
43 paintBoxDecorationBackground(paintInfo, paintOffset, overflowRect); | 43 paintBoxDecorationBackground(paintInfo, paintOffset, overflowRect); |
44 } | 44 } |
45 | 45 |
46 // Paint our children. | 46 // Paint our children. |
47 PaintInfo childInfo(paintInfo); | 47 PaintInfo childInfo(paintInfo); |
48 for (InlineBox* curr = m_inlineFlowBox.firstChild(); curr; curr = curr->next
OnLine()) { | 48 for (InlineBox* curr = m_inlineFlowBox.firstChild(); curr; curr = curr->next
OnLine()) { |
49 if (curr->lineLayoutItem().isText() || !curr->boxModelObject().hasSelfPa
intingLayer()) | 49 if (curr->getLineLayoutItem().isText() || !curr->boxModelObject().hasSel
fPaintingLayer()) |
50 curr->paint(childInfo, paintOffset, lineTop, lineBottom); | 50 curr->paint(childInfo, paintOffset, lineTop, lineBottom); |
51 } | 51 } |
52 } | 52 } |
53 | 53 |
54 void InlineFlowBoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Col
or& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op) | 54 void InlineFlowBoxPainter::paintFillLayers(const PaintInfo& paintInfo, const Col
or& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op) |
55 { | 55 { |
56 // FIXME: This should be a for loop or similar. It's a little non-trivial to
do so, however, since the layers need to be | 56 // FIXME: This should be a for loop or similar. It's a little non-trivial to
do so, however, since the layers need to be |
57 // painted in reverse order. | 57 // painted in reverse order. |
58 if (fillLayer.next()) | 58 if (fillLayer.next()) |
59 paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op); | 59 paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op); |
60 paintFillLayer(paintInfo, c, fillLayer, rect, op); | 60 paintFillLayer(paintInfo, c, fillLayer, rect, op); |
61 } | 61 } |
62 | 62 |
63 void InlineFlowBoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Colo
r& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op) | 63 void InlineFlowBoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Colo
r& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op) |
64 { | 64 { |
65 LayoutBoxModelObject* boxModel = toLayoutBoxModelObject(LineLayoutAPIShim::l
ayoutObjectFrom(m_inlineFlowBox.boxModelObject())); | 65 LayoutBoxModelObject* boxModel = toLayoutBoxModelObject(LineLayoutAPIShim::l
ayoutObjectFrom(m_inlineFlowBox.boxModelObject())); |
66 StyleImage* img = fillLayer.image(); | 66 StyleImage* img = fillLayer.image(); |
67 bool hasFillImage = img && img->canRender(); | 67 bool hasFillImage = img && img->canRender(); |
68 if ((!hasFillImage && !m_inlineFlowBox.lineLayoutItem().style()->hasBorderRa
dius()) || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) ||
!m_inlineFlowBox.parent()) { | 68 if ((!hasFillImage && !m_inlineFlowBox.getLineLayoutItem().style()->hasBorde
rRadius()) || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox())
|| !m_inlineFlowBox.parent()) { |
69 BoxPainter::paintFillLayer(*boxModel, paintInfo, c, fillLayer, rect, Bac
kgroundBleedNone, &m_inlineFlowBox, rect.size(), op); | 69 BoxPainter::paintFillLayer(*boxModel, paintInfo, c, fillLayer, rect, Bac
kgroundBleedNone, &m_inlineFlowBox, rect.size(), op); |
70 } else if (m_inlineFlowBox.lineLayoutItem().style()->boxDecorationBreak() ==
DCLONE) { | 70 } else if (m_inlineFlowBox.getLineLayoutItem().style()->boxDecorationBreak()
== DCLONE) { |
71 GraphicsContextStateSaver stateSaver(paintInfo.context); | 71 GraphicsContextStateSaver stateSaver(paintInfo.context); |
72 paintInfo.context.clip(pixelSnappedIntRect(rect)); | 72 paintInfo.context.clip(pixelSnappedIntRect(rect)); |
73 BoxPainter::paintFillLayer(*boxModel, paintInfo, c, fillLayer, rect, Bac
kgroundBleedNone, &m_inlineFlowBox, rect.size(), op); | 73 BoxPainter::paintFillLayer(*boxModel, paintInfo, c, fillLayer, rect, Bac
kgroundBleedNone, &m_inlineFlowBox, rect.size(), op); |
74 } else { | 74 } else { |
75 // We have a fill image that spans multiple lines. | 75 // We have a fill image that spans multiple lines. |
76 // FIXME: frameSize ought to be the same as rect.size(). | 76 // FIXME: frameSize ought to be the same as rect.size(). |
77 LayoutSize frameSize(m_inlineFlowBox.width(), m_inlineFlowBox.height()); | 77 LayoutSize frameSize(m_inlineFlowBox.width(), m_inlineFlowBox.height()); |
78 LayoutRect imageStripPaintRect = paintRectForImageStrip(rect.location(),
frameSize, m_inlineFlowBox.lineLayoutItem().style()->direction()); | 78 LayoutRect imageStripPaintRect = paintRectForImageStrip(rect.location(),
frameSize, m_inlineFlowBox.getLineLayoutItem().style()->direction()); |
79 GraphicsContextStateSaver stateSaver(paintInfo.context); | 79 GraphicsContextStateSaver stateSaver(paintInfo.context); |
80 // TODO(chrishtr): this should likely be pixel-snapped. | 80 // TODO(chrishtr): this should likely be pixel-snapped. |
81 paintInfo.context.clip(pixelSnappedIntRect(rect)); | 81 paintInfo.context.clip(pixelSnappedIntRect(rect)); |
82 BoxPainter::paintFillLayer(*boxModel, paintInfo, c, fillLayer, imageStri
pPaintRect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); | 82 BoxPainter::paintFillLayer(*boxModel, paintInfo, c, fillLayer, imageStri
pPaintRect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 void InlineFlowBoxPainter::paintBoxShadow(const PaintInfo& info, const ComputedS
tyle& s, ShadowStyle shadowStyle, const LayoutRect& paintRect) | 86 void InlineFlowBoxPainter::paintBoxShadow(const PaintInfo& info, const ComputedS
tyle& s, ShadowStyle shadowStyle, const LayoutRect& paintRect) |
87 { | 87 { |
88 if ((!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !m
_inlineFlowBox.parent()) { | 88 if ((!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !m
_inlineFlowBox.parent()) { |
89 BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle); | 89 BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle); |
90 } else { | 90 } else { |
91 // FIXME: We can do better here in the multi-line case. We want to push
a clip so that the shadow doesn't | 91 // FIXME: We can do better here in the multi-line case. We want to push
a clip so that the shadow doesn't |
92 // protrude incorrectly at the edges, and we want to possibly include sh
adows cast from the previous/following lines | 92 // protrude incorrectly at the edges, and we want to possibly include sh
adows cast from the previous/following lines |
93 BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle, m_inlineFlow
Box.includeLogicalLeftEdge(), m_inlineFlowBox.includeLogicalRightEdge()); | 93 BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle, m_inlineFlow
Box.includeLogicalLeftEdge(), m_inlineFlowBox.includeLogicalRightEdge()); |
94 } | 94 } |
95 } | 95 } |
96 | 96 |
97 static LayoutRect clipRectForNinePieceImageStrip(const InlineFlowBox& box, const
NinePieceImage& image, const LayoutRect& paintRect) | 97 static LayoutRect clipRectForNinePieceImageStrip(const InlineFlowBox& box, const
NinePieceImage& image, const LayoutRect& paintRect) |
98 { | 98 { |
99 LayoutRect clipRect(paintRect); | 99 LayoutRect clipRect(paintRect); |
100 const ComputedStyle& style = box.lineLayoutItem().styleRef(); | 100 const ComputedStyle& style = box.getLineLayoutItem().styleRef(); |
101 LayoutRectOutsets outsets = style.imageOutsets(image); | 101 LayoutRectOutsets outsets = style.imageOutsets(image); |
102 if (box.isHorizontal()) { | 102 if (box.isHorizontal()) { |
103 clipRect.setY(paintRect.y() - outsets.top()); | 103 clipRect.setY(paintRect.y() - outsets.top()); |
104 clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom()
); | 104 clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom()
); |
105 if (box.includeLogicalLeftEdge()) { | 105 if (box.includeLogicalLeftEdge()) { |
106 clipRect.setX(paintRect.x() - outsets.left()); | 106 clipRect.setX(paintRect.x() - outsets.left()); |
107 clipRect.setWidth(paintRect.width() + outsets.left()); | 107 clipRect.setWidth(paintRect.width() + outsets.left()); |
108 } | 108 } |
109 if (box.includeLogicalRightEdge()) | 109 if (box.includeLogicalRightEdge()) |
110 clipRect.setWidth(clipRect.width() + outsets.right()); | 110 clipRect.setWidth(clipRect.width() + outsets.right()); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 LayoutUnit stripY = paintOffset.y() - (m_inlineFlowBox.isHorizontal() ? Layo
utUnit() : logicalOffsetOnLine); | 148 LayoutUnit stripY = paintOffset.y() - (m_inlineFlowBox.isHorizontal() ? Layo
utUnit() : logicalOffsetOnLine); |
149 LayoutUnit stripWidth = m_inlineFlowBox.isHorizontal() ? totalLogicalWidth :
frameSize.width(); | 149 LayoutUnit stripWidth = m_inlineFlowBox.isHorizontal() ? totalLogicalWidth :
frameSize.width(); |
150 LayoutUnit stripHeight = m_inlineFlowBox.isHorizontal() ? frameSize.height()
: totalLogicalWidth; | 150 LayoutUnit stripHeight = m_inlineFlowBox.isHorizontal() ? frameSize.height()
: totalLogicalWidth; |
151 return LayoutRect(stripX, stripY, stripWidth, stripHeight); | 151 return LayoutRect(stripX, stripY, stripWidth, stripHeight); |
152 } | 152 } |
153 | 153 |
154 | 154 |
155 InlineFlowBoxPainter::BorderPaintingType InlineFlowBoxPainter::getBorderPaintTyp
e(const LayoutRect& adjustedFrameRect, IntRect& adjustedClipRect) const | 155 InlineFlowBoxPainter::BorderPaintingType InlineFlowBoxPainter::getBorderPaintTyp
e(const LayoutRect& adjustedFrameRect, IntRect& adjustedClipRect) const |
156 { | 156 { |
157 adjustedClipRect = pixelSnappedIntRect(adjustedFrameRect); | 157 adjustedClipRect = pixelSnappedIntRect(adjustedFrameRect); |
158 if (m_inlineFlowBox.parent() && m_inlineFlowBox.lineLayoutItem().style()->ha
sBorderDecoration()) { | 158 if (m_inlineFlowBox.parent() && m_inlineFlowBox.getLineLayoutItem().style()-
>hasBorderDecoration()) { |
159 const NinePieceImage& borderImage = m_inlineFlowBox.lineLayoutItem().sty
le()->borderImage(); | 159 const NinePieceImage& borderImage = m_inlineFlowBox.getLineLayoutItem().
style()->borderImage(); |
160 StyleImage* borderImageSource = borderImage.image(); | 160 StyleImage* borderImageSource = borderImage.image(); |
161 bool hasBorderImage = borderImageSource && borderImageSource->canRender(
); | 161 bool hasBorderImage = borderImageSource && borderImageSource->canRender(
); |
162 if (hasBorderImage && !borderImageSource->isLoaded()) | 162 if (hasBorderImage && !borderImageSource->isLoaded()) |
163 return DontPaintBorders; | 163 return DontPaintBorders; |
164 | 164 |
165 // The simple case is where we either have no border image or we are the
only box for this object. | 165 // The simple case is where we either have no border image or we are the
only box for this object. |
166 // In those cases only a single call to draw is required. | 166 // In those cases only a single call to draw is required. |
167 if (!hasBorderImage || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowB
ox.nextLineBox())) | 167 if (!hasBorderImage || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowB
ox.nextLineBox())) |
168 return PaintBordersWithoutClip; | 168 return PaintBordersWithoutClip; |
169 | 169 |
170 // We have a border image that spans multiple lines. | 170 // We have a border image that spans multiple lines. |
171 adjustedClipRect = pixelSnappedIntRect(clipRectForNinePieceImageStrip(m_
inlineFlowBox, borderImage, adjustedFrameRect)); | 171 adjustedClipRect = pixelSnappedIntRect(clipRectForNinePieceImageStrip(m_
inlineFlowBox, borderImage, adjustedFrameRect)); |
172 return PaintBordersWithClip; | 172 return PaintBordersWithClip; |
173 } | 173 } |
174 return DontPaintBorders; | 174 return DontPaintBorders; |
175 } | 175 } |
176 | 176 |
177 void InlineFlowBoxPainter::paintBoxDecorationBackground(const PaintInfo& paintIn
fo, const LayoutPoint& paintOffset, const LayoutRect& cullRect) | 177 void InlineFlowBoxPainter::paintBoxDecorationBackground(const PaintInfo& paintIn
fo, const LayoutPoint& paintOffset, const LayoutRect& cullRect) |
178 { | 178 { |
179 ASSERT(paintInfo.phase == PaintPhaseForeground); | 179 ASSERT(paintInfo.phase == PaintPhaseForeground); |
180 if (m_inlineFlowBox.lineLayoutItem().style()->visibility() != VISIBLE) | 180 if (m_inlineFlowBox.getLineLayoutItem().style()->visibility() != VISIBLE) |
181 return; | 181 return; |
182 | 182 |
183 // You can use p::first-line to specify a background. If so, the root line b
oxes for | 183 // You can use p::first-line to specify a background. If so, the root line b
oxes for |
184 // a line may actually have to paint a background. | 184 // a line may actually have to paint a background. |
185 LayoutObject* inlineFlowBoxLayoutObject = LineLayoutAPIShim::layoutObjectFro
m(m_inlineFlowBox.lineLayoutItem()); | 185 LayoutObject* inlineFlowBoxLayoutObject = LineLayoutAPIShim::layoutObjectFro
m(m_inlineFlowBox.getLineLayoutItem()); |
186 const ComputedStyle* styleToUse = m_inlineFlowBox.lineLayoutItem().style(m_i
nlineFlowBox.isFirstLineStyle()); | 186 const ComputedStyle* styleToUse = m_inlineFlowBox.getLineLayoutItem().style(
m_inlineFlowBox.isFirstLineStyle()); |
187 bool shouldPaintBoxDecorationBackground; | 187 bool shouldPaintBoxDecorationBackground; |
188 if (m_inlineFlowBox.parent()) | 188 if (m_inlineFlowBox.parent()) |
189 shouldPaintBoxDecorationBackground = inlineFlowBoxLayoutObject->hasBoxDe
corationBackground(); | 189 shouldPaintBoxDecorationBackground = inlineFlowBoxLayoutObject->hasBoxDe
corationBackground(); |
190 else | 190 else |
191 shouldPaintBoxDecorationBackground = m_inlineFlowBox.isFirstLineStyle()
&& styleToUse != m_inlineFlowBox.lineLayoutItem().style(); | 191 shouldPaintBoxDecorationBackground = m_inlineFlowBox.isFirstLineStyle()
&& styleToUse != m_inlineFlowBox.getLineLayoutItem().style(); |
192 | 192 |
193 if (!shouldPaintBoxDecorationBackground) | 193 if (!shouldPaintBoxDecorationBackground) |
194 return; | 194 return; |
195 | 195 |
196 if (DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_inlineF
lowBox, DisplayItem::BoxDecorationBackground)) | 196 if (DrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_inlineF
lowBox, DisplayItem::BoxDecorationBackground)) |
197 return; | 197 return; |
198 | 198 |
199 DrawingRecorder recorder(paintInfo.context, m_inlineFlowBox, DisplayItem::Bo
xDecorationBackground, pixelSnappedIntRect(cullRect)); | 199 DrawingRecorder recorder(paintInfo.context, m_inlineFlowBox, DisplayItem::Bo
xDecorationBackground, pixelSnappedIntRect(cullRect)); |
200 | 200 |
201 LayoutRect frameRect = frameRectClampedToLineTopAndBottomIfNeeded(); | 201 LayoutRect frameRect = frameRectClampedToLineTopAndBottomIfNeeded(); |
(...skipping 13 matching lines...) Expand all Loading... |
215 paintBoxShadow(paintInfo, *styleToUse, Normal, adjustedFrameRect); | 215 paintBoxShadow(paintInfo, *styleToUse, Normal, adjustedFrameRect); |
216 | 216 |
217 Color backgroundColor = inlineFlowBoxLayoutObject->resolveColor(*styleToUse,
CSSPropertyBackgroundColor); | 217 Color backgroundColor = inlineFlowBoxLayoutObject->resolveColor(*styleToUse,
CSSPropertyBackgroundColor); |
218 paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(),
adjustedFrameRect); | 218 paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(),
adjustedFrameRect); |
219 paintBoxShadow(paintInfo, *styleToUse, Inset, adjustedFrameRect); | 219 paintBoxShadow(paintInfo, *styleToUse, Inset, adjustedFrameRect); |
220 | 220 |
221 switch (borderPaintingType) { | 221 switch (borderPaintingType) { |
222 case DontPaintBorders: | 222 case DontPaintBorders: |
223 break; | 223 break; |
224 case PaintBordersWithoutClip: | 224 case PaintBordersWithoutClip: |
225 BoxPainter::paintBorder(*toLayoutBoxModelObject(LineLayoutAPIShim::layou
tObjectFrom(m_inlineFlowBox.boxModelObject())), paintInfo, adjustedFrameRect, m_
inlineFlowBox.lineLayoutItem().styleRef(m_inlineFlowBox.isFirstLineStyle()), Bac
kgroundBleedNone, m_inlineFlowBox.includeLogicalLeftEdge(), m_inlineFlowBox.incl
udeLogicalRightEdge()); | 225 BoxPainter::paintBorder(*toLayoutBoxModelObject(LineLayoutAPIShim::layou
tObjectFrom(m_inlineFlowBox.boxModelObject())), paintInfo, adjustedFrameRect, m_
inlineFlowBox.getLineLayoutItem().styleRef(m_inlineFlowBox.isFirstLineStyle()),
BackgroundBleedNone, m_inlineFlowBox.includeLogicalLeftEdge(), m_inlineFlowBox.i
ncludeLogicalRightEdge()); |
226 break; | 226 break; |
227 case PaintBordersWithClip: | 227 case PaintBordersWithClip: |
228 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, | 228 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, |
229 // but it isn't even clear how this should work at all. | 229 // but it isn't even clear how this should work at all. |
230 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); | 230 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); |
231 GraphicsContextStateSaver stateSaver(paintInfo.context); | 231 GraphicsContextStateSaver stateSaver(paintInfo.context); |
232 paintInfo.context.clip(adjustedClipRect); | 232 paintInfo.context.clip(adjustedClipRect); |
233 BoxPainter::paintBorder(*toLayoutBoxModelObject(LineLayoutAPIShim::layou
tObjectFrom(m_inlineFlowBox.boxModelObject())), paintInfo, imageStripPaintRect,
m_inlineFlowBox.lineLayoutItem().styleRef(m_inlineFlowBox.isFirstLineStyle())); | 233 BoxPainter::paintBorder(*toLayoutBoxModelObject(LineLayoutAPIShim::layou
tObjectFrom(m_inlineFlowBox.boxModelObject())), paintInfo, imageStripPaintRect,
m_inlineFlowBox.getLineLayoutItem().styleRef(m_inlineFlowBox.isFirstLineStyle())
); |
234 break; | 234 break; |
235 } | 235 } |
236 } | 236 } |
237 | 237 |
238 void InlineFlowBoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoi
nt& paintOffset) | 238 void InlineFlowBoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoi
nt& paintOffset) |
239 { | 239 { |
240 if (m_inlineFlowBox.lineLayoutItem().style()->visibility() != VISIBLE || pai
ntInfo.phase != PaintPhaseMask) | 240 if (m_inlineFlowBox.getLineLayoutItem().style()->visibility() != VISIBLE ||
paintInfo.phase != PaintPhaseMask) |
241 return; | 241 return; |
242 | 242 |
243 LayoutRect frameRect = frameRectClampedToLineTopAndBottomIfNeeded(); | 243 LayoutRect frameRect = frameRectClampedToLineTopAndBottomIfNeeded(); |
244 | 244 |
245 // Move x/y to our coordinates. | 245 // Move x/y to our coordinates. |
246 LayoutRect localRect(frameRect); | 246 LayoutRect localRect(frameRect); |
247 m_inlineFlowBox.flipForWritingMode(localRect); | 247 m_inlineFlowBox.flipForWritingMode(localRect); |
248 LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); | 248 LayoutPoint adjustedPaintOffset = paintOffset + localRect.location(); |
249 | 249 |
250 const NinePieceImage& maskNinePieceImage = m_inlineFlowBox.lineLayoutItem().
style()->maskBoxImage(); | 250 const NinePieceImage& maskNinePieceImage = m_inlineFlowBox.getLineLayoutItem
().style()->maskBoxImage(); |
251 StyleImage* maskBoxImage = m_inlineFlowBox.lineLayoutItem().style()->maskBox
Image().image(); | 251 StyleImage* maskBoxImage = m_inlineFlowBox.getLineLayoutItem().style()->mask
BoxImage().image(); |
252 | 252 |
253 // Figure out if we need to push a transparency layer to render our mask. | 253 // Figure out if we need to push a transparency layer to render our mask. |
254 bool pushTransparencyLayer = false; | 254 bool pushTransparencyLayer = false; |
255 bool compositedMask = m_inlineFlowBox.lineLayoutItem().hasLayer() && m_inlin
eFlowBox.boxModelObject().layer()->hasCompositedMask(); | 255 bool compositedMask = m_inlineFlowBox.getLineLayoutItem().hasLayer() && m_in
lineFlowBox.boxModelObject().layer()->hasCompositedMask(); |
256 bool flattenCompositingLayers = paintInfo.globalPaintFlags() & GlobalPaintFl
attenCompositingLayers; | 256 bool flattenCompositingLayers = paintInfo.globalPaintFlags() & GlobalPaintFl
attenCompositingLayers; |
257 SkXfermode::Mode compositeOp = SkXfermode::kSrcOver_Mode; | 257 SkXfermode::Mode compositeOp = SkXfermode::kSrcOver_Mode; |
258 if (!compositedMask || flattenCompositingLayers) { | 258 if (!compositedMask || flattenCompositingLayers) { |
259 if ((maskBoxImage && m_inlineFlowBox.lineLayoutItem().style()->maskLayer
s().hasImage()) || m_inlineFlowBox.lineLayoutItem().style()->maskLayers().next()
) { | 259 if ((maskBoxImage && m_inlineFlowBox.getLineLayoutItem().style()->maskLa
yers().hasImage()) || m_inlineFlowBox.getLineLayoutItem().style()->maskLayers().
next()) { |
260 pushTransparencyLayer = true; | 260 pushTransparencyLayer = true; |
261 paintInfo.context.beginLayer(1.0f, SkXfermode::kDstIn_Mode); | 261 paintInfo.context.beginLayer(1.0f, SkXfermode::kDstIn_Mode); |
262 } else { | 262 } else { |
263 // TODO(fmalita): passing a dst-in xfer mode down to paintFillLayers
/paintNinePieceImage | 263 // TODO(fmalita): passing a dst-in xfer mode down to paintFillLayers
/paintNinePieceImage |
264 // seems dangerous: it is only correct if applied atomically (sing
le draw call). While | 264 // seems dangerous: it is only correct if applied atomically (sing
le draw call). While |
265 // the heuristic above presumably ensures that is the case, this a
pproach seems super | 265 // the heuristic above presumably ensures that is the case, this a
pproach seems super |
266 // fragile. We should investigate dropping this optimization in fa
vour of the more | 266 // fragile. We should investigate dropping this optimization in fa
vour of the more |
267 // robust layer branch above. | 267 // robust layer branch above. |
268 compositeOp = SkXfermode::kDstIn_Mode; | 268 compositeOp = SkXfermode::kDstIn_Mode; |
269 } | 269 } |
270 } | 270 } |
271 | 271 |
272 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); | 272 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); |
273 paintFillLayers(paintInfo, Color::transparent, m_inlineFlowBox.lineLayoutIte
m().style()->maskLayers(), paintRect, compositeOp); | 273 paintFillLayers(paintInfo, Color::transparent, m_inlineFlowBox.getLineLayout
Item().style()->maskLayers(), paintRect, compositeOp); |
274 | 274 |
275 bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(); | 275 bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(); |
276 if (!hasBoxImage || !maskBoxImage->isLoaded()) { | 276 if (!hasBoxImage || !maskBoxImage->isLoaded()) { |
277 if (pushTransparencyLayer) | 277 if (pushTransparencyLayer) |
278 paintInfo.context.endLayer(); | 278 paintInfo.context.endLayer(); |
279 return; // Don't paint anything while we wait for the image to load. | 279 return; // Don't paint anything while we wait for the image to load. |
280 } | 280 } |
281 | 281 |
282 LayoutBoxModelObject* boxModel = toLayoutBoxModelObject(LineLayoutAPIShim::l
ayoutObjectFrom(m_inlineFlowBox.boxModelObject())); | 282 LayoutBoxModelObject* boxModel = toLayoutBoxModelObject(LineLayoutAPIShim::l
ayoutObjectFrom(m_inlineFlowBox.boxModelObject())); |
283 // The simple case is where we are the only box for this object. In those | 283 // The simple case is where we are the only box for this object. In those |
284 // cases only a single call to draw is required. | 284 // cases only a single call to draw is required. |
285 if (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) { | 285 if (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) { |
286 BoxPainter::paintNinePieceImage(*boxModel, paintInfo.context, paintRect,
m_inlineFlowBox.lineLayoutItem().styleRef(), maskNinePieceImage, compositeOp); | 286 BoxPainter::paintNinePieceImage(*boxModel, paintInfo.context, paintRect,
m_inlineFlowBox.getLineLayoutItem().styleRef(), maskNinePieceImage, compositeOp
); |
287 } else { | 287 } else { |
288 // We have a mask image that spans multiple lines. | 288 // We have a mask image that spans multiple lines. |
289 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, | 289 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, |
290 // but it isn't even clear how this should work at all. | 290 // but it isn't even clear how this should work at all. |
291 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); | 291 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); |
292 FloatRect clipRect(clipRectForNinePieceImageStrip(m_inlineFlowBox, maskN
inePieceImage, paintRect)); | 292 FloatRect clipRect(clipRectForNinePieceImageStrip(m_inlineFlowBox, maskN
inePieceImage, paintRect)); |
293 GraphicsContextStateSaver stateSaver(paintInfo.context); | 293 GraphicsContextStateSaver stateSaver(paintInfo.context); |
294 // TODO(chrishtr): this should be pixel-snapped. | 294 // TODO(chrishtr): this should be pixel-snapped. |
295 paintInfo.context.clip(clipRect); | 295 paintInfo.context.clip(clipRect); |
296 BoxPainter::paintNinePieceImage(*boxModel, paintInfo.context, imageStrip
PaintRect, m_inlineFlowBox.lineLayoutItem().styleRef(), maskNinePieceImage, comp
ositeOp); | 296 BoxPainter::paintNinePieceImage(*boxModel, paintInfo.context, imageStrip
PaintRect, m_inlineFlowBox.getLineLayoutItem().styleRef(), maskNinePieceImage, c
ompositeOp); |
297 } | 297 } |
298 | 298 |
299 if (pushTransparencyLayer) | 299 if (pushTransparencyLayer) |
300 paintInfo.context.endLayer(); | 300 paintInfo.context.endLayer(); |
301 } | 301 } |
302 | 302 |
303 // This method should not be needed. See crbug.com/530659. | 303 // This method should not be needed. See crbug.com/530659. |
304 LayoutRect InlineFlowBoxPainter::frameRectClampedToLineTopAndBottomIfNeeded() co
nst | 304 LayoutRect InlineFlowBoxPainter::frameRectClampedToLineTopAndBottomIfNeeded() co
nst |
305 { | 305 { |
306 LayoutRect rect(m_inlineFlowBox.frameRect()); | 306 LayoutRect rect(m_inlineFlowBox.frameRect()); |
307 | 307 |
308 bool noQuirksMode = m_inlineFlowBox.lineLayoutItem().document().inNoQuirksMo
de(); | 308 bool noQuirksMode = m_inlineFlowBox.getLineLayoutItem().document().inNoQuirk
sMode(); |
309 if (!noQuirksMode && !m_inlineFlowBox.hasTextChildren() && !(m_inlineFlowBox
.descendantsHaveSameLineHeightAndBaseline() && m_inlineFlowBox.hasTextDescendant
s())) { | 309 if (!noQuirksMode && !m_inlineFlowBox.hasTextChildren() && !(m_inlineFlowBox
.descendantsHaveSameLineHeightAndBaseline() && m_inlineFlowBox.hasTextDescendant
s())) { |
310 const RootInlineBox& rootBox = m_inlineFlowBox.root(); | 310 const RootInlineBox& rootBox = m_inlineFlowBox.root(); |
311 LayoutUnit logicalTop = m_inlineFlowBox.isHorizontal() ? rect.y() : rect
.x(); | 311 LayoutUnit logicalTop = m_inlineFlowBox.isHorizontal() ? rect.y() : rect
.x(); |
312 LayoutUnit logicalHeight = m_inlineFlowBox.isHorizontal() ? rect.height(
) : rect.width(); | 312 LayoutUnit logicalHeight = m_inlineFlowBox.isHorizontal() ? rect.height(
) : rect.width(); |
313 LayoutUnit bottom = std::min(rootBox.lineBottom(), logicalTop + logicalH
eight); | 313 LayoutUnit bottom = std::min(rootBox.lineBottom(), logicalTop + logicalH
eight); |
314 logicalTop = std::max(rootBox.lineTop(), logicalTop); | 314 logicalTop = std::max(rootBox.lineTop(), logicalTop); |
315 logicalHeight = bottom - logicalTop; | 315 logicalHeight = bottom - logicalTop; |
316 if (m_inlineFlowBox.isHorizontal()) { | 316 if (m_inlineFlowBox.isHorizontal()) { |
317 rect.setY(logicalTop); | 317 rect.setY(logicalTop); |
318 rect.setHeight(logicalHeight); | 318 rect.setHeight(logicalHeight); |
319 } else { | 319 } else { |
320 rect.setX(logicalTop); | 320 rect.setX(logicalTop); |
321 rect.setWidth(logicalHeight); | 321 rect.setWidth(logicalHeight); |
322 } | 322 } |
323 } | 323 } |
324 return rect; | 324 return rect; |
325 } | 325 } |
326 | 326 |
327 } // namespace blink | 327 } // namespace blink |
OLD | NEW |