void SVGTextLayoutAttributesBuilder::propagateLayoutAttributes(RenderObject* start, unsigned& atCharacter, UChar& lastCharacter) const { for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) { if (child->isSVGInlineText()) { RenderSVGInlineText* text = toRenderSVGInlineText(child); const UChar* characters = text->characters(); unsigned textLength = text->textLength(); bool preserveWhiteSpace = shouldPreserveAllWhiteSpace(text->style()); SVGTextLayoutAttributes attributes; attributes.reserveCapacity(textLength); unsigned valueListPosition = atCharacter; unsigned metricsLength = 1; for (unsigned textPosition = 0; textPosition < textLength; textPosition += metricsLength) { const UChar& currentCharacter = characters[textPosition]; SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(text, textPosition, 1); metricsLength = metrics.length(); if (!preserveWhiteSpace && characterIsSpace(currentCharacter) && characterIsSpaceOrNull(lastCharacter)) { assignEmptyLayoutAttributesForCharacter(attributes); attributes.textMetricsValues().append(SVGTextMetrics::emptyMetrics()); continue; } assignLayoutAttributesForCharacter(attributes, metrics, valueListPosition); if (metricsLength > 1) { for (unsigned i = 0; i < metricsLength - 1; ++i) assignEmptyLayoutAttributesForCharacter(attributes); } lastCharacter = currentCharacter; valueListPosition += metricsLength; } #if DUMP_TEXT_LAYOUT_ATTRIBUTES > 0 fprintf(stderr, "\nDumping layout attributes for RenderSVGInlineText, renderer=%p, node=%p (atCharacter: %i)\n", text, text->node(), atCharacter); attributes.dump(); #endif text->storeLayoutAttributes(attributes); atCharacter = valueListPosition; continue; } if (!child->isSVGInline()) continue; propagateLayoutAttributes(child, atCharacter, lastCharacter); } }