• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006-2012 The Android Open Source Project
3  * Copyright 2012 Mozilla Foundation
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #ifndef SKFONTHOST_FREETYPE_COMMON_H_
10 #define SKFONTHOST_FREETYPE_COMMON_H_
11 
12 #include "include/core/SkTypeface.h"
13 #include "include/core/SkTypes.h"
14 #include "src/core/SkGlyph.h"
15 #include "src/core/SkScalerContext.h"
16 #include "src/core/SkSharedMutex.h"
17 #include "src/utils/SkCharToGlyphCache.h"
18 
19 #include "include/core/SkFontMgr.h"
20 
21 // These are forward declared to avoid pimpl but also hide the FreeType implementation.
22 typedef struct FT_LibraryRec_* FT_Library;
23 typedef struct FT_FaceRec_* FT_Face;
24 typedef struct FT_StreamRec_* FT_Stream;
25 typedef signed long FT_Pos;
26 typedef struct FT_BBox_ FT_BBox;
27 
28 
29 #ifdef SK_DEBUG
30 const char* SkTraceFtrGetError(int);
31 #define SK_TRACEFTR(ERR, MSG, ...) \
32     SkDebugf("%s:%d:1: error: 0x%x '%s' " MSG "\n", __FILE__, __LINE__, ERR, \
33             SkTraceFtrGetError((int)(ERR)), __VA_ARGS__)
34 #else
35 #define SK_TRACEFTR(ERR, ...) do { sk_ignore_unused_variable(ERR); } while (false)
36 #endif
37 
38 
39 class SkScalerContext_FreeType_Base : public SkScalerContext {
40 protected:
41     // See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
42     // This value was chosen by eyeballing the result in Firefox and trying to match it.
43     static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
44 
SkScalerContext_FreeType_Base(sk_sp<SkTypeface> typeface,const SkScalerContextEffects & effects,const SkDescriptor * desc)45     SkScalerContext_FreeType_Base(sk_sp<SkTypeface> typeface, const SkScalerContextEffects& effects,
46                                   const SkDescriptor *desc)
47         : INHERITED(std::move(typeface), effects, desc)
48     {}
49 
50     bool drawColorGlyph(SkCanvas*, FT_Face, SkSpan<SkColor> palette, const SkGlyph&);
51     void generateGlyphImage(FT_Face face,
52                             SkSpan<SkColor> palette,
53                             const SkGlyph& glyph,
54                             const SkMatrix& bitmapTransform);
55     bool generateGlyphPath(FT_Face face, SkPath* path);
56     bool generateFacePath(FT_Face face, SkGlyphID glyphID, SkPath* path);
57     sk_sp<SkDrawable> generateGlyphDrawable(FT_Face face, SkSpan<SkColor> palette, const SkGlyph&);
58 
59     // Computes a bounding box for a COLRv1 glyph id in FT_BBox 26.6 format and FreeType's y-up
60     // coordinate space.
61     // Needed to call into COLRv1 from generateMetrics().
62     //
63     // Note : This method may change the configured size and transforms on FT_Face. Make sure to
64     // configure size, matrix and load glyphs as needed after using this function to restore the
65     // state of FT_Face.
66     bool computeColrV1GlyphBoundingBox(FT_Face face, SkGlyphID glyphID, FT_BBox* boundingBox);
67 
68 private:
69     using INHERITED = SkScalerContext;
70 };
71 
72 class SkTypeface_FreeType : public SkTypeface {
73 public:
74     /** For SkFontMgrs to make use of our ability to extract
75      *  name and style from a stream, using FreeType's API.
76      */
77     class Scanner : ::SkNoncopyable {
78     public:
79         Scanner();
80         ~Scanner();
81         struct AxisDefinition {
82             SkFourByteTag fTag;
83             SkFixed fMinimum;
84             SkFixed fDefault;
85             SkFixed fMaximum;
86         };
87         using AxisDefinitions = SkSTArray<4, AxisDefinition, true>;
88         bool recognizedFont(SkStreamAsset* stream, int* numFonts) const;
89         bool scanFont(SkStreamAsset* stream, int ttcIndex,
90                       SkString* name, SkFontStyle* style, bool* isFixedPitch,
91                       AxisDefinitions* axes) const;
92         static void computeAxisValues(
93             AxisDefinitions axisDefinitions,
94             const SkFontArguments::VariationPosition position,
95             SkFixed* axisValues,
96             const SkString& name,
97             const SkFontArguments::VariationPosition::Coordinate* currentPosition = nullptr);
98         static bool GetAxes(FT_Face face, AxisDefinitions* axes);
99     private:
100         FT_Face openFace(SkStreamAsset* stream, int ttcIndex, FT_Stream ftStream) const;
101         FT_Library fLibrary;
102         mutable SkMutex fLibraryMutex;
103     };
104 
105     /** Fetch units/EM from "head" table if needed (ie for bitmap fonts) */
106     static int GetUnitsPerEm(FT_Face face);
107 
108     /** Return the font data, or nullptr on failure. */
109     std::unique_ptr<SkFontData> makeFontData() const;
110     class FaceRec;
111     FaceRec* getFaceRec() const;
112 
113 protected:
114     SkTypeface_FreeType(const SkFontStyle& style, bool isFixedPitch);
115     ~SkTypeface_FreeType() override;
116 
117     std::unique_ptr<SkFontData> cloneFontData(const SkFontArguments&) const;
118     std::unique_ptr<SkScalerContext> onCreateScalerContext(const SkScalerContextEffects&,
119                                                            const SkDescriptor*) const override;
120     void onFilterRec(SkScalerContextRec*) const override;
121     void getGlyphToUnicodeMap(SkUnichar*) const override;
122     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
123     void getPostScriptGlyphNames(SkString* dstArray) const override;
124     bool onGetPostScriptName(SkString*) const override;
125     int onGetUPEM() const override;
126     bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
127                                      int32_t adjustments[]) const override;
128     void onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const override;
129     int onCountGlyphs() const override;
130 
131     LocalizedStrings* onCreateFamilyNameIterator() const override;
132 
133     bool onGlyphMaskNeedsCurrentColor() const override;
134     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
135                                      int coordinateCount) const override;
136     int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
137                                        int parameterCount) const override;
138     int onGetTableTags(SkFontTableTag tags[]) const override;
139     size_t onGetTableData(SkFontTableTag, size_t offset,
140                           size_t length, void* data) const override;
141     sk_sp<SkData> onCopyTableData(SkFontTableTag) const override;
142 
143     virtual std::unique_ptr<SkFontData> onMakeFontData() const = 0;
144     /** Utility to fill out the SkFontDescriptor palette information from the SkFontData. */
145     static void FontDataPaletteToDescriptorPalette(const SkFontData&, SkFontDescriptor*);
146 
147 private:
148     mutable SkOnce fFTFaceOnce;
149     mutable std::unique_ptr<FaceRec> fFaceRec;
150 
151     mutable SkSharedMutex fC2GCacheMutex;
152     mutable SkCharToGlyphCache fC2GCache;
153 
154     mutable SkOnce fGlyphMasksMayNeedCurrentColorOnce;
155     mutable bool fGlyphMasksMayNeedCurrentColor;
156 
157     using INHERITED = SkTypeface;
158 };
159 
160 #endif // SKFONTHOST_FREETYPE_COMMON_H_
161