| 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 21 matching lines...) Expand all Loading... |
| 32 #include "core/layout/PointerEventsHitRules.h" | 32 #include "core/layout/PointerEventsHitRules.h" |
| 33 #include "core/layout/line/InlineFlowBox.h" | 33 #include "core/layout/line/InlineFlowBox.h" |
| 34 #include "core/layout/svg/LayoutSVGInlineText.h" | 34 #include "core/layout/svg/LayoutSVGInlineText.h" |
| 35 #include "core/paint/SVGInlineTextBoxPainter.h" | 35 #include "core/paint/SVGInlineTextBoxPainter.h" |
| 36 #include "platform/FloatConversion.h" | 36 #include "platform/FloatConversion.h" |
| 37 #include "platform/fonts/FontCache.h" | 37 #include "platform/fonts/FontCache.h" |
| 38 | 38 |
| 39 namespace blink { | 39 namespace blink { |
| 40 | 40 |
| 41 struct ExpectedSVGInlineTextBoxSize : public InlineTextBox { | 41 struct ExpectedSVGInlineTextBoxSize : public InlineTextBox { |
| 42 FloatWillBeLayoutUnit float1; | 42 LayoutUnit float1; |
| 43 uint32_t bitfields : 1; | 43 uint32_t bitfields : 1; |
| 44 Vector<SVGTextFragment> vector; | 44 Vector<SVGTextFragment> vector; |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 static_assert(sizeof(SVGInlineTextBox) == sizeof(ExpectedSVGInlineTextBoxSize),
"SVGInlineTextBox has an unexpected size"); | 47 static_assert(sizeof(SVGInlineTextBox) == sizeof(ExpectedSVGInlineTextBoxSize),
"SVGInlineTextBox has an unexpected size"); |
| 48 | 48 |
| 49 SVGInlineTextBox::SVGInlineTextBox(LayoutObject& object, int start, unsigned sho
rt length) | 49 SVGInlineTextBox::SVGInlineTextBox(LayoutObject& object, int start, unsigned sho
rt length) |
| 50 : InlineTextBox(object, start, length) | 50 : InlineTextBox(object, start, length) |
| 51 , m_logicalHeight(0) | 51 , m_logicalHeight(0) |
| 52 , m_startsNewTextChunk(false) | 52 , m_startsNewTextChunk(false) |
| 53 { | 53 { |
| 54 } | 54 } |
| 55 | 55 |
| 56 void SVGInlineTextBox::dirtyLineBoxes() | 56 void SVGInlineTextBox::dirtyLineBoxes() |
| 57 { | 57 { |
| 58 InlineTextBox::dirtyLineBoxes(); | 58 InlineTextBox::dirtyLineBoxes(); |
| 59 | 59 |
| 60 // Clear the now stale text fragments | 60 // Clear the now stale text fragments |
| 61 clearTextFragments(); | 61 clearTextFragments(); |
| 62 | 62 |
| 63 // And clear any following text fragments as the text on which they | 63 // And clear any following text fragments as the text on which they |
| 64 // depend may now no longer exist, or glyph positions may be wrong | 64 // depend may now no longer exist, or glyph positions may be wrong |
| 65 InlineTextBox* nextBox = nextTextBox(); | 65 InlineTextBox* nextBox = nextTextBox(); |
| 66 if (nextBox) | 66 if (nextBox) |
| 67 nextBox->dirtyLineBoxes(); | 67 nextBox->dirtyLineBoxes(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 int SVGInlineTextBox::offsetForPosition(FloatWillBeLayoutUnit, bool) const | 70 int SVGInlineTextBox::offsetForPosition(LayoutUnit, bool) const |
| 71 { | 71 { |
| 72 // SVG doesn't use the standard offset <-> position selection system, as it'
s not suitable for SVGs complex needs. | 72 // SVG doesn't use the standard offset <-> position selection system, as it'
s not suitable for SVGs complex needs. |
| 73 // vertical text selection, inline boxes spanning multiple lines (contrary t
o HTML, etc.) | 73 // vertical text selection, inline boxes spanning multiple lines (contrary t
o HTML, etc.) |
| 74 ASSERT_NOT_REACHED(); | 74 ASSERT_NOT_REACHED(); |
| 75 return 0; | 75 return 0; |
| 76 } | 76 } |
| 77 | 77 |
| 78 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
t, FloatWillBeLayoutUnit position, bool includePartialGlyphs) const | 78 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
t, LayoutUnit position, bool includePartialGlyphs) const |
| 79 { | 79 { |
| 80 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(this->layoutOb
ject()); | 80 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(this->layoutOb
ject()); |
| 81 | 81 |
| 82 float scalingFactor = textLayoutObject.scalingFactor(); | 82 float scalingFactor = textLayoutObject.scalingFactor(); |
| 83 ASSERT(scalingFactor); | 83 ASSERT(scalingFactor); |
| 84 | 84 |
| 85 const ComputedStyle& style = textLayoutObject.styleRef(); | 85 const ComputedStyle& style = textLayoutObject.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 AffineTransform fragmentTransform; | 91 AffineTransform fragmentTransform; |
| 92 fragment.buildFragmentTransform(fragmentTransform); | 92 fragment.buildFragmentTransform(fragmentTransform); |
| 93 if (!fragmentTransform.isIdentity()) | 93 if (!fragmentTransform.isIdentity()) |
| 94 textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransfo
rm.xScale())); | 94 textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransfo
rm.xScale())); |
| 95 | 95 |
| 96 return fragment.characterOffset - start() + textLayoutObject.scaledFont().of
fsetForPosition(textRun, position * scalingFactor, includePartialGlyphs); | 96 return fragment.characterOffset - start() + textLayoutObject.scaledFont().of
fsetForPosition(textRun, position * scalingFactor, includePartialGlyphs); |
| 97 } | 97 } |
| 98 | 98 |
| 99 FloatWillBeLayoutUnit SVGInlineTextBox::positionForOffset(int) const | 99 LayoutUnit SVGInlineTextBox::positionForOffset(int) const |
| 100 { | 100 { |
| 101 // SVG doesn't use the offset <-> position selection system. | 101 // SVG doesn't use the offset <-> position selection system. |
| 102 ASSERT_NOT_REACHED(); | 102 ASSERT_NOT_REACHED(); |
| 103 return 0; | 103 return 0; |
| 104 } | 104 } |
| 105 | 105 |
| 106 FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
fragment, int startPosition, int endPosition, const ComputedStyle& style) | 106 FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
fragment, int startPosition, int endPosition, const ComputedStyle& style) |
| 107 { | 107 { |
| 108 ASSERT(startPosition < endPosition); | 108 ASSERT(startPosition < endPosition); |
| 109 | 109 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 startPosition -= fragmentOffsetInBox; | 207 startPosition -= fragmentOffsetInBox; |
| 208 endPosition -= fragmentOffsetInBox; | 208 endPosition -= fragmentOffsetInBox; |
| 209 | 209 |
| 210 // Intersect with the fragment range. | 210 // Intersect with the fragment range. |
| 211 startPosition = std::max(startPosition, 0); | 211 startPosition = std::max(startPosition, 0); |
| 212 endPosition = std::min(endPosition, static_cast<int>(fragment.length)); | 212 endPosition = std::min(endPosition, static_cast<int>(fragment.length)); |
| 213 | 213 |
| 214 return startPosition < endPosition; | 214 return startPosition < endPosition; |
| 215 } | 215 } |
| 216 | 216 |
| 217 void SVGInlineTextBox::paintDocumentMarker(GraphicsContext*, const FloatPointWil
lBeLayoutPoint&, DocumentMarker*, const ComputedStyle&, const Font&, bool) | 217 void SVGInlineTextBox::paintDocumentMarker(GraphicsContext*, const LayoutPoint&,
DocumentMarker*, const ComputedStyle&, const Font&, bool) |
| 218 { | 218 { |
| 219 // SVG does not have support for generic document markers (e.g., spellchecki
ng, etc). | 219 // SVG does not have support for generic document markers (e.g., spellchecki
ng, etc). |
| 220 } | 220 } |
| 221 | 221 |
| 222 void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const Floa
tPointWillBeLayoutPoint& point, DocumentMarker* marker, const ComputedStyle& sty
le, const Font& font) | 222 void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const Layo
utPoint& point, DocumentMarker* marker, const ComputedStyle& style, const Font&
font) |
| 223 { | 223 { |
| 224 SVGInlineTextBoxPainter(*this).paintTextMatchMarker(context, point.toFloatPo
int(), marker, style, font); | 224 SVGInlineTextBoxPainter(*this).paintTextMatchMarker(context, point, marker,
style, font); |
| 225 } | 225 } |
| 226 | 226 |
| 227 FloatRectWillBeLayoutRect SVGInlineTextBox::calculateBoundaries() const | 227 LayoutRect SVGInlineTextBox::calculateBoundaries() const |
| 228 { | 228 { |
| 229 FloatRectWillBeLayoutRect textRect; | 229 LayoutRect textRect; |
| 230 | 230 |
| 231 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(this->layoutOb
ject()); | 231 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(this->layoutOb
ject()); |
| 232 | 232 |
| 233 float scalingFactor = textLayoutObject.scalingFactor(); | 233 float scalingFactor = textLayoutObject.scalingFactor(); |
| 234 ASSERT(scalingFactor); | 234 ASSERT(scalingFactor); |
| 235 | 235 |
| 236 FloatWillBeLayoutUnit baseline = textLayoutObject.scaledFont().fontMetrics()
.floatAscent() / scalingFactor; | 236 LayoutUnit baseline = textLayoutObject.scaledFont().fontMetrics().floatAscen
t() / scalingFactor; |
| 237 | 237 |
| 238 AffineTransform fragmentTransform; | 238 AffineTransform fragmentTransform; |
| 239 unsigned textFragmentsSize = m_textFragments.size(); | 239 unsigned textFragmentsSize = m_textFragments.size(); |
| 240 for (unsigned i = 0; i < textFragmentsSize; ++i) { | 240 for (unsigned i = 0; i < textFragmentsSize; ++i) { |
| 241 const SVGTextFragment& fragment = m_textFragments.at(i); | 241 const SVGTextFragment& fragment = m_textFragments.at(i); |
| 242 FloatRectWillBeLayoutRect fragmentRect(fragment.x, fragment.y - baseline
, fragment.width, fragment.height); | 242 FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width
, fragment.height); |
| 243 fragment.buildFragmentTransform(fragmentTransform); | 243 fragment.buildFragmentTransform(fragmentTransform); |
| 244 fragmentRect = fragmentTransform.mapRect(fragmentRect.toFloatRect()); | 244 fragmentRect = fragmentTransform.mapRect(fragmentRect); |
| 245 | 245 |
| 246 textRect.unite(fragmentRect); | 246 textRect.unite(LayoutRect(fragmentRect)); |
| 247 } | 247 } |
| 248 | 248 |
| 249 return textRect; | 249 return textRect; |
| 250 } | 250 } |
| 251 | 251 |
| 252 bool SVGInlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation&
locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUn
it) | 252 bool SVGInlineTextBox::nodeAtPoint(HitTestResult& result, const HitTestLocation&
locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUn
it) |
| 253 { | 253 { |
| 254 // FIXME: integrate with InlineTextBox::nodeAtPoint better. | 254 // FIXME: integrate with InlineTextBox::nodeAtPoint better. |
| 255 ASSERT(!isLineBreak()); | 255 ASSERT(!isLineBreak()); |
| 256 | 256 |
| 257 PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, r
esult.hitTestRequest(), layoutObject().style()->pointerEvents()); | 257 PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, r
esult.hitTestRequest(), layoutObject().style()->pointerEvents()); |
| 258 bool isVisible = layoutObject().style()->visibility() == VISIBLE; | 258 bool isVisible = layoutObject().style()->visibility() == VISIBLE; |
| 259 if (isVisible || !hitRules.requireVisible) { | 259 if (isVisible || !hitRules.requireVisible) { |
| 260 if (hitRules.canHitBoundingBox | 260 if (hitRules.canHitBoundingBox |
| 261 || (hitRules.canHitStroke && (layoutObject().style()->svgStyle().has
Stroke() || !hitRules.requireStroke)) | 261 || (hitRules.canHitStroke && (layoutObject().style()->svgStyle().has
Stroke() || !hitRules.requireStroke)) |
| 262 || (hitRules.canHitFill && (layoutObject().style()->svgStyle().hasFi
ll() || !hitRules.requireFill))) { | 262 || (hitRules.canHitFill && (layoutObject().style()->svgStyle().hasFi
ll() || !hitRules.requireFill))) { |
| 263 FloatPointWillBeLayoutPoint boxOrigin(x(), y()); | 263 LayoutPoint boxOrigin(x(), y()); |
| 264 boxOrigin.moveBy(accumulatedOffset); | 264 boxOrigin.moveBy(accumulatedOffset); |
| 265 FloatRectWillBeLayoutRect rect(boxOrigin, size()); | 265 LayoutRect rect(boxOrigin, size()); |
| 266 // FIXME: both calls to rawValue() below is temporary and should be
removed once the transition | 266 // FIXME: both calls to rawValue() below is temporary and should be
removed once the transition |
| 267 // to LayoutUnit-based types is complete (crbug.com/321237) | 267 // to LayoutUnit-based types is complete (crbug.com/321237) |
| 268 if (locationInContainer.intersects(rect.rawValue())) { | 268 if (locationInContainer.intersects(rect)) { |
| 269 layoutObject().updateHitTestResult(result, locationInContainer.p
oint() - toLayoutSize(accumulatedOffset)); | 269 layoutObject().updateHitTestResult(result, locationInContainer.p
oint() - toLayoutSize(accumulatedOffset)); |
| 270 if (!result.addNodeToListBasedTestResult(layoutObject().node(),
locationInContainer, rect.rawValue())) | 270 if (!result.addNodeToListBasedTestResult(layoutObject().node(),
locationInContainer, rect)) |
| 271 return true; | 271 return true; |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 return false; | 275 return false; |
| 276 } | 276 } |
| 277 | 277 |
| 278 } // namespace blink | 278 } // namespace blink |
| OLD | NEW |