void LayoutSVGInlineText::addMetricsFromRun( const TextRun& run, bool& lastCharacterWasWhiteSpace) { Vector<CharacterRange> charRanges = scaledFont().individualCharacterRanges(run); synthesizeGraphemeWidths(run, charRanges); const float cachedFontHeight = scaledFont().getFontMetrics().floatHeight() / m_scalingFactor; const bool preserveWhiteSpace = styleRef().whiteSpace() == PRE; const unsigned runLength = static_cast<unsigned>(run.length()); // TODO(pdr): Character-based iteration is ambiguous and error-prone. It // should be unified under a single concept. See: https://crbug.com/593570 unsigned characterIndex = 0; while (characterIndex < runLength) { bool currentCharacterIsWhiteSpace = run[characterIndex] == ' '; if (!preserveWhiteSpace && lastCharacterWasWhiteSpace && currentCharacterIsWhiteSpace) { m_metrics.append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics)); characterIndex++; continue; } unsigned length = isValidSurrogatePair(run, characterIndex) ? 2 : 1; float width = charRanges[characterIndex].width() / m_scalingFactor; m_metrics.append(SVGTextMetrics(length, width, cachedFontHeight)); lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace; characterIndex += length; } }
bool UTF16TextIterator::consumeSurrogatePair(UChar32& character) { if (!U16_IS_SURROGATE(character)) return true; if (!isValidSurrogatePair(character)) { character = replacementCharacter; return true; } UChar low = m_characters[1]; character = U16_GET_SUPPLEMENTARY(character, low); m_currentGlyphLength = 2; return true; }