Index: Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
diff --git a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
index d044f2d4e18d6e1eac39828588352919c89ac1ab..344c023aa4ed64ed9eec868fb3483e8ef4ed66df 100644 |
--- a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
+++ b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp |
@@ -23,24 +23,59 @@ |
#include "core/rendering/svg/RenderSVGInlineText.h" |
#include "core/rendering/svg/RenderSVGText.h" |
+#include "core/rendering/svg/SVGTextMetrics.h" |
+#include "platform/fonts/WidthIterator.h" |
#include "platform/text/TextPath.h" |
+#include "platform/text/TextRun.h" |
+#include "wtf/Vector.h" |
namespace WebCore { |
-SVGTextMetricsBuilder::SVGTextMetricsBuilder() |
- : m_text(0) |
- , m_run(static_cast<const UChar*>(0), 0) |
+class SVGTextMetricsCalculator { |
+public: |
+ SVGTextMetricsCalculator(RenderSVGInlineText*); |
+ |
+ SVGTextMetrics computeMetricsForCharacter(unsigned textPosition); |
+ unsigned textLength() const { return static_cast<unsigned>(m_run.charactersLength()); } |
+ |
+ bool characterStartsSurrogatePair(unsigned textPosition) const |
+ { |
+ return U16_IS_LEAD(m_run[textPosition]) && textPosition + 1 < textLength() && U16_IS_TRAIL(m_run[textPosition + 1]); |
+ } |
+ bool characterIsWhiteSpace(unsigned textPosition) const |
+ { |
+ return m_run[textPosition] == ' '; |
+ } |
+ |
+private: |
+ SVGTextMetrics computeMetricsForCharacterSimple(unsigned textPosition); |
+ SVGTextMetrics computeMetricsForCharacterComplex(unsigned textPosition); |
+ |
+ RenderSVGInlineText* m_text; |
+ TextRun m_run; |
+ bool m_isComplexText; |
+ float m_totalWidth; |
+ |
+ // Simple text only. |
+ OwnPtr<WidthIterator> m_simpleWidthIterator; |
+}; |
+ |
+SVGTextMetricsCalculator::SVGTextMetricsCalculator(RenderSVGInlineText* text) |
+ : m_text(text) |
+ , m_run(SVGTextMetrics::constructTextRun(text, 0, text->textLength())) |
, m_isComplexText(false) |
, m_totalWidth(0) |
{ |
-} |
+ const Font& scaledFont = text->scaledFont(); |
+ CodePath codePath = scaledFont.codePath(m_run); |
+ m_isComplexText = codePath == ComplexPath; |
+ m_run.setCharacterScanForCodePath(!m_isComplexText); |
-inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair(unsigned textPosition) const |
-{ |
- return U16_IS_LEAD(m_run[textPosition]) && int(textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[textPosition + 1]); |
+ if (!m_isComplexText) |
+ m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run)); |
} |
-SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterSimple(unsigned textPosition) |
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterSimple(unsigned textPosition) |
{ |
GlyphBuffer glyphBuffer; |
unsigned metricsLength = m_simpleWidthIterator->advance(textPosition + 1, &glyphBuffer); |
@@ -54,9 +89,9 @@ SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterSimple(un |
return SVGTextMetrics(m_text, textPosition, metricsLength, currentWidth, glyphId); |
} |
-SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterComplex(unsigned textPosition) |
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterComplex(unsigned textPosition) |
{ |
- unsigned metricsLength = currentCharacterStartsSurrogatePair(textPosition) ? 2 : 1; |
+ unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1; |
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength); |
ASSERT(metrics.length() == metricsLength); |
@@ -73,29 +108,12 @@ SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacterComplex(u |
return metrics; |
} |
-SVGTextMetrics SVGTextMetricsBuilder::computeMetricsForCurrentCharacter(unsigned textPosition) |
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacter(unsigned textPosition) |
{ |
if (m_isComplexText) |
- return computeMetricsForCurrentCharacterComplex(textPosition); |
- |
- return computeMetricsForCurrentCharacterSimple(textPosition); |
-} |
- |
-void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText* text) |
-{ |
- m_text = text; |
- m_totalWidth = 0; |
+ return computeMetricsForCharacterComplex(textPosition); |
- const Font& scaledFont = text->scaledFont(); |
- m_run = SVGTextMetrics::constructTextRun(text, 0, text->textLength()); |
- CodePath codePath = scaledFont.codePath(m_run); |
- m_isComplexText = codePath == ComplexPath; |
- m_run.setCharacterScanForCodePath(!m_isComplexText); |
- |
- if (m_isComplexText) |
- m_simpleWidthIterator.clear(); |
- else |
- m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run)); |
+ return computeMetricsForCharacterSimple(textPosition); |
} |
struct MeasureTextData { |
@@ -124,20 +142,20 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu |
textMetricsValues->clear(); |
} |
- initializeMeasurementWithTextRenderer(text); |
+ SVGTextMetricsCalculator calculator(text); |
bool preserveWhiteSpace = text->style()->whiteSpace() == PRE; |
unsigned surrogatePairCharacters = 0; |
unsigned skippedCharacters = 0; |
unsigned textPosition = 0; |
- unsigned textLength = static_cast<unsigned>(m_run.charactersLength()); |
+ unsigned textLength = calculator.textLength(); |
SVGTextMetrics currentMetrics; |
for (; textPosition < textLength; textPosition += currentMetrics.length()) { |
- currentMetrics = computeMetricsForCurrentCharacter(textPosition); |
+ currentMetrics = calculator.computeMetricsForCharacter(textPosition); |
if (!currentMetrics.length()) |
break; |
- bool characterIsWhiteSpace = m_run[textPosition] == ' '; |
+ bool characterIsWhiteSpace = calculator.characterIsWhiteSpace(textPosition); |
if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) { |
if (processRenderer) |
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); |
@@ -155,7 +173,7 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, Measu |
textMetricsValues->append(currentMetrics); |
} |
- if (data->allCharactersMap && currentCharacterStartsSurrogatePair(textPosition)) |
+ if (data->allCharactersMap && calculator.characterStartsSurrogatePair(textPosition)) |
surrogatePairCharacters++; |
data->lastCharacterWasWhiteSpace = characterIsWhiteSpace; |