Commit b9c64a48 authored by fs@opera.com's avatar fs@opera.com

Reduce state kept in MeasureTextData by SVGTextMetricsBuilder

MeasureTextData::processRenderer is only used within
SVGTextMetricsBuilder::measureTextRenderer, and is always set before a
call to that method. This makes a good candidate for removal from the
traversal state struct (MeasureTextData) and being passed as an argument
to measureTextRenderer instead.

There's no need to track both the last character and whether there was
a previous character. It's sufficient to track if the the last character
was a whitespace or not. (The initial case which previously had
hasLastCharacter == false can be represented as having a been a whitespace
character.) This allows replacing the two fields hasLastCharacter and
lastCharacter with a single field lastCharacterWasWhiteSpace.

MeasureTextData::skippedCharacters is reset to zero (0) at the end of
SVGTextMetricsBuilder::measureTextRenderer, and is only read or written
if MeasureTextData::allCharactersMap is non-null.
This means it can be kept on the stack of measureTextRenderer instead.

Also change the type of surrogatePairCharacters from int to unsigned,
since it's a simple counter, that should never be negative (and is used
in arithmetic with unsigned typed variables.)

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

git-svn-id: svn://svn.chromium.org/blink/trunk@168342 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 9453bd46
...@@ -112,29 +112,23 @@ void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlin ...@@ -112,29 +112,23 @@ void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlin
struct MeasureTextData { struct MeasureTextData {
MeasureTextData(SVGCharacterDataMap* characterDataMap) MeasureTextData(SVGCharacterDataMap* characterDataMap)
: allCharactersMap(characterDataMap) : allCharactersMap(characterDataMap)
, hasLastCharacter(false) , lastCharacterWasWhiteSpace(true)
, lastCharacter(0)
, processRenderer(false)
, valueListPosition(0) , valueListPosition(0)
, skippedCharacters(0)
{ {
} }
SVGCharacterDataMap* allCharactersMap; SVGCharacterDataMap* allCharactersMap;
bool hasLastCharacter; bool lastCharacterWasWhiteSpace;
UChar lastCharacter;
bool processRenderer;
unsigned valueListPosition; unsigned valueListPosition;
unsigned skippedCharacters;
}; };
void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data) void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data, bool processRenderer)
{ {
ASSERT(text); ASSERT(text);
SVGTextLayoutAttributes* attributes = text->layoutAttributes(); SVGTextLayoutAttributes* attributes = text->layoutAttributes();
Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues(); Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues();
if (data->processRenderer) { if (processRenderer) {
if (data->allCharactersMap) if (data->allCharactersMap)
attributes->clear(); attributes->clear();
else else
...@@ -143,21 +137,22 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu ...@@ -143,21 +137,22 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu
initializeMeasurementWithTextRenderer(text); initializeMeasurementWithTextRenderer(text);
bool preserveWhiteSpace = text->style()->whiteSpace() == PRE; bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
int surrogatePairCharacters = 0; unsigned surrogatePairCharacters = 0;
unsigned skippedCharacters = 0;
while (advance()) { while (advance()) {
UChar currentCharacter = m_run[m_textPosition]; bool characterIsWhiteSpace = m_run[m_textPosition] == ' ';
if (currentCharacter == ' ' && !preserveWhiteSpace && (!data->hasLastCharacter || data->lastCharacter == ' ')) { if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) {
if (data->processRenderer) if (processRenderer)
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
if (data->allCharactersMap) if (data->allCharactersMap)
data->skippedCharacters += m_currentMetrics.length(); skippedCharacters += m_currentMetrics.length();
continue; continue;
} }
if (data->processRenderer) { if (processRenderer) {
if (data->allCharactersMap) { if (data->allCharactersMap) {
const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + m_textPosition - data->skippedCharacters - surrogatePairCharacters + 1); const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + m_textPosition - skippedCharacters - surrogatePairCharacters + 1);
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);
} }
...@@ -167,15 +162,13 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu ...@@ -167,15 +162,13 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu
if (data->allCharactersMap && currentCharacterStartsSurrogatePair()) if (data->allCharactersMap && currentCharacterStartsSurrogatePair())
surrogatePairCharacters++; surrogatePairCharacters++;
data->hasLastCharacter = true; data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
data->lastCharacter = currentCharacter;
} }
if (!data->allCharactersMap) if (!data->allCharactersMap)
return; return;
data->valueListPosition += m_textPosition - data->skippedCharacters; data->valueListPosition += m_textPosition - skippedCharacters;
data->skippedCharacters = 0;
} }
void SVGTextMetricsBuilder::walkTree(RenderObject* start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data) void SVGTextMetricsBuilder::walkTree(RenderObject* start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data)
...@@ -184,8 +177,7 @@ void SVGTextMetricsBuilder::walkTree(RenderObject* start, RenderSVGInlineText* s ...@@ -184,8 +177,7 @@ void SVGTextMetricsBuilder::walkTree(RenderObject* start, RenderSVGInlineText* s
while (child) { while (child) {
if (child->isSVGInlineText()) { if (child->isSVGInlineText()) {
RenderSVGInlineText* text = toRenderSVGInlineText(child); RenderSVGInlineText* text = toRenderSVGInlineText(child);
data->processRenderer = !stopAtLeaf || stopAtLeaf == text; measureTextRenderer(text, data, !stopAtLeaf || stopAtLeaf == text);
measureTextRenderer(text, data);
if (stopAtLeaf && stopAtLeaf == text) if (stopAtLeaf && stopAtLeaf == text)
return; return;
} else if (child->isSVGInline()) { } else if (child->isSVGInline()) {
......
...@@ -48,7 +48,7 @@ private: ...@@ -48,7 +48,7 @@ private:
void initializeMeasurementWithTextRenderer(RenderSVGInlineText*); void initializeMeasurementWithTextRenderer(RenderSVGInlineText*);
void walkTree(RenderObject*, RenderSVGInlineText* stopAtLeaf, MeasureTextData*); void walkTree(RenderObject*, RenderSVGInlineText* stopAtLeaf, MeasureTextData*);
void measureTextRenderer(RenderSVGInlineText*, MeasureTextData*); void measureTextRenderer(RenderSVGInlineText*, MeasureTextData*, bool processRenderer);
RenderSVGInlineText* m_text; RenderSVGInlineText* m_text;
TextRun m_run; TextRun m_run;
......
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