diff options
author | 2015-12-01 11:12:05 -0800 | |
---|---|---|
committer | 2015-12-01 11:12:05 -0800 | |
commit | 2211a7bdd1680003a4decbebef76f153cd0a28fa (patch) | |
tree | de998b224538b319b8e5c1c522d3cd82bb5247e4 /src/ports/SkFontConfigInterface_direct.cpp | |
parent | 001e74426672e00f3f2783ccf728031662d4a358 (diff) |
Fix Google3 fonts. Use fontconfig rather than custom_directory_factory. Add Google3 font caching.
Some future dependents require these changes.
Depends on internal cl/108287941.
Review URL: https://codereview.chromium.org/1471033002
Diffstat (limited to 'src/ports/SkFontConfigInterface_direct.cpp')
-rw-r--r-- | src/ports/SkFontConfigInterface_direct.cpp | 163 |
1 files changed, 68 insertions, 95 deletions
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp index 8a8e4a1b53..a25bfbdc07 100644 --- a/src/ports/SkFontConfigInterface_direct.cpp +++ b/src/ports/SkFontConfigInterface_direct.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009 Google Inc. + * Copyright 2009-2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. @@ -9,7 +9,7 @@ #include "SkBuffer.h" #include "SkDataTable.h" -#include "SkFontConfigInterface.h" +#include "SkFontConfigInterface_direct.h" #include "SkFontStyle.h" #include "SkMutex.h" #include "SkStream.h" @@ -107,37 +107,6 @@ static void fontconfiginterface_unittest() { } #endif -class SkFontConfigInterfaceDirect : public SkFontConfigInterface { -public: - SkFontConfigInterfaceDirect(); - virtual ~SkFontConfigInterfaceDirect(); - - virtual bool matchFamilyName(const char familyName[], - SkTypeface::Style requested, - FontIdentity* outFontIdentifier, - SkString* outFamilyName, - SkTypeface::Style* outStyle) override; - SkStreamAsset* openStream(const FontIdentity&) override; - - // new APIs - SkDataTable* getFamilyNames() override; - virtual bool matchFamilySet(const char inFamilyName[], - SkString* outFamilyName, - SkTArray<FontIdentity>*) override; - -private: - SkMutex mutex_; -}; - -SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBaseMutex* mutex) { - SkAutoMutexAcquire ac(mutex); - static SkFontConfigInterfaceDirect* singleton = nullptr; - if (singleton == nullptr) { - singleton = new SkFontConfigInterfaceDirect; - } - return singleton; -} - /////////////////////////////////////////////////////////////////////////////// // Returns the string from the pattern, or nullptr @@ -334,7 +303,64 @@ bool IsFallbackFontAllowed(const SkString& family) { strcasecmp(family_cstr, "monospace") == 0; } -static bool valid_pattern(FcPattern* pattern) { +// Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. +SkTypeface::Style GetFontStyle(FcPattern* font) { + int resulting_bold; + if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) + resulting_bold = FC_WEIGHT_NORMAL; + + int resulting_italic; + if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic)) + resulting_italic = FC_SLANT_ROMAN; + + // If we ask for an italic font, fontconfig might take a roman font and set + // the undocumented property FC_MATRIX to a skew matrix. It'll then say + // that the font is italic or oblique. So, if we see a matrix, we don't + // believe that it's italic. + FcValue matrix; + const bool have_matrix = FcPatternGet(font, FC_MATRIX, 0, &matrix) == 0; + + // If we ask for an italic font, fontconfig might take a roman font and set + // FC_EMBOLDEN. + FcValue embolden; + const bool have_embolden = FcPatternGet(font, FC_EMBOLDEN, 0, &embolden) == 0; + + int styleBits = 0; + if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) { + styleBits |= SkTypeface::kBold; + } + if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) { + styleBits |= SkTypeface::kItalic; + } + + return (SkTypeface::Style)styleBits; +} + +} // anonymous namespace + +/////////////////////////////////////////////////////////////////////////////// + +#define kMaxFontFamilyLength 2048 + +SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { + SkAutoMutexAcquire ac(mutex_); + + FcInit(); + + SkDEBUGCODE(fontconfiginterface_unittest();) +} + +SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { +} + +bool SkFontConfigInterfaceDirect::isAccessible(const char* filename) { + if (access(filename, R_OK) != 0) { + return false; + } + return true; +} + +bool SkFontConfigInterfaceDirect::isValidPattern(FcPattern* pattern) { #ifdef SK_FONT_CONFIG_ONLY_ALLOW_SCALABLE_FONTS FcBool is_scalable; if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch @@ -348,22 +374,19 @@ static bool valid_pattern(FcPattern* pattern) { if (!c_filename) { return false; } - if (access(c_filename, R_OK) != 0) { - return false; - } - return true; + return this->isAccessible(c_filename); } // Find matching font from |font_set| for the given font family. -FcPattern* MatchFont(FcFontSet* font_set, - const char* post_config_family, - const SkString& family) { +FcPattern* SkFontConfigInterfaceDirect::MatchFont(FcFontSet* font_set, + const char* post_config_family, + const SkString& family) { // Older versions of fontconfig have a bug where they cannot select // only scalable fonts so we have to manually filter the results. FcPattern* match = nullptr; for (int i = 0; i < font_set->nfont; ++i) { FcPattern* current = font_set->fonts[i]; - if (valid_pattern(current)) { + if (this->isValidPattern(current)) { match = current; break; } @@ -394,56 +417,6 @@ FcPattern* MatchFont(FcFontSet* font_set, return match; } -// Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. -SkTypeface::Style GetFontStyle(FcPattern* font) { - int resulting_bold; - if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) - resulting_bold = FC_WEIGHT_NORMAL; - - int resulting_italic; - if (FcPatternGetInteger(font, FC_SLANT, 0, &resulting_italic)) - resulting_italic = FC_SLANT_ROMAN; - - // If we ask for an italic font, fontconfig might take a roman font and set - // the undocumented property FC_MATRIX to a skew matrix. It'll then say - // that the font is italic or oblique. So, if we see a matrix, we don't - // believe that it's italic. - FcValue matrix; - const bool have_matrix = FcPatternGet(font, FC_MATRIX, 0, &matrix) == 0; - - // If we ask for an italic font, fontconfig might take a roman font and set - // FC_EMBOLDEN. - FcValue embolden; - const bool have_embolden = FcPatternGet(font, FC_EMBOLDEN, 0, &embolden) == 0; - - int styleBits = 0; - if (resulting_bold > FC_WEIGHT_MEDIUM && !have_embolden) { - styleBits |= SkTypeface::kBold; - } - if (resulting_italic > FC_SLANT_ROMAN && !have_matrix) { - styleBits |= SkTypeface::kItalic; - } - - return (SkTypeface::Style)styleBits; -} - -} // anonymous namespace - -/////////////////////////////////////////////////////////////////////////////// - -#define kMaxFontFamilyLength 2048 - -SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { - SkAutoMutexAcquire ac(mutex_); - - FcInit(); - - SkDEBUGCODE(fontconfiginterface_unittest();) -} - -SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { -} - bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], SkTypeface::Style style, FontIdentity* outIdentity, @@ -514,7 +487,7 @@ bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], return false; } - FcPattern* match = MatchFont(font_set, post_config_family, familyStr); + FcPattern* match = this->MatchFont(font_set, post_config_family, familyStr); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); @@ -671,7 +644,7 @@ bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[], return false; } - FcPattern* match = MatchFont(font_set, post_config_family, familyStr); + FcPattern* match = this->MatchFont(font_set, post_config_family, familyStr); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); @@ -716,7 +689,7 @@ bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[], //////////////////// int count; - FcPattern** match = MatchFont(font_set, post_config_family, &count); + FcPattern** match = this->MatchFont(font_set, post_config_family, &count); if (!match) { FcPatternDestroy(pattern); FcFontSetDestroy(font_set); |