void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float textAnchorStartOffset) { bool wasInitialLayout = isInitialLayout(); RenderSVGTextPath* textPath = toRenderSVGTextPath(flowBox->renderer()); Path path = textPath->layoutPath(); float baselineShift = calculateBaselineShift(textPath); layoutPath = path; layoutPathLength = path.length(); if (layoutPathLength <= 0.0f) return; startOffset = textPath->startOffset(); if (textPath->startOffset() >= 0.0f && textPath->startOffset() <= 1.0f) startOffset *= layoutPathLength; startOffset += textAnchorStartOffset; currentOffset = startOffset; // Only baseline-shift is handled through the normal layout system addStackContent(BaselineShiftStack, baselineShift); if (wasInitialLayout) { xStackChanged = false; yStackChanged = false; dxStackChanged = false; dyStackChanged = false; angleStackChanged = false; baselineShiftStackChanged = false; } }
void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayoutEngine& lineLayout) { ASSERT(object); m_inPathLayout = true; RenderSVGTextPath* textPath = toRenderSVGTextPath(object); Path path = textPath->layoutPath(); if (path.isEmpty()) return; m_textPathCalculator = new Path::PositionCalculator(path); m_textPathStartOffset = textPath->startOffset(); m_textPathLength = path.length(); if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1) m_textPathStartOffset *= m_textPathLength; float totalLength = 0; unsigned totalCharacters = 0; lineLayout.m_chunkLayoutBuilder.buildTextChunks(lineLayout.m_lineLayoutBoxes); const Vector<SVGTextChunk>& textChunks = lineLayout.m_chunkLayoutBuilder.textChunks(); unsigned size = textChunks.size(); for (unsigned i = 0; i < size; ++i) { const SVGTextChunk& chunk = textChunks.at(i); float length = 0; unsigned characters = 0; chunk.calculateLength(length, characters); // Handle text-anchor as additional start offset for text paths. m_textPathStartOffset += chunk.calculateTextAnchorShift(length); totalLength += length; totalCharacters += characters; } m_textPathCurrentOffset = m_textPathStartOffset; // Eventually handle textLength adjustments. SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown; float desiredTextLength = 0; if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textPath)) { SVGLengthContext lengthContext(textContentElement); lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumValue(); if (textContentElement->textLengthIsSpecifiedByUser()) desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext); else desiredTextLength = 0; } if (!desiredTextLength) return; if (lengthAdjust == SVGLengthAdjustSpacing) m_textPathSpacing = (desiredTextLength - totalLength) / totalCharacters; else m_textPathScaling = desiredTextLength / totalLength; }