aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ports
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2018-06-26 11:22:37 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-12 17:30:20 +0000
commite346b1eea442065261c14f92b304031e1330e491 (patch)
treeac71ca13242dad662d3bf157370c943596ce4dd0 /src/ports
parenta4704078b9d7f6c86cdd29c80840bfc4f15bea1a (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/ports')
-rw-r--r--src/ports/SkFontHost_FreeType.cpp73
-rw-r--r--src/ports/SkFontHost_FreeType_common.h2
-rw-r--r--src/ports/SkFontHost_win.cpp5
-rw-r--r--src/ports/SkTypeface_win_dw.cpp70
-rw-r--r--src/ports/SkTypeface_win_dw.h2
5 files changed, 141 insertions, 11 deletions
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;