| 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 "config.h" | 5 #include "config.h" |
| 6 #include "core/paint/InlineFlowBoxPainter.h" | 6 #include "core/paint/InlineFlowBoxPainter.h" |
| 7 | 7 |
| 8 #include "core/layout/LayoutBlock.h" | 8 #include "core/layout/LayoutBlock.h" |
| 9 #include "core/layout/LayoutInline.h" | 9 #include "core/layout/LayoutInline.h" |
| 10 #include "core/layout/LayoutView.h" | 10 #include "core/layout/LayoutView.h" |
| 11 #include "core/layout/api/LineLayoutBoxModel.h" | 11 #include "core/layout/api/LineLayoutBoxModel.h" |
| 12 #include "core/layout/api/SelectionState.h" | 12 #include "core/layout/api/SelectionState.h" |
| 13 #include "core/layout/line/InlineFlowBox.h" | 13 #include "core/layout/line/InlineFlowBox.h" |
| 14 #include "core/paint/BoxPainter.h" | 14 #include "core/paint/BoxPainter.h" |
| 15 #include "core/paint/DeprecatedPaintLayer.h" | 15 #include "core/paint/DeprecatedPaintLayer.h" |
| 16 #include "core/paint/LineLayoutPaintShim.h" |
| 16 #include "core/paint/PaintInfo.h" | 17 #include "core/paint/PaintInfo.h" |
| 17 #include "platform/graphics/GraphicsContextStateSaver.h" | 18 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 18 #include "platform/graphics/paint/DrawingRecorder.h" | 19 #include "platform/graphics/paint/DrawingRecorder.h" |
| 19 | 20 |
| 20 namespace blink { | 21 namespace blink { |
| 21 | 22 |
| 22 void InlineFlowBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint&
paintOffset, const LayoutUnit lineTop, const LayoutUnit lineBottom) | 23 void InlineFlowBoxPainter::paint(const PaintInfo& paintInfo, const LayoutPoint&
paintOffset, const LayoutUnit lineTop, const LayoutUnit lineBottom) |
| 23 { | 24 { |
| 24 LayoutRect overflowRect(m_inlineFlowBox.visualOverflowRect(lineTop, lineBott
om)); | 25 LayoutRect overflowRect(m_inlineFlowBox.visualOverflowRect(lineTop, lineBott
om)); |
| 25 m_inlineFlowBox.flipForWritingMode(overflowRect); | 26 m_inlineFlowBox.flipForWritingMode(overflowRect); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 { | 96 { |
| 96 // 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 | 97 // 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 |
| 97 // painted in reverse order. | 98 // painted in reverse order. |
| 98 if (fillLayer.next()) | 99 if (fillLayer.next()) |
| 99 paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op); | 100 paintFillLayers(paintInfo, c, *fillLayer.next(), rect, op); |
| 100 paintFillLayer(paintInfo, c, fillLayer, rect, op); | 101 paintFillLayer(paintInfo, c, fillLayer, rect, op); |
| 101 } | 102 } |
| 102 | 103 |
| 103 void InlineFlowBoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Colo
r& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op) | 104 void InlineFlowBoxPainter::paintFillLayer(const PaintInfo& paintInfo, const Colo
r& c, const FillLayer& fillLayer, const LayoutRect& rect, SkXfermode::Mode op) |
| 104 { | 105 { |
| 106 LayoutBoxModelObject* boxModel = toLayoutBoxModelObject(LineLayoutPaintShim:
:layoutObjectFrom(m_inlineFlowBox.boxModelObject())); |
| 105 StyleImage* img = fillLayer.image(); | 107 StyleImage* img = fillLayer.image(); |
| 106 bool hasFillImage = img && img->canRender(m_inlineFlowBox.layoutObject(), m_
inlineFlowBox.layoutObject().style()->effectiveZoom()); | 108 bool hasFillImage = img && img->canRender(m_inlineFlowBox.layoutObject(), m_
inlineFlowBox.layoutObject().style()->effectiveZoom()); |
| 107 if ((!hasFillImage && !m_inlineFlowBox.layoutObject().style()->hasBorderRadi
us()) || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !
m_inlineFlowBox.parent()) { | 109 if ((!hasFillImage && !m_inlineFlowBox.layoutObject().style()->hasBorderRadi
us()) || (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !
m_inlineFlowBox.parent()) { |
| 108 BoxPainter::paintFillLayerExtended(*m_inlineFlowBox.deprecatedBoxModelOb
ject(), paintInfo, c, fillLayer, rect, BackgroundBleedNone, &m_inlineFlowBox, re
ct.size(), op); | 110 BoxPainter::paintFillLayerExtended(*boxModel, paintInfo, c, fillLayer, r
ect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); |
| 109 } else if (m_inlineFlowBox.layoutObject().style()->boxDecorationBreak() == D
CLONE) { | 111 } else if (m_inlineFlowBox.layoutObject().style()->boxDecorationBreak() == D
CLONE) { |
| 110 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 112 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 111 // TODO(chrishtr): this should be pixel-snapped. | 113 // TODO(chrishtr): this should be pixel-snapped. |
| 112 paintInfo.context->clip(FloatRect(LayoutRect(rect.x(), rect.y(), m_inlin
eFlowBox.width(), m_inlineFlowBox.height()))); | 114 paintInfo.context->clip(FloatRect(LayoutRect(rect.x(), rect.y(), m_inlin
eFlowBox.width(), m_inlineFlowBox.height()))); |
| 113 BoxPainter::paintFillLayerExtended(*m_inlineFlowBox.deprecatedBoxModelOb
ject(), paintInfo, c, fillLayer, rect, BackgroundBleedNone, &m_inlineFlowBox, re
ct.size(), op); | 115 BoxPainter::paintFillLayerExtended(*boxModel, paintInfo, c, fillLayer, r
ect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); |
| 114 } else { | 116 } else { |
| 115 // We have a fill image that spans multiple lines. | 117 // We have a fill image that spans multiple lines. |
| 116 // FIXME: frameSize ought to be the same as rect.size(). | 118 // FIXME: frameSize ought to be the same as rect.size(). |
| 117 LayoutSize frameSize(m_inlineFlowBox.width(), m_inlineFlowBox.height()); | 119 LayoutSize frameSize(m_inlineFlowBox.width(), m_inlineFlowBox.height()); |
| 118 LayoutRect imageStripPaintRect = paintRectForImageStrip(rect.location(),
frameSize, m_inlineFlowBox.layoutObject().style()->direction()); | 120 LayoutRect imageStripPaintRect = paintRectForImageStrip(rect.location(),
frameSize, m_inlineFlowBox.layoutObject().style()->direction()); |
| 119 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 121 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 120 paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), m_inlineFlowBox.w
idth(), m_inlineFlowBox.height())); | 122 paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), m_inlineFlowBox.w
idth(), m_inlineFlowBox.height())); |
| 121 BoxPainter::paintFillLayerExtended(*m_inlineFlowBox.deprecatedBoxModelOb
ject(), paintInfo, c, fillLayer, imageStripPaintRect, BackgroundBleedNone, &m_in
lineFlowBox, rect.size(), op); | 123 BoxPainter::paintFillLayerExtended(*boxModel, paintInfo, c, fillLayer, i
mageStripPaintRect, BackgroundBleedNone, &m_inlineFlowBox, rect.size(), op); |
| 122 } | 124 } |
| 123 } | 125 } |
| 124 | 126 |
| 125 void InlineFlowBoxPainter::paintBoxShadow(const PaintInfo& info, const ComputedS
tyle& s, ShadowStyle shadowStyle, const LayoutRect& paintRect) | 127 void InlineFlowBoxPainter::paintBoxShadow(const PaintInfo& info, const ComputedS
tyle& s, ShadowStyle shadowStyle, const LayoutRect& paintRect) |
| 126 { | 128 { |
| 127 if ((!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !m
_inlineFlowBox.parent()) { | 129 if ((!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) || !m
_inlineFlowBox.parent()) { |
| 128 BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle); | 130 BoxPainter::paintBoxShadow(info, paintRect, s, shadowStyle); |
| 129 } else { | 131 } else { |
| 130 // FIXME: We can do better here in the multi-line case. We want to push
a clip so that the shadow doesn't | 132 // FIXME: We can do better here in the multi-line case. We want to push
a clip so that the shadow doesn't |
| 131 // protrude incorrectly at the edges, and we want to possibly include sh
adows cast from the previous/following lines | 133 // protrude incorrectly at the edges, and we want to possibly include sh
adows cast from the previous/following lines |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 paintBoxShadow(paintInfo, *styleToUse, Normal, adjustedFrameRect); | 257 paintBoxShadow(paintInfo, *styleToUse, Normal, adjustedFrameRect); |
| 256 | 258 |
| 257 Color backgroundColor = m_inlineFlowBox.layoutObject().resolveColor(*styleTo
Use, CSSPropertyBackgroundColor); | 259 Color backgroundColor = m_inlineFlowBox.layoutObject().resolveColor(*styleTo
Use, CSSPropertyBackgroundColor); |
| 258 paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(),
adjustedFrameRect); | 260 paintFillLayers(paintInfo, backgroundColor, styleToUse->backgroundLayers(),
adjustedFrameRect); |
| 259 paintBoxShadow(paintInfo, *styleToUse, Inset, adjustedFrameRect); | 261 paintBoxShadow(paintInfo, *styleToUse, Inset, adjustedFrameRect); |
| 260 | 262 |
| 261 switch (borderPaintingType) { | 263 switch (borderPaintingType) { |
| 262 case DontPaintBorders: | 264 case DontPaintBorders: |
| 263 break; | 265 break; |
| 264 case PaintBordersWithoutClip: | 266 case PaintBordersWithoutClip: |
| 265 BoxPainter::paintBorder(*m_inlineFlowBox.deprecatedBoxModelObject(), pai
ntInfo, adjustedFrameRect, m_inlineFlowBox.layoutObject().styleRef(m_inlineFlowB
ox.isFirstLineStyle()), | 267 BoxPainter::paintBorder(*toLayoutBoxModelObject(LineLayoutPaintShim::lay
outObjectFrom(m_inlineFlowBox.boxModelObject())), paintInfo, adjustedFrameRect,
m_inlineFlowBox.layoutObject().styleRef(m_inlineFlowBox.isFirstLineStyle()), Bac
kgroundBleedNone, m_inlineFlowBox.includeLogicalLeftEdge(), m_inlineFlowBox.incl
udeLogicalRightEdge()); |
| 266 BackgroundBleedNone, m_inlineFlowBox.includeLogicalLeftEdge(), m_inl
ineFlowBox.includeLogicalRightEdge()); | |
| 267 break; | 268 break; |
| 268 case PaintBordersWithClip: | 269 case PaintBordersWithClip: |
| 269 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, | 270 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, |
| 270 // but it isn't even clear how this should work at all. | 271 // but it isn't even clear how this should work at all. |
| 271 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); | 272 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); |
| 272 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 273 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 273 // TODO(chrishtr): this should be pixel-snapped. | 274 // TODO(chrishtr): this should be pixel-snapped. |
| 274 paintInfo.context->clip(FloatRect(adjustedClipRect)); | 275 paintInfo.context->clip(FloatRect(adjustedClipRect)); |
| 275 BoxPainter::paintBorder(*m_inlineFlowBox.deprecatedBoxModelObject(), pai
ntInfo, imageStripPaintRect, m_inlineFlowBox.layoutObject().styleRef(m_inlineFlo
wBox.isFirstLineStyle())); | 276 BoxPainter::paintBorder(*toLayoutBoxModelObject(LineLayoutPaintShim::lay
outObjectFrom(m_inlineFlowBox.boxModelObject())), paintInfo, imageStripPaintRect
, m_inlineFlowBox.layoutObject().styleRef(m_inlineFlowBox.isFirstLineStyle())); |
| 276 break; | 277 break; |
| 277 } | 278 } |
| 278 } | 279 } |
| 279 | 280 |
| 280 void InlineFlowBoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoi
nt& paintOffset) | 281 void InlineFlowBoxPainter::paintMask(const PaintInfo& paintInfo, const LayoutPoi
nt& paintOffset) |
| 281 { | 282 { |
| 282 if (!paintInfo.shouldPaintWithinRoot(&m_inlineFlowBox.layoutObject()) || m_i
nlineFlowBox.layoutObject().style()->visibility() != VISIBLE || paintInfo.phase
!= PaintPhaseMask) | 283 if (!paintInfo.shouldPaintWithinRoot(&m_inlineFlowBox.layoutObject()) || m_i
nlineFlowBox.layoutObject().style()->visibility() != VISIBLE || paintInfo.phase
!= PaintPhaseMask) |
| 283 return; | 284 return; |
| 284 | 285 |
| 285 LayoutRect frameRect = roundedFrameRectClampedToLineTopAndBottomIfNeeded(); | 286 LayoutRect frameRect = roundedFrameRectClampedToLineTopAndBottomIfNeeded(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 314 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); | 315 LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size()); |
| 315 paintFillLayers(paintInfo, Color::transparent, m_inlineFlowBox.layoutObject(
).style()->maskLayers(), paintRect, compositeOp); | 316 paintFillLayers(paintInfo, Color::transparent, m_inlineFlowBox.layoutObject(
).style()->maskLayers(), paintRect, compositeOp); |
| 316 | 317 |
| 317 bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(m_inlineFlowBox.l
ayoutObject(), m_inlineFlowBox.layoutObject().style()->effectiveZoom()); | 318 bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(m_inlineFlowBox.l
ayoutObject(), m_inlineFlowBox.layoutObject().style()->effectiveZoom()); |
| 318 if (!hasBoxImage || !maskBoxImage->isLoaded()) { | 319 if (!hasBoxImage || !maskBoxImage->isLoaded()) { |
| 319 if (pushTransparencyLayer) | 320 if (pushTransparencyLayer) |
| 320 paintInfo.context->endLayer(); | 321 paintInfo.context->endLayer(); |
| 321 return; // Don't paint anything while we wait for the image to load. | 322 return; // Don't paint anything while we wait for the image to load. |
| 322 } | 323 } |
| 323 | 324 |
| 325 LayoutBoxModelObject* boxModel = toLayoutBoxModelObject(LineLayoutPaintShim:
:layoutObjectFrom(m_inlineFlowBox.boxModelObject())); |
| 324 // The simple case is where we are the only box for this object. In those | 326 // The simple case is where we are the only box for this object. In those |
| 325 // cases only a single call to draw is required. | 327 // cases only a single call to draw is required. |
| 326 if (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) { | 328 if (!m_inlineFlowBox.prevLineBox() && !m_inlineFlowBox.nextLineBox()) { |
| 327 BoxPainter::paintNinePieceImage(*m_inlineFlowBox.deprecatedBoxModelObjec
t(), paintInfo.context, paintRect, m_inlineFlowBox.layoutObject().styleRef(), ma
skNinePieceImage, compositeOp); | 329 BoxPainter::paintNinePieceImage(*boxModel, paintInfo.context, paintRect,
m_inlineFlowBox.layoutObject().styleRef(), maskNinePieceImage, compositeOp); |
| 328 } else { | 330 } else { |
| 329 // We have a mask image that spans multiple lines. | 331 // We have a mask image that spans multiple lines. |
| 330 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, | 332 // FIXME: What the heck do we do with RTL here? The math we're using is
obviously not right, |
| 331 // but it isn't even clear how this should work at all. | 333 // but it isn't even clear how this should work at all. |
| 332 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); | 334 LayoutRect imageStripPaintRect = paintRectForImageStrip(adjustedPaintOff
set, frameRect.size(), LTR); |
| 333 FloatRect clipRect(clipRectForNinePieceImageStrip(&m_inlineFlowBox, mask
NinePieceImage, paintRect)); | 335 FloatRect clipRect(clipRectForNinePieceImageStrip(&m_inlineFlowBox, mask
NinePieceImage, paintRect)); |
| 334 GraphicsContextStateSaver stateSaver(*paintInfo.context); | 336 GraphicsContextStateSaver stateSaver(*paintInfo.context); |
| 335 // TODO(chrishtr): this should be pixel-snapped. | 337 // TODO(chrishtr): this should be pixel-snapped. |
| 336 paintInfo.context->clip(clipRect); | 338 paintInfo.context->clip(clipRect); |
| 337 BoxPainter::paintNinePieceImage(*m_inlineFlowBox.deprecatedBoxModelObjec
t(), paintInfo.context, imageStripPaintRect, m_inlineFlowBox.layoutObject().styl
eRef(), maskNinePieceImage, compositeOp); | 339 BoxPainter::paintNinePieceImage(*boxModel, paintInfo.context, imageStrip
PaintRect, m_inlineFlowBox.layoutObject().styleRef(), maskNinePieceImage, compos
iteOp); |
| 338 } | 340 } |
| 339 | 341 |
| 340 if (pushTransparencyLayer) | 342 if (pushTransparencyLayer) |
| 341 paintInfo.context->endLayer(); | 343 paintInfo.context->endLayer(); |
| 342 } | 344 } |
| 343 | 345 |
| 344 LayoutRect InlineFlowBoxPainter::roundedFrameRectClampedToLineTopAndBottomIfNeed
ed() const | 346 LayoutRect InlineFlowBoxPainter::roundedFrameRectClampedToLineTopAndBottomIfNeed
ed() const |
| 345 { | 347 { |
| 346 // Pixel snap rect painting. | 348 // Pixel snap rect painting. |
| 347 LayoutRect rect(m_inlineFlowBox.roundedFrameRect()); | 349 LayoutRect rect(m_inlineFlowBox.roundedFrameRect()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 359 rect.setHeight(logicalHeight); | 361 rect.setHeight(logicalHeight); |
| 360 } else { | 362 } else { |
| 361 rect.setX(logicalTop); | 363 rect.setX(logicalTop); |
| 362 rect.setWidth(logicalHeight); | 364 rect.setWidth(logicalHeight); |
| 363 } | 365 } |
| 364 } | 366 } |
| 365 return rect; | 367 return rect; |
| 366 } | 368 } |
| 367 | 369 |
| 368 } // namespace blink | 370 } // namespace blink |
| OLD | NEW |