Commit 4b911995 authored by fs@opera.com's avatar fs@opera.com

Refactor away SVGTextMetricsBuilder::advance

This method has two logical parts: Advancing the text position and
checking for termination, and computing the metrics for the current
character.
Split this method to better show this. The latter part is put into a
new method, computeMetricsForCurrentCharacter, while the former part is
open-coded in SVGTextMetricsBuilder::measureTextRenderer.
The advance{Simple,Complex}Text methods are renamed to
computeMetricsForCurrentCharacter{Simple,Complex}.

With this change, it becomes easier to see that
SVGTextMetricsBuilder::m_currentMetrics can be trivially removed in favor
of returning it from computeMetricsForCurrentCharacter, and storing it on
the stack in SVGTextMetricsBuilder::measureTextRenderer.
The same is true for SVGTextMetricsBuilder::m_complexStartToCurrentMetrics,
which can be made local to computeMetricsForCurrentCharacterComplex.

Review URL: https://codereview.chromium.org/184103024

git-svn-id: svn://svn.chromium.org/blink/trunk@168461 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3a1b9fe6
...@@ -41,60 +41,51 @@ inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair() const ...@@ -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]); 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() SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterSimple()
{
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()
{ {
GlyphBuffer glyphBuffer; GlyphBuffer glyphBuffer;
unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1, &glyphBuffer); unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1, &glyphBuffer);
if (!metricsLength) { if (!metricsLength)
m_currentMetrics = SVGTextMetrics(); return SVGTextMetrics();
return;
}
float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth; float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth;
m_totalWidth = m_simpleWidthIterator->runWidthSoFar(); m_totalWidth = m_simpleWidthIterator->runWidthSoFar();
Glyph glyphId = glyphBuffer.glyphAt(0); 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; unsigned metricsLength = currentCharacterStartsSurrogatePair() ? 2 : 1;
m_currentMetrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength); SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength);
m_complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, m_textPosition + metricsLength); ASSERT(metrics.length() == metricsLength);
ASSERT(m_currentMetrics.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 // 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. // 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 // 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. // not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
float currentWidth = m_complexStartToCurrentMetrics.width() - m_totalWidth; float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth;
if (currentWidth != m_currentMetrics.width()) if (currentWidth != metrics.width())
m_currentMetrics.setWidth(currentWidth); 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) void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText* text)
{ {
m_text = text; m_text = text;
m_textPosition = 0; m_textPosition = 0;
m_currentMetrics = SVGTextMetrics();
m_complexStartToCurrentMetrics = SVGTextMetrics();
m_totalWidth = 0; m_totalWidth = 0;
const Font& scaledFont = text->scaledFont(); const Font& scaledFont = text->scaledFont();
...@@ -139,14 +130,20 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu ...@@ -139,14 +130,20 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu
bool preserveWhiteSpace = text->style()->whiteSpace() == PRE; bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
unsigned surrogatePairCharacters = 0; unsigned surrogatePairCharacters = 0;
unsigned skippedCharacters = 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] == ' '; bool characterIsWhiteSpace = m_run[m_textPosition] == ' ';
if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) { if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) {
if (processRenderer) if (processRenderer)
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
if (data->allCharactersMap) if (data->allCharactersMap)
skippedCharacters += m_currentMetrics.length(); skippedCharacters += currentMetrics.length();
continue; continue;
} }
...@@ -156,7 +153,7 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu ...@@ -156,7 +153,7 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu
if (it != data->allCharactersMap->end()) if (it != data->allCharactersMap->end())
attributes->characterDataMap().set(m_textPosition + 1, it->value); attributes->characterDataMap().set(m_textPosition + 1, it->value);
} }
textMetricsValues->append(m_currentMetrics); textMetricsValues->append(currentMetrics);
} }
if (data->allCharactersMap && currentCharacterStartsSurrogatePair()) if (data->allCharactersMap && currentCharacterStartsSurrogatePair())
......
...@@ -41,9 +41,9 @@ public: ...@@ -41,9 +41,9 @@ public:
void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap); void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
private: private:
bool advance(); SVGTextMetrics computeMetricsForCurrentCharacter();
void advanceSimpleText(); SVGTextMetrics computeMetricsForCurrentCharacterSimple();
void advanceComplexText(); SVGTextMetrics computeMetricsForCurrentCharacterComplex();
bool currentCharacterStartsSurrogatePair() const; bool currentCharacterStartsSurrogatePair() const;
void initializeMeasurementWithTextRenderer(RenderSVGInlineText*); void initializeMeasurementWithTextRenderer(RenderSVGInlineText*);
...@@ -54,14 +54,10 @@ private: ...@@ -54,14 +54,10 @@ private:
TextRun m_run; TextRun m_run;
unsigned m_textPosition; unsigned m_textPosition;
bool m_isComplexText; bool m_isComplexText;
SVGTextMetrics m_currentMetrics;
float m_totalWidth; float m_totalWidth;
// Simple text only. // Simple text only.
OwnPtr<WidthIterator> m_simpleWidthIterator; OwnPtr<WidthIterator> m_simpleWidthIterator;
// Complex text only.
SVGTextMetrics m_complexStartToCurrentMetrics;
}; };
} // namespace WebCore } // namespace WebCore
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment