diff options
author | Ben Wagner <bungeman@google.com> | 2018-06-26 11:22:37 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-07-12 17:30:20 +0000 |
commit | e346b1eea442065261c14f92b304031e1330e491 (patch) | |
tree | ac71ca13242dad662d3bf157370c943596ce4dd0 /src | |
parent | a4704078b9d7f6c86cdd29c80840bfc4f15bea1a (diff) |
Add SkTypeface::getVariationDesignParameters
This adds a way for users to query the axis parameters for a typeface.
Change-Id: Idc2ac0d84bc7ae2ca484ae410cba5b01883418e5
Reviewed-on: https://skia-review.googlesource.com/137706
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkTypeface.cpp | 16 | ||||
-rw-r--r-- | src/core/SkTypeface_remote.h | 5 | ||||
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 73 | ||||
-rw-r--r-- | src/ports/SkFontHost_FreeType_common.h | 2 | ||||
-rw-r--r-- | src/ports/SkFontHost_win.cpp | 5 | ||||
-rw-r--r-- | src/ports/SkTypeface_win_dw.cpp | 70 | ||||
-rw-r--r-- | src/ports/SkTypeface_win_dw.h | 2 |
7 files changed, 162 insertions, 11 deletions
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp index 8e90f51a9b..cc0bd3f025 100644 --- a/src/core/SkTypeface.cpp +++ b/src/core/SkTypeface.cpp @@ -79,6 +79,11 @@ protected: { return 0; } + int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], + int parameterCount) const override + { + return 0; + } int onGetTableTags(SkFontTableTag tags[]) const override { return 0; } size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override { return 0; @@ -207,6 +212,12 @@ int SkTypeface::getVariationDesignPosition( return this->onGetVariationDesignPosition(coordinates, coordinateCount); } +int SkTypeface::getVariationDesignParameters( + SkFontParameters::Variation::Axis parameters[], int parameterCount) const +{ + return this->onGetVariationDesignParameters(parameters, parameterCount); +} + int SkTypeface::countTables() const { return this->onGetTableTags(nullptr); } @@ -324,6 +335,11 @@ sk_sp<SkTypeface> SkTypeface::onMakeClone(const SkFontArguments& args) const { return sk_ref_sp(this); } +int SkTypeface::onGetVariationDesignParameters( + SkFontParameters::Variation::Axis parameters[], int parameterCount) const { + return -1; +} + /////////////////////////////////////////////////////////////////////////////// #include "SkDescriptor.h" diff --git a/src/core/SkTypeface_remote.h b/src/core/SkTypeface_remote.h index 1b4ad89025..c751745b0f 100644 --- a/src/core/SkTypeface_remote.h +++ b/src/core/SkTypeface_remote.h @@ -82,6 +82,11 @@ protected: SK_ABORT("Should never be called."); return 0; } + int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], + int parameterCount) const override { + SK_ABORT("Should never be called."); + return 0; + } void onGetFamilyName(SkString* familyName) const override { // Used by SkStrikeCache::DumpMemoryStatistics. *familyName = ""; diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index b8ce2033b1..03f499fcf6 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -72,6 +72,12 @@ # define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) #endif +// FT_VAR_AXIS_FLAG_HIDDEN was introduced in FreeType 2.8.1 +// The variation axis should not be exposed to user interfaces. +#ifndef FT_VAR_AXIS_FLAG_HIDDEN +# define FT_VAR_AXIS_FLAG_HIDDEN 1 +#endif + //#define ENABLE_GLYPH_SPEW // for tracing calls //#define DUMP_STRIKE_CREATION //#define SK_FONTHOST_FREETYPE_RUNTIME_VERSION @@ -104,6 +110,7 @@ class FreeTypeLibrary : SkNoncopyable { public: FreeTypeLibrary() : fGetVarDesignCoordinates(nullptr) + , fGetVarAxisFlags(nullptr) , fLibrary(nullptr) , fIsLCDSupported(false) , fLCDExtra(0) @@ -153,6 +160,19 @@ public: } #endif +#if SK_FREETYPE_MINIMUM_RUNTIME_VERSION >= 0x02080100 + fGetVarAxisFlags = FT_Get_Var_Axis_Flags; +#elif SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN + if (major > 2 || ((major == 2 && minor > 7) || (major == 2 && minor == 7 && patch >= 0))) { + //The FreeType library is already loaded, so symbols are available in process. + void* self = dlopen(nullptr, RTLD_LAZY); + if (self) { + *(void**)(&fGetVarAxisFlags) = dlsym(self, "FT_Get_Var_Axis_Flags"); + dlclose(self); + } + } +#endif + // Setup LCD filtering. This reduces color fringes for LCD smoothed glyphs. // The default has changed over time, so this doesn't mean the same thing to all users. if (FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT) == 0) { @@ -177,6 +197,12 @@ public: using FT_Get_Var_Blend_CoordinatesProc = FT_Error (*)(FT_Face, FT_UInt, FT_Fixed*); FT_Get_Var_Blend_CoordinatesProc fGetVarDesignCoordinates; + // FT_Get_Var_Axis_Flags was introduced in FreeType 2.8.1 + // Get the ‘flags’ field of an OpenType Variation Axis Record. + // Not meaningful for Adobe MM fonts (‘*flags’ is always zero). + using FT_Get_Var_Axis_FlagsProc = FT_Error (*)(FT_MM_Var*, FT_UInt, FT_UInt*); + FT_Get_Var_Axis_FlagsProc fGetVarAxisFlags; + private: FT_Library fLibrary; bool fIsLCDSupported; @@ -1546,18 +1572,21 @@ SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() } int SkTypeface_FreeType::onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const + SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const { AutoFTAccess fta(this); FT_Face face = fta.face(); + if (!face) { + return -1; + } - if (!face || !(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { + if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { return 0; } FT_MM_Var* variations = nullptr; if (FT_Get_MM_Var(face, &variations)) { - return 0; + return -1; } SkAutoFree autoFreeVariations(variations); @@ -1590,6 +1619,44 @@ int SkTypeface_FreeType::onGetVariationDesignPosition( return variations->num_axis; } +int SkTypeface_FreeType::onGetVariationDesignParameters( + SkFontParameters::Variation::Axis parameters[], int parameterCount) const +{ + AutoFTAccess fta(this); + FT_Face face = fta.face(); + if (!face) { + return -1; + } + + if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { + return 0; + } + + FT_MM_Var* variations = nullptr; + if (FT_Get_MM_Var(face, &variations)) { + return -1; + } + SkAutoFree autoFreeVariations(variations); + + if (!parameters || parameterCount < SkToInt(variations->num_axis)) { + return variations->num_axis; + } + + for (FT_UInt i = 0; i < variations->num_axis; ++i) { + parameters[i].tag = variations->axis[i].tag; + parameters[i].min = SkFixedToScalar(variations->axis[i].minimum); + parameters[i].def = SkFixedToScalar(variations->axis[i].def); + parameters[i].max = SkFixedToScalar(variations->axis[i].maximum); + FT_UInt flags = 0; + bool hidden = gFTLibrary->fGetVarAxisFlags && + !gFTLibrary->fGetVarAxisFlags(variations, i, &flags) && + (flags & FT_VAR_AXIS_FLAG_HIDDEN); + parameters[i].setHidden(hidden); + } + + return variations->num_axis; +} + int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const { AutoFTAccess fta(this); FT_Face face = fta.face(); diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h index 1386775bb8..939aa4b643 100644 --- a/src/ports/SkFontHost_FreeType_common.h +++ b/src/ports/SkFontHost_FreeType_common.h @@ -107,6 +107,8 @@ protected: int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const override; + int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], + int parameterCount) const override; int onGetTableTags(SkFontTableTag tags[]) const override; size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 264ae9226d..07d37aedfe 100644 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -277,6 +277,11 @@ protected: { return -1; } + int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], + int parameterCount) const override + { + return -1; + } int onGetTableTags(SkFontTableTag tags[]) const override; size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; }; diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp index a7bad0d24e..3bf61347df 100644 --- a/src/ports/SkTypeface_win_dw.cpp +++ b/src/ports/SkTypeface_win_dw.cpp @@ -185,8 +185,9 @@ SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() c return nameIter; } -int DWriteFontTypeface::onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const { +int DWriteFontTypeface::onGetVariationDesignPosition( + SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const +{ #if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3 @@ -210,20 +211,73 @@ int DWriteFontTypeface::onGetVariationDesignPosition(SkFontArguments::VariationP } } - if (!coordinates || !coordinateCount || !variableAxisCount) { + if (!coordinates || coordinateCount < variableAxisCount) { return variableAxisCount; } SkAutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisValue(fontAxisCount); HR_GENERAL(fontFace5->GetFontAxisValues(fontAxisValue.get(), fontAxisCount), nullptr, -1); - UINT32 minCount = SkMin32(variableAxisCount, SkTo<UINT32>(coordinateCount)); - UINT32 coordinatesIndex = 0; + UINT32 coordIndex = 0; + + for (UINT32 axisIndex = 0; axisIndex < fontAxisCount; ++axisIndex) { + if (fontResource->GetFontAxisAttributes(axisIndex) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) { + coordinates[coordIndex].axis = SkEndian_SwapBE32(fontAxisValue[axisIndex].axisTag); + coordinates[coordIndex].value = fontAxisValue[axisIndex].value; + } + } + + return variableAxisCount; + +#endif + + return -1; +} + +int DWriteFontTypeface::onGetVariationDesignParameters( + SkFontParameters::Variation::Axis parameters[], int parameterCount) const +{ + +#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3 + + SkTScopedComPtr<IDWriteFontFace5> fontFace5; + if (FAILED(fDWriteFontFace->QueryInterface(&fontFace5))) { + return -1; + } + + // Return 0 if the font is not variable font. + if (!fontFace5->HasVariations()) { + return 0; + } + + UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount(); + SkTScopedComPtr<IDWriteFontResource> fontResource; + HR_GENERAL(fontFace5->GetFontResource(&fontResource), nullptr, -1); + int variableAxisCount = 0; + for (UINT32 i = 0; i < fontAxisCount; ++i) { + if (fontResource->GetFontAxisAttributes(i) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) { + variableAxisCount++; + } + } + + if (!parameters || parameterCount < variableAxisCount) { + return variableAxisCount; + } + + SkAutoSTMalloc<8, DWRITE_FONT_AXIS_RANGE> fontAxisRange(fontAxisCount); + HR_GENERAL(fontResource->GetFontAxisRanges(fontAxisRange.get(), fontAxisCount), nullptr, -1); + SkAutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisDefaultValue(fontAxisCount); + HR_GENERAL(fontResource->GetDefaultFontAxisValues(fontAxisDefaultValue.get(), fontAxisCount), + nullptr, -1); + UINT32 coordIndex = 0; for (UINT32 axisIndex = 0; axisIndex < fontAxisCount; ++axisIndex) { if (fontResource->GetFontAxisAttributes(axisIndex) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) { - coordinates[coordinatesIndex].axis = SkEndian_SwapBE32(fontAxisValue[axisIndex].axisTag); - coordinates[coordinatesIndex].value = fontAxisValue[axisIndex].value; - if (++coordinatesIndex == minCount) break; + parameters[coordIndex].tag = SkEndian_SwapBE32(fontAxisDefaultValue[axisIndex].axisTag); + parameters[coordIndex].min = fontAxisRange[axisIndex].minValue; + parameters[coordIndex].def = fontAxisDefaultValue[axisIndex].value; + parameters[coordIndex].max = fontAxisRange[axisIndex].maxValue; + parameters[coordIndex].setHidden(fontResource->GetFontAxisAttributes(axisIndex) & + DWRITE_FONT_AXIS_ATTRIBUTES_HIDDEN); } } diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h index 2d76b39adb..a671eb4855 100644 --- a/src/ports/SkTypeface_win_dw.h +++ b/src/ports/SkTypeface_win_dw.h @@ -117,6 +117,8 @@ protected: SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const override; + int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], + int parameterCount) const override; int onGetTableTags(SkFontTableTag tags[]) const override; size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; |