Exemple #1
0
void FontFallbackList::determinePitch(const FontDescription& fontDescription) const
{
    for (unsigned fontIndex = 0; ; ++fontIndex) {
        const FontData* fontData = fontDataAt(fontDescription, fontIndex);
        if (!fontData) {
            // All fonts are custom fonts and are loading. Fallback should be variable pitch.
            m_pitch = VariablePitch;
            break;
        }

        const SimpleFontData* simpleFontData;
        if (fontData->isSegmented()) {
            const SegmentedFontData* segmentedFontData = toSegmentedFontData(fontData);
            if (segmentedFontData->numRanges() != 1 || !segmentedFontData->rangeAt(0).isEntireRange()) {
                m_pitch = VariablePitch;
                break;
            }
            simpleFontData = segmentedFontData->rangeAt(0).fontData().get();
        } else {
            simpleFontData = toSimpleFontData(fontData);
        }
        if (!fontData->isLoadingFallback()) {
            m_pitch = simpleFontData->pitch();
            break;
        }
    }
}
Exemple #2
0
void FontGlyphs::releaseFontData()
{
    unsigned numFonts = m_realizedFontData.size();
    for (unsigned i = 0; i < numFonts; ++i) {
        if (m_realizedFontData[i]->isCustomFont())
            continue;
        ASSERT(!m_realizedFontData[i]->isSegmented());
        fontCache().releaseFontData(toSimpleFontData(m_realizedFontData[i]));
    }
}
Exemple #3
0
void FontFallbackList::releaseFontData()
{
    unsigned numFonts = m_fontList.size();
    for (unsigned i = 0; i < numFonts; ++i) {
        if (!m_fontList[i]->isCustomFont()) {
            ASSERT(!m_fontList[i]->isSegmented());
            FontCache::fontCache()->releaseFontData(toSimpleFontData(m_fontList[i]));
        }
    }
}
Exemple #4
0
void FontGlyphs::determinePitch(const FontDescription& description) const
{
    const FontData* fontData = primaryFontData(description);
    if (!fontData->isSegmented())
        m_pitch = toSimpleFontData(*fontData).pitch();
    else {
        const SegmentedFontData& segmentedFontData = toSegmentedFontData(*fontData);
        unsigned numRanges = segmentedFontData.numRanges();
        if (numRanges == 1)
            m_pitch = segmentedFontData.rangeAt(0).fontData()->pitch();
        else
            m_pitch = VariablePitch;
    }
}
const FontDataForRangeSet FontFallbackIterator::next(const Vector<UChar32>& hintList)
{
    if (m_fallbackStage == OutOfLuck)
        return FontDataForRangeSet();

    if (m_fallbackStage == FallbackPriorityFonts) {
        // Only try one fallback priority font,
        // then proceed to regular system fallback.
        m_fallbackStage = SystemFonts;
        FontDataForRangeSet fallbackPriorityFontRange(fallbackPriorityFont(hintList[0]));
        if (fallbackPriorityFontRange.hasFontData())
            return fallbackPriorityFontRange;
        return next(hintList);
    }

    if (m_fallbackStage == SystemFonts) {
        // We've reached pref + system fallback.
        ASSERT(hintList.size());
        RefPtr<SimpleFontData> systemFont = uniqueSystemFontForHint(hintList[0]);
        if (systemFont)
            return FontDataForRangeSet(systemFont);

        // If we don't have options from the system fallback anymore or had
        // previously returned them, we only have the last resort font left.
        // TODO: crbug.com/42217 Improve this by doing the last run with a last
        // resort font that has glyphs for everything, for example the Unicode
        // LastResort font, not just Times or Arial.
        FontCache* fontCache = FontCache::fontCache();
        m_fallbackStage = OutOfLuck;
        RefPtr<SimpleFontData> lastResort = fontCache->getLastResortFallbackFont(m_fontDescription).get();
        RELEASE_ASSERT(lastResort);
        return FontDataForRangeSet(lastResort);
    }

    ASSERT(m_fallbackStage == FontGroupFonts
        || m_fallbackStage == SegmentedFace);
    const FontData* fontData = m_fontFallbackList->fontDataAt(
        m_fontDescription, m_currentFontDataIndex);

    if (!fontData) {
        // If there is no fontData coming from the fallback list, it means
        // we are now looking at system fonts, either for prioritized symbol
        // or emoji fonts or by calling system fallback API.
        m_fallbackStage = isNonTextFallbackPriority(m_fontFallbackPriority)
            ? FallbackPriorityFonts
            : SystemFonts;
        return next(hintList);
    }

    // Otherwise we've received a fontData from the font-family: set of fonts,
    // and a non-segmented one in this case.
    if (!fontData->isSegmented()) {
        // Skip forward to the next font family for the next call to next().
        m_currentFontDataIndex++;
        if (!fontData->isLoading()) {
            RefPtr<SimpleFontData> nonSegmented = const_cast<SimpleFontData*>(toSimpleFontData(fontData));
            return FontDataForRangeSet(nonSegmented);
        }
        return next(hintList);
    }

    // Iterate over ranges of a segmented font below.

    const SegmentedFontData* segmented = toSegmentedFontData(fontData);
    if (m_fallbackStage != SegmentedFace) {
        m_segmentedFaceIndex = 0;
        m_fallbackStage = SegmentedFace;
    }

    ASSERT(m_segmentedFaceIndex < segmented->numFaces());
    FontDataForRangeSet currentSegmentedFace = segmented->faceAt(m_segmentedFaceIndex);
    m_segmentedFaceIndex++;

    if (m_segmentedFaceIndex == segmented->numFaces()) {
        // Switch from iterating over a segmented face to the next family from
        // the font-family: group of fonts.
        m_fallbackStage = FontGroupFonts;
        m_currentFontDataIndex++;
    }

    if (rangeSetContributesForHint(hintList, currentSegmentedFace)) {
        if (currentSegmentedFace.fontData()->customFontData())
            currentSegmentedFace.fontData()->customFontData()->beginLoadIfNeeded();
        if (!currentSegmentedFace.fontData()->isLoading())
            return currentSegmentedFace;
        m_trackedLoadingRangeSets.append(currentSegmentedFace);
    }

    return next(hintList);
}