Esempio n. 1
0
unsigned SimpleShaper::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
{
    bool hasExtraSpacing = (m_font->fontDescription().letterSpacing() || m_font->fontDescription().wordSpacing() || m_expansion)
        && !m_run.spacingDisabled();

    const SimpleFontData* primaryFont = m_font->primaryFont();
    const SimpleFontData* lastFontData = primaryFont;
    bool normalizeSpace = m_run.normalizeSpace();

    CharacterData charData;
    while (textIterator.consume(charData.character, charData.clusterLength)) {
        charData.characterOffset = textIterator.currentCharacter();

        GlyphData glyphData = glyphDataForCharacter(charData, normalizeSpace);

        // Some fonts do not have a glyph for zero-width-space,
        // in that case use the space character and override the width.
        float width;
        if (!glyphData.glyph && Character::treatAsZeroWidthSpaceInComplexScript(charData.character)) {
            charData.character = space;
            glyphData = glyphDataForCharacter(charData);
            width = 0;
        } else {
            width = characterWidth(charData.character, glyphData);
        }

        Glyph glyph = glyphData.glyph;
        const SimpleFontData* fontData = glyphData.fontData;
        ASSERT(fontData);

        if (m_fallbackFonts && lastFontData != fontData && width) {
            lastFontData = fontData;
            cacheFallbackFont(fontData, primaryFont);
        }

        if (hasExtraSpacing)
            width = adjustSpacing(width, charData, *fontData, glyphBuffer);

        if (m_bounds)
            updateGlyphBounds(glyphData, width, !charData.characterOffset);

        if (m_forTextEmphasis && !Character::canReceiveTextEmphasis(charData.character))
            glyph = 0;

        // Advance past the character we just dealt with.
        textIterator.advance(charData.clusterLength);
        m_runWidthSoFar += width;

        if (glyphBuffer)
            glyphBuffer->add(glyph, fontData, width);
    }

    unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
    m_currentCharacter = textIterator.currentCharacter();

    return consumedCharacters;
}
Esempio n. 2
0
unsigned SimpleShaper::advanceInternal(TextIterator& textIterator, GlyphBuffer* glyphBuffer)
{
    bool hasExtraSpacing = (m_font->getFontDescription().letterSpacing() || m_font->getFontDescription().wordSpacing() || m_expansion)
                           && !m_textRun.spacingDisabled();

    const SimpleFontData* lastFontData = m_font->primaryFont();
    bool normalizeSpace = m_textRun.normalizeSpace();
    const float initialRunWidth = m_runWidthSoFar;

    CharacterData charData;
    while (textIterator.consume(charData.character)) {
        charData.characterOffset = textIterator.offset();
        charData.clusterLength = textIterator.glyphLength();
        GlyphData glyphData = glyphDataForCharacter(charData, normalizeSpace);

        // Some fonts do not have a glyph for zero-width-space,
        // in that case use the space character and override the width.
        float width;
        bool spaceUsedAsZeroWidthSpace = false;
        if (!glyphData.glyph && Character::treatAsZeroWidthSpace(charData.character)) {
            charData.character = spaceCharacter;
            glyphData = glyphDataForCharacter(charData);
            width = 0;
            spaceUsedAsZeroWidthSpace = true;
        } else {
            width = characterWidth(charData.character, glyphData);
        }

        Glyph glyph = glyphData.glyph;
        const SimpleFontData* fontData = glyphData.fontData;
        ASSERT(fontData);

        if (m_fallbackFonts && lastFontData != fontData && width) {
            lastFontData = fontData;
            trackNonPrimaryFallbackFont(fontData);
        }

        if (hasExtraSpacing && !spaceUsedAsZeroWidthSpace)
            width = adjustSpacing(width, charData);

        if (m_glyphBoundingBox) {
            ASSERT(glyphData.fontData);
            FloatRect glyphBounds = glyphData.fontData->boundsForGlyph(glyphData.glyph);
            // We are handling simple text run here, so Y-Offset will be zero.
            // FIXME: Computing bounds relative to the initial advance seems odd. Are we adjusting
            // these someplace else? If not, we'll end up with different bounds depending on how
            // we segment our advance() calls.
            glyphBounds.move(m_runWidthSoFar - initialRunWidth, 0);
            m_glyphBoundingBox->unite(glyphBounds);
        }

        if (glyphBuffer) {
            if (!forTextEmphasis()) {
                glyphBuffer->add(glyph, fontData, m_runWidthSoFar);
            } else if (Character::canReceiveTextEmphasis(charData.character)) {
                addEmphasisMark(glyphBuffer, m_runWidthSoFar + width / 2);
            }
        }

        // Advance past the character we just dealt with.
        textIterator.advance();
        m_runWidthSoFar += width;
    }

    unsigned consumedCharacters = textIterator.offset() - m_currentCharacter;
    m_currentCharacter = textIterator.offset();

    return consumedCharacters;
}