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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}