Chromium Code Reviews| 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..17f2a673beaa0d756dc54fba384a84b676a029e2 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,25 @@ 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()) { |
| - case TA_START: |
| - break; |
| - case TA_MIDDLE: |
| - chunkStyle |= SVGTextChunk::MiddleAnchor; |
| - break; |
| - case TA_END: |
| - chunkStyle |= SVGTextChunk::EndAnchor; |
| - break; |
| - } |
| - |
| - // 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; |
| - } |
| - } |
| + ETextAnchor textAnchor = style.svgStyle().textAnchor(); |
| + if (textAnchor == TA_MIDDLE) |
| + return -length / 2; |
| + bool isLTR = style.isLeftToRightDirection(); |
| + if (textAnchor == TA_END) |
| + return isLTR ? -length : 0; |
| + return isLTR ? 0 : -length; |
| +} |
| - return SVGTextChunk(chunkStyle, desiredTextLength); |
| +bool needsTextAnchorAdjustment(const ComputedStyle& style) |
| +{ |
| + ETextAnchor textAnchor = style.svgStyle().textAnchor(); |
|
pdr.
2015/06/04 20:22:02
Nit: These may be a little cleaner as a switch sta
fs
2015/06/05 08:42:32
I had this in PS1, but then some of the bots bombe
|
| + if (textAnchor == TA_MIDDLE) |
| + return true; |
| + bool isLTR = style.isLeftToRightDirection(); |
| + return (isLTR && textAnchor == TA_END) |
| + || (!isLTR && textAnchor == TA_START); |
| } |
| class ChunkLengthAccumulator { |
| @@ -183,13 +150,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 +176,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 +207,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 +224,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 +248,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()) |