| OLD | NEW |
| 1 /** | 1 /** |
| 2 * Copyright (C) 2007 Rob Buis <buis@kde.org> | 2 * Copyright (C) 2007 Rob Buis <buis@kde.org> |
| 3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> | 3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> |
| 4 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 int SVGInlineTextBox::offsetForPosition(float, bool) const | 79 int SVGInlineTextBox::offsetForPosition(float, bool) const |
| 80 { | 80 { |
| 81 // SVG doesn't use the standard offset <-> position selection system, as it'
s not suitable for SVGs complex needs. | 81 // SVG doesn't use the standard offset <-> position selection system, as it'
s not suitable for SVGs complex needs. |
| 82 // vertical text selection, inline boxes spanning multiple lines (contrary t
o HTML, etc.) | 82 // vertical text selection, inline boxes spanning multiple lines (contrary t
o HTML, etc.) |
| 83 ASSERT_NOT_REACHED(); | 83 ASSERT_NOT_REACHED(); |
| 84 return 0; | 84 return 0; |
| 85 } | 85 } |
| 86 | 86 |
| 87 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
t, float position, bool includePartialGlyphs) const | 87 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
t, float position, bool includePartialGlyphs) const |
| 88 { | 88 { |
| 89 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 89 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 90 | 90 |
| 91 float scalingFactor = textRenderer.scalingFactor(); | 91 float scalingFactor = textRenderer.scalingFactor(); |
| 92 ASSERT(scalingFactor); | 92 ASSERT(scalingFactor); |
| 93 | 93 |
| 94 RenderStyle* style = textRenderer.style(); | 94 RenderStyle* style = textRenderer.style(); |
| 95 ASSERT(style); | 95 ASSERT(style); |
| 96 | 96 |
| 97 TextRun textRun = constructTextRun(style, fragment); | 97 TextRun textRun = constructTextRun(style, fragment); |
| 98 | 98 |
| 99 // Eventually handle lengthAdjust="spacingAndGlyphs". | 99 // Eventually handle lengthAdjust="spacingAndGlyphs". |
| (...skipping 13 matching lines...) Expand all Loading... |
| 113 return 0; | 113 return 0; |
| 114 } | 114 } |
| 115 | 115 |
| 116 FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
fragment, int startPosition, int endPosition, RenderStyle* style) | 116 FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
fragment, int startPosition, int endPosition, RenderStyle* style) |
| 117 { | 117 { |
| 118 ASSERT(startPosition < endPosition); | 118 ASSERT(startPosition < endPosition); |
| 119 ASSERT(style); | 119 ASSERT(style); |
| 120 | 120 |
| 121 FontCachePurgePreventer fontCachePurgePreventer; | 121 FontCachePurgePreventer fontCachePurgePreventer; |
| 122 | 122 |
| 123 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 123 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 124 | 124 |
| 125 float scalingFactor = textRenderer.scalingFactor(); | 125 float scalingFactor = textRenderer.scalingFactor(); |
| 126 ASSERT(scalingFactor); | 126 ASSERT(scalingFactor); |
| 127 | 127 |
| 128 const Font& scaledFont = textRenderer.scaledFont(); | 128 const Font& scaledFont = textRenderer.scaledFont(); |
| 129 const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); | 129 const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); |
| 130 FloatPoint textOrigin(fragment.x, fragment.y); | 130 FloatPoint textOrigin(fragment.x, fragment.y); |
| 131 if (scalingFactor != 1) | 131 if (scalingFactor != 1) |
| 132 textOrigin.scale(scalingFactor, scalingFactor); | 132 textOrigin.scale(scalingFactor, scalingFactor); |
| 133 | 133 |
| 134 textOrigin.move(0, -scaledFontMetrics.floatAscent()); | 134 textOrigin.move(0, -scaledFontMetrics.floatAscent()); |
| 135 | 135 |
| 136 FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(s
tyle, fragment), textOrigin, fragment.height * scalingFactor, startPosition, end
Position); | 136 FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(s
tyle, fragment), textOrigin, fragment.height * scalingFactor, startPosition, end
Position); |
| 137 if (scalingFactor == 1) | 137 if (scalingFactor == 1) |
| 138 return selectionRect; | 138 return selectionRect; |
| 139 | 139 |
| 140 selectionRect.scale(1 / scalingFactor); | 140 selectionRect.scale(1 / scalingFactor); |
| 141 return selectionRect; | 141 return selectionRect; |
| 142 } | 142 } |
| 143 | 143 |
| 144 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
on) | 144 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
on) |
| 145 { | 145 { |
| 146 int boxStart = start(); | 146 int boxStart = start(); |
| 147 startPosition = std::max(startPosition - boxStart, 0); | 147 startPosition = std::max(startPosition - boxStart, 0); |
| 148 endPosition = std::min(endPosition - boxStart, static_cast<int>(len())); | 148 endPosition = std::min(endPosition - boxStart, static_cast<int>(len())); |
| 149 if (startPosition >= endPosition) | 149 if (startPosition >= endPosition) |
| 150 return LayoutRect(); | 150 return LayoutRect(); |
| 151 | 151 |
| 152 RenderStyle* style = textRenderer().style(); | 152 RenderStyle* style = renderer().style(); |
| 153 ASSERT(style); | 153 ASSERT(style); |
| 154 | 154 |
| 155 AffineTransform fragmentTransform; | 155 AffineTransform fragmentTransform; |
| 156 FloatRect selectionRect; | 156 FloatRect selectionRect; |
| 157 int fragmentStartPosition = 0; | 157 int fragmentStartPosition = 0; |
| 158 int fragmentEndPosition = 0; | 158 int fragmentEndPosition = 0; |
| 159 | 159 |
| 160 unsigned textFragmentsSize = m_textFragments.size(); | 160 unsigned textFragmentsSize = m_textFragments.size(); |
| 161 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 161 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 162 const SVGTextFragment& fragment = m_textFragments.at(i); | 162 const SVGTextFragment& fragment = m_textFragments.at(i); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 // Determine whether or not we're selected. | 198 // Determine whether or not we're selected. |
| 199 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; | 199 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; |
| 200 bool hasSelection = selectionState() != RenderObject::SelectionNone; | 200 bool hasSelection = selectionState() != RenderObject::SelectionNone; |
| 201 if (!hasSelection || paintSelectedTextOnly) | 201 if (!hasSelection || paintSelectedTextOnly) |
| 202 return; | 202 return; |
| 203 | 203 |
| 204 Color backgroundColor = renderer().selectionBackgroundColor(); | 204 Color backgroundColor = renderer().selectionBackgroundColor(); |
| 205 if (!backgroundColor.alpha()) | 205 if (!backgroundColor.alpha()) |
| 206 return; | 206 return; |
| 207 | 207 |
| 208 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 208 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 209 if (!textShouldBePainted(textRenderer)) | 209 if (!textShouldBePainted(textRenderer)) |
| 210 return; | 210 return; |
| 211 | 211 |
| 212 RenderStyle* style = parentRenderer.style(); | 212 RenderStyle* style = parentRenderer.style(); |
| 213 ASSERT(style); | 213 ASSERT(style); |
| 214 | 214 |
| 215 int startPosition, endPosition; | 215 int startPosition, endPosition; |
| 216 selectionStartEnd(startPosition, endPosition); | 216 selectionStartEnd(startPosition, endPosition); |
| 217 | 217 |
| 218 int fragmentStartPosition = 0; | 218 int fragmentStartPosition = 0; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 // Note: We're explicitely not supporting composition & custom underlines an
d custom highlighters - unlike InlineTextBox. | 252 // Note: We're explicitely not supporting composition & custom underlines an
d custom highlighters - unlike InlineTextBox. |
| 253 // If we ever need that for SVG, it's very easy to refactor and reuse the co
de. | 253 // If we ever need that for SVG, it's very easy to refactor and reuse the co
de. |
| 254 | 254 |
| 255 RenderObject& parentRenderer = parent()->renderer(); | 255 RenderObject& parentRenderer = parent()->renderer(); |
| 256 | 256 |
| 257 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; | 257 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; |
| 258 bool hasSelection = !parentRenderer.document().printing() && selectionState(
) != RenderObject::SelectionNone; | 258 bool hasSelection = !parentRenderer.document().printing() && selectionState(
) != RenderObject::SelectionNone; |
| 259 if (!hasSelection && paintSelectedTextOnly) | 259 if (!hasSelection && paintSelectedTextOnly) |
| 260 return; | 260 return; |
| 261 | 261 |
| 262 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 262 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 263 if (!textShouldBePainted(textRenderer)) | 263 if (!textShouldBePainted(textRenderer)) |
| 264 return; | 264 return; |
| 265 | 265 |
| 266 RenderStyle* style = parentRenderer.style(); | 266 RenderStyle* style = parentRenderer.style(); |
| 267 ASSERT(style); | 267 ASSERT(style); |
| 268 | 268 |
| 269 paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer.sca
ledFont(), true); | 269 paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer.sca
ledFont(), true); |
| 270 | 270 |
| 271 const SVGRenderStyle& svgStyle = style->svgStyle(); | 271 const SVGRenderStyle& svgStyle = style->svgStyle(); |
| 272 | 272 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 TextRun::RenderingContext* renderingContext = textRun.renderingContext(); | 420 TextRun::RenderingContext* renderingContext = textRun.renderingContext(); |
| 421 if (renderingContext) | 421 if (renderingContext) |
| 422 static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePai
ntingResource(0); | 422 static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePai
ntingResource(0); |
| 423 #endif | 423 #endif |
| 424 } | 424 } |
| 425 | 425 |
| 426 TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
ment& fragment) const | 426 TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
ment& fragment) const |
| 427 { | 427 { |
| 428 ASSERT(style); | 428 ASSERT(style); |
| 429 | 429 |
| 430 RenderText* text = &textRenderer(); | 430 RenderText* text = &renderer(); |
| 431 | 431 |
| 432 // FIXME(crbug.com/264211): This should not be necessary but can occur if we | 432 // FIXME(crbug.com/264211): This should not be necessary but can occur if we |
| 433 // layout during layout. Remove this when 264211 is
fixed. | 433 // layout during layout. Remove this when 264211 is
fixed. |
| 434 RELEASE_ASSERT(!text->needsLayout()); | 434 RELEASE_ASSERT(!text->needsLayout()); |
| 435 | 435 |
| 436 TextRun run(static_cast<const LChar*>(0) // characters, will be set below if
non-zero. | 436 TextRun run(static_cast<const LChar*>(0) // characters, will be set below if
non-zero. |
| 437 , 0 // length, will be set below if non-zero. | 437 , 0 // length, will be set below if non-zero. |
| 438 , 0 // xPos, only relevant with allowTabs=true | 438 , 0 // xPos, only relevant with allowTabs=true |
| 439 , 0 // padding, only relevant for justified text, not relevant f
or SVG | 439 , 0 // padding, only relevant for justified text, not relevant f
or SVG |
| 440 , TextRun::AllowTrailingExpansion | 440 , TextRun::AllowTrailingExpansion |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 | 521 |
| 522 parentBox = parentBox->parent(); | 522 parentBox = parentBox->parent(); |
| 523 } | 523 } |
| 524 | 524 |
| 525 ASSERT(renderer); | 525 ASSERT(renderer); |
| 526 return renderer; | 526 return renderer; |
| 527 } | 527 } |
| 528 | 528 |
| 529 void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration
decoration, const SVGTextFragment& fragment) | 529 void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration
decoration, const SVGTextFragment& fragment) |
| 530 { | 530 { |
| 531 if (textRenderer().style()->textDecorationsInEffect() == TextDecorationNone) | 531 if (renderer().style()->textDecorationsInEffect() == TextDecorationNone) |
| 532 return; | 532 return; |
| 533 | 533 |
| 534 // Find out which render style defined the text-decoration, as its fill/stro
ke properties have to be used for drawing instead of ours. | 534 // Find out which render style defined the text-decoration, as its fill/stro
ke properties have to be used for drawing instead of ours. |
| 535 RenderObject* decorationRenderer = findRenderObjectDefininingTextDecoration(
parent()); | 535 RenderObject* decorationRenderer = findRenderObjectDefininingTextDecoration(
parent()); |
| 536 RenderStyle* decorationStyle = decorationRenderer->style(); | 536 RenderStyle* decorationStyle = decorationRenderer->style(); |
| 537 ASSERT(decorationStyle); | 537 ASSERT(decorationStyle); |
| 538 | 538 |
| 539 if (decorationStyle->visibility() == HIDDEN) | 539 if (decorationStyle->visibility() == HIDDEN) |
| 540 return; | 540 return; |
| 541 | 541 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 // acquirePaintingResource also modifies state if the scalingFactor is non-i
dentity. | 599 // acquirePaintingResource also modifies state if the scalingFactor is non-i
dentity. |
| 600 // Above we have saved the state for this case. | 600 // Above we have saved the state for this case. |
| 601 if (acquirePaintingResource(context, scalingFactor, decorationRenderer, deco
rationStyle, resourceMode)) | 601 if (acquirePaintingResource(context, scalingFactor, decorationRenderer, deco
rationStyle, resourceMode)) |
| 602 releasePaintingResource(context, &path, resourceMode); | 602 releasePaintingResource(context, &path, resourceMode); |
| 603 } | 603 } |
| 604 | 604 |
| 605 void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
e* style, | 605 void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
e* style, |
| 606 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, | 606 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, |
| 607 RenderSVGResourceModeFlags resourceMode) | 607 RenderSVGResourceModeFlags resourceMode) |
| 608 { | 608 { |
| 609 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 609 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 610 | 610 |
| 611 float scalingFactor = textRenderer.scalingFactor(); | 611 float scalingFactor = textRenderer.scalingFactor(); |
| 612 ASSERT(scalingFactor); | 612 ASSERT(scalingFactor); |
| 613 | 613 |
| 614 const Font& scaledFont = textRenderer.scaledFont(); | 614 const Font& scaledFont = textRenderer.scaledFont(); |
| 615 const ShadowList* shadowList = style->textShadow(); | 615 const ShadowList* shadowList = style->textShadow(); |
| 616 | 616 |
| 617 // Text shadows are disabled when printing. http://crbug.com/258321 | 617 // Text shadows are disabled when printing. http://crbug.com/258321 |
| 618 bool hasShadow = shadowList && !context->printing(); | 618 bool hasShadow = shadowList && !context->printing(); |
| 619 | 619 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 { | 694 { |
| 695 // SVG does not have support for generic document markers (e.g., spellchecki
ng, etc). | 695 // SVG does not have support for generic document markers (e.g., spellchecki
ng, etc). |
| 696 } | 696 } |
| 697 | 697 |
| 698 void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const Floa
tPoint&, DocumentMarker* marker, RenderStyle* style, const Font& font) | 698 void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const Floa
tPoint&, DocumentMarker* marker, RenderStyle* style, const Font& font) |
| 699 { | 699 { |
| 700 // SVG is only interested in the TextMatch markers. | 700 // SVG is only interested in the TextMatch markers. |
| 701 if (marker->type() != DocumentMarker::TextMatch) | 701 if (marker->type() != DocumentMarker::TextMatch) |
| 702 return; | 702 return; |
| 703 | 703 |
| 704 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 704 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 705 | 705 |
| 706 FloatRect markerRect; | 706 FloatRect markerRect; |
| 707 AffineTransform fragmentTransform; | 707 AffineTransform fragmentTransform; |
| 708 for (InlineTextBox* box = textRenderer.firstTextBox(); box; box = box->nextT
extBox()) { | 708 for (InlineTextBox* box = textRenderer.firstTextBox(); box; box = box->nextT
extBox()) { |
| 709 if (!box->isSVGInlineTextBox()) | 709 if (!box->isSVGInlineTextBox()) |
| 710 continue; | 710 continue; |
| 711 | 711 |
| 712 SVGInlineTextBox* textBox = toSVGInlineTextBox(box); | 712 SVGInlineTextBox* textBox = toSVGInlineTextBox(box); |
| 713 | 713 |
| 714 int markerStartPosition = std::max<int>(marker->startOffset() - textBox-
>start(), 0); | 714 int markerStartPosition = std::max<int>(marker->startOffset() - textBox-
>start(), 0); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 } | 747 } |
| 748 } | 748 } |
| 749 | 749 |
| 750 toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsolu
teQuad(markerRect).enclosingBoundingBox()); | 750 toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsolu
teQuad(markerRect).enclosingBoundingBox()); |
| 751 } | 751 } |
| 752 | 752 |
| 753 FloatRect SVGInlineTextBox::calculateBoundaries() const | 753 FloatRect SVGInlineTextBox::calculateBoundaries() const |
| 754 { | 754 { |
| 755 FloatRect textRect; | 755 FloatRect textRect; |
| 756 | 756 |
| 757 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer
()); | 757 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| 758 | 758 |
| 759 float scalingFactor = textRenderer.scalingFactor(); | 759 float scalingFactor = textRenderer.scalingFactor(); |
| 760 ASSERT(scalingFactor); | 760 ASSERT(scalingFactor); |
| 761 | 761 |
| 762 float baseline = textRenderer.scaledFont().fontMetrics().floatAscent() / sca
lingFactor; | 762 float baseline = textRenderer.scaledFont().fontMetrics().floatAscent() / sca
lingFactor; |
| 763 | 763 |
| 764 AffineTransform fragmentTransform; | 764 AffineTransform fragmentTransform; |
| 765 unsigned textFragmentsSize = m_textFragments.size(); | 765 unsigned textFragmentsSize = m_textFragments.size(); |
| 766 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 766 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 767 const SVGTextFragment& fragment = m_textFragments.at(i); | 767 const SVGTextFragment& fragment = m_textFragments.at(i); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 793 renderer().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); | 793 renderer().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); |
| 794 if (!result.addNodeToRectBasedTestResult(renderer().node(), requ
est, locationInContainer, rect)) | 794 if (!result.addNodeToRectBasedTestResult(renderer().node(), requ
est, locationInContainer, rect)) |
| 795 return true; | 795 return true; |
| 796 } | 796 } |
| 797 } | 797 } |
| 798 } | 798 } |
| 799 return false; | 799 return false; |
| 800 } | 800 } |
| 801 | 801 |
| 802 } // namespace blink | 802 } // namespace blink |
| OLD | NEW |