| 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/SVGInlineTextBoxPainter.h" | 5 #include "core/paint/SVGInlineTextBoxPainter.h" |
| 6 | 6 |
| 7 #include "core/editing/Editor.h" | 7 #include "core/editing/Editor.h" |
| 8 #include "core/editing/markers/DocumentMarkerController.h" | 8 #include "core/editing/markers/DocumentMarkerController.h" |
| 9 #include "core/editing/markers/RenderedDocumentMarker.h" | 9 #include "core/editing/markers/RenderedDocumentMarker.h" |
| 10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "core/paint/PaintInfo.h" | 22 #include "core/paint/PaintInfo.h" |
| 23 #include "core/paint/SVGPaintContext.h" | 23 #include "core/paint/SVGPaintContext.h" |
| 24 #include "core/style/ShadowList.h" | 24 #include "core/style/ShadowList.h" |
| 25 #include "platform/graphics/GraphicsContextStateSaver.h" | 25 #include "platform/graphics/GraphicsContextStateSaver.h" |
| 26 #include <memory> | 26 #include <memory> |
| 27 | 27 |
| 28 namespace blink { | 28 namespace blink { |
| 29 | 29 |
| 30 static inline bool textShouldBePainted( | 30 static inline bool textShouldBePainted( |
| 31 const LayoutSVGInlineText& textLayoutObject) { | 31 const LayoutSVGInlineText& textLayoutObject) { |
| 32 // Font::pixelSize(), returns FontDescription::computedPixelSize(), which retu
rns "int(x + 0.5)". | 32 // Font::pixelSize(), returns FontDescription::computedPixelSize(), which |
| 33 // If the absolute font size on screen is below x=0.5, don't render anything. | 33 // returns "int(x + 0.5)". If the absolute font size on screen is below |
| 34 // x=0.5, don't render anything. |
| 34 return textLayoutObject.scaledFont().getFontDescription().computedPixelSize(); | 35 return textLayoutObject.scaledFont().getFontDescription().computedPixelSize(); |
| 35 } | 36 } |
| 36 | 37 |
| 37 bool SVGInlineTextBoxPainter::shouldPaintSelection( | 38 bool SVGInlineTextBoxPainter::shouldPaintSelection( |
| 38 const PaintInfo& paintInfo) const { | 39 const PaintInfo& paintInfo) const { |
| 39 return !paintInfo.isPrinting() && | 40 return !paintInfo.isPrinting() && |
| 40 m_svgInlineTextBox.getSelectionState() != SelectionNone; | 41 m_svgInlineTextBox.getSelectionState() != SelectionNone; |
| 41 } | 42 } |
| 42 | 43 |
| 43 static bool hasShadow(const PaintInfo& paintInfo, const ComputedStyle& style) { | 44 static bool hasShadow(const PaintInfo& paintInfo, const ComputedStyle& style) { |
| 44 // Text shadows are disabled when printing. http://crbug.com/258321 | 45 // Text shadows are disabled when printing. http://crbug.com/258321 |
| 45 return style.textShadow() && !paintInfo.isPrinting(); | 46 return style.textShadow() && !paintInfo.isPrinting(); |
| 46 } | 47 } |
| 47 | 48 |
| 48 FloatRect SVGInlineTextBoxPainter::boundsForDrawingRecorder( | 49 FloatRect SVGInlineTextBoxPainter::boundsForDrawingRecorder( |
| 49 const PaintInfo& paintInfo, | 50 const PaintInfo& paintInfo, |
| 50 const ComputedStyle& style, | 51 const ComputedStyle& style, |
| 51 const LayoutPoint& paintOffset, | 52 const LayoutPoint& paintOffset, |
| 52 bool includeSelectionRect) const { | 53 bool includeSelectionRect) const { |
| 53 // We compute the paint rect with what looks like the logical values, to match
the | 54 // We compute the paint rect with what looks like the logical values, to match |
| 54 // computation in SVGInlineTextBox::calculateBoundaries, and the fact that ver
tical (etc) | 55 // the computation in SVGInlineTextBox::calculateBoundaries, and the fact that |
| 55 // layouts are handled by SVGTextLayoutEngine. | 56 // vertical (etc) layouts are handled by SVGTextLayoutEngine. |
| 56 LayoutRect bounds(LayoutPoint(m_svgInlineTextBox.topLeft() + paintOffset), | 57 LayoutRect bounds(LayoutPoint(m_svgInlineTextBox.topLeft() + paintOffset), |
| 57 LayoutSize(m_svgInlineTextBox.logicalWidth(), | 58 LayoutSize(m_svgInlineTextBox.logicalWidth(), |
| 58 m_svgInlineTextBox.logicalHeight())); | 59 m_svgInlineTextBox.logicalHeight())); |
| 59 if (hasShadow(paintInfo, style)) | 60 if (hasShadow(paintInfo, style)) |
| 60 bounds.expand(style.textShadow()->rectOutsetsIncludingOriginal()); | 61 bounds.expand(style.textShadow()->rectOutsetsIncludingOriginal()); |
| 61 if (includeSelectionRect) { | 62 if (includeSelectionRect) { |
| 62 bounds.unite(m_svgInlineTextBox.localSelectionRect( | 63 bounds.unite(m_svgInlineTextBox.localSelectionRect( |
| 63 m_svgInlineTextBox.start(), | 64 m_svgInlineTextBox.start(), |
| 64 m_svgInlineTextBox.start() + m_svgInlineTextBox.len())); | 65 m_svgInlineTextBox.start() + m_svgInlineTextBox.len())); |
| 65 } | 66 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 84 const LayoutPoint& paintOffset) { | 85 const LayoutPoint& paintOffset) { |
| 85 ASSERT(paintInfo.phase == PaintPhaseForeground || | 86 ASSERT(paintInfo.phase == PaintPhaseForeground || |
| 86 paintInfo.phase == PaintPhaseSelection); | 87 paintInfo.phase == PaintPhaseSelection); |
| 87 ASSERT(m_svgInlineTextBox.truncation() == cNoTruncation); | 88 ASSERT(m_svgInlineTextBox.truncation() == cNoTruncation); |
| 88 | 89 |
| 89 if (m_svgInlineTextBox.getLineLayoutItem().style()->visibility() != | 90 if (m_svgInlineTextBox.getLineLayoutItem().style()->visibility() != |
| 90 EVisibility::Visible || | 91 EVisibility::Visible || |
| 91 !m_svgInlineTextBox.len()) | 92 !m_svgInlineTextBox.len()) |
| 92 return; | 93 return; |
| 93 | 94 |
| 94 // We're explicitly not supporting composition & custom underlines and custom
highlighters -- unlike InlineTextBox. | 95 // We're explicitly not supporting composition & custom underlines and custom |
| 95 // If we ever need that for SVG, it's very easy to refactor and reuse the code
. | 96 // highlighters -- unlike InlineTextBox. If we ever need that for SVG, it's |
| 97 // very easy to refactor and reuse the code. |
| 96 | 98 |
| 97 bool haveSelection = shouldPaintSelection(paintInfo); | 99 bool haveSelection = shouldPaintSelection(paintInfo); |
| 98 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) | 100 if (!haveSelection && paintInfo.phase == PaintPhaseSelection) |
| 99 return; | 101 return; |
| 100 | 102 |
| 101 LayoutSVGInlineText& textLayoutObject = inlineText(); | 103 LayoutSVGInlineText& textLayoutObject = inlineText(); |
| 102 if (!textShouldBePainted(textLayoutObject)) | 104 if (!textShouldBePainted(textLayoutObject)) |
| 103 return; | 105 return; |
| 104 | 106 |
| 105 DisplayItem::Type displayItemType = | 107 DisplayItem::Type displayItemType = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); | 166 unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); |
| 165 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 167 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 166 const SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at(i); | 168 const SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at(i); |
| 167 | 169 |
| 168 GraphicsContextStateSaver stateSaver(paintInfo.context, false); | 170 GraphicsContextStateSaver stateSaver(paintInfo.context, false); |
| 169 if (fragment.isTransformed()) { | 171 if (fragment.isTransformed()) { |
| 170 stateSaver.save(); | 172 stateSaver.save(); |
| 171 paintInfo.context.concatCTM(fragment.buildFragmentTransform()); | 173 paintInfo.context.concatCTM(fragment.buildFragmentTransform()); |
| 172 } | 174 } |
| 173 | 175 |
| 174 // Spec: All text decorations except line-through should be drawn before the
text is filled and stroked; thus, the text is rendered on top of these decorati
ons. | 176 // Spec: All text decorations except line-through should be drawn before the |
| 177 // text is filled and stroked; thus, the text is rendered on top of these |
| 178 // decorations. |
| 175 unsigned decorations = style.textDecorationsInEffect(); | 179 unsigned decorations = style.textDecorationsInEffect(); |
| 176 if (decorations & TextDecorationUnderline) | 180 if (decorations & TextDecorationUnderline) |
| 177 paintDecoration(paintInfo, TextDecorationUnderline, fragment); | 181 paintDecoration(paintInfo, TextDecorationUnderline, fragment); |
| 178 if (decorations & TextDecorationOverline) | 182 if (decorations & TextDecorationOverline) |
| 179 paintDecoration(paintInfo, TextDecorationOverline, fragment); | 183 paintDecoration(paintInfo, TextDecorationOverline, fragment); |
| 180 | 184 |
| 181 for (int i = 0; i < 3; i++) { | 185 for (int i = 0; i < 3; i++) { |
| 182 switch (svgStyle.paintOrderType(i)) { | 186 switch (svgStyle.paintOrderType(i)) { |
| 183 case PT_FILL: | 187 case PT_FILL: |
| 184 if (hasFill) | 188 if (hasFill) |
| 185 paintText(paintInfo, style, *selectionStyle, fragment, | 189 paintText(paintInfo, style, *selectionStyle, fragment, |
| 186 ApplyToFillMode, shouldPaintSelection); | 190 ApplyToFillMode, shouldPaintSelection); |
| 187 break; | 191 break; |
| 188 case PT_STROKE: | 192 case PT_STROKE: |
| 189 if (hasVisibleStroke) | 193 if (hasVisibleStroke) |
| 190 paintText(paintInfo, style, *selectionStyle, fragment, | 194 paintText(paintInfo, style, *selectionStyle, fragment, |
| 191 ApplyToStrokeMode, shouldPaintSelection); | 195 ApplyToStrokeMode, shouldPaintSelection); |
| 192 break; | 196 break; |
| 193 case PT_MARKERS: | 197 case PT_MARKERS: |
| 194 // Markers don't apply to text | 198 // Markers don't apply to text |
| 195 break; | 199 break; |
| 196 default: | 200 default: |
| 197 ASSERT_NOT_REACHED(); | 201 ASSERT_NOT_REACHED(); |
| 198 break; | 202 break; |
| 199 } | 203 } |
| 200 } | 204 } |
| 201 | 205 |
| 202 // Spec: Line-through should be drawn after the text is filled and stroked;
thus, the line-through is rendered on top of the text. | 206 // Spec: Line-through should be drawn after the text is filled and stroked; |
| 207 // thus, the line-through is rendered on top of the text. |
| 203 if (decorations & TextDecorationLineThrough) | 208 if (decorations & TextDecorationLineThrough) |
| 204 paintDecoration(paintInfo, TextDecorationLineThrough, fragment); | 209 paintDecoration(paintInfo, TextDecorationLineThrough, fragment); |
| 205 } | 210 } |
| 206 } | 211 } |
| 207 | 212 |
| 208 void SVGInlineTextBoxPainter::paintSelectionBackground( | 213 void SVGInlineTextBoxPainter::paintSelectionBackground( |
| 209 const PaintInfo& paintInfo) { | 214 const PaintInfo& paintInfo) { |
| 210 if (m_svgInlineTextBox.getLineLayoutItem().style()->visibility() != | 215 if (m_svgInlineTextBox.getLineLayoutItem().style()->visibility() != |
| 211 EVisibility::Visible) | 216 EVisibility::Visible) |
| 212 return; | 217 return; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 243 paintInfo.context.setFillColor(backgroundColor); | 248 paintInfo.context.setFillColor(backgroundColor); |
| 244 paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragment( | 249 paintInfo.context.fillRect(m_svgInlineTextBox.selectionRectForTextFragment( |
| 245 fragment, fragmentWithRange.startPosition, | 250 fragment, fragmentWithRange.startPosition, |
| 246 fragmentWithRange.endPosition, style), | 251 fragmentWithRange.endPosition, style), |
| 247 backgroundColor); | 252 backgroundColor); |
| 248 } | 253 } |
| 249 } | 254 } |
| 250 | 255 |
| 251 static inline LayoutObject* findLayoutObjectDefininingTextDecoration( | 256 static inline LayoutObject* findLayoutObjectDefininingTextDecoration( |
| 252 InlineFlowBox* parentBox) { | 257 InlineFlowBox* parentBox) { |
| 253 // Lookup first layout object in parent hierarchy which has text-decoration se
t. | 258 // Lookup first layout object in parent hierarchy which has text-decoration |
| 259 // set. |
| 254 LayoutObject* layoutObject = nullptr; | 260 LayoutObject* layoutObject = nullptr; |
| 255 while (parentBox) { | 261 while (parentBox) { |
| 256 layoutObject = | 262 layoutObject = |
| 257 LineLayoutAPIShim::layoutObjectFrom(parentBox->getLineLayoutItem()); | 263 LineLayoutAPIShim::layoutObjectFrom(parentBox->getLineLayoutItem()); |
| 258 | 264 |
| 259 if (layoutObject->style() && | 265 if (layoutObject->style() && |
| 260 layoutObject->style()->getTextDecoration() != TextDecorationNone) | 266 layoutObject->style()->getTextDecoration() != TextDecorationNone) |
| 261 break; | 267 break; |
| 262 | 268 |
| 263 parentBox = parentBox->parent(); | 269 parentBox = parentBox->parent(); |
| 264 } | 270 } |
| 265 | 271 |
| 266 ASSERT(layoutObject); | 272 ASSERT(layoutObject); |
| 267 return layoutObject; | 273 return layoutObject; |
| 268 } | 274 } |
| 269 | 275 |
| 270 // Offset from the baseline for |decoration|. Positive offsets are above the bas
eline. | 276 // Offset from the baseline for |decoration|. Positive offsets are above the |
| 277 // baseline. |
| 271 static inline float baselineOffsetForDecoration(TextDecoration decoration, | 278 static inline float baselineOffsetForDecoration(TextDecoration decoration, |
| 272 const FontMetrics& fontMetrics, | 279 const FontMetrics& fontMetrics, |
| 273 float thickness) { | 280 float thickness) { |
| 274 // FIXME: For SVG Fonts we need to use the attributes defined in the <font-fac
e> if specified. | 281 // FIXME: For SVG Fonts we need to use the attributes defined in the |
| 282 // <font-face> if specified. |
| 275 // Compatible with Batik/Presto. | 283 // Compatible with Batik/Presto. |
| 276 if (decoration == TextDecorationUnderline) | 284 if (decoration == TextDecorationUnderline) |
| 277 return -thickness * 1.5f; | 285 return -thickness * 1.5f; |
| 278 if (decoration == TextDecorationOverline) | 286 if (decoration == TextDecorationOverline) |
| 279 return fontMetrics.floatAscent() - thickness; | 287 return fontMetrics.floatAscent() - thickness; |
| 280 if (decoration == TextDecorationLineThrough) | 288 if (decoration == TextDecorationLineThrough) |
| 281 return fontMetrics.floatAscent() * 3 / 8.0f; | 289 return fontMetrics.floatAscent() * 3 / 8.0f; |
| 282 | 290 |
| 283 ASSERT_NOT_REACHED(); | 291 ASSERT_NOT_REACHED(); |
| 284 return 0.0f; | 292 return 0.0f; |
| 285 } | 293 } |
| 286 | 294 |
| 287 static inline float thicknessForDecoration(TextDecoration, const Font& font) { | 295 static inline float thicknessForDecoration(TextDecoration, const Font& font) { |
| 288 // FIXME: For SVG Fonts we need to use the attributes defined in the <font-fac
e> if specified. | 296 // FIXME: For SVG Fonts we need to use the attributes defined in the |
| 297 // <font-face> if specified. |
| 289 // Compatible with Batik/Presto | 298 // Compatible with Batik/Presto |
| 290 return font.getFontDescription().computedSize() / 20.0f; | 299 return font.getFontDescription().computedSize() / 20.0f; |
| 291 } | 300 } |
| 292 | 301 |
| 293 void SVGInlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, | 302 void SVGInlineTextBoxPainter::paintDecoration(const PaintInfo& paintInfo, |
| 294 TextDecoration decoration, | 303 TextDecoration decoration, |
| 295 const SVGTextFragment& fragment) { | 304 const SVGTextFragment& fragment) { |
| 296 if (m_svgInlineTextBox.getLineLayoutItem() | 305 if (m_svgInlineTextBox.getLineLayoutItem() |
| 297 .style() | 306 .style() |
| 298 ->textDecorationsInEffect() == TextDecorationNone) | 307 ->textDecorationsInEffect() == TextDecorationNone) |
| 299 return; | 308 return; |
| 300 | 309 |
| 301 if (fragment.width <= 0) | 310 if (fragment.width <= 0) |
| 302 return; | 311 return; |
| 303 | 312 |
| 304 // Find out which style defined the text-decoration, as its fill/stroke proper
ties have to be used for drawing instead of ours. | 313 // Find out which style defined the text-decoration, as its fill/stroke |
| 314 // properties have to be used for drawing instead of ours. |
| 305 LayoutObject* decorationLayoutObject = | 315 LayoutObject* decorationLayoutObject = |
| 306 findLayoutObjectDefininingTextDecoration(m_svgInlineTextBox.parent()); | 316 findLayoutObjectDefininingTextDecoration(m_svgInlineTextBox.parent()); |
| 307 const ComputedStyle& decorationStyle = decorationLayoutObject->styleRef(); | 317 const ComputedStyle& decorationStyle = decorationLayoutObject->styleRef(); |
| 308 | 318 |
| 309 if (decorationStyle.visibility() != EVisibility::Visible) | 319 if (decorationStyle.visibility() != EVisibility::Visible) |
| 310 return; | 320 return; |
| 311 | 321 |
| 312 float scalingFactor = 1; | 322 float scalingFactor = 1; |
| 313 Font scaledFont; | 323 Font scaledFont; |
| 314 LayoutSVGInlineText::computeNewScaledFontForStyle(decorationLayoutObject, | 324 LayoutSVGInlineText::computeNewScaledFontForStyle(decorationLayoutObject, |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 bool shouldPaintSelection) { | 464 bool shouldPaintSelection) { |
| 455 int startPosition = 0; | 465 int startPosition = 0; |
| 456 int endPosition = 0; | 466 int endPosition = 0; |
| 457 if (shouldPaintSelection) { | 467 if (shouldPaintSelection) { |
| 458 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); | 468 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); |
| 459 shouldPaintSelection = | 469 shouldPaintSelection = |
| 460 m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates( | 470 m_svgInlineTextBox.mapStartEndPositionsIntoFragmentCoordinates( |
| 461 fragment, startPosition, endPosition); | 471 fragment, startPosition, endPosition); |
| 462 } | 472 } |
| 463 | 473 |
| 464 // Fast path if there is no selection, just draw the whole chunk part using th
e regular style | 474 // Fast path if there is no selection, just draw the whole chunk part using |
| 475 // the regular style. |
| 465 TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment); | 476 TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment); |
| 466 if (!shouldPaintSelection || startPosition >= endPosition) { | 477 if (!shouldPaintSelection || startPosition >= endPosition) { |
| 467 SkPaint paint; | 478 SkPaint paint; |
| 468 if (setupTextPaint(paintInfo, style, resourceMode, paint)) | 479 if (setupTextPaint(paintInfo, style, resourceMode, paint)) |
| 469 paintText(paintInfo, textRun, fragment, 0, fragment.length, paint); | 480 paintText(paintInfo, textRun, fragment, 0, fragment.length, paint); |
| 470 return; | 481 return; |
| 471 } | 482 } |
| 472 | 483 |
| 473 // Eventually draw text using regular style until the start position of the se
lection | 484 // Eventually draw text using regular style until the start position of the |
| 485 // selection. |
| 474 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; | 486 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; |
| 475 if (startPosition > 0 && !paintSelectedTextOnly) { | 487 if (startPosition > 0 && !paintSelectedTextOnly) { |
| 476 SkPaint paint; | 488 SkPaint paint; |
| 477 if (setupTextPaint(paintInfo, style, resourceMode, paint)) | 489 if (setupTextPaint(paintInfo, style, resourceMode, paint)) |
| 478 paintText(paintInfo, textRun, fragment, 0, startPosition, paint); | 490 paintText(paintInfo, textRun, fragment, 0, startPosition, paint); |
| 479 } | 491 } |
| 480 | 492 |
| 481 // Draw text using selection style from the start to the end position of the s
election | 493 // Draw text using selection style from the start to the end position of the |
| 494 // selection. |
| 482 if (style != selectionStyle) { | 495 if (style != selectionStyle) { |
| 483 StyleDifference diff; | 496 StyleDifference diff; |
| 484 diff.setNeedsPaintInvalidationObject(); | 497 diff.setNeedsPaintInvalidationObject(); |
| 485 SVGResourcesCache::clientStyleChanged(&parentInlineLayoutObject(), diff, | 498 SVGResourcesCache::clientStyleChanged(&parentInlineLayoutObject(), diff, |
| 486 selectionStyle); | 499 selectionStyle); |
| 487 } | 500 } |
| 488 | 501 |
| 489 SkPaint paint; | 502 SkPaint paint; |
| 490 if (setupTextPaint(paintInfo, selectionStyle, resourceMode, paint)) | 503 if (setupTextPaint(paintInfo, selectionStyle, resourceMode, paint)) |
| 491 paintText(paintInfo, textRun, fragment, startPosition, endPosition, paint); | 504 paintText(paintInfo, textRun, fragment, startPosition, endPosition, paint); |
| 492 | 505 |
| 493 if (style != selectionStyle) { | 506 if (style != selectionStyle) { |
| 494 StyleDifference diff; | 507 StyleDifference diff; |
| 495 diff.setNeedsPaintInvalidationObject(); | 508 diff.setNeedsPaintInvalidationObject(); |
| 496 SVGResourcesCache::clientStyleChanged(&parentInlineLayoutObject(), diff, | 509 SVGResourcesCache::clientStyleChanged(&parentInlineLayoutObject(), diff, |
| 497 style); | 510 style); |
| 498 } | 511 } |
| 499 | 512 |
| 500 // Eventually draw text using regular style from the end position of the selec
tion to the end of the current chunk part | 513 // Eventually draw text using regular style from the end position of the |
| 514 // selection to the end of the current chunk part. |
| 501 if (endPosition < static_cast<int>(fragment.length) && | 515 if (endPosition < static_cast<int>(fragment.length) && |
| 502 !paintSelectedTextOnly) { | 516 !paintSelectedTextOnly) { |
| 503 SkPaint paint; | 517 SkPaint paint; |
| 504 if (setupTextPaint(paintInfo, style, resourceMode, paint)) | 518 if (setupTextPaint(paintInfo, style, resourceMode, paint)) |
| 505 paintText(paintInfo, textRun, fragment, endPosition, fragment.length, | 519 paintText(paintInfo, textRun, fragment, endPosition, fragment.length, |
| 506 paint); | 520 paint); |
| 507 } | 521 } |
| 508 } | 522 } |
| 509 | 523 |
| 510 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches( | 524 Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::collectTextMatches( |
| 511 DocumentMarker* marker) const { | 525 DocumentMarker* marker) const { |
| 512 const Vector<SVGTextFragmentWithRange> emptyTextMatchList; | 526 const Vector<SVGTextFragmentWithRange> emptyTextMatchList; |
| 513 | 527 |
| 514 // SVG does not support grammar or spellcheck markers, so skip anything but Te
xtMatch. | 528 // SVG does not support grammar or spellcheck markers, so skip anything but |
| 529 // TextMatch. |
| 515 if (marker->type() != DocumentMarker::TextMatch) | 530 if (marker->type() != DocumentMarker::TextMatch) |
| 516 return emptyTextMatchList; | 531 return emptyTextMatchList; |
| 517 | 532 |
| 518 if (!inlineLayoutObject().frame()->editor().markedTextMatchesAreHighlighted()) | 533 if (!inlineLayoutObject().frame()->editor().markedTextMatchesAreHighlighted()) |
| 519 return emptyTextMatchList; | 534 return emptyTextMatchList; |
| 520 | 535 |
| 521 int markerStartPosition = | 536 int markerStartPosition = |
| 522 std::max<int>(marker->startOffset() - m_svgInlineTextBox.start(), 0); | 537 std::max<int>(marker->startOffset() - m_svgInlineTextBox.start(), 0); |
| 523 int markerEndPosition = | 538 int markerEndPosition = |
| 524 std::min<int>(marker->endOffset() - m_svgInlineTextBox.start(), | 539 std::min<int>(marker->endOffset() - m_svgInlineTextBox.start(), |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 } | 628 } |
| 614 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment( | 629 FloatRect fragmentRect = m_svgInlineTextBox.selectionRectForTextFragment( |
| 615 fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, | 630 fragment, textMatchInfo.startPosition, textMatchInfo.endPosition, |
| 616 style); | 631 style); |
| 617 paintInfo.context.setFillColor(color); | 632 paintInfo.context.setFillColor(color); |
| 618 paintInfo.context.fillRect(fragmentRect); | 633 paintInfo.context.fillRect(fragmentRect); |
| 619 } | 634 } |
| 620 } | 635 } |
| 621 | 636 |
| 622 } // namespace blink | 637 } // namespace blink |
| OLD | NEW |