コード例 #1
0
void computeNormalizedSpaces(const TextRun& run, bool mirror, String& normalizedSpacesStringCache)
{
    if (normalizedSpacesStringCache.length() == static_cast<unsigned>(run.charactersLength()))
        return;
    if (run.is8Bit())
        normalizedSpacesStringCache = Font::normalizeSpaces(run.characters8(), run.charactersLength());
    else
        normalizedSpacesStringCache = Font::normalizeSpaces(run.characters16(), run.charactersLength());
    if (mirror)
        normalizedSpacesStringCache = createStringWithMirroredCharacters(normalizedSpacesStringCache);
}
コード例 #2
0
void LayoutSVGInlineText::updateMetricsList(bool& lastCharacterWasWhiteSpace)
{
    m_metrics.clear();

    if (!textLength())
        return;

    TextRun run = constructTextRun(*this, 0, textLength(), styleRef().direction());
    BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
    BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs();
    bool bidiOverride = isOverride(styleRef().unicodeBidi());
    BidiStatus status(LTR, bidiOverride);
    if (run.is8Bit() || bidiOverride) {
        WTF::Unicode::CharDirection direction = WTF::Unicode::LeftToRight;
        // If BiDi override is in effect, use the specified direction.
        if (bidiOverride && !styleRef().isLeftToRightDirection())
            direction = WTF::Unicode::RightToLeft;
        bidiRuns.addRun(new BidiCharacterRun(0, run.charactersLength(), status.context.get(), direction));
    } else {
        status.last = status.lastStrong = WTF::Unicode::OtherNeutral;
        bidiResolver.setStatus(status);
        bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0));
        const bool hardLineBreak = false;
        const bool reorderRuns = false;
        bidiResolver.createBidiRunsForLine(TextRunIterator(&run, run.length()), NoVisualOverride, hardLineBreak, reorderRuns);
    }

    for (const BidiCharacterRun* bidiRun = bidiRuns.firstRun(); bidiRun; bidiRun = bidiRun->next()) {
        TextRun subRun = constructTextRun(*this, bidiRun->start(), bidiRun->stop() - bidiRun->start(),
            bidiRun->direction());
        addMetricsFromRun(subRun, lastCharacterWasWhiteSpace);
    }

    bidiResolver.runs().deleteRuns();
}
コード例 #3
0
static float textWidth(const RenderText& text, unsigned from, unsigned length, float xPosition, const RenderStyle& style)
{
    if (style.font().isFixedPitch() || (!from && length == text.textLength()))
        return text.width(from, length, style.font(), xPosition, nullptr, nullptr);
    // FIXME: Add templated UChar/LChar paths.
    TextRun run = text.is8Bit() ? TextRun(text.characters8() + from, length) : TextRun(text.characters16() + from, length);
    run.setCharactersLength(text.textLength() - from);
    ASSERT(run.charactersLength() >= run.length());

    run.setXPos(xPosition);
    return style.font().width(run);
}
コード例 #4
0
float ShapeResult::fillGlyphBufferForTextEmphasisRun(GlyphBuffer* glyphBuffer,
    const RunInfo* run, const TextRun& textRun, const GlyphData* emphasisData,
    float initialAdvance, unsigned from, unsigned to, unsigned runOffset)
{
    if (!run)
        return 0;

    unsigned graphemesInCluster = 1;
    float clusterAdvance = 0;

    FloatPoint glyphCenter = emphasisData->fontData->
        boundsForGlyph(emphasisData->glyph).center();

    TextDirection direction = textRun.direction();

    // A "cluster" in this context means a cluster as it is used by HarfBuzz:
    // The minimal group of characters and corresponding glyphs, that cannot be broken
    // down further from a text shaping point of view.
    // A cluster can contain multiple glyphs and grapheme clusters, with mutually
    // overlapping boundaries. Below we count grapheme clusters per HarfBuzz clusters,
    // then linearly split the sum of corresponding glyph advances by the number of
    // grapheme clusters in order to find positions for emphasis mark drawing.
    uint16_t clusterStart = direction == RTL
        ? run->m_startIndex + run->m_numCharacters + runOffset
        : run->glyphToCharacterIndex(0) + runOffset;

    float advanceSoFar = initialAdvance;
    unsigned numGlyphs = run->m_numGlyphs;
    for (unsigned i = 0; i < numGlyphs; ++i) {
        const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
        uint16_t currentCharacterIndex = run->m_startIndex + glyphData.characterIndex + runOffset;
        bool isRunEnd = (i + 1 == numGlyphs);
        bool isClusterEnd =  isRunEnd || (run->glyphToCharacterIndex(i + 1) + runOffset != currentCharacterIndex);

        if ((direction == RTL && currentCharacterIndex >= to) || (direction != RTL && currentCharacterIndex < from)) {
            advanceSoFar += glyphData.advance;
            direction == RTL ? --clusterStart : ++clusterStart;
            continue;
        }

        clusterAdvance += glyphData.advance;

        if (textRun.is8Bit()) {
            float glyphAdvanceX = glyphData.advance;
            if (Character::canReceiveTextEmphasis(textRun[currentCharacterIndex])) {
                addEmphasisMark(glyphBuffer, emphasisData, glyphCenter, advanceSoFar + glyphAdvanceX / 2);
            }
            advanceSoFar += glyphAdvanceX;
        } else if (isClusterEnd) {
            uint16_t clusterEnd;
            if (direction == RTL)
                clusterEnd = currentCharacterIndex;
            else
                clusterEnd = isRunEnd ? run->m_startIndex + run->m_numCharacters + runOffset : run->glyphToCharacterIndex(i + 1) + runOffset;

            graphemesInCluster = countGraphemesInCluster(textRun.characters16(), textRun.charactersLength(), clusterStart, clusterEnd);
            if (!graphemesInCluster || !clusterAdvance)
                continue;

            float glyphAdvanceX = clusterAdvance / graphemesInCluster;
            for (unsigned j = 0; j < graphemesInCluster; ++j) {
                // Do not put emphasis marks on space, separator, and control characters.
                if (Character::canReceiveTextEmphasis(textRun[currentCharacterIndex]))
                    addEmphasisMark(glyphBuffer, emphasisData, glyphCenter, advanceSoFar + glyphAdvanceX / 2);
                advanceSoFar += glyphAdvanceX;
            }
            clusterStart = clusterEnd;
            clusterAdvance = 0;
        }
    }
    return advanceSoFar - initialAdvance;
}