Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(885)

Unified Diff: Source/core/layout/svg/SVGTextLayoutEngine.cpp

Issue 1158033006: Track if textLength spacing is in effect while walking the line box tree (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/layout/svg/SVGTextLayoutEngine.h ('k') | Source/core/layout/svg/line/SVGRootInlineBox.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/layout/svg/SVGTextLayoutEngine.cpp
diff --git a/Source/core/layout/svg/SVGTextLayoutEngine.cpp b/Source/core/layout/svg/SVGTextLayoutEngine.cpp
index 94783b42f8659457ce1ff6f8ef673c89d7d7d1ac..36d860b289ff2f66a0434c57e9e114383caacbb1 100644
--- a/Source/core/layout/svg/SVGTextLayoutEngine.cpp
+++ b/Source/core/layout/svg/SVGTextLayoutEngine.cpp
@@ -25,6 +25,7 @@
#include "core/layout/svg/SVGTextChunkBuilder.h"
#include "core/layout/svg/SVGTextLayoutEngineBaseline.h"
#include "core/layout/svg/SVGTextLayoutEngineSpacing.h"
+#include "core/layout/svg/line/SVGInlineFlowBox.h"
#include "core/layout/svg/line/SVGInlineTextBox.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGLengthContext.h"
@@ -43,6 +44,7 @@ SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou
, m_dy(0)
, m_isVerticalText(false)
, m_inPathLayout(false)
+ , m_textLengthSpacingInEffect(false)
, m_textPathCalculator(0)
, m_textPathLength(0)
, m_textPathCurrentOffset(0)
@@ -140,32 +142,16 @@ void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox)
m_currentTextFragment = SVGTextFragment();
}
-bool SVGTextLayoutEngine::parentDefinesTextLength(LayoutObject* parent) const
+void SVGTextLayoutEngine::beginTextPathLayout(SVGInlineFlowBox* flowBox)
{
- LayoutObject* currentParent = parent;
- while (currentParent) {
- if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromLayoutObject(currentParent)) {
- SVGLengthContext lengthContext(textContentElement);
- if (textContentElement->lengthAdjust()->currentValue()->enumValue() == SVGLengthAdjustSpacing && textContentElement->textLengthIsSpecifiedByUser())
- return true;
- }
-
- if (currentParent->isSVGText())
- return false;
-
- currentParent = currentParent->parent();
- }
-
- ASSERT_NOT_REACHED();
- return false;
-}
-
-void SVGTextLayoutEngine::beginTextPathLayout(LayoutObject* object, SVGTextLayoutEngine& lineLayout)
-{
- ASSERT(object);
+ // Build text chunks for all <textPath> children, using the line layout algorithm.
+ // This is needeed as text-anchor is just an additional startOffset for text paths.
+ SVGTextLayoutEngine lineLayout(m_layoutAttributes);
+ lineLayout.m_textLengthSpacingInEffect = m_textLengthSpacingInEffect;
+ lineLayout.layoutCharactersInTextBoxes(flowBox);
m_inPathLayout = true;
- LayoutSVGTextPath* textPath = toLayoutSVGTextPath(object);
+ LayoutSVGTextPath* textPath = &toLayoutSVGTextPath(flowBox->layoutObject());
Path path = textPath->layoutPath();
if (path.isEmpty())
@@ -238,6 +224,42 @@ void SVGTextLayoutEngine::layoutInlineTextBox(SVGInlineTextBox* textBox)
m_lineLayoutBoxes.append(textBox);
}
+static bool definesTextLengthWithSpacing(const InlineFlowBox* start)
+{
+ SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromLayoutObject(&start->layoutObject());
+ return textContentElement
+ && textContentElement->lengthAdjust()->currentValue()->enumValue() == SVGLengthAdjustSpacing
+ && textContentElement->textLengthIsSpecifiedByUser();
+}
+
+void SVGTextLayoutEngine::layoutCharactersInTextBoxes(InlineFlowBox* start)
+{
+ bool textLengthSpacingInEffect = m_textLengthSpacingInEffect || definesTextLengthWithSpacing(start);
+ TemporaryChange<bool> textLengthSpacingScope(m_textLengthSpacingInEffect, textLengthSpacingInEffect);
+
+ for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
+ if (child->isSVGInlineTextBox()) {
+ ASSERT(child->layoutObject().isSVGInlineText());
+ layoutInlineTextBox(toSVGInlineTextBox(child));
+ } else {
+ // Skip generated content.
+ Node* node = child->layoutObject().node();
+ if (!node)
+ continue;
+
+ SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
+ bool isTextPath = isSVGTextPathElement(*node);
+ if (isTextPath)
+ beginTextPathLayout(flowBox);
+
+ layoutCharactersInTextBoxes(flowBox);
+
+ if (isTextPath)
+ endTextPathLayout();
+ }
+ }
+}
+
void SVGTextLayoutEngine::finishLayout()
{
m_visualMetricsIterator = SVGInlineTextMetricsIterator();
@@ -316,9 +338,6 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
if (m_inPathLayout && !m_textPathCalculator)
return;
- LayoutObject* textParent = text.parent();
- bool definesTextLength = textParent ? parentDefinesTextLength(textParent) : false;
-
const SVGComputedStyle& svgStyle = style.svgStyle();
// Find the start of the current text box in the metrics list.
@@ -454,7 +473,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, cons
// Determine whether we have to start a new fragment.
bool shouldStartNewFragment = m_dx || m_dy || m_isVerticalText || m_inPathLayout || angle || angle != lastAngle
- || orientationAngle || applySpacingToNextCharacter || definesTextLength;
+ || orientationAngle || applySpacingToNextCharacter || m_textLengthSpacingInEffect;
// If we already started a fragment, close it now.
if (didStartTextFragment && shouldStartNewFragment) {
« no previous file with comments | « Source/core/layout/svg/SVGTextLayoutEngine.h ('k') | Source/core/layout/svg/line/SVGRootInlineBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698