| Index: Source/core/layout/svg/SVGTextLayoutEngine.cpp
|
| diff --git a/Source/core/layout/svg/SVGTextLayoutEngine.cpp b/Source/core/layout/svg/SVGTextLayoutEngine.cpp
|
| index 7dfb40dab2b50a2d5488e0f898ff820b3e736d9d..301f94354dfbb3460a4997162282c1f0a9580115 100644
|
| --- a/Source/core/layout/svg/SVGTextLayoutEngine.cpp
|
| +++ b/Source/core/layout/svg/SVGTextLayoutEngine.cpp
|
| @@ -37,8 +37,6 @@ SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou
|
| , m_layoutAttributesPosition(0)
|
| , m_logicalCharacterOffset(0)
|
| , m_logicalMetricsListOffset(0)
|
| - , m_visualCharacterOffset(0)
|
| - , m_visualMetricsListOffset(0)
|
| , m_x(0)
|
| , m_y(0)
|
| , m_dx(0)
|
| @@ -110,16 +108,17 @@ void SVGTextLayoutEngine::updateRelativePositionAdjustmentsIfNeeded(float dx, fl
|
| m_dy = dy;
|
| }
|
|
|
| -void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox, const Vector<SVGTextMetrics>& textMetricsValues)
|
| +void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox)
|
| {
|
| ASSERT(!m_currentTextFragment.length);
|
| - ASSERT(m_visualMetricsListOffset > 0);
|
|
|
| // Figure out length of fragment.
|
| - m_currentTextFragment.length = m_visualCharacterOffset - m_currentTextFragment.characterOffset;
|
| + m_currentTextFragment.length = m_visualMetricsIterator.characterOffset() - m_currentTextFragment.characterOffset;
|
|
|
| // Figure out fragment metrics.
|
| - const SVGTextMetrics& lastCharacterMetrics = textMetricsValues.at(m_visualMetricsListOffset - 1);
|
| + const unsigned visualMetricsListOffset = m_visualMetricsIterator.metricsListOffset();
|
| + const Vector<SVGTextMetrics>& textMetricsValues = m_visualMetricsIterator.metricsList();
|
| + const SVGTextMetrics& lastCharacterMetrics = textMetricsValues.at(visualMetricsListOffset - 1);
|
| m_currentTextFragment.width = lastCharacterMetrics.width();
|
| m_currentTextFragment.height = lastCharacterMetrics.height();
|
|
|
| @@ -127,11 +126,11 @@ void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox, const Ve
|
| // SVGTextLayoutAttributesBuilder assures that the length of the range is equal to the sum of the individual lengths of the glyphs.
|
| float length = 0;
|
| if (m_isVerticalText) {
|
| - for (unsigned i = m_currentTextFragment.metricsListOffset; i < m_visualMetricsListOffset; ++i)
|
| + for (unsigned i = m_currentTextFragment.metricsListOffset; i < visualMetricsListOffset; ++i)
|
| length += textMetricsValues.at(i).height();
|
| m_currentTextFragment.height = length;
|
| } else {
|
| - for (unsigned i = m_currentTextFragment.metricsListOffset; i < m_visualMetricsListOffset; ++i)
|
| + for (unsigned i = m_currentTextFragment.metricsListOffset; i < visualMetricsListOffset; ++i)
|
| length += textMetricsValues.at(i).width();
|
| m_currentTextFragment.width = length;
|
| }
|
| @@ -260,6 +259,8 @@ void SVGTextLayoutEngine::layoutInlineTextBox(SVGInlineTextBox* textBox)
|
|
|
| void SVGTextLayoutEngine::finishLayout()
|
| {
|
| + m_visualMetricsIterator = SVGInlineTextMetricsIterator();
|
| +
|
| // After all text fragments are stored in their correpsonding SVGInlineTextBoxes, we can layout individual text chunks.
|
| // Chunk layouting is only performed for line layout boxes, not for path layout, where it has already been done.
|
| SVGTextChunkBuilder chunkLayoutBuilder;
|
| @@ -328,43 +329,12 @@ bool SVGTextLayoutEngine::currentLogicalCharacterMetrics(SVGTextLayoutAttributes
|
| return true;
|
| }
|
|
|
| -bool SVGTextLayoutEngine::currentVisualCharacterMetrics(SVGInlineTextBox* textBox, const Vector<SVGTextMetrics>& visualMetricsValues, SVGTextMetrics& visualMetrics)
|
| -{
|
| - ASSERT(!visualMetricsValues.isEmpty());
|
| - unsigned textMetricsSize = visualMetricsValues.size();
|
| - unsigned boxStart = textBox->start();
|
| - unsigned boxLength = textBox->len();
|
| -
|
| - while (m_visualMetricsListOffset < textMetricsSize) {
|
| - // Advance to text box start location.
|
| - if (m_visualCharacterOffset < boxStart) {
|
| - advanceToNextVisualCharacter(visualMetricsValues[m_visualMetricsListOffset]);
|
| - continue;
|
| - }
|
| -
|
| - // Stop if we've finished processing this text box.
|
| - if (m_visualCharacterOffset >= boxStart + boxLength)
|
| - return false;
|
| -
|
| - visualMetrics = visualMetricsValues[m_visualMetricsListOffset];
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| void SVGTextLayoutEngine::advanceToNextLogicalCharacter(const SVGTextMetrics& logicalMetrics)
|
| {
|
| ++m_logicalMetricsListOffset;
|
| m_logicalCharacterOffset += logicalMetrics.length();
|
| }
|
|
|
| -void SVGTextLayoutEngine::advanceToNextVisualCharacter(const SVGTextMetrics& visualMetrics)
|
| -{
|
| - ++m_visualMetricsListOffset;
|
| - m_visualCharacterOffset += visualMetrics.length();
|
| -}
|
| -
|
| void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, const LayoutSVGInlineText& text, const ComputedStyle& style)
|
| {
|
| if (m_inPathLayout && !m_textPathCalculator)
|
| @@ -375,11 +345,8 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
|
|
| const SVGComputedStyle& svgStyle = style.svgStyle();
|
|
|
| - m_visualMetricsListOffset = 0;
|
| - m_visualCharacterOffset = 0;
|
| -
|
| - const Vector<SVGTextMetrics>& visualMetricsValues = text.layoutAttributes()->textMetricsValues();
|
| - ASSERT(!visualMetricsValues.isEmpty());
|
| + // Find the start of the current text box in the metrics list.
|
| + m_visualMetricsIterator.advanceToTextStart(&text, textBox->start());
|
|
|
| const Font& font = style.font();
|
|
|
| @@ -394,14 +361,11 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
| baselineShift -= baselineLayout.calculateAlignmentBaselineShift(m_isVerticalText, &text);
|
|
|
| // Main layout algorithm.
|
| - while (true) {
|
| - // Find the start of the current text box in this list, respecting ligatures.
|
| - SVGTextMetrics visualMetrics(SVGTextMetrics::SkippedSpaceMetrics);
|
| - if (!currentVisualCharacterMetrics(textBox, visualMetricsValues, visualMetrics))
|
| - break;
|
| -
|
| + const unsigned boxEndOffset = textBox->start() + textBox->len();
|
| + while (m_visualMetricsIterator.characterOffset() < boxEndOffset) {
|
| + const SVGTextMetrics& visualMetrics = m_visualMetricsIterator.metrics();
|
| if (visualMetrics.isEmpty()) {
|
| - advanceToNextVisualCharacter(visualMetrics);
|
| + m_visualMetricsIterator.next();
|
| continue;
|
| }
|
|
|
| @@ -425,13 +389,13 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
|
|
| // When we've advanced to the box start offset, determine using the original x/y values,
|
| // whether this character starts a new text chunk, before doing any further processing.
|
| - if (m_visualCharacterOffset == textBox->start())
|
| + if (m_visualMetricsIterator.characterOffset() == textBox->start())
|
| textBox->setStartsNewTextChunk(logicalAttributes->context()->characterStartsNewTextChunk(m_logicalCharacterOffset));
|
|
|
| float angle = SVGTextLayoutAttributes::isEmptyValue(data.rotate) ? 0 : data.rotate;
|
|
|
| // Calculate glyph orientation angle.
|
| - UChar currentCharacter = text.characterAt(m_visualCharacterOffset);
|
| + UChar currentCharacter = text.characterAt(m_visualMetricsIterator.characterOffset());
|
| float orientationAngle = baselineLayout.calculateGlyphOrientationAngle(m_isVerticalText, svgStyle, currentCharacter);
|
|
|
| // Calculate glyph advance & x/y orientation shifts.
|
| @@ -484,7 +448,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
| // Skip character, if we're before the path.
|
| if (textPathOffset < 0) {
|
| advanceToNextLogicalCharacter(logicalMetrics);
|
| - advanceToNextVisualCharacter(visualMetrics);
|
| + m_visualMetricsIterator.next();
|
| continue;
|
| }
|
|
|
| @@ -519,7 +483,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
| // If we already started a fragment, close it now.
|
| if (didStartTextFragment && shouldStartNewFragment) {
|
| applySpacingToNextCharacter = false;
|
| - recordTextFragment(textBox, visualMetricsValues);
|
| + recordTextFragment(textBox);
|
| }
|
|
|
| // Eventually start a new fragment, if not yet done.
|
| @@ -528,8 +492,8 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
| ASSERT(!m_currentTextFragment.length);
|
|
|
| didStartTextFragment = true;
|
| - m_currentTextFragment.characterOffset = m_visualCharacterOffset;
|
| - m_currentTextFragment.metricsListOffset = m_visualMetricsListOffset;
|
| + m_currentTextFragment.characterOffset = m_visualMetricsIterator.characterOffset();
|
| + m_currentTextFragment.metricsListOffset = m_visualMetricsIterator.metricsListOffset();
|
| m_currentTextFragment.x = x;
|
| m_currentTextFragment.y = y;
|
|
|
| @@ -572,7 +536,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
| }
|
|
|
| advanceToNextLogicalCharacter(logicalMetrics);
|
| - advanceToNextVisualCharacter(visualMetrics);
|
| + m_visualMetricsIterator.next();
|
| lastAngle = angle;
|
| }
|
|
|
| @@ -580,7 +544,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
|
| return;
|
|
|
| // Close last open fragment, if needed.
|
| - recordTextFragment(textBox, visualMetricsValues);
|
| + recordTextFragment(textBox);
|
| }
|
|
|
| }
|
|
|