Index: Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
diff --git a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
index a7cccd026d5456ea721e521447ea754b507112cc..0eb4f368defa2ba35b59539d8ddf9757a8cc8832 100644 |
--- a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
+++ b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
@@ -41,60 +41,51 @@ inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair() const |
return U16_IS_LEAD(m_run[m_textPosition]) && int(m_textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]); |
} |
-bool SVGTextMetricsBuilder::advance() |
-{ |
- m_textPosition += m_currentMetrics.length(); |
- if (int(m_textPosition) >= m_run.charactersLength()) |
- return false; |
- |
- if (m_isComplexText) |
- advanceComplexText(); |
- else |
- advanceSimpleText(); |
- |
- return m_currentMetrics.length() > 0; |
-} |
- |
-void SVGTextMetricsBuilder::advanceSimpleText() |
+SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterSimple() |
{ |
GlyphBuffer glyphBuffer; |
unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1, &glyphBuffer); |
- if (!metricsLength) { |
- m_currentMetrics = SVGTextMetrics(); |
- return; |
- } |
+ if (!metricsLength) |
+ return SVGTextMetrics(); |
float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth; |
m_totalWidth = m_simpleWidthIterator->runWidthSoFar(); |
Glyph glyphId = glyphBuffer.glyphAt(0); |
- m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, glyphId); |
+ return SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, glyphId); |
} |
-void SVGTextMetricsBuilder::advanceComplexText() |
+SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterComplex() |
{ |
unsigned metricsLength = currentCharacterStartsSurrogatePair() ? 2 : 1; |
- m_currentMetrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength); |
- m_complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, m_textPosition + metricsLength); |
- ASSERT(m_currentMetrics.length() == metricsLength); |
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength); |
+ ASSERT(metrics.length() == metricsLength); |
+ SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, m_textPosition + metricsLength); |
// Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken |
// when rendering the glyph "in context" (with it's surrounding characters) it changes due to shaping. |
// So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is |
// not equal to the sum of the individual lengths of the glyphs, when measuring them isolated. |
- float currentWidth = m_complexStartToCurrentMetrics.width() - m_totalWidth; |
- if (currentWidth != m_currentMetrics.width()) |
- m_currentMetrics.setWidth(currentWidth); |
+ float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth; |
+ if (currentWidth != metrics.width()) |
+ metrics.setWidth(currentWidth); |
- m_totalWidth = m_complexStartToCurrentMetrics.width(); |
+ m_totalWidth = complexStartToCurrentMetrics.width(); |
+ return metrics; |
+} |
+ |
+SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacter() |
+{ |
+ if (m_isComplexText) |
+ return computeMetricsForCurrentCharacterComplex(); |
+ |
+ return computeMetricsForCurrentCharacterSimple(); |
} |
void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText* text) |
{ |
m_text = text; |
m_textPosition = 0; |
- m_currentMetrics = SVGTextMetrics(); |
- m_complexStartToCurrentMetrics = SVGTextMetrics(); |
m_totalWidth = 0; |
const Font& scaledFont = text->scaledFont(); |
@@ -139,14 +130,20 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu |
bool preserveWhiteSpace = text->style()->whiteSpace() == PRE; |
unsigned surrogatePairCharacters = 0; |
unsigned skippedCharacters = 0; |
+ unsigned textLength = static_cast<unsigned>(m_run.charactersLength()); |
+ |
+ SVGTextMetrics currentMetrics; |
+ for (; m_textPosition < textLength; m_textPosition += currentMetrics.length()) { |
+ currentMetrics = computeMetricsForCurrentCharacter(); |
+ if (!currentMetrics.length()) |
+ break; |
- while (advance()) { |
bool characterIsWhiteSpace = m_run[m_textPosition] == ' '; |
if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) { |
if (processRenderer) |
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); |
if (data->allCharactersMap) |
- skippedCharacters += m_currentMetrics.length(); |
+ skippedCharacters += currentMetrics.length(); |
continue; |
} |
@@ -156,7 +153,7 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu |
if (it != data->allCharactersMap->end()) |
attributes->characterDataMap().set(m_textPosition + 1, it->value); |
} |
- textMetricsValues->append(m_currentMetrics); |
+ textMetricsValues->append(currentMetrics); |
} |
if (data->allCharactersMap && currentCharacterStartsSurrogatePair()) |