aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontMgr_custom.cpp601
-rw-r--r--src/ports/SkFontMgr_custom.h158
-rw-r--r--src/ports/SkFontMgr_custom_directory.cpp104
-rw-r--r--src/ports/SkFontMgr_custom_directory_factory.cpp2
-rw-r--r--src/ports/SkFontMgr_custom_embedded.cpp87
-rw-r--r--src/ports/SkFontMgr_custom_empty.cpp27
6 files changed, 545 insertions, 434 deletions
diff --git a/src/ports/SkFontMgr_custom.cpp b/src/ports/SkFontMgr_custom.cpp
index 1b6baa19a4..4e4887d27d 100644
--- a/src/ports/SkFontMgr_custom.cpp
+++ b/src/ports/SkFontMgr_custom.cpp
@@ -11,15 +11,12 @@
#include "SkFontMgr_custom.h"
#include "SkFontStyle.h"
#include "SkMakeUnique.h"
-#include "SkOSFile.h"
-#include "SkOSPath.h"
#include "SkRefCnt.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTemplates.h"
#include "SkTypeface.h"
-#include "SkTypefaceCache.h"
#include "SkTypes.h"
#include <limits>
@@ -27,497 +24,235 @@
class SkData;
-/** The base SkTypeface implementation for the custom font manager. */
-class SkTypeface_Custom : public SkTypeface_FreeType {
-public:
- SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
- bool sysFont, const SkString familyName, int index)
- : INHERITED(style, isFixedPitch)
- , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
- { }
+SkTypeface_Custom::SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
+ bool sysFont, const SkString familyName, int index)
+ : INHERITED(style, isFixedPitch)
+ , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
+{ }
- bool isSysFont() const { return fIsSysFont; }
+bool SkTypeface_Custom::isSysFont() const { return fIsSysFont; }
-protected:
- void onGetFamilyName(SkString* familyName) const override {
- *familyName = fFamilyName;
- }
-
- void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override {
- desc->setFamilyName(fFamilyName.c_str());
- desc->setStyle(this->fontStyle());
- *isLocal = !this->isSysFont();
- }
-
- int getIndex() const { return fIndex; }
-
-private:
- const bool fIsSysFont;
- const SkString fFamilyName;
- const int fIndex;
-
- typedef SkTypeface_FreeType INHERITED;
-};
-
-/** The empty SkTypeface implementation for the custom font manager.
- * Used as the last resort fallback typeface.
- */
-class SkTypeface_Empty : public SkTypeface_Custom {
-public:
- SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
-
-protected:
- SkStreamAsset* onOpenStream(int*) const override { return nullptr; }
-
-private:
- typedef SkTypeface_Custom INHERITED;
-};
-
-/** The stream SkTypeface implementation for the custom font manager. */
-class SkTypeface_Stream : public SkTypeface_Custom {
-public:
- SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
- const SkFontStyle& style, bool isFixedPitch, bool sysFont,
- const SkString familyName)
- : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
- , fData(std::move(fontData))
- { }
-
-protected:
- SkStreamAsset* onOpenStream(int* ttcIndex) const override {
- *ttcIndex = fData->getIndex();
- return fData->getStream()->duplicate();
- }
-
- std::unique_ptr<SkFontData> onMakeFontData() const override {
- return skstd::make_unique<SkFontData>(*fData);
- }
-
-private:
- const std::unique_ptr<const SkFontData> fData;
-
- typedef SkTypeface_Custom INHERITED;
-};
-
-/** The file SkTypeface implementation for the custom font manager. */
-class SkTypeface_File : public SkTypeface_Custom {
-public:
- SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
- const SkString familyName, const char path[], int index)
- : INHERITED(style, isFixedPitch, sysFont, familyName, index)
- , fPath(path)
- { }
-
-protected:
- SkStreamAsset* onOpenStream(int* ttcIndex) const override {
- *ttcIndex = this->getIndex();
- return SkStream::MakeFromFile(fPath.c_str()).release();
- }
-
-private:
- SkString fPath;
-
- typedef SkTypeface_Custom INHERITED;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * SkFontStyleSet_Custom
- *
- * This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families.
- */
-class SkFontStyleSet_Custom : public SkFontStyleSet {
-public:
- explicit SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) { }
-
- /** Should only be called during the inital build phase. */
- void appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
- fStyles.emplace_back(std::move(typeface));
- }
-
- int count() override {
- return fStyles.count();
- }
+void SkTypeface_Custom::onGetFamilyName(SkString* familyName) const {
+ *familyName = fFamilyName;
+}
- void getStyle(int index, SkFontStyle* style, SkString* name) override {
- SkASSERT(index < fStyles.count());
- if (style) {
- *style = fStyles[index]->fontStyle();
- }
- if (name) {
- name->reset();
- }
- }
+void SkTypeface_Custom::onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const {
+ desc->setFamilyName(fFamilyName.c_str());
+ desc->setStyle(this->fontStyle());
+ *isLocal = !this->isSysFont();
+}
- SkTypeface* createTypeface(int index) override {
- SkASSERT(index < fStyles.count());
- return SkRef(fStyles[index].get());
- }
+int SkTypeface_Custom::getIndex() const { return fIndex; }
- SkTypeface* matchStyle(const SkFontStyle& pattern) override {
- return this->matchStyleCSS3(pattern);
- }
- SkString getFamilyName() { return fFamilyName; }
+SkTypeface_Empty::SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
-private:
- SkTArray<sk_sp<SkTypeface_Custom>> fStyles;
- SkString fFamilyName;
+SkStreamAsset* SkTypeface_Empty::onOpenStream(int*) const { return nullptr; }
- friend class SkFontMgr_Custom;
-};
-/**
- * SkFontMgr_Custom
- *
- * This class is essentially a collection of SkFontStyleSet_Custom,
- * one SkFontStyleSet_Custom for each family. This class may be modified
- * to load fonts from any source by changing the initialization.
- */
-class SkFontMgr_Custom : public SkFontMgr {
-public:
- typedef SkTArray<sk_sp<SkFontStyleSet_Custom>> Families;
- class SystemFontLoader {
- public:
- virtual ~SystemFontLoader() { }
- virtual void loadSystemFonts(const SkTypeface_FreeType::Scanner&, Families*) const = 0;
- };
- explicit SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
- loader.loadSystemFonts(fScanner, &fFamilies);
-
- // Try to pick a default font.
- static const char* defaultNames[] = {
- "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
- };
- for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
- sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
- if (nullptr == set) {
- continue;
- }
+SkTypeface_Stream::SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
+ const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+ const SkString familyName)
+ : INHERITED(style, isFixedPitch, sysFont, familyName, fontData->getIndex())
+ , fData(std::move(fontData))
+{ }
- sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
- SkFontStyle::kNormal_Width,
- SkFontStyle::kUpright_Slant)));
- if (nullptr == tf) {
- continue;
- }
+SkStreamAsset* SkTypeface_Stream::onOpenStream(int* ttcIndex) const {
+ *ttcIndex = fData->getIndex();
+ return fData->getStream()->duplicate();
+}
- fDefaultFamily = set.get();
- break;
- }
- if (nullptr == fDefaultFamily) {
- fDefaultFamily = fFamilies[0].get();
- }
- }
+std::unique_ptr<SkFontData> SkTypeface_Stream::onMakeFontData() const {
+ return skstd::make_unique<SkFontData>(*fData);
+}
-protected:
- int onCountFamilies() const override {
- return fFamilies.count();
- }
- void onGetFamilyName(int index, SkString* familyName) const override {
- SkASSERT(index < fFamilies.count());
- familyName->set(fFamilies[index]->getFamilyName());
- }
+SkTypeface_File::SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+ const SkString familyName, const char path[], int index)
+ : INHERITED(style, isFixedPitch, sysFont, familyName, index)
+ , fPath(path)
+{ }
- SkFontStyleSet_Custom* onCreateStyleSet(int index) const override {
- SkASSERT(index < fFamilies.count());
- return SkRef(fFamilies[index].get());
- }
+SkStreamAsset* SkTypeface_File::onOpenStream(int* ttcIndex) const {
+ *ttcIndex = this->getIndex();
+ return SkStream::MakeFromFile(fPath.c_str()).release();
+}
- SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const override {
- for (int i = 0; i < fFamilies.count(); ++i) {
- if (fFamilies[i]->getFamilyName().equals(familyName)) {
- return SkRef(fFamilies[i].get());
- }
- }
- return nullptr;
- }
+///////////////////////////////////////////////////////////////////////////////
- SkTypeface* onMatchFamilyStyle(const char familyName[],
- const SkFontStyle& fontStyle) const override
- {
- sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
- return sset->matchStyle(fontStyle);
- }
+SkFontStyleSet_Custom::SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(familyName) {}
- SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
- const char* bcp47[], int bcp47Count,
- SkUnichar character) const override
- {
- return nullptr;
- }
+void SkFontStyleSet_Custom::appendTypeface(sk_sp<SkTypeface_Custom> typeface) {
+ fStyles.emplace_back(std::move(typeface));
+}
- SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
- const SkFontStyle& fontStyle) const override
- {
- for (int i = 0; i < fFamilies.count(); ++i) {
- for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
- if (fFamilies[i]->fStyles[j].get() == familyMember) {
- return fFamilies[i]->matchStyle(fontStyle);
- }
- }
- }
- return nullptr;
- }
+int SkFontStyleSet_Custom::count() {
+ return fStyles.count();
+}
- SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override {
- return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex);
+void SkFontStyleSet_Custom::getStyle(int index, SkFontStyle* style, SkString* name) {
+ SkASSERT(index < fStyles.count());
+ if (style) {
+ *style = fStyles[index]->fontStyle();
}
-
- SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override {
- return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex));
+ if (name) {
+ name->reset();
}
+}
- SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override {
- using Scanner = SkTypeface_FreeType::Scanner;
- std::unique_ptr<SkStreamAsset> stream(s);
- bool isFixedPitch;
- SkFontStyle style;
- SkString name;
- Scanner::AxisDefinitions axisDefinitions;
- if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(),
- &name, &style, &isFixedPitch, &axisDefinitions))
- {
- return nullptr;
- }
-
- int paramAxisCount;
- const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
- SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
- Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name);
+SkTypeface* SkFontStyleSet_Custom::createTypeface(int index) {
+ SkASSERT(index < fStyles.count());
+ return SkRef(fStyles[index].get());
+}
- auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(),
- axisValues.get(), axisDefinitions.count());
- return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
- }
+SkTypeface* SkFontStyleSet_Custom::matchStyle(const SkFontStyle& pattern) {
+ return this->matchStyleCSS3(pattern);
+}
- SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> data) const override {
- bool isFixedPitch;
- SkFontStyle style;
- SkString name;
- if (!fScanner.scanFont(data->getStream(), data->getIndex(),
- &name, &style, &isFixedPitch, nullptr))
- {
- return nullptr;
- }
- return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
- }
+SkString SkFontStyleSet_Custom::getFamilyName() { return fFamilyName; }
- SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override {
- std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
- return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
- }
- SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
- SkTypeface* tf = nullptr;
+SkFontMgr_Custom::SkFontMgr_Custom(const SystemFontLoader& loader) : fDefaultFamily(nullptr) {
+ loader.loadSystemFonts(fScanner, &fFamilies);
- if (familyName) {
- tf = this->onMatchFamilyStyle(familyName, style);
+ // Try to pick a default font.
+ static const char* defaultNames[] = {
+ "Arial", "Verdana", "Times New Roman", "Droid Sans", nullptr
+ };
+ for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) {
+ sk_sp<SkFontStyleSet_Custom> set(this->onMatchFamily(defaultNames[i]));
+ if (nullptr == set) {
+ continue;
}
+ sk_sp<SkTypeface> tf(set->matchStyle(SkFontStyle(SkFontStyle::kNormal_Weight,
+ SkFontStyle::kNormal_Width,
+ SkFontStyle::kUpright_Slant)));
if (nullptr == tf) {
- tf = fDefaultFamily->matchStyle(style);
+ continue;
}
- return tf;
+ fDefaultFamily = set.get();
+ break;
}
+ if (nullptr == fDefaultFamily) {
+ fDefaultFamily = fFamilies[0].get();
+ }
+}
-private:
- Families fFamilies;
- SkFontStyleSet_Custom* fDefaultFamily;
- SkTypeface_FreeType::Scanner fScanner;
-};
-
-///////////////////////////////////////////////////////////////////////////////
+int SkFontMgr_Custom::onCountFamilies() const {
+ return fFamilies.count();
+}
-class DirectorySystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
-public:
- DirectorySystemFontLoader(const char* dir) : fBaseDirectory(dir) { }
+void SkFontMgr_Custom::onGetFamilyName(int index, SkString* familyName) const {
+ SkASSERT(index < fFamilies.count());
+ familyName->set(fFamilies[index]->getFamilyName());
+}
- void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
- SkFontMgr_Custom::Families* families) const override
- {
- load_directory_fonts(scanner, fBaseDirectory, ".ttf", families);
- load_directory_fonts(scanner, fBaseDirectory, ".ttc", families);
- load_directory_fonts(scanner, fBaseDirectory, ".otf", families);
- load_directory_fonts(scanner, fBaseDirectory, ".pfb", families);
-
- if (families->empty()) {
- SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
- families->push_back().reset(family);
- family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
- }
- }
+SkFontStyleSet_Custom* SkFontMgr_Custom::onCreateStyleSet(int index) const {
+ SkASSERT(index < fFamilies.count());
+ return SkRef(fFamilies[index].get());
+}
-private:
- static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
- const char familyName[])
- {
- for (int i = 0; i < families.count(); ++i) {
- if (families[i]->getFamilyName().equals(familyName)) {
- return families[i].get();
- }
+SkFontStyleSet_Custom* SkFontMgr_Custom::onMatchFamily(const char familyName[]) const {
+ for (int i = 0; i < fFamilies.count(); ++i) {
+ if (fFamilies[i]->getFamilyName().equals(familyName)) {
+ return SkRef(fFamilies[i].get());
}
- return nullptr;
}
+ return nullptr;
+}
- static void load_directory_fonts(const SkTypeface_FreeType::Scanner& scanner,
- const SkString& directory, const char* suffix,
- SkFontMgr_Custom::Families* families)
- {
- SkOSFile::Iter iter(directory.c_str(), suffix);
- SkString name;
-
- while (iter.next(&name, false)) {
- SkString filename(SkOSPath::Join(directory.c_str(), name.c_str()));
- std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(filename.c_str());
- if (!stream) {
- SkDebugf("---- failed to open <%s>\n", filename.c_str());
- continue;
- }
-
- int numFaces;
- if (!scanner.recognizedFont(stream.get(), &numFaces)) {
- SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
- continue;
- }
+SkTypeface* SkFontMgr_Custom::onMatchFamilyStyle(const char familyName[],
+ const SkFontStyle& fontStyle) const
+{
+ sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName));
+ return sset->matchStyle(fontStyle);
+}
- for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
- bool isFixedPitch;
- SkString realname;
- SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
- if (!scanner.scanFont(stream.get(), faceIndex,
- &realname, &style, &isFixedPitch, nullptr))
- {
- SkDebugf("---- failed to open <%s> <%d> as a font\n",
- filename.c_str(), faceIndex);
- continue;
- }
-
- SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
- if (nullptr == addTo) {
- addTo = new SkFontStyleSet_Custom(realname);
- families->push_back().reset(addTo);
- }
- addTo->appendTypeface(sk_make_sp<SkTypeface_File>(style, isFixedPitch, true,
- realname, filename.c_str(),
- faceIndex));
- }
- }
+SkTypeface* SkFontMgr_Custom::onMatchFamilyStyleCharacter(const char familyName[],
+ const SkFontStyle&,
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const
+{
+ return nullptr;
+}
- SkOSFile::Iter dirIter(directory.c_str());
- while (dirIter.next(&name, true)) {
- if (name.startsWith(".")) {
- continue;
+SkTypeface* SkFontMgr_Custom::onMatchFaceStyle(const SkTypeface* familyMember,
+ const SkFontStyle& fontStyle) const
+{
+ for (int i = 0; i < fFamilies.count(); ++i) {
+ for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) {
+ if (fFamilies[i]->fStyles[j].get() == familyMember) {
+ return fFamilies[i]->matchStyle(fontStyle);
}
- SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str()));
- load_directory_fonts(scanner, dirname, suffix, families);
}
}
-
- SkString fBaseDirectory;
-};
-
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir) {
- return sk_make_sp<SkFontMgr_Custom>(DirectorySystemFontLoader(dir));
+ return nullptr;
}
-///////////////////////////////////////////////////////////////////////////////
-
-struct SkEmbeddedResource { const uint8_t* data; size_t size; };
-struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count; };
-
-class EmbeddedSystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
-public:
- EmbeddedSystemFontLoader(const SkEmbeddedResourceHeader* header) : fHeader(header) { }
-
- void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
- SkFontMgr_Custom::Families* families) const override
- {
- for (int i = 0; i < fHeader->count; ++i) {
- const SkEmbeddedResource& fontEntry = fHeader->entries[i];
- load_embedded_font(scanner, fontEntry.data, fontEntry.size, i, families);
- }
+SkTypeface* SkFontMgr_Custom::onCreateFromData(SkData* data, int ttcIndex) const {
+ return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex);
+}
- if (families->empty()) {
- SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
- families->push_back().reset(family);
- family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
- }
- }
+SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const {
+ return this->createFromStream(bareStream, FontParameters().setCollectionIndex(ttcIndex));
+}
-private:
- static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
- const char familyName[])
+SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s,
+ const FontParameters& params) const
+{
+ using Scanner = SkTypeface_FreeType::Scanner;
+ std::unique_ptr<SkStreamAsset> stream(s);
+ bool isFixedPitch;
+ SkFontStyle style;
+ SkString name;
+ Scanner::AxisDefinitions axisDefinitions;
+ if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(),
+ &name, &style, &isFixedPitch, &axisDefinitions))
{
- for (int i = 0; i < families.count(); ++i) {
- if (families[i]->getFamilyName().equals(familyName)) {
- return families[i].get();
- }
- }
return nullptr;
}
- static void load_embedded_font(const SkTypeface_FreeType::Scanner& scanner,
- const uint8_t* data, size_t size, int index,
- SkFontMgr_Custom::Families* families)
- {
- auto stream = skstd::make_unique<SkMemoryStream>(data, size, false);
-
- int numFaces;
- if (!scanner.recognizedFont(stream.get(), &numFaces)) {
- SkDebugf("---- failed to open <%d> as a font\n", index);
- return;
- }
+ int paramAxisCount;
+ const FontParameters::Axis* paramAxes = params.getAxes(&paramAxisCount);
+ SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count());
+ Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name);
- for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
- bool isFixedPitch;
- SkString realname;
- SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
- if (!scanner.scanFont(stream.get(), faceIndex,
- &realname, &style, &isFixedPitch, nullptr))
- {
- SkDebugf("---- failed to open <%d> <%d> as a font\n", index, faceIndex);
- return;
- }
+ auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(),
+ axisValues.get(), axisDefinitions.count());
+ return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
+}
- SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
- if (nullptr == addTo) {
- addTo = new SkFontStyleSet_Custom(realname);
- families->push_back().reset(addTo);
- }
- auto data = skstd::make_unique<SkFontData>(std::move(stream), faceIndex, nullptr, 0);
- addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data),
- style, isFixedPitch,
- true, realname));
- }
+SkTypeface* SkFontMgr_Custom::onCreateFromFontData(std::unique_ptr<SkFontData> data) const {
+ bool isFixedPitch;
+ SkFontStyle style;
+ SkString name;
+ if (!fScanner.scanFont(data->getStream(), data->getIndex(),
+ &name, &style, &isFixedPitch, nullptr))
+ {
+ return nullptr;
}
-
- const SkEmbeddedResourceHeader* fHeader;
-};
-
-sk_sp<SkFontMgr> SkFontMgr_New_Custom_Embedded(const SkEmbeddedResourceHeader* header) {
- return sk_make_sp<SkFontMgr_Custom>(EmbeddedSystemFontLoader(header));
+ return new SkTypeface_Stream(std::move(data), style, isFixedPitch, false, name);
}
-///////////////////////////////////////////////////////////////////////////////
+SkTypeface* SkFontMgr_Custom::onCreateFromFile(const char path[], int ttcIndex) const {
+ std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
+ return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
+}
-class EmptyFontLoader : public SkFontMgr_Custom::SystemFontLoader {
-public:
- EmptyFontLoader() { }
+SkTypeface* SkFontMgr_Custom::onLegacyCreateTypeface(const char familyName[],
+ SkFontStyle style) const
+{
+ SkTypeface* tf = nullptr;
- void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
- SkFontMgr_Custom::Families* families) const override
- {
- SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
- families->push_back().reset(family);
- family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+ if (familyName) {
+ tf = this->onMatchFamilyStyle(familyName, style);
}
-};
+ if (nullptr == tf) {
+ tf = fDefaultFamily->matchStyle(style);
+ }
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Empty() {
- return sk_make_sp<SkFontMgr_Custom>(EmptyFontLoader());
+ return tf;
}
diff --git a/src/ports/SkFontMgr_custom.h b/src/ports/SkFontMgr_custom.h
new file mode 100644
index 0000000000..9149378a50
--- /dev/null
+++ b/src/ports/SkFontMgr_custom.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontMgr_custom_DEFINED
+#define SkFontMgr_custom_DEFINED
+
+#include "SkFontHost_FreeType_common.h"
+#include "SkFontMgr.h"
+#include "SkFontStyle.h"
+#include "SkRefCnt.h"
+#include "SkString.h"
+#include "SkTArray.h"
+#include "SkTypes.h"
+
+class SkData;
+class SkFontDescriptor;
+class SkStreamAsset;
+class SkTypeface;
+
+/** The base SkTypeface implementation for the custom font manager. */
+class SkTypeface_Custom : public SkTypeface_FreeType {
+public:
+ SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
+ bool sysFont, const SkString familyName, int index);
+ bool isSysFont() const;
+
+protected:
+ void onGetFamilyName(SkString* familyName) const override;
+ void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
+ int getIndex() const;
+
+private:
+ const bool fIsSysFont;
+ const SkString fFamilyName;
+ const int fIndex;
+
+ typedef SkTypeface_FreeType INHERITED;
+};
+
+/** The empty SkTypeface implementation for the custom font manager.
+ * Used as the last resort fallback typeface.
+ */
+class SkTypeface_Empty : public SkTypeface_Custom {
+public:
+ SkTypeface_Empty() ;
+
+protected:
+ SkStreamAsset* onOpenStream(int*) const override;
+
+private:
+ typedef SkTypeface_Custom INHERITED;
+};
+
+/** The stream SkTypeface implementation for the custom font manager. */
+class SkTypeface_Stream : public SkTypeface_Custom {
+public:
+ SkTypeface_Stream(std::unique_ptr<SkFontData> fontData,
+ const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+ const SkString familyName);
+
+protected:
+ SkStreamAsset* onOpenStream(int* ttcIndex) const override;
+ std::unique_ptr<SkFontData> onMakeFontData() const override;
+
+private:
+ const std::unique_ptr<const SkFontData> fData;
+
+ typedef SkTypeface_Custom INHERITED;
+};
+
+/** The file SkTypeface implementation for the custom font manager. */
+class SkTypeface_File : public SkTypeface_Custom {
+public:
+ SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+ const SkString familyName, const char path[], int index);
+
+protected:
+ SkStreamAsset* onOpenStream(int* ttcIndex) const override;
+
+private:
+ SkString fPath;
+
+ typedef SkTypeface_Custom INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * SkFontStyleSet_Custom
+ *
+ * This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families.
+ */
+class SkFontStyleSet_Custom : public SkFontStyleSet {
+public:
+ explicit SkFontStyleSet_Custom(const SkString familyName);
+
+ /** Should only be called during the inital build phase. */
+ void appendTypeface(sk_sp<SkTypeface_Custom> typeface);
+ int count() override;
+ void getStyle(int index, SkFontStyle* style, SkString* name) override;
+ SkTypeface* createTypeface(int index) override;
+ SkTypeface* matchStyle(const SkFontStyle& pattern) override;
+ SkString getFamilyName();
+
+private:
+ SkTArray<sk_sp<SkTypeface_Custom>> fStyles;
+ SkString fFamilyName;
+
+ friend class SkFontMgr_Custom;
+};
+
+/**
+ * SkFontMgr_Custom
+ *
+ * This class is essentially a collection of SkFontStyleSet_Custom,
+ * one SkFontStyleSet_Custom for each family. This class may be modified
+ * to load fonts from any source by changing the initialization.
+ */
+class SkFontMgr_Custom : public SkFontMgr {
+public:
+ typedef SkTArray<sk_sp<SkFontStyleSet_Custom>> Families;
+ class SystemFontLoader {
+ public:
+ virtual ~SystemFontLoader() { }
+ virtual void loadSystemFonts(const SkTypeface_FreeType::Scanner&, Families*) const = 0;
+ };
+ explicit SkFontMgr_Custom(const SystemFontLoader& loader);
+
+protected:
+ int onCountFamilies() const override;
+ void onGetFamilyName(int index, SkString* familyName) const override;
+ SkFontStyleSet_Custom* onCreateStyleSet(int index) const override;
+ SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const override;
+ SkTypeface* onMatchFamilyStyle(const char familyName[],
+ const SkFontStyle& fontStyle) const override;
+ SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+ const char* bcp47[], int bcp47Count,
+ SkUnichar character) const override;
+ SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+ const SkFontStyle& fontStyle) const override;
+ SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override;
+ SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override;
+ SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override;
+ SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> data) const override;
+ SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override;
+ SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override;
+
+private:
+ Families fFamilies;
+ SkFontStyleSet_Custom* fDefaultFamily;
+ SkTypeface_FreeType::Scanner fScanner;
+};
+
+#endif
diff --git a/src/ports/SkFontMgr_custom_directory.cpp b/src/ports/SkFontMgr_custom_directory.cpp
new file mode 100644
index 0000000000..af322875f3
--- /dev/null
+++ b/src/ports/SkFontMgr_custom_directory.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontMgr_custom.h"
+#include "SkFontMgr_directory.h"
+#include "SkOSFile.h"
+#include "SkOSPath.h"
+#include "SkStream.h"
+
+class DirectorySystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
+public:
+ DirectorySystemFontLoader(const char* dir) : fBaseDirectory(dir) { }
+
+ void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
+ SkFontMgr_Custom::Families* families) const override
+ {
+ load_directory_fonts(scanner, fBaseDirectory, ".ttf", families);
+ load_directory_fonts(scanner, fBaseDirectory, ".ttc", families);
+ load_directory_fonts(scanner, fBaseDirectory, ".otf", families);
+ load_directory_fonts(scanner, fBaseDirectory, ".pfb", families);
+
+ if (families->empty()) {
+ SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
+ families->push_back().reset(family);
+ family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+ }
+ }
+
+private:
+ static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
+ const char familyName[])
+ {
+ for (int i = 0; i < families.count(); ++i) {
+ if (families[i]->getFamilyName().equals(familyName)) {
+ return families[i].get();
+ }
+ }
+ return nullptr;
+ }
+
+ static void load_directory_fonts(const SkTypeface_FreeType::Scanner& scanner,
+ const SkString& directory, const char* suffix,
+ SkFontMgr_Custom::Families* families)
+ {
+ SkOSFile::Iter iter(directory.c_str(), suffix);
+ SkString name;
+
+ while (iter.next(&name, false)) {
+ SkString filename(SkOSPath::Join(directory.c_str(), name.c_str()));
+ std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(filename.c_str());
+ if (!stream) {
+ SkDebugf("---- failed to open <%s>\n", filename.c_str());
+ continue;
+ }
+
+ int numFaces;
+ if (!scanner.recognizedFont(stream.get(), &numFaces)) {
+ SkDebugf("---- failed to open <%s> as a font\n", filename.c_str());
+ continue;
+ }
+
+ for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
+ bool isFixedPitch;
+ SkString realname;
+ SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
+ if (!scanner.scanFont(stream.get(), faceIndex,
+ &realname, &style, &isFixedPitch, nullptr))
+ {
+ SkDebugf("---- failed to open <%s> <%d> as a font\n",
+ filename.c_str(), faceIndex);
+ continue;
+ }
+
+ SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
+ if (nullptr == addTo) {
+ addTo = new SkFontStyleSet_Custom(realname);
+ families->push_back().reset(addTo);
+ }
+ addTo->appendTypeface(sk_make_sp<SkTypeface_File>(style, isFixedPitch, true,
+ realname, filename.c_str(),
+ faceIndex));
+ }
+ }
+
+ SkOSFile::Iter dirIter(directory.c_str());
+ while (dirIter.next(&name, true)) {
+ if (name.startsWith(".")) {
+ continue;
+ }
+ SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str()));
+ load_directory_fonts(scanner, dirname, suffix, families);
+ }
+ }
+
+ SkString fBaseDirectory;
+};
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Directory(const char* dir) {
+ return sk_make_sp<SkFontMgr_Custom>(DirectorySystemFontLoader(dir));
+}
diff --git a/src/ports/SkFontMgr_custom_directory_factory.cpp b/src/ports/SkFontMgr_custom_directory_factory.cpp
index 7ed47118e4..e8d4bb3f3e 100644
--- a/src/ports/SkFontMgr_custom_directory_factory.cpp
+++ b/src/ports/SkFontMgr_custom_directory_factory.cpp
@@ -6,7 +6,7 @@
*/
#include "SkFontMgr.h"
-#include "SkFontMgr_custom.h"
+#include "SkFontMgr_directory.h"
#ifndef SK_FONT_FILE_PREFIX
# define SK_FONT_FILE_PREFIX "/usr/share/fonts/"
diff --git a/src/ports/SkFontMgr_custom_embedded.cpp b/src/ports/SkFontMgr_custom_embedded.cpp
new file mode 100644
index 0000000000..bb8d9f20b7
--- /dev/null
+++ b/src/ports/SkFontMgr_custom_embedded.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontDescriptor.h"
+#include "SkFontMgr_custom.h"
+#include "SkMakeUnique.h"
+#include "SkStream.h"
+
+struct SkEmbeddedResource { const uint8_t* data; size_t size; };
+struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count; };
+
+class EmbeddedSystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
+public:
+ EmbeddedSystemFontLoader(const SkEmbeddedResourceHeader* header) : fHeader(header) { }
+
+ void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
+ SkFontMgr_Custom::Families* families) const override
+ {
+ for (int i = 0; i < fHeader->count; ++i) {
+ const SkEmbeddedResource& fontEntry = fHeader->entries[i];
+ load_embedded_font(scanner, fontEntry.data, fontEntry.size, i, families);
+ }
+
+ if (families->empty()) {
+ SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
+ families->push_back().reset(family);
+ family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+ }
+ }
+
+private:
+ static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
+ const char familyName[])
+ {
+ for (int i = 0; i < families.count(); ++i) {
+ if (families[i]->getFamilyName().equals(familyName)) {
+ return families[i].get();
+ }
+ }
+ return nullptr;
+ }
+
+ static void load_embedded_font(const SkTypeface_FreeType::Scanner& scanner,
+ const uint8_t* data, size_t size, int index,
+ SkFontMgr_Custom::Families* families)
+ {
+ auto stream = skstd::make_unique<SkMemoryStream>(data, size, false);
+
+ int numFaces;
+ if (!scanner.recognizedFont(stream.get(), &numFaces)) {
+ SkDebugf("---- failed to open <%d> as a font\n", index);
+ return;
+ }
+
+ for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
+ bool isFixedPitch;
+ SkString realname;
+ SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
+ if (!scanner.scanFont(stream.get(), faceIndex,
+ &realname, &style, &isFixedPitch, nullptr))
+ {
+ SkDebugf("---- failed to open <%d> <%d> as a font\n", index, faceIndex);
+ return;
+ }
+
+ SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
+ if (nullptr == addTo) {
+ addTo = new SkFontStyleSet_Custom(realname);
+ families->push_back().reset(addTo);
+ }
+ auto data = skstd::make_unique<SkFontData>(std::move(stream), faceIndex, nullptr, 0);
+ addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data),
+ style, isFixedPitch,
+ true, realname));
+ }
+ }
+
+ const SkEmbeddedResourceHeader* fHeader;
+};
+
+sk_sp<SkFontMgr> SkFontMgr_New_Custom_Embedded(const SkEmbeddedResourceHeader* header) {
+ return sk_make_sp<SkFontMgr_Custom>(EmbeddedSystemFontLoader(header));
+}
diff --git a/src/ports/SkFontMgr_custom_empty.cpp b/src/ports/SkFontMgr_custom_empty.cpp
new file mode 100644
index 0000000000..8732bc32b4
--- /dev/null
+++ b/src/ports/SkFontMgr_custom_empty.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkFontMgr_custom.h"
+#include "SkFontMgr_empty.h"
+
+class EmptyFontLoader : public SkFontMgr_Custom::SystemFontLoader {
+public:
+ EmptyFontLoader() { }
+
+ void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
+ SkFontMgr_Custom::Families* families) const override
+ {
+ SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
+ families->push_back().reset(family);
+ family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
+ }
+
+};
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Custom_Empty() {
+ return sk_make_sp<SkFontMgr_Custom>(EmptyFontLoader());
+}