| 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/SVGInlineTextBoxPainter.h" | 6 #include "core/paint/SVGInlineTextBoxPainter.h" |
| 7 | 7 |
| 8 #include "core/dom/DocumentMarkerController.h" | 8 #include "core/dom/DocumentMarkerController.h" |
| 9 #include "core/dom/RenderedDocumentMarker.h" | 9 #include "core/dom/RenderedDocumentMarker.h" |
| 10 #include "core/editing/Editor.h" | 10 #include "core/editing/Editor.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 // If we ever need that for SVG, it's very easy to refactor and reuse the co
de. | 49 // If we ever need that for SVG, it's very easy to refactor and reuse the co
de. |
| 50 | 50 |
| 51 if (paintInfo.phase == PaintPhaseSelection && !shouldPaintSelection()) | 51 if (paintInfo.phase == PaintPhaseSelection && !shouldPaintSelection()) |
| 52 return; | 52 return; |
| 53 | 53 |
| 54 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); | 54 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); |
| 55 if (!textShouldBePainted(textRenderer)) | 55 if (!textShouldBePainted(textRenderer)) |
| 56 return; | 56 return; |
| 57 | 57 |
| 58 LayoutObject& parentRenderer = m_svgInlineTextBox.parent()->layoutObject(); | 58 LayoutObject& parentRenderer = m_svgInlineTextBox.parent()->layoutObject(); |
| 59 const LayoutStyle& style = parentRenderer.styleRef(); | 59 const ComputedStyle& style = parentRenderer.styleRef(); |
| 60 | 60 |
| 61 { | 61 { |
| 62 DrawingRecorder recorder(paintInfo.context, m_svgInlineTextBox, DisplayI
tem::paintPhaseToDrawingType(paintInfo.phase), paintInfo.rect); | 62 DrawingRecorder recorder(paintInfo.context, m_svgInlineTextBox, DisplayI
tem::paintPhaseToDrawingType(paintInfo.phase), paintInfo.rect); |
| 63 if (!recorder.canUseCachedDrawing()) { | 63 if (!recorder.canUseCachedDrawing()) { |
| 64 InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers( | 64 InlineTextBoxPainter(m_svgInlineTextBox).paintDocumentMarkers( |
| 65 paintInfo.context, FloatPoint(paintOffset), style, | 65 paintInfo.context, FloatPoint(paintOffset), style, |
| 66 textRenderer.scaledFont(), true); | 66 textRenderer.scaledFont(), true); |
| 67 | 67 |
| 68 if (!m_svgInlineTextBox.textFragments().isEmpty()) | 68 if (!m_svgInlineTextBox.textFragments().isEmpty()) |
| 69 paintTextFragments(paintInfo, parentRenderer); | 69 paintTextFragments(paintInfo, parentRenderer); |
| 70 } | 70 } |
| 71 } | 71 } |
| 72 | 72 |
| 73 if (style.hasOutline() && parentRenderer.isLayoutInline()) | 73 if (style.hasOutline() && parentRenderer.isLayoutInline()) |
| 74 InlinePainter(toLayoutInline(parentRenderer)).paintOutline(paintInfo, pa
intOffset); | 74 InlinePainter(toLayoutInline(parentRenderer)).paintOutline(paintInfo, pa
intOffset); |
| 75 } | 75 } |
| 76 | 76 |
| 77 void SVGInlineTextBoxPainter::paintTextFragments(const PaintInfo& paintInfo, Lay
outObject& parentRenderer) | 77 void SVGInlineTextBoxPainter::paintTextFragments(const PaintInfo& paintInfo, Lay
outObject& parentRenderer) |
| 78 { | 78 { |
| 79 const LayoutStyle& style = parentRenderer.styleRef(); | 79 const ComputedStyle& style = parentRenderer.styleRef(); |
| 80 const SVGLayoutStyle& svgStyle = style.svgStyle(); | 80 const SVGComputedStyle& svgStyle = style.svgStyle(); |
| 81 | 81 |
| 82 bool hasFill = svgStyle.hasFill(); | 82 bool hasFill = svgStyle.hasFill(); |
| 83 bool hasVisibleStroke = svgStyle.hasVisibleStroke(); | 83 bool hasVisibleStroke = svgStyle.hasVisibleStroke(); |
| 84 | 84 |
| 85 const LayoutStyle* selectionStyle = &style; | 85 const ComputedStyle* selectionStyle = &style; |
| 86 bool shouldPaintSelection = this->shouldPaintSelection(); | 86 bool shouldPaintSelection = this->shouldPaintSelection(); |
| 87 if (shouldPaintSelection) { | 87 if (shouldPaintSelection) { |
| 88 selectionStyle = parentRenderer.getCachedPseudoStyle(SELECTION); | 88 selectionStyle = parentRenderer.getCachedPseudoStyle(SELECTION); |
| 89 if (selectionStyle) { | 89 if (selectionStyle) { |
| 90 const SVGLayoutStyle& svgSelectionStyle = selectionStyle->svgStyle()
; | 90 const SVGComputedStyle& svgSelectionStyle = selectionStyle->svgStyle
(); |
| 91 | 91 |
| 92 if (!hasFill) | 92 if (!hasFill) |
| 93 hasFill = svgSelectionStyle.hasFill(); | 93 hasFill = svgSelectionStyle.hasFill(); |
| 94 if (!hasVisibleStroke) | 94 if (!hasVisibleStroke) |
| 95 hasVisibleStroke = svgSelectionStyle.hasVisibleStroke(); | 95 hasVisibleStroke = svgSelectionStyle.hasVisibleStroke(); |
| 96 } else { | 96 } else { |
| 97 selectionStyle = &style; | 97 selectionStyle = &style; |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 | 100 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 return; | 158 return; |
| 159 | 159 |
| 160 Color backgroundColor = m_svgInlineTextBox.layoutObject().selectionBackgroun
dColor(); | 160 Color backgroundColor = m_svgInlineTextBox.layoutObject().selectionBackgroun
dColor(); |
| 161 if (!backgroundColor.alpha()) | 161 if (!backgroundColor.alpha()) |
| 162 return; | 162 return; |
| 163 | 163 |
| 164 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); | 164 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); |
| 165 if (!textShouldBePainted(textRenderer)) | 165 if (!textShouldBePainted(textRenderer)) |
| 166 return; | 166 return; |
| 167 | 167 |
| 168 const LayoutStyle& style = m_svgInlineTextBox.parent()->layoutObject().style
Ref(); | 168 const ComputedStyle& style = m_svgInlineTextBox.parent()->layoutObject().sty
leRef(); |
| 169 | 169 |
| 170 int startPosition, endPosition; | 170 int startPosition, endPosition; |
| 171 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); | 171 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); |
| 172 | 172 |
| 173 int fragmentStartPosition = 0; | 173 int fragmentStartPosition = 0; |
| 174 int fragmentEndPosition = 0; | 174 int fragmentEndPosition = 0; |
| 175 AffineTransform fragmentTransform; | 175 AffineTransform fragmentTransform; |
| 176 unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); | 176 unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); |
| 177 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 177 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 178 SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at(i); | 178 SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at(i); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 void SVGInlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, TextDe
coration decoration, const SVGTextFragment& fragment) | 235 void SVGInlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, TextDe
coration decoration, const SVGTextFragment& fragment) |
| 236 { | 236 { |
| 237 if (m_svgInlineTextBox.layoutObject().style()->textDecorationsInEffect() ==
TextDecorationNone) | 237 if (m_svgInlineTextBox.layoutObject().style()->textDecorationsInEffect() ==
TextDecorationNone) |
| 238 return; | 238 return; |
| 239 | 239 |
| 240 if (fragment.width <= 0) | 240 if (fragment.width <= 0) |
| 241 return; | 241 return; |
| 242 | 242 |
| 243 // Find out which render style defined the text-decoration, as its fill/stro
ke properties have to be used for drawing instead of ours. | 243 // Find out which render style defined the text-decoration, as its fill/stro
ke properties have to be used for drawing instead of ours. |
| 244 LayoutObject* decorationRenderer = findLayoutObjectDefininingTextDecoration(
m_svgInlineTextBox.parent()); | 244 LayoutObject* decorationRenderer = findLayoutObjectDefininingTextDecoration(
m_svgInlineTextBox.parent()); |
| 245 const LayoutStyle& decorationStyle = decorationRenderer->styleRef(); | 245 const ComputedStyle& decorationStyle = decorationRenderer->styleRef(); |
| 246 | 246 |
| 247 if (decorationStyle.visibility() == HIDDEN) | 247 if (decorationStyle.visibility() == HIDDEN) |
| 248 return; | 248 return; |
| 249 | 249 |
| 250 float scalingFactor = 1; | 250 float scalingFactor = 1; |
| 251 Font scaledFont; | 251 Font scaledFont; |
| 252 LayoutSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, &decor
ationStyle, scalingFactor, scaledFont); | 252 LayoutSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, &decor
ationStyle, scalingFactor, scaledFont); |
| 253 ASSERT(scalingFactor); | 253 ASSERT(scalingFactor); |
| 254 | 254 |
| 255 float thickness = thicknessForDecoration(decoration, scaledFont); | 255 float thickness = thicknessForDecoration(decoration, scaledFont); |
| 256 if (thickness <= 0) | 256 if (thickness <= 0) |
| 257 return; | 257 return; |
| 258 | 258 |
| 259 float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.
fontMetrics(), thickness); | 259 float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.
fontMetrics(), thickness); |
| 260 FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal
ingFactor); | 260 FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal
ingFactor); |
| 261 | 261 |
| 262 Path path; | 262 Path path; |
| 263 path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness
/ scalingFactor))); | 263 path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness
/ scalingFactor))); |
| 264 | 264 |
| 265 const SVGLayoutStyle& svgDecorationStyle = decorationStyle.svgStyle(); | 265 const SVGComputedStyle& svgDecorationStyle = decorationStyle.svgStyle(); |
| 266 | 266 |
| 267 for (int i = 0; i < 3; i++) { | 267 for (int i = 0; i < 3; i++) { |
| 268 switch (svgDecorationStyle.paintOrderType(i)) { | 268 switch (svgDecorationStyle.paintOrderType(i)) { |
| 269 case PT_FILL: | 269 case PT_FILL: |
| 270 if (svgDecorationStyle.hasFill()) { | 270 if (svgDecorationStyle.hasFill()) { |
| 271 GraphicsContextStateSaver stateSaver(*paintInfo.context, false); | 271 GraphicsContextStateSaver stateSaver(*paintInfo.context, false); |
| 272 if (!SVGLayoutSupport::updateGraphicsContext(paintInfo, stateSav
er, decorationStyle, *decorationRenderer, ApplyToFillMode)) | 272 if (!SVGLayoutSupport::updateGraphicsContext(paintInfo, stateSav
er, decorationStyle, *decorationRenderer, ApplyToFillMode)) |
| 273 break; | 273 break; |
| 274 paintInfo.context->fillPath(path); | 274 paintInfo.context->fillPath(path); |
| 275 } | 275 } |
| 276 break; | 276 break; |
| 277 case PT_STROKE: | 277 case PT_STROKE: |
| 278 if (svgDecorationStyle.hasVisibleStroke()) { | 278 if (svgDecorationStyle.hasVisibleStroke()) { |
| 279 // FIXME: Non-scaling stroke is not applied here. | 279 // FIXME: Non-scaling stroke is not applied here. |
| 280 GraphicsContextStateSaver stateSaver(*paintInfo.context, false); | 280 GraphicsContextStateSaver stateSaver(*paintInfo.context, false); |
| 281 if (!SVGLayoutSupport::updateGraphicsContext(paintInfo, stateSav
er, decorationStyle, *decorationRenderer, ApplyToStrokeMode)) | 281 if (!SVGLayoutSupport::updateGraphicsContext(paintInfo, stateSav
er, decorationStyle, *decorationRenderer, ApplyToStrokeMode)) |
| 282 break; | 282 break; |
| 283 paintInfo.context->strokePath(path); | 283 paintInfo.context->strokePath(path); |
| 284 } | 284 } |
| 285 break; | 285 break; |
| 286 case PT_MARKERS: | 286 case PT_MARKERS: |
| 287 break; | 287 break; |
| 288 default: | 288 default: |
| 289 ASSERT_NOT_REACHED(); | 289 ASSERT_NOT_REACHED(); |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 | 293 |
| 294 void SVGInlineTextBoxPainter::paintTextWithShadows(const PaintInfo& paintInfo, c
onst LayoutStyle& style, | 294 void SVGInlineTextBoxPainter::paintTextWithShadows(const PaintInfo& paintInfo, c
onst ComputedStyle& style, |
| 295 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, | 295 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, |
| 296 LayoutSVGResourceMode resourceMode) | 296 LayoutSVGResourceMode resourceMode) |
| 297 { | 297 { |
| 298 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); | 298 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); |
| 299 | 299 |
| 300 float scalingFactor = textRenderer.scalingFactor(); | 300 float scalingFactor = textRenderer.scalingFactor(); |
| 301 ASSERT(scalingFactor); | 301 ASSERT(scalingFactor); |
| 302 | 302 |
| 303 const Font& scaledFont = textRenderer.scaledFont(); | 303 const Font& scaledFont = textRenderer.scaledFont(); |
| 304 const ShadowList* shadowList = style.textShadow(); | 304 const ShadowList* shadowList = style.textShadow(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 textRunPaintInfo.from = startPosition; | 342 textRunPaintInfo.from = startPosition; |
| 343 textRunPaintInfo.to = endPosition; | 343 textRunPaintInfo.to = endPosition; |
| 344 | 344 |
| 345 float baseline = scaledFont.fontMetrics().floatAscent(); | 345 float baseline = scaledFont.fontMetrics().floatAscent(); |
| 346 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baselin
e, | 346 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baselin
e, |
| 347 textSize.width(), textSize.height()); | 347 textSize.width(), textSize.height()); |
| 348 | 348 |
| 349 context->drawText(scaledFont, textRunPaintInfo, textOrigin); | 349 context->drawText(scaledFont, textRunPaintInfo, textOrigin); |
| 350 } | 350 } |
| 351 | 351 |
| 352 void SVGInlineTextBoxPainter::paintText(const PaintInfo& paintInfo, const Layout
Style& style, | 352 void SVGInlineTextBoxPainter::paintText(const PaintInfo& paintInfo, const Comput
edStyle& style, |
| 353 const LayoutStyle& selectionStyle, const SVGTextFragment& fragment, | 353 const ComputedStyle& selectionStyle, const SVGTextFragment& fragment, |
| 354 LayoutSVGResourceMode resourceMode, bool shouldPaintSelection) | 354 LayoutSVGResourceMode resourceMode, bool shouldPaintSelection) |
| 355 { | 355 { |
| 356 int startPosition = 0; | 356 int startPosition = 0; |
| 357 int endPosition = 0; | 357 int endPosition = 0; |
| 358 if (shouldPaintSelection) { | 358 if (shouldPaintSelection) { |
| 359 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); | 359 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); |
| 360 shouldPaintSelection = m_svgInlineTextBox.mapStartEndPositionsIntoFragme
ntCoordinates(fragment, startPosition, endPosition); | 360 shouldPaintSelection = m_svgInlineTextBox.mapStartEndPositionsIntoFragme
ntCoordinates(fragment, startPosition, endPosition); |
| 361 } | 361 } |
| 362 | 362 |
| 363 // Fast path if there is no selection, just draw the whole chunk part using
the regular style | 363 // Fast path if there is no selection, just draw the whole chunk part using
the regular style |
| (...skipping 21 matching lines...) Expand all Loading... |
| 385 StyleDifference diff; | 385 StyleDifference diff; |
| 386 diff.setNeedsPaintInvalidationObject(); | 386 diff.setNeedsPaintInvalidationObject(); |
| 387 SVGResourcesCache::clientStyleChanged(&m_svgInlineTextBox.parent()->layo
utObject(), diff, style); | 387 SVGResourcesCache::clientStyleChanged(&m_svgInlineTextBox.parent()->layo
utObject(), diff, style); |
| 388 } | 388 } |
| 389 | 389 |
| 390 // Eventually draw text using regular style from the end position of the sel
ection to the end of the current chunk part | 390 // Eventually draw text using regular style from the end position of the sel
ection to the end of the current chunk part |
| 391 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl
y) | 391 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl
y) |
| 392 paintTextWithShadows(paintInfo, style, textRun, fragment, endPosition, f
ragment.length, resourceMode); | 392 paintTextWithShadows(paintInfo, style, textRun, fragment, endPosition, f
ragment.length, resourceMode); |
| 393 } | 393 } |
| 394 | 394 |
| 395 void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* context, con
st FloatPoint&, DocumentMarker* marker, const LayoutStyle& style, const Font& fo
nt) | 395 void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext* context, con
st FloatPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font&
font) |
| 396 { | 396 { |
| 397 // SVG is only interested in the TextMatch markers. | 397 // SVG is only interested in the TextMatch markers. |
| 398 if (marker->type() != DocumentMarker::TextMatch) | 398 if (marker->type() != DocumentMarker::TextMatch) |
| 399 return; | 399 return; |
| 400 | 400 |
| 401 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); | 401 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(m_svgInlineTextBox
.layoutObject()); |
| 402 | 402 |
| 403 FloatRect markerRect; | 403 FloatRect markerRect; |
| 404 AffineTransform fragmentTransform; | 404 AffineTransform fragmentTransform; |
| 405 for (InlineTextBox* box = textRenderer.firstTextBox(); box; box = box->nextT
extBox()) { | 405 for (InlineTextBox* box = textRenderer.firstTextBox(); box; box = box->nextT
extBox()) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 | 441 |
| 442 fragmentRect = fragmentTransform.mapRect(fragmentRect); | 442 fragmentRect = fragmentTransform.mapRect(fragmentRect); |
| 443 markerRect.unite(fragmentRect); | 443 markerRect.unite(fragmentRect); |
| 444 } | 444 } |
| 445 } | 445 } |
| 446 | 446 |
| 447 toRenderedDocumentMarker(marker)->setRenderedRect(LayoutRect(textRenderer.lo
calToAbsoluteQuad(markerRect).enclosingBoundingBox())); | 447 toRenderedDocumentMarker(marker)->setRenderedRect(LayoutRect(textRenderer.lo
calToAbsoluteQuad(markerRect).enclosingBoundingBox())); |
| 448 } | 448 } |
| 449 | 449 |
| 450 } // namespace blink | 450 } // namespace blink |
| OLD | NEW |