void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGTextLayoutEngine& characterLayout) { for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) { if (child->isSVGInlineTextBox()) { ASSERT(child->renderer().isSVGInlineText()); SVGInlineTextBox* textBox = toSVGInlineTextBox(child); characterLayout.layoutInlineTextBox(textBox); } else { // Skip generated content. Node* node = child->renderer().node(); if (!node) continue; ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox()); SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child); bool isTextPath = node->hasTagName(SVGNames::textPathTag); if (isTextPath) { // 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(characterLayout.layoutAttributes()); layoutCharactersInTextBoxes(flowBox, lineLayout); characterLayout.beginTextPathLayout(&child->renderer(), lineLayout); } layoutCharactersInTextBoxes(flowBox, characterLayout); if (isTextPath) characterLayout.endTextPathLayout(); } } }
void SVGRootInlineBox::computePerCharacterLayoutInformation() { RenderSVGText* textRoot = toRenderSVGText(&blockFlow()); ASSERT(textRoot); Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot->layoutAttributes(); if (layoutAttributes.isEmpty()) return; if (textRoot->needsReordering()) reorderValueLists(layoutAttributes); // Perform SVG text layout phase two (see SVGTextLayoutEngine for details). SVGTextLayoutEngine characterLayout(layoutAttributes); layoutCharactersInTextBoxes(this, characterLayout); // Perform SVG text layout phase three (see SVGTextChunkBuilder for details). characterLayout.finishLayout(); // Perform SVG text layout phase four // Position & resize all SVGInlineText/FlowBoxes in the inline box tree, resize the root box as well as the RenderSVGText parent block. FloatRect childRect; layoutChildBoxes(this, &childRect); layoutRootBox(childRect); }
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 SVGRootInlineBox::computePerCharacterLayoutInformation() { // Perform SVG text layout phase two (see SVGTextLayoutEngine for details). SVGTextLayoutEngine characterLayout; layoutCharactersInTextBoxes(this, characterLayout); // Perform SVG text layout phase three (see SVGTextChunkBuilder for details). characterLayout.finishLayout(); // Perform SVG text layout phase four // Position & resize all SVGInlineText/FlowBoxes in the inline box tree, resize the root box as well as the RenderSVGText parent block. layoutChildBoxes(this); layoutRootBox(); }