Index: third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp |
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp |
index 201ed833b31da0b7e9074053b17130d17d816f8d..8c3173e3171fb19055ac71e968374813c92f7cd8 100644 |
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp |
+++ b/third_party/WebKit/Source/core/layout/svg/SVGTextQuery.cpp |
@@ -168,38 +168,6 @@ static void logicalQuery(LayoutObject* queryRoot, QueryData* queryData, ProcessT |
} |
} |
-static void modifyStartEndPositionsRespectingLigatures(const QueryData* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) |
-{ |
- const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLineLayout.layoutAttributes()->textMetricsValues(); |
- |
- unsigned textMetricsOffset = fragment.metricsListOffset; |
- int fragmentOffset = 0; |
- int fragmentEnd = static_cast<int>(fragment.length); |
- |
- // Find the text metrics cell that start at or contain the character startPosition. |
- while (fragmentOffset < fragmentEnd) { |
- const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; |
- int glyphEnd = fragmentOffset + metrics.length(); |
- if (startPosition < glyphEnd) |
- break; |
- fragmentOffset = glyphEnd; |
- textMetricsOffset++; |
- } |
- |
- startPosition = fragmentOffset; |
- |
- // Find the text metrics cell that contain or ends at the character endPosition. |
- while (fragmentOffset < fragmentEnd) { |
- const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset]; |
- fragmentOffset += metrics.length(); |
- if (fragmentOffset >= endPosition) |
- break; |
- textMetricsOffset++; |
- } |
- |
- endPosition = fragmentOffset; |
-} |
- |
static bool mapStartEndPositionsIntoFragmentCoordinates(const QueryData* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) |
{ |
unsigned boxStart = queryData->currentOffset; |
@@ -210,12 +178,7 @@ static bool mapStartEndPositionsIntoFragmentCoordinates(const QueryData* queryDa |
// Reuse the same logic used for text selection & painting, to map our |
// query start/length into start/endPositions of the current text fragment. |
- if (!queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, startPosition, endPosition)) |
- return false; |
- |
- modifyStartEndPositionsRespectingLigatures(queryData, fragment, startPosition, endPosition); |
- ASSERT(startPosition < endPosition); |
- return true; |
+ return queryData->textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, startPosition, endPosition); |
} |
// numberOfCharacters() implementation |
@@ -256,29 +219,31 @@ float SVGTextQuery::textLength() const |
return data.textLength; |
} |
-const SVGTextMetrics& findMetricsForCharacter(const Vector<SVGTextMetrics>& textMetricsValues, const SVGTextFragment& fragment, unsigned startInFragment) |
+using MetricsList = Vector<SVGTextMetrics>; |
+ |
+MetricsList::const_iterator findMetricsForCharacter(const MetricsList& metricsList, const SVGTextFragment& fragment, unsigned startInFragment) |
{ |
// Find the text metrics cell that starts at or contains the character at |startInFragment|. |
- unsigned textMetricsOffset = fragment.metricsListOffset; |
+ MetricsList::const_iterator metrics = metricsList.begin() + fragment.metricsListOffset; |
unsigned fragmentOffset = 0; |
while (fragmentOffset < fragment.length) { |
- const SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset++]; |
- unsigned glyphEnd = fragmentOffset + metrics.length(); |
- if (startInFragment < glyphEnd) |
+ fragmentOffset += metrics->length(); |
+ if (startInFragment < fragmentOffset) |
break; |
- fragmentOffset = glyphEnd; |
+ ++metrics; |
} |
- return textMetricsValues[textMetricsOffset - 1]; |
+ ASSERT(metrics <= metricsList.end()); |
+ return metrics; |
} |
static float calculateGlyphRange(const QueryData* queryData, const SVGTextFragment& fragment, unsigned start, unsigned end) |
{ |
+ const MetricsList& metricsList = queryData->textLineLayout.layoutAttributes()->textMetricsValues(); |
+ auto metrics = findMetricsForCharacter(metricsList, fragment, start); |
+ auto endMetrics = findMetricsForCharacter(metricsList, fragment, end); |
float glyphRange = 0; |
- const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLineLayout.layoutAttributes()->textMetricsValues(); |
- for (unsigned character = start; character < end; character++) { |
- const SVGTextMetrics& metrics = findMetricsForCharacter(textMetricsValues, fragment, character); |
- glyphRange += queryData->isVerticalText ? metrics.height() : metrics.width(); |
- } |
+ for (; metrics != endMetrics; ++metrics) |
+ glyphRange += queryData->isVerticalText ? metrics->height() : metrics->width(); |
return glyphRange; |
} |
@@ -328,7 +293,7 @@ struct StartPositionOfCharacterData : QueryData { |
FloatPoint startPosition; |
}; |
-static FloatPoint calculateGlyphPositionWithoutTransform(const QueryData* queryData, const SVGTextFragment& fragment, int offsetInFragment) |
+static FloatPoint calculateGlyphPositionWithoutTransform(const QueryData* queryData, const SVGTextFragment& fragment, unsigned offsetInFragment) |
{ |
float glyphOffsetInDirection = calculateGlyphRange(queryData, fragment, 0, offsetInFragment); |
@@ -346,7 +311,7 @@ static FloatPoint calculateGlyphPositionWithoutTransform(const QueryData* queryD |
return glyphPosition; |
} |
-static FloatPoint calculateGlyphPosition(const QueryData* queryData, const SVGTextFragment& fragment, int offsetInFragment) |
+static FloatPoint calculateGlyphPosition(const QueryData* queryData, const SVGTextFragment& fragment, unsigned offsetInFragment) |
{ |
FloatPoint glyphPosition = calculateGlyphPositionWithoutTransform(queryData, fragment, offsetInFragment); |
if (fragment.isTransformed()) { |
@@ -396,10 +361,7 @@ static bool endPositionOfCharacterCallback(QueryData* queryData, const SVGTextFr |
if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition)) |
return false; |
- // TODO(fs): mapStartEndPositionsIntoFragmentCoordinates(...) above applies |
- // some heuristics for ligatures, so why not just use endPosition here? |
- // (rather than startPosition+1) |
- data->endPosition = calculateGlyphPosition(queryData, fragment, startPosition + 1); |
+ data->endPosition = calculateGlyphPosition(queryData, fragment, endPosition); |
return true; |
} |
@@ -470,12 +432,12 @@ static inline FloatRect calculateGlyphBoundaries(const QueryData* queryData, con |
// Use the SVGTextMetrics computed by SVGTextMetricsBuilder (which spends |
// time attempting to compute more correct glyph bounds already, handling |
// cursive scripts to some degree.) |
- const Vector<SVGTextMetrics>& textMetricsValues = queryData->textLineLayout.layoutAttributes()->textMetricsValues(); |
- const SVGTextMetrics& metrics = findMetricsForCharacter(textMetricsValues, fragment, startPosition); |
+ const MetricsList& textMetricsValues = queryData->textLineLayout.layoutAttributes()->textMetricsValues(); |
+ auto metrics = findMetricsForCharacter(textMetricsValues, fragment, startPosition); |
// TODO(fs): Negative glyph extents seems kind of weird to have, but |
// presently it can occur in some cases (like Arabic.) |
- FloatSize glyphSize(std::max<float>(metrics.width(), 0), std::max<float>(metrics.height(), 0)); |
+ FloatSize glyphSize(std::max<float>(metrics->width(), 0), std::max<float>(metrics->height(), 0)); |
// If RTL, adjust the starting point to align with the LHS of the glyph bounding box. |
if (!queryData->textBox->isLeftToRightDirection()) { |