| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 int SVGInlineTextBox::offsetForPosition(FloatWillBeLayoutUnit, bool) const | 71 int SVGInlineTextBox::offsetForPosition(FloatWillBeLayoutUnit, bool) const |
| 72 { | 72 { |
| 73 // SVG doesn't use the standard offset <-> position selection system, as it'
s not suitable for SVGs complex needs. | 73 // SVG doesn't use the standard offset <-> position selection system, as it'
s not suitable for SVGs complex needs. |
| 74 // vertical text selection, inline boxes spanning multiple lines (contrary t
o HTML, etc.) | 74 // vertical text selection, inline boxes spanning multiple lines (contrary t
o HTML, etc.) |
| 75 ASSERT_NOT_REACHED(); | 75 ASSERT_NOT_REACHED(); |
| 76 return 0; | 76 return 0; |
| 77 } | 77 } |
| 78 | 78 |
| 79 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
t, FloatWillBeLayoutUnit position, bool includePartialGlyphs) const | 79 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
t, FloatWillBeLayoutUnit position, bool includePartialGlyphs) const |
| 80 { | 80 { |
| 81 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(this->renderer()); | 81 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(this->layoutObject
()); |
| 82 | 82 |
| 83 float scalingFactor = textRenderer.scalingFactor(); | 83 float scalingFactor = textRenderer.scalingFactor(); |
| 84 ASSERT(scalingFactor); | 84 ASSERT(scalingFactor); |
| 85 | 85 |
| 86 const LayoutStyle& style = textRenderer.styleRef(); | 86 const LayoutStyle& style = textRenderer.styleRef(); |
| 87 | 87 |
| 88 TextRun textRun = constructTextRun(style, fragment); | 88 TextRun textRun = constructTextRun(style, fragment); |
| 89 | 89 |
| 90 // Eventually handle lengthAdjust="spacingAndGlyphs". | 90 // Eventually handle lengthAdjust="spacingAndGlyphs". |
| 91 // FIXME: Handle vertical text. | 91 // FIXME: Handle vertical text. |
| 92 AffineTransform fragmentTransform; | 92 AffineTransform fragmentTransform; |
| 93 fragment.buildFragmentTransform(fragmentTransform); | 93 fragment.buildFragmentTransform(fragmentTransform); |
| 94 if (!fragmentTransform.isIdentity()) | 94 if (!fragmentTransform.isIdentity()) |
| 95 textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransfo
rm.xScale())); | 95 textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransfo
rm.xScale())); |
| 96 | 96 |
| 97 return fragment.characterOffset - start() + textRenderer.scaledFont().offset
ForPosition(textRun, position * scalingFactor, includePartialGlyphs); | 97 return fragment.characterOffset - start() + textRenderer.scaledFont().offset
ForPosition(textRun, position * scalingFactor, includePartialGlyphs); |
| 98 } | 98 } |
| 99 | 99 |
| 100 FloatWillBeLayoutUnit SVGInlineTextBox::positionForOffset(int) const | 100 FloatWillBeLayoutUnit SVGInlineTextBox::positionForOffset(int) const |
| 101 { | 101 { |
| 102 // SVG doesn't use the offset <-> position selection system. | 102 // SVG doesn't use the offset <-> position selection system. |
| 103 ASSERT_NOT_REACHED(); | 103 ASSERT_NOT_REACHED(); |
| 104 return 0; | 104 return 0; |
| 105 } | 105 } |
| 106 | 106 |
| 107 FloatRectWillBeLayoutRect SVGInlineTextBox::selectionRectForTextFragment(const S
VGTextFragment& fragment, int startPosition, int endPosition, const LayoutStyle&
style) | 107 FloatRectWillBeLayoutRect SVGInlineTextBox::selectionRectForTextFragment(const S
VGTextFragment& fragment, int startPosition, int endPosition, const LayoutStyle&
style) |
| 108 { | 108 { |
| 109 ASSERT(startPosition < endPosition); | 109 ASSERT(startPosition < endPosition); |
| 110 | 110 |
| 111 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(this->renderer()); | 111 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(this->layoutObject
()); |
| 112 | 112 |
| 113 float scalingFactor = textRenderer.scalingFactor(); | 113 float scalingFactor = textRenderer.scalingFactor(); |
| 114 ASSERT(scalingFactor); | 114 ASSERT(scalingFactor); |
| 115 | 115 |
| 116 const Font& scaledFont = textRenderer.scaledFont(); | 116 const Font& scaledFont = textRenderer.scaledFont(); |
| 117 const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); | 117 const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); |
| 118 FloatPointWillBeLayoutPoint textOrigin(fragment.x, fragment.y); | 118 FloatPointWillBeLayoutPoint textOrigin(fragment.x, fragment.y); |
| 119 if (scalingFactor != 1) | 119 if (scalingFactor != 1) |
| 120 textOrigin.scale(scalingFactor, scalingFactor); | 120 textOrigin.scale(scalingFactor, scalingFactor); |
| 121 | 121 |
| 122 textOrigin.move(0, -scaledFontMetrics.floatAscent()); | 122 textOrigin.move(0, -scaledFontMetrics.floatAscent()); |
| 123 | 123 |
| 124 FloatRectWillBeLayoutRect selectionRect = scaledFont.selectionRectForText(co
nstructTextRun(style, fragment), textOrigin.toFloatPoint(), fragment.height * sc
alingFactor, startPosition, endPosition); | 124 FloatRectWillBeLayoutRect selectionRect = scaledFont.selectionRectForText(co
nstructTextRun(style, fragment), textOrigin.toFloatPoint(), fragment.height * sc
alingFactor, startPosition, endPosition); |
| 125 if (scalingFactor == 1) | 125 if (scalingFactor == 1) |
| 126 return selectionRect; | 126 return selectionRect; |
| 127 | 127 |
| 128 selectionRect.scale(1 / scalingFactor); | 128 selectionRect.scale(1 / scalingFactor); |
| 129 return selectionRect; | 129 return selectionRect; |
| 130 } | 130 } |
| 131 | 131 |
| 132 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
on) | 132 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
on) |
| 133 { | 133 { |
| 134 int boxStart = start(); | 134 int boxStart = start(); |
| 135 startPosition = std::max(startPosition - boxStart, 0); | 135 startPosition = std::max(startPosition - boxStart, 0); |
| 136 endPosition = std::min(endPosition - boxStart, static_cast<int>(len())); | 136 endPosition = std::min(endPosition - boxStart, static_cast<int>(len())); |
| 137 if (startPosition >= endPosition) | 137 if (startPosition >= endPosition) |
| 138 return LayoutRect(); | 138 return LayoutRect(); |
| 139 | 139 |
| 140 const LayoutStyle& style = renderer().styleRef(); | 140 const LayoutStyle& style = layoutObject().styleRef(); |
| 141 | 141 |
| 142 AffineTransform fragmentTransform; | 142 AffineTransform fragmentTransform; |
| 143 FloatRectWillBeLayoutRect selectionRect; | 143 FloatRectWillBeLayoutRect selectionRect; |
| 144 int fragmentStartPosition = 0; | 144 int fragmentStartPosition = 0; |
| 145 int fragmentEndPosition = 0; | 145 int fragmentEndPosition = 0; |
| 146 | 146 |
| 147 unsigned textFragmentsSize = m_textFragments.size(); | 147 unsigned textFragmentsSize = m_textFragments.size(); |
| 148 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 148 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 149 const SVGTextFragment& fragment = m_textFragments.at(i); | 149 const SVGTextFragment& fragment = m_textFragments.at(i); |
| 150 | 150 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 165 return LayoutRect(enclosingIntRect(selectionRect.rawValue())); | 165 return LayoutRect(enclosingIntRect(selectionRect.rawValue())); |
| 166 } | 166 } |
| 167 | 167 |
| 168 void SVGInlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& pain
tOffset, LayoutUnit, LayoutUnit) | 168 void SVGInlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& pain
tOffset, LayoutUnit, LayoutUnit) |
| 169 { | 169 { |
| 170 SVGInlineTextBoxPainter(*this).paint(paintInfo, paintOffset); | 170 SVGInlineTextBoxPainter(*this).paint(paintInfo, paintOffset); |
| 171 } | 171 } |
| 172 | 172 |
| 173 TextRun SVGInlineTextBox::constructTextRun(const LayoutStyle& style, const SVGTe
xtFragment& fragment) const | 173 TextRun SVGInlineTextBox::constructTextRun(const LayoutStyle& style, const SVGTe
xtFragment& fragment) const |
| 174 { | 174 { |
| 175 LayoutText* text = &renderer(); | 175 LayoutText* text = &layoutObject(); |
| 176 | 176 |
| 177 // FIXME(crbug.com/264211): This should not be necessary but can occur if we | 177 // FIXME(crbug.com/264211): This should not be necessary but can occur if we |
| 178 // layout during layout. Remove this when 264211 is
fixed. | 178 // layout during layout. Remove this when 264211 is
fixed. |
| 179 RELEASE_ASSERT(!text->needsLayout()); | 179 RELEASE_ASSERT(!text->needsLayout()); |
| 180 | 180 |
| 181 TextRun run(static_cast<const LChar*>(0) // characters, will be set below if
non-zero. | 181 TextRun run(static_cast<const LChar*>(0) // characters, will be set below if
non-zero. |
| 182 , 0 // length, will be set below if non-zero. | 182 , 0 // length, will be set below if non-zero. |
| 183 , 0 // xPos, only relevant with allowTabs=true | 183 , 0 // xPos, only relevant with allowTabs=true |
| 184 , 0 // padding, only relevant for justified text, not relevant for SVG | 184 , 0 // padding, only relevant for justified text, not relevant for SVG |
| 185 , TextRun::AllowTrailingExpansion | 185 , TextRun::AllowTrailingExpansion |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 | 236 |
| 237 void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const Floa
tPointWillBeLayoutPoint& point, DocumentMarker* marker, const LayoutStyle& style
, const Font& font) | 237 void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const Floa
tPointWillBeLayoutPoint& point, DocumentMarker* marker, const LayoutStyle& style
, const Font& font) |
| 238 { | 238 { |
| 239 SVGInlineTextBoxPainter(*this).paintTextMatchMarker(context, point.toFloatPo
int(), marker, style, font); | 239 SVGInlineTextBoxPainter(*this).paintTextMatchMarker(context, point.toFloatPo
int(), marker, style, font); |
| 240 } | 240 } |
| 241 | 241 |
| 242 FloatRectWillBeLayoutRect SVGInlineTextBox::calculateBoundaries() const | 242 FloatRectWillBeLayoutRect SVGInlineTextBox::calculateBoundaries() const |
| 243 { | 243 { |
| 244 FloatRectWillBeLayoutRect textRect; | 244 FloatRectWillBeLayoutRect textRect; |
| 245 | 245 |
| 246 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(this->renderer()); | 246 LayoutSVGInlineText& textRenderer = toLayoutSVGInlineText(this->layoutObject
()); |
| 247 | 247 |
| 248 float scalingFactor = textRenderer.scalingFactor(); | 248 float scalingFactor = textRenderer.scalingFactor(); |
| 249 ASSERT(scalingFactor); | 249 ASSERT(scalingFactor); |
| 250 | 250 |
| 251 FloatWillBeLayoutUnit baseline = textRenderer.scaledFont().fontMetrics().flo
atAscent() / scalingFactor; | 251 FloatWillBeLayoutUnit baseline = textRenderer.scaledFont().fontMetrics().flo
atAscent() / scalingFactor; |
| 252 | 252 |
| 253 AffineTransform fragmentTransform; | 253 AffineTransform fragmentTransform; |
| 254 unsigned textFragmentsSize = m_textFragments.size(); | 254 unsigned textFragmentsSize = m_textFragments.size(); |
| 255 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 255 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 256 const SVGTextFragment& fragment = m_textFragments.at(i); | 256 const SVGTextFragment& fragment = m_textFragments.at(i); |
| 257 FloatRectWillBeLayoutRect fragmentRect(fragment.x, fragment.y - baseline
, fragment.width, fragment.height); | 257 FloatRectWillBeLayoutRect fragmentRect(fragment.x, fragment.y - baseline
, fragment.width, fragment.height); |
| 258 fragment.buildFragmentTransform(fragmentTransform); | 258 fragment.buildFragmentTransform(fragmentTransform); |
| 259 fragmentRect = fragmentTransform.mapRect(fragmentRect.toFloatRect()); | 259 fragmentRect = fragmentTransform.mapRect(fragmentRect.toFloatRect()); |
| 260 | 260 |
| 261 textRect.unite(fragmentRect); | 261 textRect.unite(fragmentRect); |
| 262 } | 262 } |
| 263 | 263 |
| 264 return textRect; | 264 return textRect; |
| 265 } | 265 } |
| 266 | 266 |
| 267 bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult&
result, const HitTestLocation& locationInContainer, const LayoutPoint& accumula
tedOffset, LayoutUnit, LayoutUnit) | 267 bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult&
result, const HitTestLocation& locationInContainer, const LayoutPoint& accumula
tedOffset, LayoutUnit, LayoutUnit) |
| 268 { | 268 { |
| 269 // FIXME: integrate with InlineTextBox::nodeAtPoint better. | 269 // FIXME: integrate with InlineTextBox::nodeAtPoint better. |
| 270 ASSERT(!isLineBreak()); | 270 ASSERT(!isLineBreak()); |
| 271 | 271 |
| 272 PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, r
equest, renderer().style()->pointerEvents()); | 272 PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, r
equest, layoutObject().style()->pointerEvents()); |
| 273 bool isVisible = renderer().style()->visibility() == VISIBLE; | 273 bool isVisible = layoutObject().style()->visibility() == VISIBLE; |
| 274 if (isVisible || !hitRules.requireVisible) { | 274 if (isVisible || !hitRules.requireVisible) { |
| 275 if (hitRules.canHitBoundingBox | 275 if (hitRules.canHitBoundingBox |
| 276 || (hitRules.canHitStroke && (renderer().style()->svgStyle().hasStro
ke() || !hitRules.requireStroke)) | 276 || (hitRules.canHitStroke && (layoutObject().style()->svgStyle().has
Stroke() || !hitRules.requireStroke)) |
| 277 || (hitRules.canHitFill && (renderer().style()->svgStyle().hasFill()
|| !hitRules.requireFill))) { | 277 || (hitRules.canHitFill && (layoutObject().style()->svgStyle().hasFi
ll() || !hitRules.requireFill))) { |
| 278 FloatPointWillBeLayoutPoint boxOrigin(x(), y()); | 278 FloatPointWillBeLayoutPoint boxOrigin(x(), y()); |
| 279 boxOrigin.moveBy(accumulatedOffset); | 279 boxOrigin.moveBy(accumulatedOffset); |
| 280 FloatRectWillBeLayoutRect rect(boxOrigin, size()); | 280 FloatRectWillBeLayoutRect rect(boxOrigin, size()); |
| 281 // FIXME: both calls to rawValue() below is temporary and should be
removed once the transition | 281 // FIXME: both calls to rawValue() below is temporary and should be
removed once the transition |
| 282 // to LayoutUnit-based types is complete (crbug.com/321237) | 282 // to LayoutUnit-based types is complete (crbug.com/321237) |
| 283 if (locationInContainer.intersects(rect.rawValue())) { | 283 if (locationInContainer.intersects(rect.rawValue())) { |
| 284 renderer().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); | 284 layoutObject().updateHitTestResult(result, locationInContainer.p
oint() - toLayoutSize(accumulatedOffset)); |
| 285 if (!result.addNodeToListBasedTestResult(renderer().node(), requ
est, locationInContainer, rect.rawValue())) | 285 if (!result.addNodeToListBasedTestResult(layoutObject().node(),
request, locationInContainer, rect.rawValue())) |
| 286 return true; | 286 return true; |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 return false; | 290 return false; |
| 291 } | 291 } |
| 292 | 292 |
| 293 } // namespace blink | 293 } // namespace blink |
| OLD | NEW |