static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, WidthIterator& iterator, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace) { ASSERT(typesettingFeatures & (Kerning | Ligatures)); if (!glyphBuffer) return 0; int glyphBufferSize = glyphBuffer->size(); if (glyphBuffer->size() <= lastGlyphCount + 1) return 0; GlyphBufferAdvance* advances = glyphBuffer->advances(0); float widthDifference = 0; for (int i = lastGlyphCount; i < glyphBufferSize; ++i) widthDifference -= advances[i].width(); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); #if !ENABLE(SVG_FONTS) UNUSED_PARAM(iterator); #else // We need to handle transforms on SVG fonts internally, since they are rendered internally. if (fontData->isSVGFont()) { // SVG font ligatures are handled during glyph selection, only kerning remaining. if (iterator.run().renderingContext() && (typesettingFeatures & Kerning)) { // FIXME: We could pass the necessary context down to this level so we can lazily create rendering contexts at this point. // However, a larger refactoring of SVG fonts might necessary to sidestep this problem completely. iterator.run().renderingContext()->applySVGKerning(fontData, iterator, glyphBuffer, lastGlyphCount); } } else #endif fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) { int spaceOffset = charactersTreatedAsSpace[i].first; const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second; if (spaceOffset && !originalAdvances.characterIsSpace) glyphBuffer->advances(spaceOffset - 1)->setWidth(originalAdvances.advanceBeforeCharacter); glyphBuffer->advances(spaceOffset)->setWidth(originalAdvances.advanceAtCharacter); } charactersTreatedAsSpace.clear(); for (int i = lastGlyphCount; i < glyphBufferSize; ++i) widthDifference += advances[i].width(); lastGlyphCount = glyphBufferSize; return widthDifference; }
static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, WidthIterator& iterator, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace) { ASSERT(typesettingFeatures & (Kerning | Ligatures)); if (!glyphBuffer) return 0; int glyphBufferSize = glyphBuffer->size(); if (glyphBuffer->size() <= lastGlyphCount + 1) return 0; GlyphBufferAdvance* advances = glyphBuffer->advances(0); float widthDifference = 0; for (int i = lastGlyphCount; i < glyphBufferSize; ++i) widthDifference -= advances[i].width(); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); #if ENABLE(SVG_FONTS) // We need to handle transforms on SVG fonts internally, since they are rendered internally. if (fontData->isSVGFont()) { // SVG font fallbacks doesn't work properly and will not have a renderingContext. see: textRunNeedsRenderingContext() // SVG font ligatures are handled during glyph selection, only kerning remaining. if (iterator.run().renderingContext() && (typesettingFeatures & Kerning)) iterator.run().renderingContext()->applySVGKerning(fontData, iterator, glyphBuffer, lastGlyphCount); } else #endif fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) { int spaceOffset = charactersTreatedAsSpace[i].first; const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second; if (spaceOffset && !originalAdvances.characterIsSpace) glyphBuffer->advances(spaceOffset - 1)->setWidth(originalAdvances.advanceBeforeCharacter); glyphBuffer->advances(spaceOffset)->setWidth(originalAdvances.advanceAtCharacter); } charactersTreatedAsSpace.clear(); for (int i = lastGlyphCount; i < glyphBufferSize; ++i) widthDifference += advances[i].width(); lastGlyphCount = glyphBufferSize; return widthDifference; }
static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace) { ASSERT(typesettingFeatures & (Kerning | Ligatures)); if (!glyphBuffer) return 0; int glyphBufferSize = glyphBuffer->size(); if (glyphBuffer->size() <= lastGlyphCount + 1) return 0; GlyphBufferAdvance* advances = glyphBuffer->advances(0); float widthDifference = 0; for (int i = lastGlyphCount; i < glyphBufferSize; ++i) widthDifference -= advances[i].width(); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures); if (!ltr) glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) { int spaceOffset = charactersTreatedAsSpace[i].first; const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second; if (spaceOffset && !originalAdvances.characterIsSpace) glyphBuffer->advances(spaceOffset - 1)->setWidth(originalAdvances.advanceBeforeCharacter); glyphBuffer->advances(spaceOffset)->setWidth(originalAdvances.advanceAtCharacter); } charactersTreatedAsSpace.clear(); for (int i = lastGlyphCount; i < glyphBufferSize; ++i) widthDifference += advances[i].width(); lastGlyphCount = glyphBufferSize; return widthDifference; }