Skip to content

Commit

Permalink
Fix Google3 fonts. Use fontconfig rather than custom_directory_factor…
Browse files Browse the repository at this point in the history
…y. Add Google3 font caching.

Some future dependents require these changes.

Depends on internal cl/108287941.

Review URL: https://codereview.chromium.org/1471033002
  • Loading branch information
dogben authored and Commit bot committed Dec 1, 2015
1 parent 001e744 commit 2211a7b
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 102 deletions.
15 changes: 11 additions & 4 deletions BUILD.public
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ BASE_SRCS = glob(
# Exclude platform-dependent files.
"src/device/xps/*", # Windows-only. Move to ports?
"src/doc/*_XPS.cpp", # Windows-only. Move to ports?
"src/fonts/SkFontMgr_fontconfig.cpp",
"src/gpu/gl/android/*",
"src/gpu/gl/egl/*",
"src/gpu/gl/glx/*",
Expand All @@ -41,7 +42,6 @@ BASE_SRCS = glob(
# Exclude multiple definitions.
# TODO(mtklein): Move to opts?
"src/doc/SkDocument_PDF_None.cpp", # We use SkDocument_PDF.cpp.
"src/fonts/*fontconfig*",
"src/gpu/gl/GrGLCreateNativeInterface_none.cpp",
"src/gpu/gl/GrGLDefaultInterface_native.cpp",

Expand All @@ -67,6 +67,7 @@ BASE_SRCS = glob(
# Platform-dependent SRCS for google3-default platform.
BASE_SRCS_UNIX = glob(
[
"src/fonts/SkFontMgr_fontconfig.cpp",
"src/opts/**/*.cpp",
"src/opts/**/*.h",
"src/ports/**/*.cpp",
Expand All @@ -88,15 +89,16 @@ BASE_SRCS_UNIX = glob(
"src/opts/SkBlitRow_opts_none.cpp",
"src/ports/*android*",
"src/ports/*chromium*",
"src/ports/*fontconfig*",
"src/ports/*FontConfig*",
"src/ports/*mac*",
"src/ports/*mozalloc*",
"src/ports/*nacl*",
"src/ports/*win*",
"src/ports/SkFontConfigInterface_direct_factory.cpp",
"src/ports/SkFontMgr_custom_directory_factory.cpp",
"src/ports/SkFontMgr_custom_embedded_factory.cpp",
"src/ports/SkFontMgr_empty_factory.cpp",
"src/ports/SkImageDecoder_CG.cpp",
"src/ports/SkFontMgr_fontconfig_factory.cpp",
"src/ports/SkImageDecoder_WIC.cpp",
"src/ports/SkImageDecoder_empty.cpp",
"src/ports/SkImageGenerator_none.cpp",
Expand Down Expand Up @@ -132,6 +134,8 @@ BASE_SRCS_ANDROID = glob(
"src/ports/*nacl*",
"src/ports/*win*",
"src/ports/SkDebug_stdio.cpp",
"src/ports/SkFontConfigInterface_direct_factory.cpp",
"src/ports/SkFontConfigInterface_direct_google3_factory.cpp",
"src/ports/SkFontMgr_custom_directory_factory.cpp",
"src/ports/SkFontMgr_custom_embedded_factory.cpp",
"src/ports/SkFontMgr_empty_factory.cpp",
Expand Down Expand Up @@ -174,6 +178,8 @@ BASE_SRCS_IOS = glob(
"src/ports/*win*",
"src/ports/SkDebug_stdio.cpp",
"src/ports/SkFontMgr_custom.cpp",
"src/ports/SkFontConfigInterface_direct_factory.cpp",
"src/ports/SkFontConfigInterface_direct_google3_factory.cpp",
"src/ports/SkFontMgr_custom_directory_factory.cpp",
"src/ports/SkFontMgr_custom_embedded_factory.cpp",
"src/ports/SkFontMgr_empty_factory.cpp",
Expand Down Expand Up @@ -261,12 +267,13 @@ INCLUDES = [
"src/image",
"src/lazy",
"src/opts",
"src/ports",
"src/pdf",
"src/sfnt",
"src/utils",
"third_party/etc1",
"third_party/ktx",
]
] + EXTERNAL_INCLUDES

## :dm

Expand Down
1 change: 1 addition & 0 deletions gyp/ports.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
'../src/ports/SkFontMgr_fontconfig.cpp',
'../src/ports/SkFontHost_fontconfig.cpp',
'../src/ports/SkFontConfigInterface_direct.cpp',
'../src/ports/SkFontConfigInterface_direct_factory.cpp',
],
'sources/': [['include', '../src/ports/SkFontMgr_fontconfig_factory.cpp']],
}]
Expand Down
163 changes: 68 additions & 95 deletions src/ports/SkFontConfigInterface_direct.cpp
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
43 changes: 43 additions & 0 deletions src/ports/SkFontConfigInterface_direct.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.
*/

/* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */

#include "SkFontConfigInterface.h"
#include "SkMutex.h"

#include <fontconfig/fontconfig.h>

class SkFontConfigInterfaceDirect : public SkFontConfigInterface {
public:
SkFontConfigInterfaceDirect();
~SkFontConfigInterfaceDirect() override;

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;
bool matchFamilySet(const char inFamilyName[],
SkString* outFamilyName,
SkTArray<FontIdentity>*) override;

protected:
virtual bool isAccessible(const char* filename);

private:
SkMutex mutex_;

bool isValidPattern(FcPattern* pattern);
FcPattern* MatchFont(FcFontSet* font_set, const char* post_config_family,
const SkString& family);
typedef SkFontConfigInterface INHERITED;
};
20 changes: 20 additions & 0 deletions src/ports/SkFontConfigInterface_direct_factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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.
*/

/* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */

#include "SkFontConfigInterface_direct.h"
#include "SkMutex.h"

SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBaseMutex* mutex) {
SkAutoMutexAcquire ac(mutex);
static SkFontConfigInterfaceDirect* singleton = nullptr;
if (singleton == nullptr) {
singleton = new SkFontConfigInterfaceDirect;
}
return singleton;
}
Loading

0 comments on commit 2211a7b

Please sign in to comment.