Beispiel #1
0
SkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const {
    if (id.fDataId == SkFontIdentity::kInvalidDataId) {
        return nullptr;
    }

    SkAutoMutexAcquire ama(fDataCacheMutex);

    SkAutoTUnref<SkTypeface> dataTypeface;
    int dataTypefaceIndex = 0;
    for (int i = 0; i < fDataCache.count(); ++i) {
        const DataEntry& entry = fDataCache[i];
        if (entry.fDataId == id.fDataId) {
            if (entry.fTtcIndex == id.fTtcIndex &&
                !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref())
            {
                return entry.fTypeface;
            }
            if (dataTypeface.get() == nullptr &&
                !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref())
            {
                dataTypeface.reset(entry.fTypeface);
                dataTypefaceIndex = entry.fTtcIndex;
            }
        }

        if (entry.fTypeface->weak_expired()) {
            fDataCache.removeShuffle(i);
            --i;
        }
    }

    // No exact match, but did find a data match.
    if (dataTypeface.get() != nullptr) {
        SkAutoTDelete<SkStreamAsset> stream(dataTypeface->openStream(nullptr));
        if (stream.get() != nullptr) {
            return fImpl->createFromStream(stream.release(), dataTypefaceIndex);
        }
    }

    // No data match, request data and add entry.
    SkAutoTDelete<SkStreamAsset> stream(fProxy->getData(id.fDataId));
    if (stream.get() == nullptr) {
        return nullptr;
    }

    SkAutoTUnref<SkTypeface> typeface(fImpl->createFromStream(stream.release(), id.fTtcIndex));
    if (typeface.get() == nullptr) {
        return nullptr;
    }

    DataEntry& newEntry = fDataCache.push_back();
    typeface->weak_ref();
    newEntry.fDataId = id.fDataId;
    newEntry.fTtcIndex = id.fTtcIndex;
    newEntry.fTypeface = typeface.get();  // weak reference passed to new entry.

    return typeface.release();
}