diff options
author | Ben Wagner <bungeman@google.com> | 2017-02-23 20:48:43 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-23 20:48:53 +0000 |
commit | 97043299cb352f50f604878b7a1dc8ad127fc1c6 (patch) | |
tree | 3363bfc674ab808e735336898386076d9c3b9558 | |
parent | 3f81f3703a68755c88f5cc4a87728b98f34c4cd4 (diff) |
Revert "Add SkTypeface::getVariationDesignPosition."
This reverts commit 0f3d0c37dbcaf4ec271d5fe847becc9b1aa6f537.
Reason for revert: <INSERT REASONING HERE>
Original change's description:
> Add SkTypeface::getVariationDesignPosition.
>
> Allow users to query a typeface's position in variation design space.
>
> Change-Id: I173ee9eefdddee6b2613435ebcc6b08c25b382ed
> Reviewed-on: https://skia-review.googlesource.com/8684
> Commit-Queue: Ben Wagner <bungeman@google.com>
> Reviewed-by: Mike Reed <reed@google.com>
>
TBR=bungeman@google.com,reed@google.com,reviews@skia.org,drott@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Change-Id: I484fe52c1f89e7b6d0024dcabf7c59d0e8b5b5e7
Reviewed-on: https://skia-review.googlesource.com/8929
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
29 files changed, 314 insertions, 729 deletions
@@ -335,8 +335,8 @@ optional("fontmgr_android") { enabled = fontmgr_android_enabled deps = [ - ":typeface_freetype", "//third_party/expat", + "//third_party/freetype2", ] sources = [ "src/ports/SkFontMgr_android.cpp", @@ -349,7 +349,7 @@ optional("fontmgr_custom") { enabled = is_linux && skia_use_freetype && !skia_use_fontconfig deps = [ - ":typeface_freetype", + "//third_party/freetype2", ] sources = [ "src/ports/SkFontMgr_custom.cpp", @@ -365,8 +365,8 @@ optional("fontmgr_fontconfig") { enabled = skia_use_freetype && skia_use_fontconfig deps = [ - ":typeface_freetype", "//third_party:fontconfig", + "//third_party/freetype2", ] sources = [ "src/ports/SkFontConfigInterface.cpp", @@ -382,7 +382,7 @@ optional("fontmgr_fuchsia") { enabled = is_fuchsia && skia_use_freetype deps = [ - ":typeface_freetype", + "//third_party/freetype2", ] sources = [ "src/ports/SkFontMgr_custom.cpp", @@ -581,6 +581,7 @@ component("skia") { ":sse41", ":sse42", ":ssse3", + ":typeface_freetype", ":webp", ":xml", ] diff --git a/gm/fontscalerdistortable.cpp b/gm/fontscalerdistortable.cpp index 1823b50efa..c557ec573d 100644 --- a/gm/fontscalerdistortable.cpp +++ b/gm/fontscalerdistortable.cpp @@ -49,12 +49,9 @@ protected: SkFourByteTag tag = SkSetFourByteTag('w','g','h','t'); SkScalar styleValue = SkDoubleToScalar(0.5 + (5*j + i) * ((2.0 - 0.5) / (2 * 5))); - SkFontArguments::VariationPosition::Coordinate coordinates[] = {{tag, styleValue}}; - SkFontArguments::VariationPosition position = - { coordinates, SK_ARRAY_COUNT(coordinates) }; + SkFontMgr::FontParameters::Axis axes[] = { { tag, styleValue } }; paint.setTypeface(sk_sp<SkTypeface>(fontMgr->createFromStream( - distortable->duplicate(), - SkFontArguments().setVariationDesignPosition(position)))); + distortable->duplicate(), SkFontMgr::FontParameters().setAxes(axes, 1)))); SkAutoCanvasRestore acr(canvas, true); canvas->translate(SkIntToScalar(30 + i * 100), SkIntToScalar(20)); diff --git a/gn/core.gni b/gn/core.gni index bd2a66e4c3..b6ad6a9960 100644 --- a/gn/core.gni +++ b/gn/core.gni @@ -397,7 +397,6 @@ skia_core_sources = [ "$_include/core/SkDrawLooper.h", "$_include/core/SkFlattenable.h", "$_include/core/SkFlattenableSerialization.h", - "$_include/core/SkFontArguments.h", "$_include/core/SkFontLCDConfig.h", "$_include/core/SkFontStyle.h", "$_include/core/SkGraphics.h", diff --git a/include/core/SkFontArguments.h b/include/core/SkFontArguments.h deleted file mode 100644 index 473798fb84..0000000000 --- a/include/core/SkFontArguments.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2017 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkFontAgruments_DEFINED -#define SkFontAgruments_DEFINED - -#include "SkScalar.h" -#include "SkTypes.h" - -/** Represents a set of actual arguments for a font. */ -struct SkFontArguments { - struct VariationPosition { - struct Coordinate { - SkFourByteTag axis; - SkScalar value; - }; - const Coordinate* coordinates; - int coordinateCount; - }; - // deprecated, use VariationCoordinate instead - struct Axis { - SkFourByteTag fTag; - SkScalar fStyleValue; - }; - - SkFontArguments() : fCollectionIndex(0), fVariationDesignPosition{nullptr, 0} {} - - /** Specify the index of the desired font. - * - * Font formats like ttc, dfont, cff, cid, pfr, t42, t1, and fon may actually be indexed - * collections of fonts. - */ - SkFontArguments& setCollectionIndex(int collectionIndex) { - fCollectionIndex = collectionIndex; - return *this; - } - - // deprecated, use setVariationDesignPosition instead. - SkFontArguments& setAxes(const Axis* axes, int axisCount) { - fVariationDesignPosition.coordinates = - reinterpret_cast<const VariationPosition::Coordinate*>(axes); - fVariationDesignPosition.coordinateCount = axisCount; - return *this; - } - - /** Specify a position in the variation design space. - * - * Any axis not specified will use the default value. - * Any specified axis not actually present in the font will be ignored. - * - * @param position not copied. The value must remain valid for life of SkFontArguments. - */ - SkFontArguments& setVariationDesignPosition(VariationPosition position) { - fVariationDesignPosition.coordinates = position.coordinates; - fVariationDesignPosition.coordinateCount = position.coordinateCount; - return *this; - } - - int getCollectionIndex() const { - return fCollectionIndex; - } - // deprecated, use getVariationDesignPosition instead. - const Axis* getAxes(int* axisCount) const { - *axisCount = fVariationDesignPosition.coordinateCount; - return reinterpret_cast<const Axis*>(fVariationDesignPosition.coordinates); - } - VariationPosition getVariationDesignPosition() const { - return fVariationDesignPosition; - } -private: - int fCollectionIndex; - VariationPosition fVariationDesignPosition; -}; - -#endif diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h index 07d8bc395b..51d5a0b11c 100644 --- a/include/core/SkTypeface.h +++ b/include/core/SkTypeface.h @@ -11,7 +11,6 @@ #include "../private/SkBitmaskEnum.h" #include "../private/SkOnce.h" #include "../private/SkWeakRefCnt.h" -#include "SkFontArguments.h" #include "SkFontStyle.h" #include "SkRect.h" #include "SkString.h" @@ -78,20 +77,6 @@ public: */ bool isFixedPitch() const { return fIsFixedPitch; } - /** Copy into 'coordinates' (allocated by the caller) the design variation coordinates. - * - * @param coordinates the buffer into which to write the design variation coordinates. - * @param coordinateCount the number of entries available through 'coordinates'. - * - * @return The number of axes, or -1 if there is an error. - * If 'coordinates != nullptr' and 'coordinateCount >= numAxes' then 'coordinates' will be - * filled with the variation coordinates describing the position of this typeface in design - * variation space. It is possible the number of axes can be retrieved but actual position - * cannot. - */ - int getVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const; - /** Return a 32bit value for this typeface, unique for the underlying font data. Will never return 0. */ @@ -111,16 +96,16 @@ public: /** Returns the default typeface, which is never nullptr. */ static sk_sp<SkTypeface> MakeDefault(Style style = SkTypeface::kNormal); - /** Creates a new reference to the typeface that most closely matches the - requested familyName and fontStyle. This method allows extended font - face specifiers as in the SkFontStyle type. Will never return null. + /** Creates a new reference to the typeface that most closely matches the + requested familyName and fontStyle. This method allows extended font + face specifiers as in the SkFontStyle type. Will never return null. - @param familyName May be NULL. The name of the font family. - @param fontStyle The style of the typeface. - @return reference to the closest-matching typeface. Call must call + @param familyName May be NULL. The name of the font family. + @param fontStyle The style of the typeface. + @return reference to the closest-matching typeface. Call must call unref() when they are done. */ - static sk_sp<SkTypeface> MakeFromName(const char familyName[], SkFontStyle fontStyle); + static sk_sp<SkTypeface> MakeFromName(const char familyName[], SkFontStyle fontStyle); /** Return the typeface that most closely matches the requested typeface and style. Use this to pick a new style from the same family of the existing typeface. @@ -356,10 +341,6 @@ protected: // TODO: make pure virtual. virtual std::unique_ptr<SkFontData> onMakeFontData() const; - virtual int onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const = 0; - virtual void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const = 0; virtual int onCharsToGlyphs(const void* chars, Encoding, SkGlyphID glyphs[], diff --git a/include/ports/SkFontMgr.h b/include/ports/SkFontMgr.h index b5879d35b8..4103e8747e 100644 --- a/include/ports/SkFontMgr.h +++ b/include/ports/SkFontMgr.h @@ -8,9 +8,9 @@ #ifndef SkFontMgr_DEFINED #define SkFontMgr_DEFINED -#include "SkFontArguments.h" #include "SkFontStyle.h" #include "SkRefCnt.h" +#include "SkScalar.h" #include "SkTypes.h" class SkData; @@ -102,10 +102,51 @@ public: */ SkTypeface* createFromStream(SkStreamAsset*, int ttcIndex = 0) const; - // deprecated, use SkFontArguments instead. - using FontParameters = SkFontArguments; + struct FontParameters { + struct Axis { + SkFourByteTag fTag; + SkScalar fStyleValue; + }; + + FontParameters() : fCollectionIndex(0), fAxisCount(0), fAxes(nullptr) {} + + /** Specify the index of the desired font. + * + * Font formats like ttc, dfont, cff, cid, pfr, t42, t1, and fon may actually be indexed + * collections of fonts. + */ + FontParameters& setCollectionIndex(int collectionIndex) { + fCollectionIndex = collectionIndex; + return *this; + } + + /** Specify the GX variation axis values. + * + * Any axes not specified will use the default value. Specified axes not present in the + * font will be ignored. + * + * @param axes not copied. This pointer must remain valid for life of FontParameters. + */ + FontParameters& setAxes(const Axis* axes, int axisCount) { + fAxisCount = axisCount; + fAxes = axes; + return *this; + } + + int getCollectionIndex() const { + return fCollectionIndex; + } + const Axis* getAxes(int* axisCount) const { + *axisCount = fAxisCount; + return fAxes; + } + private: + int fCollectionIndex; + int fAxisCount; + const Axis* fAxes; + }; /* Experimental, API subject to change. */ - SkTypeface* createFromStream(SkStreamAsset*, const SkFontArguments&) const; + SkTypeface* createFromStream(SkStreamAsset*, const FontParameters&) const; /** * Create a typeface from the specified font data. @@ -146,7 +187,7 @@ protected: virtual SkTypeface* onCreateFromData(SkData*, int ttcIndex) const = 0; virtual SkTypeface* onCreateFromStream(SkStreamAsset*, int ttcIndex) const = 0; // TODO: make pure virtual. - virtual SkTypeface* onCreateFromStream(SkStreamAsset*, const SkFontArguments&) const; + virtual SkTypeface* onCreateFromStream(SkStreamAsset*, const FontParameters&) const; virtual SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData>) const; virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const = 0; diff --git a/src/core/SkFontMgr.cpp b/src/core/SkFontMgr.cpp index 8ce0b39682..03ac2eba83 100644 --- a/src/core/SkFontMgr.cpp +++ b/src/core/SkFontMgr.cpp @@ -132,11 +132,11 @@ SkTypeface* SkFontMgr::createFromStream(SkStreamAsset* stream, int ttcIndex) con return this->onCreateFromStream(stream, ttcIndex); } -SkTypeface* SkFontMgr::createFromStream(SkStreamAsset* stream, const SkFontArguments& args) const { +SkTypeface* SkFontMgr::createFromStream(SkStreamAsset* stream, const FontParameters& params) const { if (nullptr == stream) { return nullptr; } - return this->onCreateFromStream(stream, args); + return this->onCreateFromStream(stream, params); } SkTypeface* SkFontMgr::createFromFontData(std::unique_ptr<SkFontData> data) const { @@ -147,8 +147,8 @@ SkTypeface* SkFontMgr::createFromFontData(std::unique_ptr<SkFontData> data) cons } // This implementation is temporary until it can be made pure virtual. -SkTypeface* SkFontMgr::onCreateFromStream(SkStreamAsset* stream, const SkFontArguments& args) const{ - return this->createFromStream(stream, args.getCollectionIndex()); +SkTypeface* SkFontMgr::onCreateFromStream(SkStreamAsset* stream, const FontParameters& p) const { + return this->createFromStream(stream, p.getCollectionIndex()); } // This implementation is temporary until it can be made pure virtual. diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp index 2d8f920ba9..70c0c76d06 100644 --- a/src/core/SkTypeface.cpp +++ b/src/core/SkTypeface.cpp @@ -73,11 +73,6 @@ protected: SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override { return new EmptyLocalizedStrings; } - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) 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,12 +202,6 @@ sk_sp<SkTypeface> SkTypeface::MakeDeserialize(SkStream* stream) { /////////////////////////////////////////////////////////////////////////////// -int SkTypeface::getVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const -{ - return this->onGetVariationDesignPosition(coordinates, coordinateCount); -} - int SkTypeface::countTables() const { return this->onGetTableTags(nullptr); } diff --git a/src/fonts/SkGScalerContext.cpp b/src/fonts/SkGScalerContext.cpp index 3b9c660636..8a0ac4cd64 100644 --- a/src/fonts/SkGScalerContext.cpp +++ b/src/fonts/SkGScalerContext.cpp @@ -195,12 +195,6 @@ SkTypeface::LocalizedStrings* SkGTypeface::onCreateFamilyNameIterator() const { return fProxy->createFamilyNameIterator(); } -int SkGTypeface::onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const -{ - return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount); -} - int SkGTypeface::onGetTableTags(SkFontTableTag tags[]) const { return fProxy->getTableTags(tags); } diff --git a/src/fonts/SkGScalerContext.h b/src/fonts/SkGScalerContext.h index 562513c7bc..3eb25a81da 100644 --- a/src/fonts/SkGScalerContext.h +++ b/src/fonts/SkGScalerContext.h @@ -37,8 +37,6 @@ protected: void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) 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/fonts/SkRandomScalerContext.cpp b/src/fonts/SkRandomScalerContext.cpp index 3a292dcd79..55c7fb30d4 100644 --- a/src/fonts/SkRandomScalerContext.cpp +++ b/src/fonts/SkRandomScalerContext.cpp @@ -242,12 +242,6 @@ SkTypeface::LocalizedStrings* SkRandomTypeface::onCreateFamilyNameIterator() con return fProxy->createFamilyNameIterator(); } -int SkRandomTypeface::onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const -{ - return fProxy->onGetVariationDesignPosition(coordinates, coordinateCount); -} - int SkRandomTypeface::onGetTableTags(SkFontTableTag tags[]) const { return fProxy->getTableTags(tags); } diff --git a/src/fonts/SkRandomScalerContext.h b/src/fonts/SkRandomScalerContext.h index c84b76470e..076689d93a 100644 --- a/src/fonts/SkRandomScalerContext.h +++ b/src/fonts/SkRandomScalerContext.h @@ -42,8 +42,6 @@ protected: void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) 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/fonts/SkTestScalerContext.h b/src/fonts/SkTestScalerContext.h index 20cce91ab9..217e57c2a4 100644 --- a/src/fonts/SkTestScalerContext.h +++ b/src/fonts/SkTestScalerContext.h @@ -91,12 +91,6 @@ protected: void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const override - { - return 0; - } - int onGetTableTags(SkFontTableTag tags[]) const override { return 0; } diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index 111b16d4d2..47790f3644 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -27,6 +27,9 @@ #include "SkTemplates.h" #include <memory> +#if defined(SK_CAN_USE_DLOPEN) +#include <dlfcn.h> +#endif #include <ft2build.h> #include FT_ADVANCES_H #include FT_BITMAP_H @@ -41,20 +44,6 @@ #include FT_TYPE1_TABLES_H #include FT_XFREE86_H -// SK_FREETYPE_MINIMUM_RUNTIME_VERSION 0x<major><minor><patch><flags> -// Flag SK_FREETYPE_DLOPEN: also try dlopen to get newer features. -#define SK_FREETYPE_DLOPEN (0x1) -#ifndef SK_FREETYPE_MINIMUM_RUNTIME_VERSION -# if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || defined (GOOGLE3) -# define SK_FREETYPE_MINIMUM_RUNTIME_VERSION (((FREETYPE_MAJOR) << 24) | ((FREETYPE_MINOR) << 16) | ((FREETYPE_PATCH) << 8)) -# else -# define SK_FREETYPE_MINIMUM_RUNTIME_VERSION ((2 << 24) | (3 << 16) | (11 << 8) | (SK_FREETYPE_DLOPEN)) -# endif -#endif -#if SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN -# include <dlfcn.h> -#endif - // FT_LOAD_COLOR and the corresponding FT_Pixel_Mode::FT_PIXEL_MODE_BGRA // were introduced in FreeType 2.5.0. // The following may be removed once FreeType 2.5.0 is required to build. @@ -96,37 +85,12 @@ FT_MemoryRec_ gFTMemory = { nullptr, sk_ft_alloc, sk_ft_free, sk_ft_realloc }; class FreeTypeLibrary : SkNoncopyable { public: - FreeTypeLibrary() - : fGetVarDesignCoordinates(nullptr) - , fLibrary(nullptr) - , fIsLCDSupported(false) - , fLCDExtra(0) - { + FreeTypeLibrary() : fLibrary(nullptr), fIsLCDSupported(false), fLCDExtra(0) { if (FT_New_Library(&gFTMemory, &fLibrary)) { return; } FT_Add_Default_Modules(fLibrary); -#if SK_FREETYPE_MINIMUM_RUNTIME_VERSION >= 0x02070100 - fGetVarDesignCoordinates = FT_Get_Var_Design_Coordinates; -#elif SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN - FT_Int major, minor, patch; - FT_Library_Version(fLibrary, &major, &minor, &patch); - if (major > 2 || ((major == 2 && minor > 7) || (major == 2 && minor == 7 && patch >= 1))) { - //The FreeType library is already loaded, so symbols are available in process. - void* self = dlopen(nullptr, RTLD_LAZY); - if (self) { - // The following cast is non-standard, but safe for POSIX. - // Cannot write this with reinterpret_cast, because clang has not implemented DR573. - // See http://clang.llvm.org/cxx_dr_status.html . - //*reinterpret_cast<void**>(&fGetVarDesignCoordinates) = - // dlsym(self, "FT_Get_Var_Design_Coordinates"); - *(void**)(&fGetVarDesignCoordinates) = dlsym(self, "FT_Get_Var_Design_Coordinates"); - dlclose(self); - } - } -#endif - // Setup LCD filtering. This reduces color fringes for LCD smoothed glyphs. // Default { 0x10, 0x40, 0x70, 0x40, 0x10 } adds up to 0x110, simulating ink spread. // SetLcdFilter must be called before SetLcdFilterWeights. @@ -138,26 +102,23 @@ public: // Adds to 0x110 simulating ink spread, but provides better results than default. static unsigned char gGaussianLikeHeavyWeights[] = { 0x1A, 0x43, 0x56, 0x43, 0x1A, }; -# if SK_FREETYPE_MINIMUM_RUNTIME_VERSION >= 0x02040000 +# if SK_FONTHOST_FREETYPE_RUNTIME_VERSION > 0x020400 FT_Library_SetLcdFilterWeights(fLibrary, gGaussianLikeHeavyWeights); -# elif SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN +# elif SK_CAN_USE_DLOPEN == 1 //The FreeType library is already loaded, so symbols are available in process. void* self = dlopen(nullptr, RTLD_LAZY); if (self) { FT_Library_SetLcdFilterWeightsProc setLcdFilterWeights; - // The following cast is non-standard, but safe for POSIX. - // Cannot write this with reinterpret_cast, because clang has not implemented DR573. - // See http://clang.llvm.org/cxx_dr_status.html . - //*reinterpret_cast<void**>(&setLcdFilterWeights) = - // dlsym(self, "FT_Library_SetLcdFilterWeights"); - *(void**)(&setLcdFilterWeights) = dlsym(self, "FT_Library_SetLcdFilterWeights"); + //The following cast is non-standard, but safe for POSIX. + *reinterpret_cast<void**>(&setLcdFilterWeights) = + dlsym(self, "FT_Library_SetLcdFilterWeights"); dlclose(self); if (setLcdFilterWeights) { setLcdFilterWeights(fLibrary, gGaussianLikeHeavyWeights); } } -# endif +# endif #endif } } @@ -171,13 +132,6 @@ public: bool isLCDSupported() { return fIsLCDSupported; } int lcdExtra() { return fLCDExtra; } - // FT_Get_{MM,Var}_{Blend,Design}_Coordinates were added in FreeType 2.7.1. - // Prior to this there was no way to get the coordinates out of the FT_Face. - // This wasn't too bad because you needed to specify them anyway, and the clamp was provided. - // However, this doesn't work when face_index specifies named variations as introduced in 2.6.1. - using FT_Get_Var_Blend_CoordinatesProc = FT_Error (*)(FT_Face, FT_UInt, FT_Fixed*); - FT_Get_Var_Blend_CoordinatesProc fGetVarDesignCoordinates; - private: FT_Library fLibrary; bool fIsLCDSupported; @@ -190,8 +144,7 @@ private: // OpenSuse >= 11.4 (previous deprecated January 2012 / Nov 2013 for Evergreen 11.2) // Fedora >= 14 (good) // Android >= Gingerbread (good) - // RHEL >= 7 (6 has 2.3.11, EOL Nov 2020, Phase 3 May 2017) - using FT_Library_SetLcdFilterWeightsProc = FT_Error (*)(FT_Library, unsigned char*); + typedef FT_Error (*FT_Library_SetLcdFilterWeightsProc)(FT_Library, unsigned char*); }; struct SkFaceRec; @@ -230,21 +183,69 @@ static void unref_ft_library() { } } +class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { +public: + SkScalerContext_FreeType(sk_sp<SkTypeface>, + const SkScalerContextEffects&, + const SkDescriptor* desc); + virtual ~SkScalerContext_FreeType(); + + bool success() const { + return fFTSize != nullptr && fFace != nullptr; + } + +protected: + unsigned generateGlyphCount() override; + uint16_t generateCharToGlyph(SkUnichar uni) override; + void generateAdvance(SkGlyph* glyph) override; + void generateMetrics(SkGlyph* glyph) override; + void generateImage(const SkGlyph& glyph) override; + void generatePath(SkGlyphID glyphID, SkPath* path) override; + void generateFontMetrics(SkPaint::FontMetrics*) override; + SkUnichar generateGlyphToChar(uint16_t glyph) override; + +private: + FT_Face fFace; // Shared face from gFaceRecHead. + FT_Size fFTSize; // The size on the fFace for this scaler. + FT_Int fStrikeIndex; + + /** The rest of the matrix after FreeType handles the size. + * With outline font rasterization this is handled by FreeType with FT_Set_Transform. + * With bitmap only fonts this matrix must be applied to scale the bitmap. + */ + SkMatrix fMatrix22Scalar; + /** Same as fMatrix22Scalar, but in FreeType units and space. */ + FT_Matrix fMatrix22; + /** The actual size requested. */ + SkVector fScale; + + uint32_t fLoadGlyphFlags; + bool fDoLinearMetrics; + bool fLCDIsVert; + + FT_Error setupSize(); + void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, + bool snapToPixelBoundary = false); + bool getCBoxForLetter(char letter, FT_BBox* bbox); + // Caller must lock gFTMutex before calling this function. + void updateGlyphIfLCD(SkGlyph* glyph); + // Caller must lock gFTMutex before calling this function. + // update FreeType2 glyph slot with glyph emboldened + void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph); + bool shouldSubpixelBitmap(const SkGlyph&, const SkMatrix&); +}; + +/////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// struct SkFaceRec { SkFaceRec* fNext; - std::unique_ptr<FT_FaceRec, SkFunctionWrapper<FT_Error, FT_FaceRec, FT_Done_Face>> fFace; + FT_Face fFace; FT_StreamRec fFTStream; std::unique_ptr<SkStreamAsset> fSkStream; uint32_t fRefCnt; uint32_t fFontID; - // FreeType prior to 2.7.1 does not implement retreiving variation design metrics. - // Cache the variation design metrics used to create the font if the user specifies them. - SkAutoSTMalloc<4, SkFixed> fAxes; - int fAxesCount; - SkFaceRec(std::unique_ptr<SkStreamAsset> stream, uint32_t fontID); }; @@ -269,7 +270,7 @@ extern "C" { } SkFaceRec::SkFaceRec(std::unique_ptr<SkStreamAsset> stream, uint32_t fontID) - : fNext(nullptr), fSkStream(std::move(stream)), fRefCnt(1), fFontID(fontID), fAxesCount(0) + : fNext(nullptr), fSkStream(std::move(stream)), fRefCnt(1), fFontID(fontID) { sk_bzero(&fFTStream, sizeof(fFTStream)); fFTStream.size = fSkStream->getLength(); @@ -278,28 +279,22 @@ SkFaceRec::SkFaceRec(std::unique_ptr<SkStreamAsset> stream, uint32_t fontID) fFTStream.close = sk_ft_stream_close; } -static void ft_face_setup_axes(SkFaceRec* rec, const SkFontData& data) { - if (!(rec->fFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { - return; - } - - // If a named variation is requested, don't overwrite the named variation's position. - if (data.getIndex() > 0xFFFF) { +static void ft_face_setup_axes(FT_Face face, const SkFontData& data) { + if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) { return; } SkDEBUGCODE( FT_MM_Var* variations = nullptr; - if (FT_Get_MM_Var(rec->fFace.get(), &variations)) { - SkDEBUGF(("INFO: font %s claims variations, but none found.\n", - rec->fFace->family_name)); + if (FT_Get_MM_Var(face, &variations)) { + SkDEBUGF(("INFO: font %s claims variations, but none found.\n", face->family_name)); return; } SkAutoFree autoFreeVariations(variations); if (static_cast<FT_UInt>(data.getAxisCount()) != variations->num_axis) { SkDEBUGF(("INFO: font %s has %d variations, but %d were specified.\n", - rec->fFace->family_name, variations->num_axis, data.getAxisCount())); + face->family_name, variations->num_axis, data.getAxisCount())); return; } ) @@ -308,33 +303,27 @@ static void ft_face_setup_axes(SkFaceRec* rec, const SkFontData& data) { for (int i = 0; i < data.getAxisCount(); ++i) { coords[i] = data.getAxis()[i]; } - if (FT_Set_Var_Design_Coordinates(rec->fFace.get(), data.getAxisCount(), coords.get())) { + if (FT_Set_Var_Design_Coordinates(face, data.getAxisCount(), coords.get())) { SkDEBUGF(("INFO: font %s has variations, but specified variations could not be set.\n", - rec->fFace->family_name)); + face->family_name)); return; } - - rec->fAxesCount = data.getAxisCount(); - rec->fAxes.reset(rec->fAxesCount); - for (int i = 0; i < rec->fAxesCount; ++i) { - rec->fAxes[i] = data.getAxis()[i]; - } } -// Will return nullptr on failure +// Will return 0 on failure // Caller must lock gFTMutex before calling this function. -static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { +static FT_Face ref_ft_face(const SkTypeface* typeface) { gFTMutex.assertHeld(); const SkFontID fontID = typeface->uniqueID(); - SkFaceRec* cachedRec = gFaceRecHead; - while (cachedRec) { - if (cachedRec->fFontID == fontID) { - SkASSERT(cachedRec->fFace); - cachedRec->fRefCnt += 1; - return cachedRec; + SkFaceRec* rec = gFaceRecHead; + while (rec) { + if (rec->fFontID == fontID) { + SkASSERT(rec->fFace); + rec->fRefCnt += 1; + return rec->fFace; } - cachedRec = cachedRec->fNext; + rec = rec->fNext; } std::unique_ptr<SkFontData> data = typeface->makeFontData(); @@ -342,7 +331,7 @@ static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { return nullptr; } - std::unique_ptr<SkFaceRec> rec(new SkFaceRec(data->detachStream(), fontID)); + rec = new SkFaceRec(data->detachStream(), fontID); FT_Open_Args args; memset(&args, 0, sizeof(args)); @@ -356,18 +345,15 @@ static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { args.stream = &rec->fFTStream; } - { - FT_Face rawFace; - FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(), &rawFace); - if (err) { - SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); - return nullptr; - } - rec->fFace.reset(rawFace); + FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(), &rec->fFace); + if (err) { + SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); + delete rec; + return nullptr; } SkASSERT(rec->fFace); - ft_face_setup_axes(rec.get(), *data); + ft_face_setup_axes(rec->fFace, *data); // FreeType will set the charmap to the "most unicode" cmap if it exists. // If there are no unicode cmaps, the charmap is set to nullptr. @@ -376,29 +362,31 @@ static SkFaceRec* ref_ft_face(const SkTypeface* typeface) { // This is the last on the fallback list at // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html if (!rec->fFace->charmap) { - FT_Select_Charmap(rec->fFace.get(), FT_ENCODING_MS_SYMBOL); + FT_Select_Charmap(rec->fFace, FT_ENCODING_MS_SYMBOL); } rec->fNext = gFaceRecHead; - gFaceRecHead = rec.get(); - return rec.release(); + gFaceRecHead = rec; + return rec->fFace; } // Caller must lock gFTMutex before calling this function. -static void unref_ft_face(SkFaceRec* faceRec) { +extern void unref_ft_face(FT_Face face); +void unref_ft_face(FT_Face face) { gFTMutex.assertHeld(); SkFaceRec* rec = gFaceRecHead; SkFaceRec* prev = nullptr; while (rec) { SkFaceRec* next = rec->fNext; - if (rec->fFace == faceRec->fFace) { + if (rec->fFace == face) { if (--rec->fRefCnt == 0) { if (prev) { prev->fNext = next; } else { gFaceRecHead = next; } + FT_Done_Face(face); delete rec; } return; @@ -411,85 +399,26 @@ static void unref_ft_face(SkFaceRec* faceRec) { class AutoFTAccess { public: - AutoFTAccess(const SkTypeface* tf) : fFaceRec(nullptr) { + AutoFTAccess(const SkTypeface* tf) : fFace(nullptr) { gFTMutex.acquire(); if (!ref_ft_library()) { sk_throw(); } - fFaceRec = ref_ft_face(tf); + fFace = ref_ft_face(tf); } ~AutoFTAccess() { - if (fFaceRec) { - unref_ft_face(fFaceRec); + if (fFace) { + unref_ft_face(fFace); } unref_ft_library(); gFTMutex.release(); } - FT_Face face() { return fFaceRec ? fFaceRec->fFace.get() : nullptr; } - int getAxesCount() { return fFaceRec ? fFaceRec->fAxesCount : 0; } - SkFixed* getAxes() { return fFaceRec ? fFaceRec->fAxes.get() : nullptr; } - -private: - SkFaceRec* fFaceRec; -}; - -/////////////////////////////////////////////////////////////////////////// - -class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { -public: - SkScalerContext_FreeType(sk_sp<SkTypeface>, - const SkScalerContextEffects&, - const SkDescriptor* desc); - virtual ~SkScalerContext_FreeType(); - - bool success() const { - return fFTSize != nullptr && fFace != nullptr; - } - -protected: - unsigned generateGlyphCount() override; - uint16_t generateCharToGlyph(SkUnichar uni) override; - void generateAdvance(SkGlyph* glyph) override; - void generateMetrics(SkGlyph* glyph) override; - void generateImage(const SkGlyph& glyph) override; - void generatePath(SkGlyphID glyphID, SkPath* path) override; - void generateFontMetrics(SkPaint::FontMetrics*) override; - SkUnichar generateGlyphToChar(uint16_t glyph) override; + FT_Face face() { return fFace; } private: - using UnrefFTFace = SkFunctionWrapper<void, SkFaceRec, unref_ft_face>; - std::unique_ptr<SkFaceRec, UnrefFTFace> fFaceRec; - - FT_Face fFace; // Borrowed face from gFaceRecHead. - FT_Size fFTSize; // The size on the fFace for this scaler. - FT_Int fStrikeIndex; - - /** The rest of the matrix after FreeType handles the size. - * With outline font rasterization this is handled by FreeType with FT_Set_Transform. - * With bitmap only fonts this matrix must be applied to scale the bitmap. - */ - SkMatrix fMatrix22Scalar; - /** Same as fMatrix22Scalar, but in FreeType units and space. */ - FT_Matrix fMatrix22; - /** The actual size requested. */ - SkVector fScale; - - uint32_t fLoadGlyphFlags; - bool fDoLinearMetrics; - bool fLCDIsVert; - - FT_Error setupSize(); - void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, - bool snapToPixelBoundary = false); - bool getCBoxForLetter(char letter, FT_BBox* bbox); - // Caller must lock gFTMutex before calling this function. - void updateGlyphIfLCD(SkGlyph* glyph); - // Caller must lock gFTMutex before calling this function. - // update FreeType2 glyph slot with glyph emboldened - void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph); - bool shouldSubpixelBitmap(const SkGlyph&, const SkMatrix&); + FT_Face fFace; }; /////////////////////////////////////////////////////////////////////////// @@ -817,10 +746,11 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface, sk_throw(); } - fFaceRec.reset(ref_ft_face(this->getTypeface())); - // load the font file - if (nullptr == fFaceRec) { + using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face>, unref_ft_face>; + using FT_FaceRef = skstd::remove_pointer_t<FT_Face>; + std::unique_ptr<FT_FaceRef, UnrefFTFace> ftFace(ref_ft_face(this->getTypeface())); + if (nullptr == ftFace) { SkDEBUGF(("Could not create FT_Face.\n")); return; } @@ -906,11 +836,11 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface, } using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Size>, FT_Done_Size>; - std::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([this]() -> FT_Size { + std::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftFace]() -> FT_Size { FT_Size size; - FT_Error err = FT_New_Size(fFaceRec->fFace.get(), &size); + FT_Error err = FT_New_Size(ftFace.get(), &size); if (err != 0) { - SkDEBUGF(("FT_New_Size(%s) returned 0x%x.\n", fFaceRec->fFace->family_name, err)); + SkDEBUGF(("FT_New_Size(%s) returned 0x%x.\n", ftFace->family_name, err)); return nullptr; } return size; @@ -922,37 +852,36 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface, FT_Error err = FT_Activate_Size(ftSize.get()); if (err != 0) { - SkDEBUGF(("FT_Activate_Size(%s) returned 0x%x.\n", fFaceRec->fFace->family_name, err)); + SkDEBUGF(("FT_Activate_Size(%s) returned 0x%x.\n", ftFace->family_name, err)); return; } - if (FT_IS_SCALABLE(fFaceRec->fFace)) { - err = FT_Set_Char_Size(fFaceRec->fFace.get(), scaleX, scaleY, 72, 72); + if (FT_IS_SCALABLE(ftFace)) { + err = FT_Set_Char_Size(ftFace.get(), scaleX, scaleY, 72, 72); if (err != 0) { SkDEBUGF(("FT_Set_CharSize(%s, %f, %f) returned 0x%x.\n", - fFaceRec->fFace->family_name, fScale.fX, fScale.fY, err)); + ftFace->family_name, fScale.fX, fScale.fY, err)); return; } - } else if (FT_HAS_FIXED_SIZES(fFaceRec->fFace)) { - fStrikeIndex = chooseBitmapStrike(fFaceRec->fFace.get(), scaleY); + } else if (FT_HAS_FIXED_SIZES(ftFace)) { + fStrikeIndex = chooseBitmapStrike(ftFace.get(), scaleY); if (fStrikeIndex == -1) { - SkDEBUGF(("No glyphs for font \"%s\" size %f.\n", - fFaceRec->fFace->family_name, fScale.fY)); + SkDEBUGF(("No glyphs for font \"%s\" size %f.\n", ftFace->family_name, fScale.fY)); return; } - err = FT_Select_Size(fFaceRec->fFace.get(), fStrikeIndex); + err = FT_Select_Size(ftFace.get(), fStrikeIndex); if (err != 0) { SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x.\n", - fFaceRec->fFace->family_name, fStrikeIndex, err)); + ftFace->family_name, fStrikeIndex, err)); fStrikeIndex = -1; return; } // A non-ideal size was picked, so recompute the matrix. // This adjusts for the difference between FT_Set_Char_Size and FT_Select_Size. - fMatrix22Scalar.preScale(fScale.x() / fFaceRec->fFace->size->metrics.x_ppem, - fScale.y() / fFaceRec->fFace->size->metrics.y_ppem); + fMatrix22Scalar.preScale(fScale.x() / ftFace->size->metrics.x_ppem, + fScale.y() / ftFace->size->metrics.y_ppem); fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX()); fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY()); @@ -969,12 +898,12 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface> typeface, // Force this flag off for bitmap only fonts. fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP; } else { - SkDEBUGF(("Unknown kind of font \"%s\" size %f.\n", fFaceRec->fFace->family_name, fScale.fY)); + SkDEBUGF(("Unknown kind of font \"%s\" size %f.\n", fFace->family_name, fScale.fY)); return; } fFTSize = ftSize.release(); - fFace = fFaceRec->fFace.get(); + fFace = ftFace.release(); fDoLinearMetrics = linearMetrics; } @@ -985,7 +914,9 @@ SkScalerContext_FreeType::~SkScalerContext_FreeType() { FT_Done_Size(fFTSize); } - fFaceRec = nullptr; + if (fFace != nullptr) { + unref_ft_face(fFace); + } unref_ft_library(); } @@ -1569,51 +1500,6 @@ SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() return nameIter; } -int SkTypeface_FreeType::onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const -{ - AutoFTAccess fta(this); - FT_Face face = fta.face(); - - 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; - } - SkAutoFree autoFreeVariations(variations); - - if (!coordinates || coordinateCount < SkToInt(variations->num_axis)) { - return variations->num_axis; - } - - SkAutoSTMalloc<4, FT_Fixed> coords(variations->num_axis); - // FT_Get_{MM,Var}_{Blend,Design}_Coordinates were added in FreeType 2.7.1. - if (gFTLibrary->fGetVarDesignCoordinates && - !gFTLibrary->fGetVarDesignCoordinates(face, variations->num_axis, coords.get())) - { - for (FT_UInt i = 0; i < variations->num_axis; ++i) { - coordinates[i].axis = variations->axis[i].tag; - coordinates[i].value = SkFixedToScalar(coords[i]); - } - } else if (static_cast<FT_UInt>(fta.getAxesCount()) == variations->num_axis) { - for (FT_UInt i = 0; i < variations->num_axis; ++i) { - coordinates[i].axis = variations->axis[i].tag; - coordinates[i].value = SkFixedToScalar(fta.getAxes()[i]); - } - } else if (face->face_index <= 0xFFFF) { - // The font has axes, they cannot be retrieved, but no named instance was specified. - return 0; - } else { - // The font has axes, they cannot be retrieved, and some named axis was specified. - return -1; - } - - return variations->num_axis; -} - int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const { AutoFTAccess fta(this); FT_Face face = fta.face(); @@ -1844,7 +1730,7 @@ bool SkTypeface_FreeType::Scanner::scanFont( /*static*/ void SkTypeface_FreeType::Scanner::computeAxisValues( AxisDefinitions axisDefinitions, - const SkFontArguments::VariationPosition position, + const SkFontMgr::FontParameters::Axis* requestedAxes, int requestedAxisCount, SkFixed* axisValues, const SkString& name) { @@ -1853,11 +1739,11 @@ bool SkTypeface_FreeType::Scanner::scanFont( const SkScalar axisMin = SkFixedToScalar(axisDefinition.fMinimum); const SkScalar axisMax = SkFixedToScalar(axisDefinition.fMaximum); axisValues[i] = axisDefinition.fDefault; - for (int j = 0; j < position.coordinateCount; ++j) { - const auto& coordinate = position.coordinates[j]; - if (axisDefinition.fTag == coordinate.axis) { - const SkScalar axisValue = SkTPin(coordinate.value, axisMin, axisMax); - if (coordinate.value != axisValue) { + for (int j = 0; j < requestedAxisCount; ++j) { + const SkFontMgr::FontParameters::Axis& axisSpecified = requestedAxes[j]; + if (axisDefinition.fTag == axisSpecified.fTag) { + const SkScalar axisValue = SkTPin(axisSpecified.fStyleValue, axisMin, axisMax); + if (axisSpecified.fStyleValue != axisValue) { SkDEBUGF(("Requested font axis value out of range: " "%s '%c%c%c%c' %f; pinned to %f.\n", name.c_str(), @@ -1865,7 +1751,7 @@ bool SkTypeface_FreeType::Scanner::scanFont( (axisDefinition.fTag >> 16) & 0xFF, (axisDefinition.fTag >> 8) & 0xFF, (axisDefinition.fTag ) & 0xFF, - SkScalarToDouble(coordinate.value), + SkScalarToDouble(axisSpecified.fStyleValue), SkScalarToDouble(axisValue))); } axisValues[i] = SkScalarToFixed(axisValue); @@ -1877,8 +1763,8 @@ bool SkTypeface_FreeType::Scanner::scanFont( SkDEBUGCODE( // Check for axis specified, but not matched in font. - for (int i = 0; i < position.coordinateCount; ++i) { - SkFourByteTag skTag = position.coordinates[i].axis; + for (int i = 0; i < requestedAxisCount; ++i) { + SkFourByteTag skTag = requestedAxes[i].fTag; bool found = false; for (int j = 0; j < axisDefinitions.count(); ++j) { if (skTag == axisDefinitions[j].fTag) { diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h index b9e8b13d7f..867e139c21 100644 --- a/src/ports/SkFontHost_FreeType_common.h +++ b/src/ports/SkFontHost_FreeType_common.h @@ -17,11 +17,8 @@ #include "SkFontMgr.h" -// These are forward declared to avoid pimpl but also hide the FreeType implementation. -typedef struct FT_LibraryRec_* FT_Library; -typedef struct FT_FaceRec_* FT_Face; -typedef struct FT_StreamRec_* FT_Stream; -typedef signed long FT_Pos; +#include <ft2build.h> +#include FT_FREETYPE_H class SkScalerContext_FreeType_Base : public SkScalerContext { protected: @@ -62,7 +59,7 @@ public: AxisDefinitions* axes) const; static void computeAxisValues( AxisDefinitions axisDefinitions, - const SkFontArguments::VariationPosition position, + const SkFontMgr::FontParameters::Axis* requestedAxis, int requestedAxisCount, SkFixed* axisValues, const SkString& name); @@ -91,8 +88,6 @@ protected: LocalizedStrings* onCreateFamilyNameIterator() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) 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_mac.cpp b/src/ports/SkFontHost_mac.cpp index b5022d9af9..7a46d40ec6 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -492,8 +492,6 @@ protected: int onGetUPEM() const override; SkStreamAsset* onOpenStream(int* ttcIndex) const override; std::unique_ptr<SkFontData> onMakeFontData() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const override; void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; int onGetTableTags(SkFontTableTag tags[]) const override; @@ -1376,10 +1374,7 @@ void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element // Returns nullptr on failure // Call must still manage its ownership of provider -static SkTypeface* create_from_dataProvider(UniqueCFRef<CGDataProviderRef> provider, int ttcIndex) { - if (ttcIndex != 0) { - return nullptr; - } +static SkTypeface* create_from_dataProvider(UniqueCFRef<CGDataProviderRef> provider) { UniqueCFRef<CGFontRef> cg(CGFontCreateWithDataProvider(provider.get())); if (!cg) { return nullptr; @@ -1700,14 +1695,13 @@ static void set_non_default_axes(CFTypeRef key, CFTypeRef value, void* context) } self->axisValue[keyIndex] = SkDoubleToFixed(valueDouble); } -static bool get_variations(CTFontRef ctFont, CFIndex* cgAxisCount, +static bool get_variations(CTFontRef fFontRef, CFIndex* cgAxisCount, SkAutoSTMalloc<4, SkFixed>* axisValues) { - // In 10.10 and earlier, CTFontCopyVariationAxes and CTFontCopyVariation do not work when - // applied to fonts which started life with CGFontCreateWithDataProvider (they simply always - // return nullptr). As a result, we are limited to CGFontCopyVariationAxes and - // CGFontCopyVariations here until support for 10.10 and earlier is removed. - UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(ctFont, nullptr)); + // CTFontCopyVariationAxes and CTFontCopyVariation do not work when applied to fonts which + // started life with CGFontCreateWithDataProvider (they simply always return nullptr). + // As a result, we are limited to CGFontCopyVariationAxes and CGFontCopyVariations. + UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef, nullptr)); if (!cgFont) { return false; } @@ -1772,126 +1766,6 @@ std::unique_ptr<SkFontData> SkTypeface_Mac::onMakeFontData() const { return skstd::make_unique<SkFontData>(std::move(stream), index, nullptr, 0); } -/** Creates a CT variation dictionary {tag, value} from a CG variation dictionary {name, value}. */ -static UniqueCFRef<CFDictionaryRef> ct_variation_from_cg_variation(CFDictionaryRef cgVariations, - CFArrayRef ctAxes) { - - UniqueCFRef<CFMutableDictionaryRef> ctVariations( - CFDictionaryCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks)); - - CFIndex axisCount = CFArrayGetCount(ctAxes); - for (CFIndex i = 0; i < axisCount; ++i) { - CFTypeRef axisInfo = CFArrayGetValueAtIndex(ctAxes, i); - if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { - return nullptr; - } - CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo); - - // The assumption is that values produced by kCTFontVariationAxisNameKey and - // kCGFontVariationAxisName will always be equal. - CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisNameKey); - if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) { - return nullptr; - } - - CFTypeRef axisValue = CFDictionaryGetValue(cgVariations, axisName); - if (!axisValue || CFGetTypeID(axisValue) != CFNumberGetTypeID()) { - return nullptr; - } - - CFTypeRef axisTag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey); - if (!axisTag || CFGetTypeID(axisTag) != CFNumberGetTypeID()) { - return nullptr; - } - - CFDictionaryAddValue(ctVariations.get(), axisTag, axisValue); - } - return std::move(ctVariations); -} - -int SkTypeface_Mac::onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const -{ - // The CGFont variation data does not contain the tag. - - // This call always returns nullptr on 10.10 and under for CGFontCreateWithDataProvider fonts. - // When this happens, there is no API to provide the tag. - UniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(fFontRef.get())); - if (!ctAxes) { - return -1; - } - CFIndex axisCount = CFArrayGetCount(ctAxes.get()); - if (!coordinates || coordinateCount < axisCount) { - return axisCount; - } - - // This call always returns nullptr on 10.11 and under for CGFontCreateWithDataProvider fonts. - // When this happens, try converting the CG variation to a CT variation. - // On 10.12 and later, this only returns non-default variations. - UniqueCFRef<CFDictionaryRef> ctVariations(CTFontCopyVariation(fFontRef.get())); - if (!ctVariations) { - // When 10.11 and earlier are no longer supported, the following code can be replaced with - // return -1 and ct_variation_from_cg_variation can be removed. - UniqueCFRef<CGFontRef> cgFont(CTFontCopyGraphicsFont(fFontRef.get(), nullptr)); - if (!cgFont) { - return -1; - } - UniqueCFRef<CFDictionaryRef> cgVariations(CGFontCopyVariations(cgFont.get())); - if (!cgVariations) { - return -1; - } - ctVariations = ct_variation_from_cg_variation(cgVariations.get(), ctAxes.get()); - if (!ctVariations) { - return -1; - } - } - - for (int i = 0; i < axisCount; ++i) { - CFTypeRef axisInfo = CFArrayGetValueAtIndex(ctAxes.get(), i); - if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { - return -1; - } - CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo); - - CFTypeRef tag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey); - if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) { - return -1; - } - CFNumberRef tagNumber = static_cast<CFNumberRef>(tag); - int64_t tagLong; - if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) { - return -1; - } - coordinates[i].axis = tagLong; - - CGFloat variationCGFloat; - CFTypeRef variationValue = CFDictionaryGetValue(ctVariations.get(), tagNumber); - if (variationValue) { - if (CFGetTypeID(variationValue) != CFNumberGetTypeID()) { - return -1; - } - CFNumberRef variationNumber = static_cast<CFNumberRef>(variationValue); - if (!CFNumberGetValue(variationNumber, kCFNumberCGFloatType, &variationCGFloat)) { - return -1; - } - } else { - CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisDefaultValueKey); - if (!def || CFGetTypeID(def) != CFNumberGetTypeID()) { - return -1; - } - CFNumberRef defNumber = static_cast<CFNumberRef>(def); - if (!CFNumberGetValue(defNumber, kCFNumberCGFloatType, &variationCGFloat)) { - return -1; - } - } - coordinates[i].value = CGToScalar(variationCGFloat); - - } - return axisCount; -} - /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -2373,7 +2247,7 @@ protected: if (!pr) { return nullptr; } - return create_from_dataProvider(std::move(pr), ttcIndex); + return create_from_dataProvider(std::move(pr)); } SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override { @@ -2382,26 +2256,55 @@ protected: if (!pr) { return nullptr; } - return create_from_dataProvider(std::move(pr), ttcIndex); + return create_from_dataProvider(std::move(pr)); } - /** Creates a dictionary suitable for setting the axes on a CGFont. */ - static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, const SkFontArguments& args) { - // The CGFont variation data is keyed by name, but lacks the tag. + static CFNumberRef get_tag_for_name(CFStringRef name, CFArrayRef ctAxes) { + CFIndex ctAxisCount = CFArrayGetCount(ctAxes); + for (int i = 0; i < ctAxisCount; ++i) { + CFTypeRef ctAxisInfo = CFArrayGetValueAtIndex(ctAxes, i); + if (CFDictionaryGetTypeID() != CFGetTypeID(ctAxisInfo)) { + return nullptr; + } + CFDictionaryRef ctAxisInfoDict = static_cast<CFDictionaryRef>(ctAxisInfo); + + CFTypeRef ctAxisName = CFDictionaryGetValue(ctAxisInfoDict, + kCTFontVariationAxisNameKey); + if (!ctAxisName || CFGetTypeID(ctAxisName) != CFStringGetTypeID()) { + return nullptr; + } + + if (CFEqual(name, ctAxisName)) { + CFTypeRef tag = CFDictionaryGetValue(ctAxisInfoDict, + kCTFontVariationAxisIdentifierKey); + if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) { + return nullptr; + } + return static_cast<CFNumberRef>(tag); + } + } + return nullptr; + } + static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, const FontParameters& params) { + UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); + if (!cgAxes) { + return nullptr; + } + CFIndex axisCount = CFArrayGetCount(cgAxes.get()); + + // The CGFont variation data is keyed by name, and lacks the tag. // The CTFont variation data is keyed by tag, and also has the name. - // We would like to work with CTFont variations, but creating a CTFont font with + // We would like to work with CTFont variaitons, but creating a CTFont font with // CTFont variation dictionary runs into bugs. So use the CTFont variation data // to match names to tags to create the appropriate CGFont. UniqueCFRef<CTFontRef> ct(CTFontCreateWithGraphicsFont(cg, 0, nullptr, nullptr)); - // This call always returns nullptr on 10.10 and under. - // When this happens, there is no API to provide the tag. UniqueCFRef<CFArrayRef> ctAxes(CTFontCopyVariationAxes(ct.get())); - if (!ctAxes) { + if (!ctAxes || CFArrayGetCount(ctAxes.get()) != axisCount) { return nullptr; } - CFIndex axisCount = CFArrayGetCount(ctAxes.get()); - const SkFontArguments::VariationPosition position = args.getVariationDesignPosition(); + int paramAxisCount; + const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); UniqueCFRef<CFMutableDictionaryRef> dict( CFDictionaryCreateMutable(kCFAllocatorDefault, axisCount, @@ -2409,25 +2312,24 @@ protected: &kCFTypeDictionaryValueCallBacks)); for (int i = 0; i < axisCount; ++i) { - CFTypeRef axisInfo = CFArrayGetValueAtIndex(ctAxes.get(), i); + CFTypeRef axisInfo = CFArrayGetValueAtIndex(cgAxes.get(), i); if (CFDictionaryGetTypeID() != CFGetTypeID(axisInfo)) { return nullptr; } CFDictionaryRef axisInfoDict = static_cast<CFDictionaryRef>(axisInfo); - // The assumption is that values produced by kCTFontVariationAxisNameKey and - // kCGFontVariationAxisName will always be equal. - // If they are ever not, seach the project history for "get_tag_for_name". - CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisNameKey); + CFTypeRef axisName = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisName); if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) { return nullptr; } - CFTypeRef tag = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisIdentifierKey); - if (!tag || CFGetTypeID(tag) != CFNumberGetTypeID()) { - return nullptr; + CFNumberRef tagNumber = + get_tag_for_name(static_cast<CFStringRef>(axisName), ctAxes.get()); + if (!tagNumber) { + // Could not find a tag to go with the name of this index. + // This would be a bug in CG/CT. + continue; } - CFNumberRef tagNumber = static_cast<CFNumberRef>(tag); int64_t tagLong; if (!CFNumberGetValue(tagNumber, kCFNumberSInt64Type, &tagLong)) { return nullptr; @@ -2435,9 +2337,9 @@ protected: // The variation axes can be set to any value, but cg will effectively pin them. // Pin them here to normalize. - CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMinimumValueKey); - CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisMaximumValueKey); - CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCTFontVariationAxisDefaultValueKey); + CFTypeRef min = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMinValue); + CFTypeRef max = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisMaxValue); + CFTypeRef def = CFDictionaryGetValue(axisInfoDict, kCGFontVariationAxisDefaultValue); if (!min || CFGetTypeID(min) != CFNumberGetTypeID() || !max || CFGetTypeID(max) != CFNumberGetTypeID() || !def || CFGetTypeID(def) != CFNumberGetTypeID()) @@ -2458,10 +2360,9 @@ protected: } double value = defDouble; - for (int j = 0; j < position.coordinateCount; ++j) { - if (position.coordinates[j].axis == tagLong) { - value = SkTPin(SkScalarToDouble(position.coordinates[j].value), - minDouble, maxDouble); + for (int j = 0; j < paramAxisCount; ++j) { + if (paramAxes[j].fTag == tagLong) { + value = SkTPin(SkScalarToDouble(paramAxes[j].fStyleValue),minDouble,maxDouble); break; } } @@ -2471,11 +2372,8 @@ protected: } return std::move(dict); } - SkTypeface* onCreateFromStream(SkStreamAsset* bs, const SkFontArguments& args) const override { + SkTypeface* onCreateFromStream(SkStreamAsset* bs, const FontParameters& params) const override { std::unique_ptr<SkStreamAsset> s(bs); - if (args.getCollectionIndex() != 0) { - return nullptr; - } UniqueCFRef<CGDataProviderRef> provider(SkCreateDataProviderFromStream(std::move(s))); if (!provider) { return nullptr; @@ -2485,7 +2383,7 @@ protected: return nullptr; } - UniqueCFRef<CFDictionaryRef> cgVariations = copy_axes(cg.get(), args); + UniqueCFRef<CFDictionaryRef> cgVariations = copy_axes(cg.get(), params); // The CGFontRef returned by CGFontCreateCopyWithVariations when the passed CGFontRef was // created from a data provider does not appear to have any ownership of the underlying // data. The original CGFontRef must be kept alive until the copy will no longer be used. @@ -2504,7 +2402,6 @@ protected: return create_from_CTFontRef(std::move(ct), std::move(cg), true); } - /** Creates a dictionary suitable for setting the axes on a CGFont. */ static UniqueCFRef<CFDictionaryRef> copy_axes(CGFontRef cg, SkFontData* fontData) { UniqueCFRef<CFArrayRef> cgAxes(CGFontCopyVariationAxes(cg)); if (!cgAxes) { @@ -2559,9 +2456,6 @@ protected: return std::move(dict); } SkTypeface* onCreateFromFontData(std::unique_ptr<SkFontData> fontData) const override { - if (fontData->getIndex() != 0) { - return nullptr; - } UniqueCFRef<CGDataProviderRef> provider( SkCreateDataProviderFromStream(fontData->detachStream())); if (!provider) { @@ -2596,7 +2490,7 @@ protected: if (!pr) { return nullptr; } - return create_from_dataProvider(std::move(pr), ttcIndex); + return create_from_dataProvider(std::move(pr)); } SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override { diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index fbcd01a0ff..e6e07159c4 100644 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -262,19 +262,15 @@ protected: SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( PerGlyphInfo, const uint32_t*, uint32_t) const override; void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; - int onCharsToGlyphs(const void* chars, Encoding encoding, - uint16_t glyphs[], int glyphCount) const override; + virtual int onCharsToGlyphs(const void* chars, Encoding encoding, + uint16_t glyphs[], int glyphCount) const override; int onCountGlyphs() const override; int onGetUPEM() const override; void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const override - { - return -1; - } int onGetTableTags(SkFontTableTag tags[]) const override; - size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; + virtual size_t onGetTableData(SkFontTableTag, size_t offset, + size_t length, void* data) const override; }; class FontMemResourceTypeface : public LogFontTypeface { @@ -2459,20 +2455,17 @@ protected: SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) const override { std::unique_ptr<SkStreamAsset> stream(bareStream); - if (ttcIndex != 0) { - return nullptr; - } return create_from_stream(stream.get()); } SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { // could be in base impl - return this->createFromStream(new SkMemoryStream(sk_ref_sp(data)), ttcIndex); + return this->createFromStream(new SkMemoryStream(sk_ref_sp(data))); } SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override { // could be in base impl - return this->createFromStream(SkStream::MakeFromFile(path).release(), ttcIndex); + return this->createFromStream(SkStream::MakeFromFile(path).release()); } SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override { diff --git a/src/ports/SkFontMgr_FontConfigInterface.cpp b/src/ports/SkFontMgr_FontConfigInterface.cpp index 6264710008..81c4868e5d 100644 --- a/src/ports/SkFontMgr_FontConfigInterface.cpp +++ b/src/ports/SkFontMgr_FontConfigInterface.cpp @@ -222,7 +222,7 @@ protected: return SkTypeface_FCI::Create(std::move(fontData), std::move(name), style, isFixedPitch); } - SkTypeface* onCreateFromStream(SkStreamAsset* s, const SkFontArguments& args) const override { + SkTypeface* onCreateFromStream(SkStreamAsset* s, const FontParameters& params) const override { using Scanner = SkTypeface_FreeType::Scanner; std::unique_ptr<SkStreamAsset> stream(s); const size_t length = stream->getLength(); @@ -237,18 +237,19 @@ protected: SkFontStyle style; SkString name; Scanner::AxisDefinitions axisDefinitions; - if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), + if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(), &name, &style, &isFixedPitch, &axisDefinitions)) { return nullptr; } + int paramAxisCount; + const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); - Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), - axisValues, name); + Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name); auto fontData = skstd::make_unique<SkFontData>(std::move(stream), - args.getCollectionIndex(), + params.getCollectionIndex(), axisValues.get(), axisDefinitions.count()); return SkTypeface_FCI::Create(std::move(fontData), std::move(name), style, isFixedPitch); diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp index a180215e88..d4d7967dc5 100644 --- a/src/ports/SkFontMgr_android.cpp +++ b/src/ports/SkFontMgr_android.cpp @@ -201,11 +201,8 @@ public: } SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); - SkFontArguments::VariationPosition position = { - fontFile.fVariationDesignPosition.begin(), - fontFile.fVariationDesignPosition.count() - }; - Scanner::computeAxisValues(axisDefinitions, position, + Scanner::computeAxisValues(axisDefinitions, + fontFile.fAxes.begin(), fontFile.fAxes.count(), axisValues, familyName); fStyles.push_back().reset(new SkTypeface_AndroidSystem( @@ -431,24 +428,25 @@ protected: return new SkTypeface_AndroidStream(std::move(data), style, isFixedPitch, name); } - SkTypeface* onCreateFromStream(SkStreamAsset* s, const SkFontArguments& args) const override { + 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(), args.getCollectionIndex(), + if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(), &name, &style, &isFixedPitch, &axisDefinitions)) { return nullptr; } + int paramAxisCount; + const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); - Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), - axisValues, name); + Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name); - auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), + auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(), axisValues.get(), axisDefinitions.count()); return new SkTypeface_AndroidStream(std::move(data), style, isFixedPitch, name); } diff --git a/src/ports/SkFontMgr_android_parser.cpp b/src/ports/SkFontMgr_android_parser.cpp index e50a73946a..e5fdcd0dbf 100644 --- a/src/ports/SkFontMgr_android_parser.cpp +++ b/src/ports/SkFontMgr_android_parser.cpp @@ -167,8 +167,8 @@ static const TagHandler axisHandler = { if (valueLen == 4) { axisTag = SkSetFourByteTag(value[0], value[1], value[2], value[3]); axisTagIsValid = true; - for (int j = 0; j < file.fVariationDesignPosition.count() - 1; ++j) { - if (file.fVariationDesignPosition[j].axis == axisTag) { + for (int j = 0; j < file.fAxes.count() - 1; ++j) { + if (file.fAxes[j].fTag == axisTag) { axisTagIsValid = false; SK_FONTCONFIGPARSER_WARNING("'%c%c%c%c' axis specified more than once", (axisTag >> 24) & 0xFF, @@ -189,9 +189,9 @@ static const TagHandler axisHandler = { } } if (axisTagIsValid && axisStyleValueIsValid) { - auto& coordinate = file.fVariationDesignPosition.push_back(); - coordinate.axis = axisTag; - coordinate.value = SkFixedToScalar(axisStyleValue); + SkFontMgr::FontParameters::Axis& axis = file.fAxes.push_back(); + axis.fTag = axisTag; + axis.fStyleValue = SkFixedToScalar(axisStyleValue); } }, /*end*/nullptr, diff --git a/src/ports/SkFontMgr_android_parser.h b/src/ports/SkFontMgr_android_parser.h index 75b31c300e..efd8144f14 100644 --- a/src/ports/SkFontMgr_android_parser.h +++ b/src/ports/SkFontMgr_android_parser.h @@ -73,7 +73,7 @@ struct FontFileInfo { int fIndex; int fWeight; enum class Style { kAuto, kNormal, kItalic } fStyle; - SkTArray<SkFontArguments::VariationPosition::Coordinate, true> fVariationDesignPosition; + SkTArray<SkFontMgr::FontParameters::Axis, true> fAxes; }; /** diff --git a/src/ports/SkFontMgr_custom.cpp b/src/ports/SkFontMgr_custom.cpp index 91a590827c..4e4887d27d 100644 --- a/src/ports/SkFontMgr_custom.cpp +++ b/src/ports/SkFontMgr_custom.cpp @@ -5,7 +5,6 @@ * found in the LICENSE file. */ -#include "SkFontArguments.h" #include "SkFontDescriptor.h" #include "SkFontHost_FreeType_common.h" #include "SkFontMgr.h" @@ -201,7 +200,7 @@ SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* bareStream, int } SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s, - const SkFontArguments& args) const + const FontParameters& params) const { using Scanner = SkTypeface_FreeType::Scanner; std::unique_ptr<SkStreamAsset> stream(s); @@ -209,18 +208,19 @@ SkTypeface* SkFontMgr_Custom::onCreateFromStream(SkStreamAsset* s, SkFontStyle style; SkString name; Scanner::AxisDefinitions axisDefinitions; - if (!fScanner.scanFont(stream.get(), args.getCollectionIndex(), + if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(), &name, &style, &isFixedPitch, &axisDefinitions)) { return nullptr; } - const SkFontArguments::VariationPosition position = args.getVariationDesignPosition(); + int paramAxisCount; + const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); - Scanner::computeAxisValues(axisDefinitions, position, axisValues, name); + Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name); - auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), - axisValues.get(), axisDefinitions.count()); + 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); } diff --git a/src/ports/SkFontMgr_custom.h b/src/ports/SkFontMgr_custom.h index f8d083c049..9149378a50 100644 --- a/src/ports/SkFontMgr_custom.h +++ b/src/ports/SkFontMgr_custom.h @@ -144,7 +144,7 @@ protected: 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 SkFontArguments& args) 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; diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp index 85230b394e..63d720b390 100644 --- a/src/ports/SkFontMgr_fontconfig.cpp +++ b/src/ports/SkFontMgr_fontconfig.cpp @@ -899,24 +899,25 @@ protected: return new SkTypeface_stream(std::move(data), std::move(name), style, isFixedWidth); } - SkTypeface* onCreateFromStream(SkStreamAsset* s, const SkFontArguments& args) const override { + 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(), args.getCollectionIndex(), + if (!fScanner.scanFont(stream.get(), params.getCollectionIndex(), &name, &style, &isFixedPitch, &axisDefinitions)) { return nullptr; } + int paramAxisCount; + const FontParameters::Axis* paramAxes = params.getAxes(¶mAxisCount); SkAutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.count()); - Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), - axisValues, name); + Scanner::computeAxisValues(axisDefinitions, paramAxes, paramAxisCount, axisValues, name); - auto data = skstd::make_unique<SkFontData>(std::move(stream), args.getCollectionIndex(), + auto data = skstd::make_unique<SkFontData>(std::move(stream), params.getCollectionIndex(), axisValues.get(), axisDefinitions.count()); return new SkTypeface_stream(std::move(data), std::move(name), style, isFixedPitch); } diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h index ffc49f3d86..1119841e00 100644 --- a/src/ports/SkTypeface_win_dw.h +++ b/src/ports/SkTypeface_win_dw.h @@ -104,19 +104,15 @@ protected: SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( PerGlyphInfo, const uint32_t*, uint32_t) const override; void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; - int onCharsToGlyphs(const void* chars, Encoding encoding, - uint16_t glyphs[], int glyphCount) const override; + virtual int onCharsToGlyphs(const void* chars, Encoding encoding, + uint16_t glyphs[], int glyphCount) const override; int onCountGlyphs() const override; int onGetUPEM() const override; void onGetFamilyName(SkString* familyName) const override; SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) const override - { - return -1; - } int onGetTableTags(SkFontTableTag tags[]) const override; - size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; + virtual size_t onGetTableData(SkFontTableTag, size_t offset, + size_t length, void* data) const override; private: typedef SkTypeface INHERITED; diff --git a/tests/FontMgrAndroidParserTest.cpp b/tests/FontMgrAndroidParserTest.cpp index cbcfb3be2a..92dbd951c0 100644 --- a/tests/FontMgrAndroidParserTest.cpp +++ b/tests/FontMgrAndroidParserTest.cpp @@ -90,13 +90,13 @@ void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies, const char* label) { for (int j = 0; j < fontFamilies[i]->fFonts.count(); ++j) { const FontFileInfo& ffi = fontFamilies[i]->fFonts[j]; SkDebugf(" file (%d) %s#%d", ffi.fWeight, ffi.fFileName.c_str(), ffi.fIndex); - for (const auto& coordinate : ffi.fVariationDesignPosition) { + for (const auto& axis : ffi.fAxes) { SkDebugf(" @'%c%c%c%c'=%f", - (coordinate.axis >> 24) & 0xFF, - (coordinate.axis >> 16) & 0xFF, - (coordinate.axis >> 8) & 0xFF, - (coordinate.axis ) & 0xFF, - coordinate.value); + (axis.fTag >> 24) & 0xFF, + (axis.fTag >> 16) & 0xFF, + (axis.fTag >> 8) & 0xFF, + (axis.fTag ) & 0xFF, + axis.fStyleValue); } SkDebugf("\n"); } diff --git a/tests/FontMgrTest.cpp b/tests/FontMgrTest.cpp index b6a0cc5a74..50e2d5a606 100644 --- a/tests/FontMgrTest.cpp +++ b/tests/FontMgrTest.cpp @@ -150,12 +150,6 @@ static void test_matchStyleCSS3(skiatest::Reporter* reporter) { SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override { return new EmptyLocalizedStrings; } - int onGetVariationDesignPosition( - SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) 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; diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp index 4786cc278c..2a3b32d2cf 100644 --- a/tests/TypefaceTest.cpp +++ b/tests/TypefaceTest.cpp @@ -6,9 +6,6 @@ */ #include "SkData.h" -#include "SkFixed.h" -#include "SkFontMgr.h" -#include "SkMakeUnique.h" #include "SkOTTable_OS_2.h" #include "SkSFNTHeader.h" #include "SkStream.h" @@ -90,77 +87,6 @@ DEF_TEST(TypefaceStyle, reporter) { } } -DEF_TEST(TypefaceAxes, reporter) { - std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("/fonts/Distortable.ttf")); - if (!distortable) { - REPORT_FAILURE(reporter, "distortable", SkString()); - return; - } - - sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault(); - const SkFontArguments::VariationPosition::Coordinate position[] = { - { SkSetFourByteTag('w','g','h','t'), SK_ScalarSqrt2 } - }; - SkFontArguments params; - params.setVariationDesignPosition({position, SK_ARRAY_COUNT(position)}); - // TODO: if axes are set and the back-end doesn't support them, should we create the typeface? - sk_sp<SkTypeface> typeface(fm->createFromStream(distortable.release(), params)); - - int count = typeface->getVariationDesignPosition(nullptr, 0); - if (count == -1) { - return; - } - REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(position)); - - SkFontArguments::VariationPosition::Coordinate positionRead[SK_ARRAY_COUNT(position)]; - count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead)); - REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(position)); - - REPORTER_ASSERT(reporter, positionRead[0].axis == position[0].axis); - - // Convert to fixed for "almost equal". - SkFixed fixedRead = SkScalarToFixed(positionRead[0].value); - SkFixed fixedOriginal = SkScalarToFixed(position[0].value); - REPORTER_ASSERT(reporter, fixedRead == fixedOriginal); -} - -DEF_TEST(TypefaceVariationIndex, reporter) { - std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("/fonts/Distortable.ttf")); - if (!distortable) { - REPORT_FAILURE(reporter, "distortable", SkString()); - return; - } - - sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault(); - SkFontArguments params; - // The first named variation position in Distortable is 'Thin'. - params.setCollectionIndex(0x00010000); - sk_sp<SkTypeface> typeface(fm->createFromStream(distortable.release(), params)); - if (!typeface) { - // FreeType is the only weird thing that supports this, Skia just needs to make sure if it - // gets one of these things make sense. - return; - } - - int count = typeface->getVariationDesignPosition(nullptr, 0); - if (!(count == 1)) { - REPORT_FAILURE(reporter, "count == 1", SkString()); - return; - } - - SkFontArguments::VariationPosition::Coordinate positionRead[1]; - count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead)); - if (count == -1) { - return; - } - if (!(count == 1)) { - REPORT_FAILURE(reporter, "count == 1", SkString()); - return; - } - REPORTER_ASSERT(reporter, positionRead[0].axis == SkSetFourByteTag('w','g','h','t')); - REPORTER_ASSERT(reporter, positionRead[0].value == 0.5); -} - DEF_TEST(Typeface, reporter) { sk_sp<SkTypeface> t1(SkTypeface::MakeFromName(nullptr, SkFontStyle())); @@ -208,11 +134,6 @@ protected: SK_ABORT("unimplemented"); return nullptr; } - int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], - int coordinateCount) 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; } }; diff --git a/third_party/freetype2/BUILD.gn b/third_party/freetype2/BUILD.gn index d543dac347..89b64e4ed9 100644 --- a/third_party/freetype2/BUILD.gn +++ b/third_party/freetype2/BUILD.gn @@ -17,7 +17,6 @@ if (skia_use_system_freetype2) { } } else { third_party("freetype2") { - public_defines = [ "SK_FREETYPE_MINIMUM_RUNTIME_VERSION=(((FREETYPE_MAJOR) << 24) | ((FREETYPE_MINOR) << 16) | ((FREETYPE_PATCH) << 8))" ] public_include_dirs = [ "../externals/freetype/include" ] deps = [ |