Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp |
| index 82557fd256b0ee7a5c9c215f0f728d91cb41f306..fc03d131ed0f8b8629ff03de1ff1bd293fd27bde 100644 |
| --- a/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp |
| +++ b/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp |
| @@ -20,9 +20,7 @@ |
| #include "core/layout/svg/SVGTextMetricsBuilder.h" |
| #include "core/layout/api/LineLayoutSVGInlineText.h" |
| -#include "core/layout/svg/LayoutSVGInline.h" |
| #include "core/layout/svg/LayoutSVGInlineText.h" |
| -#include "core/layout/svg/LayoutSVGText.h" |
| #include "core/layout/svg/SVGTextMetrics.h" |
| #include "platform/fonts/CharacterRange.h" |
| #include "platform/text/BidiCharacterRun.h" |
| @@ -47,7 +45,7 @@ inline bool characterStartsSurrogatePair(const TextRun& run, unsigned index) |
| class SVGTextMetricsCalculator { |
| public: |
| - SVGTextMetricsCalculator(LineLayoutSVGInlineText); |
| + SVGTextMetricsCalculator(LayoutSVGInlineText&); |
| ~SVGTextMetricsCalculator(); |
| bool advancePosition(); |
| @@ -73,7 +71,7 @@ public: |
| private: |
| void setupBidiRuns(); |
| - static TextRun constructTextRun(LineLayoutSVGInlineText, unsigned position, unsigned length, TextDirection); |
| + static TextRun constructTextRun(LayoutSVGInlineText&, unsigned position, unsigned length, TextDirection); |
| // Ensure |m_subrunRanges| is updated for the current bidi run, or the |
| // complete m_run if no bidi runs are present. Returns the current position |
| @@ -83,7 +81,7 @@ private: |
| // Current character position in m_text. |
| unsigned m_currentPosition; |
| - LineLayoutSVGInlineText m_text; |
| + LayoutSVGInlineText& m_text; |
| float m_fontScalingFactor; |
| float m_cachedFontHeight; |
| TextRun m_run; |
| @@ -95,9 +93,9 @@ private: |
| Vector<CharacterRange> m_subrunRanges; |
| }; |
| -TextRun SVGTextMetricsCalculator::constructTextRun(LineLayoutSVGInlineText textLayoutItem, unsigned position, unsigned length, TextDirection textDirection) |
| +TextRun SVGTextMetricsCalculator::constructTextRun(LayoutSVGInlineText& text, unsigned position, unsigned length, TextDirection textDirection) |
| { |
| - const ComputedStyle& style = textLayoutItem.styleRef(); |
| + const ComputedStyle& style = text.styleRef(); |
| TextRun run(static_cast<const LChar*>(nullptr) // characters, will be set below if non-zero. |
| , 0 // length, will be set below if non-zero. |
| @@ -108,22 +106,22 @@ TextRun SVGTextMetricsCalculator::constructTextRun(LineLayoutSVGInlineText textL |
| , isOverride(style.unicodeBidi()) /* directionalOverride */); |
| if (length) { |
| - if (textLayoutItem.is8Bit()) |
| - run.setText(textLayoutItem.characters8() + position, length); |
| + if (text.is8Bit()) |
| + run.setText(text.characters8() + position, length); |
| else |
| - run.setText(textLayoutItem.characters16() + position, length); |
| + run.setText(text.characters16() + position, length); |
| } |
| // We handle letter & word spacing ourselves. |
| run.disableSpacing(); |
| // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. |
| - run.setCharactersLength(textLayoutItem.textLength() - position); |
| + run.setCharactersLength(text.textLength() - position); |
| ASSERT(run.charactersLength() >= run.length()); |
| return run; |
| } |
| -SVGTextMetricsCalculator::SVGTextMetricsCalculator(LineLayoutSVGInlineText text) |
| +SVGTextMetricsCalculator::SVGTextMetricsCalculator(LayoutSVGInlineText& text) |
| : m_currentPosition(0) |
| , m_text(text) |
| , m_fontScalingFactor(m_text.scalingFactor()) |
| @@ -233,128 +231,33 @@ SVGTextMetrics SVGTextMetricsCalculator::currentCharacterMetrics() |
| return SVGTextMetrics(length, width / m_fontScalingFactor, m_cachedFontHeight); |
| } |
| -struct TreeWalkTextState { |
| - TreeWalkTextState() |
| - : lastCharacterWasWhiteSpace(true) |
| - , valueListPosition(0) { } |
| - |
| - bool lastCharacterWasWhiteSpace; |
| - unsigned valueListPosition; |
| -}; |
| - |
| -// Struct for updating SVGTextLayoutAttributes. If an SVGCharacterDataMap is |
| -// available, the attribute's character data map will also be updated. |
| -// TreeWalkTextState should be used to maintain the value list position which |
| -// indexes into the SVGCharacterDataMap of all characters. |
| -struct UpdateAttributes { |
| - UpdateAttributes( |
| - SVGTextLayoutAttributes& textAttributes, |
| - Vector<SVGTextMetrics>& metricsList, |
| - const SVGCharacterDataMap* allCharacters) |
| - : metricsList(metricsList) |
| - , attributes(textAttributes) |
| - , allCharactersMap(allCharacters) { } |
| - |
| - void clearExistingAttributes() |
| - { |
| - metricsList.clear(); |
| - |
| - if (allCharactersMap) |
| - attributes.clear(); |
| - } |
| - |
| - void addMetrics(SVGTextMetrics metrics) |
| - { |
| - metricsList.append(metrics); |
| - } |
| - |
| - void updateCharacterDataMap(unsigned valueListPosition, unsigned currentTextPosition) |
| - { |
| - if (!allCharactersMap) |
| - return; |
| - const SVGCharacterDataMap::const_iterator it = allCharactersMap->find(valueListPosition); |
| - if (it != allCharactersMap->end()) |
| - attributes.characterDataMap().set(currentTextPosition, it->value); |
| - } |
| - |
| - Vector<SVGTextMetrics>& metricsList; |
| - SVGTextLayoutAttributes& attributes; |
| - const SVGCharacterDataMap* allCharactersMap; |
| -}; |
| +} // namespace |
| -void walkInlineText(LayoutSVGInlineText* text, TreeWalkTextState& textState, UpdateAttributes* attributesToUpdate = nullptr) |
| +void SVGTextMetricsBuilder::updateTextMetrics(LayoutSVGInlineText& text, bool& lastCharacterWasWhiteSpace) |
| { |
| - LineLayoutSVGInlineText textLayoutItem(text); |
| - if (attributesToUpdate) |
| - attributesToUpdate->clearExistingAttributes(); |
| + Vector<SVGTextMetrics>& metricsList = text.metricsList(); |
| + metricsList.clear(); |
| - if (!textLayoutItem.textLength()) |
| + if (!text.textLength()) |
| return; |
| // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator. |
|
pdr.
2016/04/06 23:07:33
Is this comment still useful? If not, lets just re
fs
2016/04/07 09:26:17
I think it might still be useful given that what i
|
| // We should refactor SVGTextMetricsCalculator to be a simple bidi run |
| // iterator and move all subrun logic to a single function. |
| - SVGTextMetricsCalculator calculator(textLayoutItem); |
| - bool preserveWhiteSpace = textLayoutItem.styleRef().whiteSpace() == PRE; |
| - unsigned surrogatePairCharacters = 0; |
| - unsigned skippedWhitespace = 0; |
| + SVGTextMetricsCalculator calculator(text); |
| + bool preserveWhiteSpace = text.styleRef().whiteSpace() == PRE; |
| do { |
| bool currentCharacterIsWhiteSpace = calculator.currentCharacterIsWhiteSpace(); |
| - if (currentCharacterIsWhiteSpace && !preserveWhiteSpace && textState.lastCharacterWasWhiteSpace) { |
| - if (attributesToUpdate) |
| - attributesToUpdate->addMetrics(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); |
| + if (!preserveWhiteSpace && lastCharacterWasWhiteSpace && currentCharacterIsWhiteSpace) { |
| + metricsList.append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); |
| ASSERT(calculator.currentCharacterMetrics().length() == 1); |
| - skippedWhitespace++; |
| continue; |
| } |
| - if (attributesToUpdate) { |
| - attributesToUpdate->updateCharacterDataMap(textState.valueListPosition - skippedWhitespace - surrogatePairCharacters + calculator.currentPosition() + 1, calculator.currentPosition() + 1); |
| - attributesToUpdate->addMetrics(calculator.currentCharacterMetrics()); |
| - } |
| + metricsList.append(calculator.currentCharacterMetrics()); |
| - if (calculator.currentCharacterStartsSurrogatePair()) |
| - surrogatePairCharacters++; |
| - textState.lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace; |
| + lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace; |
| } while (calculator.advancePosition()); |
| - |
| - textState.valueListPosition += calculator.currentPosition() - skippedWhitespace; |
| -} |
| - |
| -void walkTree(LayoutSVGText& start, LayoutSVGInlineText* stopAtText, SVGCharacterDataMap* allCharactersMap = nullptr) |
| -{ |
| - TreeWalkTextState textState; |
| - LayoutObject* child = start.firstChild(); |
| - while (child) { |
| - if (child->isSVGInlineText()) { |
| - LayoutSVGInlineText* text = toLayoutSVGInlineText(child); |
| - OwnPtr<UpdateAttributes> attributesToUpdate = nullptr; |
| - if (!stopAtText || stopAtText == text) |
| - attributesToUpdate = adoptPtr(new UpdateAttributes(*text->layoutAttributes(), text->metricsList(), allCharactersMap)); |
| - walkInlineText(text, textState, attributesToUpdate.get()); |
| - if (stopAtText == text) |
| - return; |
| - } else if (child->isSVGInline()) { |
| - // Visit children of text content elements. |
| - if (LayoutObject* inlineChild = toLayoutSVGInline(child)->firstChild()) { |
| - child = inlineChild; |
| - continue; |
| - } |
| - } |
| - child = child->nextInPreOrderAfterChildren(&start); |
| - } |
| -} |
| - |
| -} // namespace |
| - |
| -void SVGTextMetricsBuilder::measureTextLayoutObject(LayoutSVGText& textRoot, LayoutSVGInlineText& text) |
| -{ |
| - walkTree(textRoot, &text); |
| -} |
| - |
| -void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(LayoutSVGText& textRoot, SVGCharacterDataMap& allCharactersMap) |
| -{ |
| - walkTree(textRoot, nullptr, &allCharactersMap); |
| } |
| } // namespace blink |