diff options
Diffstat (limited to 'gfx/skia/skia/src/fonts')
-rw-r--r-- | gfx/skia/skia/src/fonts/SkFontMgr_indirect.cpp | 185 | ||||
-rw-r--r-- | gfx/skia/skia/src/fonts/SkRemotableFontMgr.cpp | 23 |
2 files changed, 208 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/fonts/SkFontMgr_indirect.cpp b/gfx/skia/skia/src/fonts/SkFontMgr_indirect.cpp new file mode 100644 index 0000000000..98c9663684 --- /dev/null +++ b/gfx/skia/skia/src/fonts/SkFontMgr_indirect.cpp @@ -0,0 +1,185 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkFontMgr.h" +#include "include/core/SkFontStyle.h" +#include "include/core/SkRefCnt.h" +#include "include/core/SkStream.h" +#include "include/core/SkString.h" +#include "include/core/SkTypeface.h" +#include "include/core/SkTypes.h" +#include "include/ports/SkFontMgr_indirect.h" +#include "include/ports/SkRemotableFontMgr.h" +#include "include/private/base/SkMutex.h" +#include "include/private/base/SkOnce.h" +#include "include/private/base/SkTArray.h" +#include "include/private/base/SkTemplates.h" + +class SkData; + +class SkStyleSet_Indirect : public SkFontStyleSet { +public: + /** Takes ownership of the SkRemotableFontIdentitySet. */ + SkStyleSet_Indirect(const SkFontMgr_Indirect* owner, int familyIndex, + SkRemotableFontIdentitySet* data) + : fOwner(SkRef(owner)), fFamilyIndex(familyIndex), fData(data) + { } + + int count() override { return fData->count(); } + + void getStyle(int index, SkFontStyle* fs, SkString* style) override { + if (fs) { + *fs = fData->at(index).fFontStyle; + } + if (style) { + // TODO: is this useful? Current locale? + style->reset(); + } + } + + SkTypeface* createTypeface(int index) override { + return fOwner->createTypefaceFromFontId(fData->at(index)); + } + + SkTypeface* matchStyle(const SkFontStyle& pattern) override { + if (fFamilyIndex >= 0) { + SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pattern); + return fOwner->createTypefaceFromFontId(id); + } + + return this->matchStyleCSS3(pattern); + } +private: + sk_sp<const SkFontMgr_Indirect> fOwner; + int fFamilyIndex; + sk_sp<SkRemotableFontIdentitySet> fData; +}; + +int SkFontMgr_Indirect::onCountFamilies() const { + return 0; +} + +void SkFontMgr_Indirect::onGetFamilyName(int index, SkString* familyName) const { + SK_ABORT("Not implemented"); +} + +SkFontStyleSet* SkFontMgr_Indirect::onCreateStyleSet(int index) const { + SK_ABORT("Not implemented"); +} + +SkFontStyleSet* SkFontMgr_Indirect::onMatchFamily(const char familyName[]) const { + return new SkStyleSet_Indirect(this, -1, fProxy->matchName(familyName)); +} + +SkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const { + if (id.fDataId == SkFontIdentity::kInvalidDataId) { + return nullptr; + } + + SkAutoMutexExclusive ama(fDataCacheMutex); + + sk_sp<SkTypeface> dataTypeface; + int dataTypefaceIndex = 0; + for (int i = 0; i < fDataCache.size(); ++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) { + std::unique_ptr<SkStreamAsset> stream(dataTypeface->openStream(nullptr)); + if (stream.get() != nullptr) { + return fImpl->makeFromStream(std::move(stream), dataTypefaceIndex).release(); + } + } + + // No data match, request data and add entry. + std::unique_ptr<SkStreamAsset> stream(fProxy->getData(id.fDataId)); + if (stream.get() == nullptr) { + return nullptr; + } + + sk_sp<SkTypeface> typeface(fImpl->makeFromStream(std::move(stream), 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(); +} + +SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyle(const char familyName[], + const SkFontStyle& fontStyle) const { + SkFontIdentity id = fProxy->matchNameStyle(familyName, fontStyle); + return this->createTypefaceFromFontId(id); +} + +SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[], + const SkFontStyle& style, + const char* bcp47[], + int bcp47Count, + SkUnichar character) const { + SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47, + bcp47Count, character); + return this->createTypefaceFromFontId(id); +} + +sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, + int ttcIndex) const { + return fImpl->makeFromStream(std::move(stream), ttcIndex); +} + +sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream, + const SkFontArguments& args) const { + return fImpl->makeFromStream(std::move(stream), args); +} + +sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromFile(const char path[], int ttcIndex) const { + return fImpl->makeFromFile(path, ttcIndex); +} + +sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const { + return fImpl->makeFromData(std::move(data), ttcIndex); +} + +sk_sp<SkTypeface> SkFontMgr_Indirect::onLegacyMakeTypeface(const char familyName[], + SkFontStyle style) const { + sk_sp<SkTypeface> face(this->matchFamilyStyle(familyName, style)); + + if (nullptr == face.get()) { + face.reset(this->matchFamilyStyle(nullptr, style)); + } + + if (nullptr == face.get()) { + SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style); + face.reset(this->createTypefaceFromFontId(fontId)); + } + + return face; +} diff --git a/gfx/skia/skia/src/fonts/SkRemotableFontMgr.cpp b/gfx/skia/skia/src/fonts/SkRemotableFontMgr.cpp new file mode 100644 index 0000000000..d8c904a566 --- /dev/null +++ b/gfx/skia/skia/src/fonts/SkRemotableFontMgr.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/ports/SkRemotableFontMgr.h" +#include "include/private/base/SkOnce.h" + +SkRemotableFontIdentitySet::SkRemotableFontIdentitySet(int count, SkFontIdentity** data) + : fCount(count), fData(count) +{ + SkASSERT(data); + *data = fData.get(); +} + +SkRemotableFontIdentitySet* SkRemotableFontIdentitySet::NewEmpty() { + static SkOnce once; + static SkRemotableFontIdentitySet* empty; + once([]{ empty = new SkRemotableFontIdentitySet; }); + return SkRef(empty); +} |