Index: Source/core/layout/svg/SVGTextChunkBuilder.cpp |
diff --git a/Source/core/layout/svg/SVGTextChunkBuilder.cpp b/Source/core/layout/svg/SVGTextChunkBuilder.cpp |
index 84e2dc5f37c48b90447383654ce3962d281fb7c9..127fd4f5596b0a31abcbc313bc49be0a98eb52c8 100644 |
--- a/Source/core/layout/svg/SVGTextChunkBuilder.cpp |
+++ b/Source/core/layout/svg/SVGTextChunkBuilder.cpp |
@@ -21,7 +21,6 @@ |
#include "core/layout/svg/SVGTextChunkBuilder.h" |
#include "core/layout/svg/LayoutSVGInlineText.h" |
-#include "core/layout/svg/SVGTextChunk.h" |
#include "core/layout/svg/line/SVGInlineTextBox.h" |
#include "core/svg/SVGLengthContext.h" |
#include "core/svg/SVGTextContentElement.h" |
@@ -30,57 +29,34 @@ namespace blink { |
namespace { |
-SVGTextChunk createTextChunk(const SVGInlineTextBox& textBox) |
+float calculateTextAnchorShift(const ComputedStyle& style, float length) |
{ |
- LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(textBox.layoutObject()); |
- const ComputedStyle& style = textLayoutObject.styleRef(); |
- const SVGComputedStyle& svgStyle = style.svgStyle(); |
- |
- // Build chunk style flags. |
- unsigned chunkStyle = SVGTextChunk::DefaultStyle; |
- |
- // Handle 'direction' property. |
- if (!style.isLeftToRightDirection()) |
- chunkStyle |= SVGTextChunk::RightToLeftText; |
- |
- // Handle 'writing-mode' property. |
- if (svgStyle.isVerticalWritingMode()) |
- chunkStyle |= SVGTextChunk::VerticalText; |
- |
- // Handle 'text-anchor' property. |
- switch (svgStyle.textAnchor()) { |
+ bool isLTR = style.isLeftToRightDirection(); |
+ switch (style.svgStyle().textAnchor()) { |
+ default: |
+ ASSERT_NOT_REACHED(); |
case TA_START: |
- break; |
+ return isLTR ? 0 : -length; |
case TA_MIDDLE: |
- chunkStyle |= SVGTextChunk::MiddleAnchor; |
- break; |
+ return -length / 2; |
case TA_END: |
- chunkStyle |= SVGTextChunk::EndAnchor; |
- break; |
+ return isLTR ? -length : 0; |
} |
+} |
- // Handle 'lengthAdjust' property. |
- float desiredTextLength = 0; |
- if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromLayoutObject(textLayoutObject.parent())) { |
- SVGLengthContext lengthContext(textContentElement); |
- if (textContentElement->textLengthIsSpecifiedByUser()) |
- desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext); |
- else |
- desiredTextLength = 0; |
- |
- switch (textContentElement->lengthAdjust()->currentValue()->enumValue()) { |
- case SVGLengthAdjustUnknown: |
- break; |
- case SVGLengthAdjustSpacing: |
- chunkStyle |= SVGTextChunk::LengthAdjustSpacing; |
- break; |
- case SVGLengthAdjustSpacingAndGlyphs: |
- chunkStyle |= SVGTextChunk::LengthAdjustSpacingAndGlyphs; |
- break; |
- } |
+bool needsTextAnchorAdjustment(const ComputedStyle& style) |
+{ |
+ bool isLTR = style.isLeftToRightDirection(); |
+ switch (style.svgStyle().textAnchor()) { |
+ default: |
+ ASSERT_NOT_REACHED(); |
+ case TA_START: |
+ return !isLTR; |
+ case TA_MIDDLE: |
+ return true; |
+ case TA_END: |
+ return isLTR; |
} |
- |
- return SVGTextChunk(chunkStyle, desiredTextLength); |
} |
class ChunkLengthAccumulator { |
@@ -183,13 +159,13 @@ SVGTextPathChunkBuilder::SVGTextPathChunkBuilder() |
void SVGTextPathChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxListConstIterator boxEnd) |
{ |
- SVGTextChunk chunk = createTextChunk(**boxStart); |
+ const ComputedStyle& style = (*boxStart)->layoutObject().styleRef(); |
- ChunkLengthAccumulator lengthAccumulator(chunk.isVerticalText()); |
+ ChunkLengthAccumulator lengthAccumulator(style.svgStyle().isVerticalWritingMode()); |
lengthAccumulator.processRange(boxStart, boxEnd); |
// Handle text-anchor as additional start offset for text paths. |
- m_totalTextAnchorShift += chunk.calculateTextAnchorShift(lengthAccumulator.length()); |
+ m_totalTextAnchorShift += calculateTextAnchorShift(style, lengthAccumulator.length()); |
m_totalLength += lengthAccumulator.length(); |
m_totalCharacters += lengthAccumulator.numCharacters(); |
@@ -209,14 +185,30 @@ static void buildSpacingAndGlyphsTransform(bool isVerticalText, float scale, con |
void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxListConstIterator boxEnd) |
{ |
- SVGTextChunk chunk = createTextChunk(**boxStart); |
+ ASSERT(*boxStart); |
+ |
+ const LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText((*boxStart)->layoutObject()); |
+ const ComputedStyle& style = textLayoutObject.styleRef(); |
+ |
+ // Handle 'lengthAdjust' property. |
+ float desiredTextLength = 0; |
+ SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown; |
+ if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromLayoutObject(textLayoutObject.parent())) { |
+ lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumValue(); |
+ |
+ SVGLengthContext lengthContext(textContentElement); |
+ if (textContentElement->textLengthIsSpecifiedByUser()) |
+ desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext); |
+ else |
+ desiredTextLength = 0; |
+ } |
- bool processTextLength = chunk.hasDesiredTextLength(); |
- bool processTextAnchor = chunk.hasTextAnchor(); |
+ bool processTextLength = desiredTextLength > 0; |
+ bool processTextAnchor = needsTextAnchorAdjustment(style); |
if (!processTextAnchor && !processTextLength) |
return; |
- bool isVerticalText = chunk.isVerticalText(); |
+ bool isVerticalText = style.svgStyle().isVerticalWritingMode(); |
// Calculate absolute length of whole text chunk (starting from text box 'start', spanning 'length' text boxes). |
ChunkLengthAccumulator lengthAccumulator(isVerticalText); |
@@ -224,8 +216,8 @@ void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxList |
if (processTextLength) { |
float chunkLength = lengthAccumulator.length(); |
- if (chunk.hasLengthAdjustSpacing()) { |
- float textLengthShift = (chunk.desiredTextLength() - chunkLength) / lengthAccumulator.numCharacters(); |
+ if (lengthAdjust == SVGLengthAdjustSpacing) { |
+ float textLengthShift = (desiredTextLength - chunkLength) / lengthAccumulator.numCharacters(); |
unsigned atCharacter = 0; |
for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) { |
Vector<SVGTextFragment>& fragments = (*boxIter)->textFragments(); |
@@ -241,8 +233,8 @@ void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxList |
lengthAccumulator.processRange(boxStart, boxEnd); |
} |
} else { |
- ASSERT(chunk.hasLengthAdjustSpacingAndGlyphs()); |
- float textLengthScale = chunk.desiredTextLength() / chunkLength; |
+ ASSERT(lengthAdjust == SVGLengthAdjustSpacingAndGlyphs); |
+ float textLengthScale = desiredTextLength / chunkLength; |
AffineTransform spacingAndGlyphsTransform; |
bool foundFirstFragment = false; |
@@ -265,7 +257,7 @@ void SVGTextChunkBuilder::handleTextChunk(BoxListConstIterator boxStart, BoxList |
if (!processTextAnchor) |
return; |
- float textAnchorShift = chunk.calculateTextAnchorShift(lengthAccumulator.length()); |
+ float textAnchorShift = calculateTextAnchorShift(style, lengthAccumulator.length()); |
for (auto boxIter = boxStart; boxIter != boxEnd; ++boxIter) { |
Vector<SVGTextFragment>& fragments = (*boxIter)->textFragments(); |
if (fragments.isEmpty()) |