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 |