Index: Source/core/rendering/svg/SVGTextQuery.cpp |
diff --git a/Source/core/rendering/svg/SVGTextQuery.cpp b/Source/core/rendering/svg/SVGTextQuery.cpp |
index 294e8deb658f9e6a3f038dffdb256764c19706dd..fc0b81471a0680891ed61b0e33b58bae5f2a6970 100644 |
--- a/Source/core/rendering/svg/SVGTextQuery.cpp |
+++ b/Source/core/rendering/svg/SVGTextQuery.cpp |
@@ -151,7 +151,7 @@ bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, |
if (startPosition >= endPosition) |
return false; |
- modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosition); |
+ modifyStartEndPositionsRespectingLigatures(queryData, fragment, startPosition, endPosition); |
if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, startPosition, endPosition)) |
return false; |
@@ -159,74 +159,40 @@ bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, |
return true; |
} |
-void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, int& startPosition, int& endPosition) const |
+void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) const |
{ |
SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutAttributes(); |
Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsValues(); |
- unsigned boxStart = queryData->textBox->start(); |
- unsigned boxLength = queryData->textBox->len(); |
- unsigned textMetricsOffset = 0; |
- unsigned textMetricsSize = textMetricsValues.size(); |
- |
- unsigned positionOffset = 0; |
- unsigned positionSize = layoutAttributes->context()->textLength(); |
+ unsigned textMetricsOffset = fragment.metricsListOffset; |
- bool alterStartPosition = true; |
- bool alterEndPosition = true; |
+ // Compute the offset of the fragment within the box, since that's the |
+ // space <startPosition, endPosition> is in (and that's what we need). |
+ int fragmentOffsetInBox = fragment.characterOffset - queryData->textBox->start(); |
+ int fragmentEndInBox = fragmentOffsetInBox + fragment.length; |
- int lastPositionOffset = -1; |
- for (; textMetricsOffset < textMetricsSize && positionOffset < positionSize; ++textMetricsOffset) { |
+ // Find the text metrics cell that start at or contain the character startPosition. |
+ while (fragmentOffsetInBox < fragmentEndInBox) { |
SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; |
- |
- // Advance to text box start location. |
- if (positionOffset < boxStart) { |
- positionOffset += metrics.length(); |
- continue; |
- } |
- |
- // Stop if we've finished processing this text box. |
- if (positionOffset >= boxStart + boxLength) |
+ int glyphEnd = fragmentOffsetInBox + metrics.length(); |
+ if (startPosition < glyphEnd) |
break; |
+ fragmentOffsetInBox = glyphEnd; |
+ textMetricsOffset++; |
+ } |
- // If the start position maps to a character in the metrics list, we don't need to modify it. |
- if (startPosition == static_cast<int>(positionOffset)) |
- alterStartPosition = false; |
- |
- // If the start position maps to a character in the metrics list, we don't need to modify it. |
- if (endPosition == static_cast<int>(positionOffset)) |
- alterEndPosition = false; |
- |
- // Detect ligatures. |
- if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) { |
- if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) { |
- startPosition = lastPositionOffset; |
- alterStartPosition = false; |
- } |
- |
- if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) { |
- endPosition = positionOffset; |
- alterEndPosition = false; |
- } |
- } |
+ startPosition = fragmentOffsetInBox; |
- if (!alterStartPosition && !alterEndPosition) |
+ // Find the text metrics cell that contain or ends at the character endPosition. |
+ while (fragmentOffsetInBox < fragmentEndInBox) { |
+ SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; |
+ fragmentOffsetInBox += metrics.length(); |
+ if (fragmentOffsetInBox >= endPosition) |
break; |
- |
- lastPositionOffset = positionOffset; |
- positionOffset += metrics.length(); |
+ textMetricsOffset++; |
} |
- if (!alterStartPosition && !alterEndPosition) |
- return; |
- |
- if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) { |
- if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) |
- startPosition = lastPositionOffset; |
- |
- if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) |
- endPosition = positionOffset; |
- } |
+ endPosition = fragmentOffsetInBox; |
} |
// numberOfCharacters() implementation |