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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 float scalingFactor = lineLayoutItem.scalingFactor(); | 82 float scalingFactor = lineLayoutItem.scalingFactor(); |
83 ASSERT(scalingFactor); | 83 ASSERT(scalingFactor); |
84 | 84 |
85 const ComputedStyle& style = lineLayoutItem.styleRef(); | 85 const ComputedStyle& style = lineLayoutItem.styleRef(); |
86 | 86 |
87 TextRun textRun = constructTextRun(style, fragment); | 87 TextRun textRun = constructTextRun(style, fragment); |
88 | 88 |
89 // Eventually handle lengthAdjust="spacingAndGlyphs". | 89 // Eventually handle lengthAdjust="spacingAndGlyphs". |
90 // FIXME: Handle vertical text. | 90 // FIXME: Handle vertical text. |
91 if (fragment.isTransformed()) { | 91 if (fragment.isTransformed()) { |
92 AffineTransform fragmentTransform; | 92 AffineTransform fragmentTransform = fragment.buildFragmentTransform(); |
93 fragment.buildFragmentTransform(fragmentTransform); | |
94 textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransfo
rm.xScale())); | 93 textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransfo
rm.xScale())); |
95 } | 94 } |
96 | 95 |
97 return fragment.characterOffset - start() + lineLayoutItem.scaledFont().offs
etForPosition(textRun, position * scalingFactor, includePartialGlyphs); | 96 return fragment.characterOffset - start() + lineLayoutItem.scaledFont().offs
etForPosition(textRun, position * scalingFactor, includePartialGlyphs); |
98 } | 97 } |
99 | 98 |
100 LayoutUnit SVGInlineTextBox::positionForOffset(int) const | 99 LayoutUnit SVGInlineTextBox::positionForOffset(int) const |
101 { | 100 { |
102 // SVG doesn't use the offset <-> position selection system. | 101 // SVG doesn't use the offset <-> position selection system. |
103 ASSERT_NOT_REACHED(); | 102 ASSERT_NOT_REACHED(); |
(...skipping 28 matching lines...) Expand all Loading... |
132 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
on) const | 131 LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
on) const |
133 { | 132 { |
134 int boxStart = start(); | 133 int boxStart = start(); |
135 startPosition = std::max(startPosition - boxStart, 0); | 134 startPosition = std::max(startPosition - boxStart, 0); |
136 endPosition = std::min(endPosition - boxStart, static_cast<int>(len())); | 135 endPosition = std::min(endPosition - boxStart, static_cast<int>(len())); |
137 if (startPosition >= endPosition) | 136 if (startPosition >= endPosition) |
138 return LayoutRect(); | 137 return LayoutRect(); |
139 | 138 |
140 const ComputedStyle& style = lineLayoutItem().styleRef(); | 139 const ComputedStyle& style = lineLayoutItem().styleRef(); |
141 | 140 |
142 AffineTransform fragmentTransform; | |
143 FloatRect selectionRect; | 141 FloatRect selectionRect; |
144 int fragmentStartPosition = 0; | 142 int fragmentStartPosition = 0; |
145 int fragmentEndPosition = 0; | 143 int fragmentEndPosition = 0; |
146 | 144 |
147 unsigned textFragmentsSize = m_textFragments.size(); | 145 unsigned textFragmentsSize = m_textFragments.size(); |
148 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 146 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
149 const SVGTextFragment& fragment = m_textFragments.at(i); | 147 const SVGTextFragment& fragment = m_textFragments.at(i); |
150 | 148 |
151 fragmentStartPosition = startPosition; | 149 fragmentStartPosition = startPosition; |
152 fragmentEndPosition = endPosition; | 150 fragmentEndPosition = endPosition; |
153 if (!mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStart
Position, fragmentEndPosition)) | 151 if (!mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStart
Position, fragmentEndPosition)) |
154 continue; | 152 continue; |
155 | 153 |
156 FloatRect fragmentRect = selectionRectForTextFragment(fragment, fragment
StartPosition, fragmentEndPosition, style); | 154 FloatRect fragmentRect = selectionRectForTextFragment(fragment, fragment
StartPosition, fragmentEndPosition, style); |
157 if (fragment.isTransformed()) { | 155 if (fragment.isTransformed()) |
158 fragment.buildFragmentTransform(fragmentTransform); | 156 fragmentRect = fragment.buildFragmentTransform().mapRect(fragmentRec
t); |
159 fragmentRect = fragmentTransform.mapRect(fragmentRect); | |
160 } | |
161 | 157 |
162 selectionRect.unite(fragmentRect); | 158 selectionRect.unite(fragmentRect); |
163 } | 159 } |
164 | 160 |
165 return LayoutRect(enclosingIntRect(selectionRect)); | 161 return LayoutRect(enclosingIntRect(selectionRect)); |
166 } | 162 } |
167 | 163 |
168 void SVGInlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& pain
tOffset, LayoutUnit, LayoutUnit) const | 164 void SVGInlineTextBox::paint(const PaintInfo& paintInfo, const LayoutPoint& pain
tOffset, LayoutUnit, LayoutUnit) const |
169 { | 165 { |
170 SVGInlineTextBoxPainter(*this).paint(paintInfo, paintOffset); | 166 SVGInlineTextBoxPainter(*this).paint(paintInfo, paintOffset); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 SVGInlineTextBoxPainter(*this).paintTextMatchMarkerForeground(paintInfo, poi
nt, marker, style, font); | 223 SVGInlineTextBoxPainter(*this).paintTextMatchMarkerForeground(paintInfo, poi
nt, marker, style, font); |
228 } | 224 } |
229 | 225 |
230 void SVGInlineTextBox::paintTextMatchMarkerBackground(const PaintInfo& paintInfo
, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style,
const Font& font) const | 226 void SVGInlineTextBox::paintTextMatchMarkerBackground(const PaintInfo& paintInfo
, const LayoutPoint& point, DocumentMarker* marker, const ComputedStyle& style,
const Font& font) const |
231 { | 227 { |
232 SVGInlineTextBoxPainter(*this).paintTextMatchMarkerBackground(paintInfo, poi
nt, marker, style, font); | 228 SVGInlineTextBoxPainter(*this).paintTextMatchMarkerBackground(paintInfo, poi
nt, marker, style, font); |
233 } | 229 } |
234 | 230 |
235 LayoutRect SVGInlineTextBox::calculateBoundaries() const | 231 LayoutRect SVGInlineTextBox::calculateBoundaries() const |
236 { | 232 { |
237 LayoutRect textRect; | |
238 | |
239 LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->lineL
ayoutItem()); | 233 LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText(this->lineL
ayoutItem()); |
240 | |
241 float scalingFactor = lineLayoutItem.scalingFactor(); | 234 float scalingFactor = lineLayoutItem.scalingFactor(); |
242 ASSERT(scalingFactor); | 235 ASSERT(scalingFactor); |
243 | |
244 LayoutUnit baseline = lineLayoutItem.scaledFont().fontMetrics().floatAscent(
) / scalingFactor; | 236 LayoutUnit baseline = lineLayoutItem.scaledFont().fontMetrics().floatAscent(
) / scalingFactor; |
245 | 237 |
246 AffineTransform fragmentTransform; | 238 LayoutRect textBoundingRect; |
247 unsigned textFragmentsSize = m_textFragments.size(); | 239 for (const SVGTextFragment& fragment : m_textFragments) |
248 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 240 textBoundingRect.unite(LayoutRect(fragment.overflowBoundingBox(baseline)
)); |
249 const SVGTextFragment& fragment = m_textFragments.at(i); | |
250 | 241 |
251 FloatRect fragmentRect( | 242 return textBoundingRect; |
252 fragment.x - fragment.glyphOverflowLeft, | |
253 fragment.y - baseline - fragment.glyphOverflowTop, | |
254 fragment.width + fragment.glyphOverflowLeft + fragment.glyphOverflow
Right, | |
255 fragment.height + fragment.glyphOverflowTop + fragment.glyphOverflow
Bottom); | |
256 fragment.buildFragmentTransform(fragmentTransform); | |
257 fragmentRect = fragmentTransform.mapRect(fragmentRect); | |
258 | |
259 textRect.unite(LayoutRect(fragmentRect)); | |
260 } | |
261 | |
262 return textRect; | |
263 } | 243 } |
264 | 244 |
265 bool SVGInlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation&
locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUn
it) | 245 bool SVGInlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation&
locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUn
it) |
266 { | 246 { |
267 // FIXME: integrate with InlineTextBox::nodeAtPoint better. | 247 // FIXME: integrate with InlineTextBox::nodeAtPoint better. |
268 ASSERT(!isLineBreak()); | 248 ASSERT(!isLineBreak()); |
269 | 249 |
270 PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, r
esult.hitTestRequest(), lineLayoutItem().style()->pointerEvents()); | 250 PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, r
esult.hitTestRequest(), lineLayoutItem().style()->pointerEvents()); |
271 bool isVisible = lineLayoutItem().style()->visibility() == VISIBLE; | 251 bool isVisible = lineLayoutItem().style()->visibility() == VISIBLE; |
272 if (isVisible || !hitRules.requireVisible) { | 252 if (isVisible || !hitRules.requireVisible) { |
273 if (hitRules.canHitBoundingBox | 253 if (hitRules.canHitBoundingBox |
274 || (hitRules.canHitStroke && (lineLayoutItem().style()->svgStyle().h
asStroke() || !hitRules.requireStroke)) | 254 || (hitRules.canHitStroke && (lineLayoutItem().style()->svgStyle().h
asStroke() || !hitRules.requireStroke)) |
275 || (hitRules.canHitFill && (lineLayoutItem().style()->svgStyle().has
Fill() || !hitRules.requireFill))) { | 255 || (hitRules.canHitFill && (lineLayoutItem().style()->svgStyle().has
Fill() || !hitRules.requireFill))) { |
276 LayoutPoint boxOrigin(x(), y()); | 256 LayoutPoint boxOrigin(x(), y()); |
277 boxOrigin.moveBy(accumulatedOffset); | 257 boxOrigin.moveBy(accumulatedOffset); |
278 LayoutRect rect(boxOrigin, size()); | 258 LayoutRect rect(boxOrigin, size()); |
279 if (locationInContainer.intersects(rect)) { | 259 if (locationInContainer.intersects(rect)) { |
280 LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText
(this->lineLayoutItem()); | 260 LineLayoutSVGInlineText lineLayoutItem = LineLayoutSVGInlineText
(this->lineLayoutItem()); |
281 ASSERT(lineLayoutItem.scalingFactor()); | 261 ASSERT(lineLayoutItem.scalingFactor()); |
282 float baseline = lineLayoutItem.scaledFont().fontMetrics().float
Ascent() / lineLayoutItem.scalingFactor(); | 262 float baseline = lineLayoutItem.scaledFont().fontMetrics().float
Ascent() / lineLayoutItem.scalingFactor(); |
283 | 263 |
284 AffineTransform fragmentTransform; | 264 FloatPoint floatLocation = FloatPoint(locationInContainer.point(
)); |
285 for (const auto& fragment : m_textFragments) { | 265 for (const SVGTextFragment& fragment : m_textFragments) { |
286 FloatQuad fragmentQuad(FloatRect(fragment.x, fragment.y - ba
seline, fragment.width, fragment.height)); | 266 FloatQuad fragmentQuad = fragment.boundingQuad(baseline); |
287 if (fragment.isTransformed()) { | 267 if (fragmentQuad.containsPoint(floatLocation)) { |
288 fragment.buildFragmentTransform(fragmentTransform); | |
289 fragmentQuad = fragmentTransform.mapQuad(fragmentQuad); | |
290 } | |
291 | |
292 if (fragmentQuad.containsPoint(FloatPoint(locationInContaine
r.point()))) { | |
293 lineLayoutItem.updateHitTestResult(result, locationInCon
tainer.point() - toLayoutSize(accumulatedOffset)); | 268 lineLayoutItem.updateHitTestResult(result, locationInCon
tainer.point() - toLayoutSize(accumulatedOffset)); |
294 if (!result.addNodeToListBasedTestResult(lineLayoutItem.
node(), locationInContainer, rect)) | 269 if (!result.addNodeToListBasedTestResult(lineLayoutItem.
node(), locationInContainer, rect)) |
295 return true; | 270 return true; |
296 } | 271 } |
297 } | 272 } |
298 } | 273 } |
299 } | 274 } |
300 } | 275 } |
301 return false; | 276 return false; |
302 } | 277 } |
303 | 278 |
304 } // namespace blink | 279 } // namespace blink |
OLD | NEW |