• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkBBHFactory.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkData.h"
12 #include "include/core/SkDrawable.h"
13 #include "include/core/SkFontMetrics.h"
14 #include "include/core/SkGraphics.h"
15 #include "include/core/SkPath.h"
16 #include "include/core/SkPictureRecorder.h"
17 #include "include/core/SkScalar.h"
18 #include "include/core/SkStream.h"
19 #include "include/core/SkString.h"
20 #include "include/private/base/SkMalloc.h"
21 #include "include/private/base/SkMutex.h"
22 #include "include/private/base/SkTPin.h"
23 #include "include/private/base/SkTemplates.h"
24 #include "include/private/base/SkTo.h"
25 #include "src/base/SkTSearch.h"
26 #include "src/core/SkAdvancedTypefaceMetrics.h"
27 #include "src/core/SkColorData.h"
28 #include "src/core/SkDescriptor.h"
29 #include "src/core/SkFDot6.h"
30 #include "src/core/SkFontDescriptor.h"
31 #include "src/core/SkGlyph.h"
32 #include "src/core/SkMask.h"
33 #include "src/core/SkMaskGamma.h"
34 #include "src/core/SkScalerContext.h"
35 #include "src/ports/SkFontHost_FreeType_common.h"
36 #include "src/ports/SkFontScanner_FreeType_priv.h"
37 #include "src/ports/SkTypeface_FreeType.h"
38 #include "src/sfnt/SkOTUtils.h"
39 #include "src/sfnt/SkSFNTHeader.h"
40 #include "src/sfnt/SkTTCFHeader.h"
41 #include "src/utils/SkCallableTraits.h"
42 #include "src/utils/SkMatrix22.h"
43 
44 #include <memory>
45 #include <optional>
46 #include <tuple>
47 
48 #include <ft2build.h>
49 #include <freetype/ftadvanc.h>
50 #include <freetype/ftimage.h>
51 #include <freetype/ftbitmap.h>
52 #ifdef FT_COLOR_H  // 2.10.0
53 #   include <freetype/ftcolor.h>
54 #endif
55 #include <freetype/freetype.h>
56 #include <freetype/ftlcdfil.h>
57 #include <freetype/ftmodapi.h>
58 #include <freetype/ftmm.h>
59 #include <freetype/ftoutln.h>
60 #include <freetype/ftsizes.h>
61 #include <freetype/ftsystem.h>
62 #include <freetype/tttables.h>
63 #include <freetype/t1tables.h>
64 #include <freetype/ftfntfmt.h>
65 
66 using namespace skia_private;
67 
68 namespace {
69 [[maybe_unused]] static inline const constexpr bool kSkShowTextBlitCoverage = false;
70 
71 using SkUniqueFTFace = std::unique_ptr<FT_FaceRec, SkFunctionObject<FT_Done_Face>>;
72 using SkUniqueFTSize = std::unique_ptr<FT_SizeRec, SkFunctionObject<FT_Done_Size>>;
73 }
74 
75 // SK_FREETYPE_MINIMUM_RUNTIME_VERSION 0x<major><minor><patch><flags>
76 // Flag SK_FREETYPE_DLOPEN: also try dlopen to get newer features.
77 #define SK_FREETYPE_DLOPEN (0x1)
78 #ifndef SK_FREETYPE_MINIMUM_RUNTIME_VERSION
79 #  if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || \
80       defined(SK_BUILD_FOR_GOOGLE3) ||           \
81       defined(SK_FREETYPE_MINIMUM_RUNTIME_VERSION_IS_BUILD_VERSION)
82 #    define SK_FREETYPE_MINIMUM_RUNTIME_VERSION (((FREETYPE_MAJOR) << 24) | ((FREETYPE_MINOR) << 16) | ((FREETYPE_PATCH) << 8))
83 #  else
84 #    define SK_FREETYPE_MINIMUM_RUNTIME_VERSION ((2 << 24) | (8 << 16) | (1 << 8) | (SK_FREETYPE_DLOPEN))
85 #  endif
86 #endif
87 #if SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN
88 #  include <dlfcn.h>
89 #endif
90 
91 #ifdef TT_SUPPORT_COLRV1
92 // FT_ClipBox and FT_Get_Color_Glyph_ClipBox introduced VER-2-11-0-18-g47cf8ebf4
93 // FT_COLR_COMPOSITE_PLUS and renumbering introduced VER-2-11-0-21-ge40ae7569
94 // FT_SIZEOF_LONG_LONG introduced VER-2-11-0-31-gffdac8d67
95 // FT_PaintRadialGradient changed size and layout at VER-2-11-0-147-gd3d3ff76d
96 // FT_STATIC_CAST introduced VER-2-11-0-172-g9079c5d91
97 // So undefine TT_SUPPORT_COLRV1 before 2.11.1 but not if FT_STATIC_CAST is defined.
98 #if (((FREETYPE_MAJOR)  < 2) || \
99      ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR)  < 11) || \
100      ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) == 11 && (FREETYPE_PATCH) < 1)) && \
101     !defined(FT_STATIC_CAST)
102 #    undef TT_SUPPORT_COLRV1
103 #endif
104 #endif
105 
106 //#define ENABLE_GLYPH_SPEW     // for tracing calls
107 //#define DUMP_STRIKE_CREATION
108 //#define SK_FONTHOST_FREETYPE_RUNTIME_VERSION
109 //#define SK_GAMMA_APPLY_TO_A8
110 
111 #if 1
112     #define LOG_INFO(...)
113 #else
114     #define LOG_INFO SkDEBUGF
115 #endif
116 
isLCD(const SkScalerContextRec & rec)117 static bool isLCD(const SkScalerContextRec& rec) {
118     return SkMask::kLCD16_Format == rec.fMaskFormat;
119 }
120 
SkFT_FixedToScalar(FT_Fixed x)121 static SkScalar SkFT_FixedToScalar(FT_Fixed x) {
122   return SkFixedToScalar(x);
123 }
124 
GetAxes(FT_Face face,SkFontScanner::AxisDefinitions * axes)125 static bool GetAxes(FT_Face face, SkFontScanner::AxisDefinitions* axes) {
126     SkASSERT(face && axes);
127     if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
128         FT_MM_Var* variations = nullptr;
129         FT_Error err = FT_Get_MM_Var(face, &variations);
130         if (err) {
131             LOG_INFO("INFO: font %s claims to have variations, but none found.\n",
132                      face->family_name);
133             return false;
134         }
135         UniqueVoidPtr autoFreeVariations(variations);
136 
137         axes->reset(variations->num_axis);
138         for (FT_UInt i = 0; i < variations->num_axis; ++i) {
139             const FT_Var_Axis& ftAxis = variations->axis[i];
140             (*axes)[i].tag = ftAxis.tag;
141             (*axes)[i].min = SkFT_FixedToScalar(ftAxis.minimum);
142             (*axes)[i].def = SkFT_FixedToScalar(ftAxis.def);
143             (*axes)[i].max = SkFT_FixedToScalar(ftAxis.maximum);
144         }
145     }
146     return true;
147 }
148 
149 //////////////////////////////////////////////////////////////////////////
150 
151 using FT_Alloc_size_t = SkCallableTraits<FT_Alloc_Func>::argument<1>::type;
152 static_assert(std::is_same<FT_Alloc_size_t, long  >::value ||
153               std::is_same<FT_Alloc_size_t, size_t>::value,"");
154 
155 extern "C" {
sk_ft_alloc(FT_Memory,FT_Alloc_size_t size)156     static void* sk_ft_alloc(FT_Memory, FT_Alloc_size_t size) {
157         return sk_malloc_canfail(size);
158     }
sk_ft_free(FT_Memory,void * block)159     static void sk_ft_free(FT_Memory, void* block) {
160         sk_free(block);
161     }
sk_ft_realloc(FT_Memory,FT_Alloc_size_t cur_size,FT_Alloc_size_t new_size,void * block)162     static void* sk_ft_realloc(FT_Memory, FT_Alloc_size_t cur_size,
163                                           FT_Alloc_size_t new_size, void* block) {
164         return sk_realloc_throw(block, new_size);
165     }
166 }
167 FT_MemoryRec_ gFTMemory = { nullptr, sk_ft_alloc, sk_ft_free, sk_ft_realloc };
168 
169 class FreeTypeLibrary : SkNoncopyable {
170 public:
FreeTypeLibrary()171     FreeTypeLibrary() : fLibrary(nullptr) {
172         if (FT_New_Library(&gFTMemory, &fLibrary)) {
173             return;
174         }
175         FT_Add_Default_Modules(fLibrary);
176         FT_Set_Default_Properties(fLibrary);
177 
178         // Subpixel anti-aliasing may be unfiltered until the LCD filter is set.
179         // Newer versions may still need this, so this test with side effects must come first.
180         // The default has changed over time, so this doesn't mean the same thing to all users.
181         FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT);
182     }
~FreeTypeLibrary()183     ~FreeTypeLibrary() {
184         if (fLibrary) {
185             FT_Done_Library(fLibrary);
186         }
187     }
188 
library()189     FT_Library library() { return fLibrary; }
190 
191 private:
192     FT_Library fLibrary;
193 
194     // FT_Library_SetLcdFilterWeights 2.4.0
195     // FT_LOAD_COLOR 2.5.0
196     // FT_Pixel_Mode::FT_PIXEL_MODE_BGRA 2.5.0
197     // Thread safety in 2.6.0
198     // freetype/ftfntfmt.h (rename) 2.6.0
199     // Direct header inclusion 2.6.1
200     // FT_Get_Var_Design_Coordinates 2.7.1
201     // FT_LOAD_BITMAP_METRICS_ONLY 2.7.1
202     // FT_Set_Default_Properties 2.7.2
203     // The 'light' hinting is vertical only from 2.8.0
204     // FT_Get_Var_Axis_Flags 2.8.1
205     // FT_VAR_AXIS_FLAG_HIDDEN was introduced in FreeType 2.8.1
206     // --------------------
207     // FT_Done_MM_Var 2.9.0 (Currenty setting ft_free to a known allocator.)
208     // freetype/ftcolor.h 2.10.0 (Currently assuming if compiled with FT_COLOR_H runtime available.)
209 
210     // Ubuntu 18.04       2.8.1
211     // Debian 10          2.9.1
212     // openSUSE Leap 15.2 2.10.1
213     // Fedora 32          2.10.4
214     // RHEL 8             2.9.1
215 };
216 
f_t_mutex()217 static SkMutex& f_t_mutex() {
218     static SkMutex& mutex = *(new SkMutex);
219     return mutex;
220 }
221 
222 static FreeTypeLibrary* gFTLibrary;
223 
224 ///////////////////////////////////////////////////////////////////////////
225 
226 class SkTypeface_FreeType::FaceRec {
227 public:
228     SkUniqueFTFace fFace;
229     FT_StreamRec fFTStream;
230     std::unique_ptr<SkStreamAsset> fSkStream;
231     FT_UShort fFTPaletteEntryCount = 0;
232     std::unique_ptr<SkColor[]> fSkPalette;
233 
234     static std::unique_ptr<FaceRec> Make(const SkTypeface_FreeType* typeface);
235     ~FaceRec();
236 
237 private:
238     FaceRec(std::unique_ptr<SkStreamAsset> stream);
239     void setupAxes(const SkFontData& data);
240     void setupPalette(const SkFontData& data);
241 
242     // Private to ref_ft_library and unref_ft_library
243     static int gFTCount;
244 
245     // Caller must lock f_t_mutex() before calling this function.
ref_ft_library()246     static bool ref_ft_library() {
247         f_t_mutex().assertHeld();
248         SkASSERT(gFTCount >= 0);
249 
250         if (0 == gFTCount) {
251             SkASSERT(nullptr == gFTLibrary);
252             gFTLibrary = new FreeTypeLibrary;
253         }
254         ++gFTCount;
255         return gFTLibrary->library();
256     }
257 
258     // Caller must lock f_t_mutex() before calling this function.
unref_ft_library()259     static void unref_ft_library() {
260         f_t_mutex().assertHeld();
261         SkASSERT(gFTCount > 0);
262 
263         --gFTCount;
264         if (0 == gFTCount) {
265             SkASSERT(nullptr != gFTLibrary);
266             delete gFTLibrary;
267             SkDEBUGCODE(gFTLibrary = nullptr;)
268         }
269     }
270 };
271 int SkTypeface_FreeType::FaceRec::gFTCount;
272 
273 extern "C" {
sk_ft_stream_io(FT_Stream ftStream,unsigned long offset,unsigned char * buffer,unsigned long count)274     static unsigned long sk_ft_stream_io(FT_Stream ftStream,
275                                          unsigned long offset,
276                                          unsigned char* buffer,
277                                          unsigned long count)
278     {
279         SkStreamAsset* stream = static_cast<SkStreamAsset*>(ftStream->descriptor.pointer);
280 
281         if (count) {
282             if (!stream->seek(offset)) {
283                 return 0;
284             }
285             count = stream->read(buffer, count);
286         }
287         return count;
288     }
289 
sk_ft_stream_close(FT_Stream)290     static void sk_ft_stream_close(FT_Stream) {}
291 }
292 
FaceRec(std::unique_ptr<SkStreamAsset> stream)293 SkTypeface_FreeType::FaceRec::FaceRec(std::unique_ptr<SkStreamAsset> stream)
294         : fSkStream(std::move(stream))
295 {
296     sk_bzero(&fFTStream, sizeof(fFTStream));
297     fFTStream.size = fSkStream->getLength();
298     fFTStream.descriptor.pointer = fSkStream.get();
299     fFTStream.read  = sk_ft_stream_io;
300     fFTStream.close = sk_ft_stream_close;
301 
302     f_t_mutex().assertHeld();
303     ref_ft_library();
304 }
305 
~FaceRec()306 SkTypeface_FreeType::FaceRec::~FaceRec() {
307     f_t_mutex().assertHeld();
308     fFace.reset(); // Must release face before the library, the library frees existing faces.
309     unref_ft_library();
310 }
311 
setupAxes(const SkFontData & data)312 void SkTypeface_FreeType::FaceRec::setupAxes(const SkFontData& data) {
313     if (!(fFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
314         return;
315     }
316 
317     SkDEBUGCODE(
318         FT_MM_Var* variations = nullptr;
319         if (FT_Get_MM_Var(fFace.get(), &variations)) {
320             LOG_INFO("INFO: font %s claims variations, but none found.\n",
321                      rec->fFace->family_name);
322             return;
323         }
324         UniqueVoidPtr autoFreeVariations(variations);
325 
326         if (static_cast<FT_UInt>(data.getAxisCount()) != variations->num_axis) {
327             LOG_INFO("INFO: font %s has %d variations, but %d were specified.\n",
328                      rec->fFace->family_name, variations->num_axis, data.getAxisCount());
329             return;
330         }
331     )
332 
333     AutoSTMalloc<4, FT_Fixed> coords(data.getAxisCount());
334     for (int i = 0; i < data.getAxisCount(); ++i) {
335         coords[i] = data.getAxis()[i];
336     }
337     if (FT_Set_Var_Design_Coordinates(fFace.get(), data.getAxisCount(), coords.get())) {
338         LOG_INFO("INFO: font %s has variations, but specified variations could not be set.\n",
339                  rec->fFace->family_name);
340         return;
341     }
342 }
343 
setupPalette(const SkFontData & data)344 void SkTypeface_FreeType::FaceRec::setupPalette(const SkFontData& data) {
345 #ifdef FT_COLOR_H
346     FT_Palette_Data paletteData;
347     if (FT_Palette_Data_Get(fFace.get(), &paletteData)) {
348         return;
349     }
350 
351     // Treat out of range values as 0. Still apply overrides.
352     // https://www.w3.org/TR/css-fonts-4/#base-palette-desc
353     FT_UShort basePaletteIndex = 0;
354     if (SkTFitsIn<FT_UShort>(data.getPaletteIndex()) &&
355         SkTo<FT_UShort>(data.getPaletteIndex()) < paletteData.num_palettes)
356     {
357         basePaletteIndex = data.getPaletteIndex();
358     }
359 
360     FT_Color* ftPalette = nullptr;
361     if (FT_Palette_Select(fFace.get(), basePaletteIndex, &ftPalette)) {
362         return;
363     }
364     fFTPaletteEntryCount = paletteData.num_palette_entries;
365 
366     for (int i = 0; i < data.getPaletteOverrideCount(); ++i) {
367         const SkFontArguments::Palette::Override& paletteOverride = data.getPaletteOverrides()[i];
368         if (paletteOverride.index < fFTPaletteEntryCount) {
369             const SkColor& skColor = paletteOverride.color;
370             FT_Color& ftColor = ftPalette[paletteOverride.index];
371             ftColor.blue  = SkColorGetB(skColor);
372             ftColor.green = SkColorGetG(skColor);
373             ftColor.red   = SkColorGetR(skColor);
374             ftColor.alpha = SkColorGetA(skColor);
375         }
376     }
377 
378     fSkPalette.reset(new SkColor[fFTPaletteEntryCount]);
379     for (int i = 0; i < fFTPaletteEntryCount; ++i) {
380         fSkPalette[i] = SkColorSetARGB(ftPalette[i].alpha,
381                                        ftPalette[i].red,
382                                        ftPalette[i].green,
383                                        ftPalette[i].blue);
384     }
385 #endif
386 }
387 
388 // Will return nullptr on failure
389 // Caller must lock f_t_mutex() before calling this function.
390 std::unique_ptr<SkTypeface_FreeType::FaceRec>
Make(const SkTypeface_FreeType * typeface)391 SkTypeface_FreeType::FaceRec::Make(const SkTypeface_FreeType* typeface) {
392     f_t_mutex().assertHeld();
393 
394     std::unique_ptr<SkFontData> data = typeface->makeFontData();
395     if (nullptr == data || !data->hasStream()) {
396         return nullptr;
397     }
398 
399     std::unique_ptr<FaceRec> rec(new FaceRec(data->detachStream()));
400 
401     FT_Open_Args args;
402     memset(&args, 0, sizeof(args));
403     const void* memoryBase = rec->fSkStream->getMemoryBase();
404     if (memoryBase) {
405         args.flags = FT_OPEN_MEMORY;
406         args.memory_base = (const FT_Byte*)memoryBase;
407         args.memory_size = rec->fSkStream->getLength();
408     } else {
409         args.flags = FT_OPEN_STREAM;
410         args.stream = &rec->fFTStream;
411     }
412 
413     {
414         FT_Face rawFace;
415         FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(), &rawFace);
416         if (err) {
417             SK_TRACEFTR(err, "unable to open font '%x'", (uint32_t)typeface->uniqueID());
418             return nullptr;
419         }
420         rec->fFace.reset(rawFace);
421     }
422     SkASSERT(rec->fFace);
423 
424     rec->setupAxes(*data);
425     rec->setupPalette(*data);
426 
427     // FreeType will set the charmap to the "most unicode" cmap if it exists.
428     // If there are no unicode cmaps, the charmap is set to nullptr.
429     // However, "symbol" cmaps should also be considered "fallback unicode" cmaps
430     // because they are effectively private use area only (even if they aren't).
431     // This is the last on the fallback list at
432     // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
433     if (!rec->fFace->charmap) {
434         FT_Select_Charmap(rec->fFace.get(), FT_ENCODING_MS_SYMBOL);
435     }
436 
437     return rec;
438 }
439 
440 class AutoFTAccess {
441 public:
AutoFTAccess(const SkTypeface_FreeType * tf)442     AutoFTAccess(const SkTypeface_FreeType* tf) : fFaceRec(nullptr) {
443         f_t_mutex().acquire();
444         fFaceRec = tf->getFaceRec();
445     }
446 
~AutoFTAccess()447     ~AutoFTAccess() {
448         f_t_mutex().release();
449     }
450 
face()451     FT_Face face() { return fFaceRec ? fFaceRec->fFace.get() : nullptr; }
452 
453 private:
454     SkTypeface_FreeType::FaceRec* fFaceRec;
455 };
456 
457 ///////////////////////////////////////////////////////////////////////////
458 
459 class SkScalerContext_FreeType : public SkScalerContext {
460 public:
461     SkScalerContext_FreeType(const SkTypeface_FreeType& realTypeface,
462                              const SkScalerContextEffects&,
463                              const SkDescriptor* desc,
464                              SkTypeface& proxyTypeface);
465     ~SkScalerContext_FreeType() override;
466 
success() const467     bool success() const {
468         return fFTSize != nullptr && fFace != nullptr;
469     }
470 
471 protected:
472     GlyphMetrics generateMetrics(const SkGlyph&, SkArenaAlloc*) override;
473     void generateImage(const SkGlyph&, void*) override;
474     bool generatePath(const SkGlyph& glyph, SkPath* path, bool* modified) override;
475     sk_sp<SkDrawable> generateDrawable(const SkGlyph&) override;
476     void generateFontMetrics(SkFontMetrics*) override;
477 
478 private:
479     struct ScalerContextBits {
480         static const constexpr uint32_t COLRv0 = 1;
481         static const constexpr uint32_t COLRv1 = 2;
482         static const constexpr uint32_t SVG    = 3;
483     };
484 
485     // See http://freetype.sourceforge.net/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden
486     // This value was chosen by eyeballing the result in Firefox and trying to match it.
487     static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
488 
489     SkTypeface_FreeType::FaceRec* fFaceRec; // Borrowed face from the typeface's FaceRec.
490     FT_Face   fFace;  // Borrowed face from fFaceRec.
491     FT_Size   fFTSize;  // The size to apply to the fFace.
492     FT_Int    fStrikeIndex; // The bitmap strike for the fFace (or -1 if none).
493 
494     SkScalerContextFTUtils fUtils;
495 
496     /** The rest of the matrix after FreeType handles the size.
497      *  With outline font rasterization this is handled by FreeType with FT_Set_Transform.
498      *  With bitmap only fonts this matrix must be applied to scale the bitmap.
499      */
500     SkMatrix  fMatrix22Scalar;
501     /** Same as fMatrix22Scalar, but in FreeType units and space. */
502     FT_Matrix fMatrix22;
503     /** The actual size requested. */
504     SkVector  fScale;
505 
506     uint32_t  fLoadGlyphFlags;
507     bool      fDoLinearMetrics;
508     bool      fLCDIsVert;
509 
510     FT_Error setupSize();
511     // Caller must lock f_t_mutex() before calling this function.
512     static bool getBoundsOfCurrentOutlineGlyph(FT_GlyphSlot glyph, SkRect* bounds);
513     // Caller must lock f_t_mutex() before calling this function.
514     bool getCBoxForLetter(char letter, FT_BBox* bbox);
515     static void updateGlyphBoundsIfSubpixel(const SkGlyph&, SkRect* bounds, bool subpixel);
516     void updateGlyphBoundsIfLCD(GlyphMetrics* mx);
517     // Caller must lock f_t_mutex() before calling this function.
518     // update FreeType2 glyph slot with glyph emboldened
519     bool emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph, SkGlyphID gid);
520     bool shouldSubpixelBitmap(const SkGlyph&, const SkMatrix&);
521 };
522 
523 ///////////////////////////////////////////////////////////////////////////
524 
canEmbed(FT_Face face)525 static bool canEmbed(FT_Face face) {
526     FT_UShort fsType = FT_Get_FSType_Flags(face);
527     return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
528                       FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0;
529 }
530 
canSubset(FT_Face face)531 static bool canSubset(FT_Face face) {
532     FT_UShort fsType = FT_Get_FSType_Flags(face);
533     return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0;
534 }
535 
get_font_type(FT_Face face)536 static SkAdvancedTypefaceMetrics::FontType get_font_type(FT_Face face) {
537     const char* fontType = FT_Get_X11_Font_Format(face);
538     static struct { const char* s; SkAdvancedTypefaceMetrics::FontType t; } values[] = {
539         { "Type 1",     SkAdvancedTypefaceMetrics::kType1_Font    },
540         { "CID Type 1", SkAdvancedTypefaceMetrics::kType1CID_Font },
541         { "CFF",        SkAdvancedTypefaceMetrics::kCFF_Font      },
542         { "TrueType",   SkAdvancedTypefaceMetrics::kTrueType_Font },
543     };
544     for(const auto& v : values) { if (strcmp(fontType, v.s) == 0) { return v.t; } }
545     return SkAdvancedTypefaceMetrics::kOther_Font;
546 }
547 
is_opentype_font_data_standard_format(const SkTypeface & typeface)548 static bool is_opentype_font_data_standard_format(const SkTypeface& typeface) {
549     // FreeType reports TrueType for any data that can be decoded to TrueType or OpenType.
550     // However, there are alternate data formats for OpenType, like wOFF and wOF2.
551     std::unique_ptr<SkStreamAsset> stream = typeface.openStream(nullptr);
552     if (!stream) {
553         return false;
554     }
555     char buffer[4];
556     if (stream->read(buffer, 4) < 4) {
557         return false;
558     }
559 
560     SkFourByteTag tag = SkSetFourByteTag(buffer[0], buffer[1], buffer[2], buffer[3]);
561     SK_OT_ULONG otTag = SkEndian_SwapBE32(tag);
562     return otTag == SkSFNTHeader::fontType_WindowsTrueType::TAG ||
563            otTag == SkSFNTHeader::fontType_MacTrueType::TAG ||
564            otTag == SkSFNTHeader::fontType_PostScript::TAG ||
565            otTag == SkSFNTHeader::fontType_OpenTypeCFF::TAG ||
566            otTag == SkTTCFHeader::TAG;
567 }
568 
onGetAdvancedMetrics() const569 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_FreeType::onGetAdvancedMetrics() const {
570     AutoFTAccess fta(this);
571     FT_Face face = fta.face();
572     if (!face) {
573         return nullptr;
574     }
575 
576     std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics);
577     info->fPostScriptName.set(FT_Get_Postscript_Name(face));
578 
579     if (FT_HAS_MULTIPLE_MASTERS(face)) {
580         info->fFlags |= SkAdvancedTypefaceMetrics::kVariable_FontFlag;
581     }
582     if (!canEmbed(face)) {
583         info->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
584     }
585     if (!canSubset(face)) {
586         info->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag;
587     }
588 
589     info->fType = get_font_type(face);
590     if ((info->fType == SkAdvancedTypefaceMetrics::kTrueType_Font ||
591          info->fType == SkAdvancedTypefaceMetrics::kCFF_Font) &&
592         !is_opentype_font_data_standard_format(*this))
593     {
594         info->fFlags |= SkAdvancedTypefaceMetrics::kAltDataFormat_FontFlag;
595     }
596 
597     info->fStyle = (SkAdvancedTypefaceMetrics::StyleFlags)0;
598     if (FT_IS_FIXED_WIDTH(face)) {
599         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
600     }
601     if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
602         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
603     }
604 
605     PS_FontInfoRec psFontInfo;
606     TT_Postscript* postTable;
607     if (FT_Get_PS_Font_Info(face, &psFontInfo) == 0) {
608         info->fItalicAngle = psFontInfo.italic_angle;
609     } else if ((postTable = (TT_Postscript*)FT_Get_Sfnt_Table(face, ft_sfnt_post)) != nullptr) {
610         info->fItalicAngle = SkFixedFloorToInt(postTable->italicAngle);
611     } else {
612         info->fItalicAngle = 0;
613     }
614 
615     info->fAscent = face->ascender;
616     info->fDescent = face->descender;
617 
618     TT_PCLT* pcltTable;
619     TT_OS2* os2Table;
620     if ((pcltTable = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != nullptr) {
621         info->fCapHeight = pcltTable->CapHeight;
622         uint8_t serif_style = pcltTable->SerifStyle & 0x3F;
623         if (2 <= serif_style && serif_style <= 6) {
624             info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
625         } else if (9 <= serif_style && serif_style <= 12) {
626             info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
627         }
628     } else if (((os2Table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != nullptr) &&
629                // sCapHeight is available only when version 2 or later.
630                os2Table->version != 0xFFFF &&
631                os2Table->version >= 2)
632     {
633         info->fCapHeight = os2Table->sCapHeight;
634     }
635     info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
636                                     face->bbox.xMax, face->bbox.yMin);
637     return info;
638 }
639 
getGlyphToUnicodeMap(SkUnichar * dstArray) const640 void SkTypeface_FreeType::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
641     AutoFTAccess fta(this);
642     FT_Face face = fta.face();
643     if (!face) {
644         return;
645     }
646 
647     FT_Long numGlyphs = face->num_glyphs;
648     if (!dstArray) { SkASSERT(numGlyphs == 0); }
649     sk_bzero(dstArray, sizeof(SkUnichar) * numGlyphs);
650 
651     FT_UInt glyphIndex;
652     SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
653     while (glyphIndex) {
654         SkASSERT(glyphIndex < SkToUInt(numGlyphs));
655         // Use the first character that maps to this glyphID. https://crbug.com/359065
656         if (0 == dstArray[glyphIndex]) {
657             dstArray[glyphIndex] = charCode;
658         }
659         charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
660     }
661 }
662 
getPostScriptGlyphNames(SkString * dstArray) const663 void SkTypeface_FreeType::getPostScriptGlyphNames(SkString* dstArray) const {
664     AutoFTAccess fta(this);
665     FT_Face face = fta.face();
666     if (!face) {
667         return;
668     }
669 
670     FT_Long numGlyphs = face->num_glyphs;
671     if (!dstArray) { SkASSERT(numGlyphs == 0); }
672 
673     if (FT_HAS_GLYPH_NAMES(face)) {
674         for (int gID = 0; gID < numGlyphs; ++gID) {
675             char glyphName[128];  // PS limit for names is 127 bytes.
676             FT_Get_Glyph_Name(face, gID, glyphName, 128);
677             dstArray[gID] = glyphName;
678         }
679     }
680 }
681 
onGetPostScriptName(SkString * skPostScriptName) const682 bool SkTypeface_FreeType::onGetPostScriptName(SkString* skPostScriptName) const {
683     AutoFTAccess fta(this);
684     FT_Face face = fta.face();
685     if (!face) {
686         return false;
687     }
688 
689     const char* ftPostScriptName = FT_Get_Postscript_Name(face);
690     if (!ftPostScriptName) {
691         return false;
692     }
693     if (skPostScriptName) {
694         *skPostScriptName = ftPostScriptName;
695     }
696     return true;
697 }
698 
699 ///////////////////////////////////////////////////////////////////////////
700 
bothZero(SkScalar a,SkScalar b)701 static bool bothZero(SkScalar a, SkScalar b) {
702     return 0 == a && 0 == b;
703 }
704 
705 // returns false if there is any non-90-rotation or skew
isAxisAligned(const SkScalerContextRec & rec)706 static bool isAxisAligned(const SkScalerContextRec& rec) {
707     return 0 == rec.fPreSkewX &&
708            (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
709             bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
710 }
711 
onCreateScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const712 std::unique_ptr<SkScalerContext> SkTypeface_FreeType::onCreateScalerContext(
713     const SkScalerContextEffects& effects, const SkDescriptor* desc) const {
714     return this->onCreateScalerContextAsProxyTypeface(effects, desc, nullptr);
715 }
716 
onCreateScalerContextAsProxyTypeface(const SkScalerContextEffects & effects,const SkDescriptor * desc,SkTypeface * proxyTypeface) const717 std::unique_ptr<SkScalerContext> SkTypeface_FreeType::onCreateScalerContextAsProxyTypeface(
718         const SkScalerContextEffects& effects,
719         const SkDescriptor* desc,
720         SkTypeface* proxyTypeface) const {
721     std::unique_ptr<SkScalerContext_FreeType> scalerContext(new SkScalerContext_FreeType(
722             *this,
723             effects,
724             desc,
725             proxyTypeface ? *proxyTypeface : *const_cast<SkTypeface_FreeType*>(this)));
726     if (scalerContext->success()) {
727         return scalerContext;
728     }
729     return SkScalerContext::MakeEmpty(*const_cast<SkTypeface_FreeType*>(this), effects, desc);
730 }
731 
732 /** Copy the design variation coordinates into 'coordinates'.
733  *
734  *  @param coordinates the buffer into which to write the design variation coordinates.
735  *  @param coordinateCount the number of entries available through 'coordinates'.
736  *
737  *  @return The number of axes, or -1 if there is an error.
738  *  If 'coordinates != nullptr' and 'coordinateCount >= numAxes' then 'coordinates' will be
739  *  filled with the variation coordinates describing the position of this typeface in design
740  *  variation space. It is possible the number of axes can be retrieved but actual position
741  *  cannot.
742  */
GetVariationDesignPosition(FT_Face face,SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount)743 static int GetVariationDesignPosition(FT_Face face,
744     SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount)
745 {
746     if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
747         return 0;
748     }
749 
750     FT_MM_Var* variations = nullptr;
751     if (FT_Get_MM_Var(face, &variations)) {
752         return -1;
753     }
754     UniqueVoidPtr autoFreeVariations(variations);
755 
756     if (!coordinates || coordinateCount < SkToInt(variations->num_axis)) {
757         return variations->num_axis;
758     }
759 
760     AutoSTMalloc<4, FT_Fixed> coords(variations->num_axis);
761     if (FT_Get_Var_Design_Coordinates(face, variations->num_axis, coords.get())) {
762         return -1;
763     }
764     for (FT_UInt i = 0; i < variations->num_axis; ++i) {
765         coordinates[i].axis = variations->axis[i].tag;
766         coordinates[i].value = SkFixedToScalar(coords[i]);
767     }
768 
769     return variations->num_axis;
770 }
771 
cloneFontData(const SkFontArguments & args,SkFontStyle * style) const772 std::unique_ptr<SkFontData> SkTypeface_FreeType::cloneFontData(const SkFontArguments& args,
773                                                                SkFontStyle* style) const {
774     AutoFTAccess fta(this);
775     FT_Face face = fta.face();
776     if (!face) {
777         return nullptr;
778     }
779 
780     SkFontScanner::AxisDefinitions axisDefinitions;
781     if (!GetAxes(face, &axisDefinitions)) {
782         return nullptr;
783     }
784     int axisCount = axisDefinitions.size();
785 
786     AutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate> currentPosition(axisCount);
787     int currentAxisCount = GetVariationDesignPosition(face, currentPosition, axisCount);
788 
789     SkString name;
790     AutoSTMalloc<4, SkFixed> axisValues(axisCount);
791     SkFontScanner_FreeType::computeAxisValues(
792             axisDefinitions,
793             currentAxisCount == axisCount
794                 ? SkFontArguments::VariationPosition{currentPosition.data(), currentAxisCount}
795                 : SkFontArguments::VariationPosition{nullptr, 0},
796             args.getVariationDesignPosition(),
797             axisValues, name, style);
798 
799     int ttcIndex;
800     std::unique_ptr<SkStreamAsset> stream = this->openStream(&ttcIndex);
801 
802     return std::make_unique<SkFontData>(std::move(stream),
803                                         ttcIndex,
804                                         args.getPalette().index,
805                                         axisValues.get(),
806                                         axisCount,
807                                         args.getPalette().overrides,
808                                         args.getPalette().overrideCount);
809 }
810 
onFilterRec(SkScalerContextRec * rec) const811 void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
812 #if !defined(SK_USE_FREETYPE_EMBOLDEN)
813     rec->useStrokeForFakeBold();
814 #endif
815     //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119
816     //Cap the requested size as larger sizes give bogus values.
817     //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed.
818     //Note that this also currently only protects against large text size requests,
819     //the total matrix is not taken into account here.
820     if (rec->fTextSize > SkIntToScalar(1 << 14)) {
821         rec->fTextSize = SkIntToScalar(1 << 14);
822     }
823 
824     SkFontHinting h = rec->getHinting();
825     if (SkFontHinting::kFull == h && !isLCD(*rec)) {
826         // collapse full->normal hinting if we're not doing LCD
827         h = SkFontHinting::kNormal;
828     }
829 
830     // rotated text looks bad with hinting, so we disable it as needed
831     if (!isAxisAligned(*rec)) {
832         h = SkFontHinting::kNone;
833     }
834     rec->setHinting(h);
835 
836 #ifndef SK_GAMMA_APPLY_TO_A8
837     if (!isLCD(*rec)) {
838         // SRGBTODO: Is this correct? Do we want contrast boost?
839         rec->ignorePreBlend();
840     }
841 #endif
842 }
843 
GetUnitsPerEm(FT_Face face)844 int SkTypeface_FreeType::GetUnitsPerEm(FT_Face face) {
845     SkASSERT(face);
846 
847     SkScalar upem = SkIntToScalar(face->units_per_EM);
848     // At least some versions of FreeType set face->units_per_EM to 0 for bitmap only fonts.
849     if (upem == 0) {
850         TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
851         if (ttHeader) {
852             upem = SkIntToScalar(ttHeader->Units_Per_EM);
853         }
854     }
855     return upem;
856 }
857 
onGetUPEM() const858 int SkTypeface_FreeType::onGetUPEM() const {
859     AutoFTAccess fta(this);
860     FT_Face face = fta.face();
861     if (!face) {
862         return 0;
863     }
864     return GetUnitsPerEm(face);
865 }
866 
onGetKerningPairAdjustments(const SkGlyphID glyphs[],int count,int32_t adjustments[]) const867 bool SkTypeface_FreeType::onGetKerningPairAdjustments(const SkGlyphID glyphs[],
868                                       int count, int32_t adjustments[]) const {
869     AutoFTAccess fta(this);
870     FT_Face face = fta.face();
871     if (!face || !FT_HAS_KERNING(face)) {
872         return false;
873     }
874 
875     for (int i = 0; i < count - 1; ++i) {
876         FT_Vector delta;
877         FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1],
878                                       FT_KERNING_UNSCALED, &delta);
879         if (err) {
880             return false;
881         }
882         adjustments[i] = delta.x;
883     }
884     return true;
885 }
886 
887 /** Returns the bitmap strike equal to or just larger than the requested size. */
chooseBitmapStrike(FT_Face face,FT_F26Dot6 scaleY)888 static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) {
889     if (face == nullptr) {
890         LOG_INFO("chooseBitmapStrike aborted due to nullptr face.\n");
891         return -1;
892     }
893 
894     FT_Pos requestedPPEM = scaleY;  // FT_Bitmap_Size::y_ppem is in 26.6 format.
895     FT_Int chosenStrikeIndex = -1;
896     FT_Pos chosenPPEM = 0;
897     for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIndex) {
898         FT_Pos strikePPEM = face->available_sizes[strikeIndex].y_ppem;
899         if (strikePPEM == requestedPPEM) {
900             // exact match - our search stops here
901             return strikeIndex;
902         } else if (chosenPPEM < requestedPPEM) {
903             // attempt to increase chosenPPEM
904             if (chosenPPEM < strikePPEM) {
905                 chosenPPEM = strikePPEM;
906                 chosenStrikeIndex = strikeIndex;
907             }
908         } else {
909             // attempt to decrease chosenPPEM, but not below requestedPPEM
910             if (requestedPPEM < strikePPEM && strikePPEM < chosenPPEM) {
911                 chosenPPEM = strikePPEM;
912                 chosenStrikeIndex = strikeIndex;
913             }
914         }
915     }
916     return chosenStrikeIndex;
917 }
918 
SkScalerContext_FreeType(const SkTypeface_FreeType & realTypeface,const SkScalerContextEffects & effects,const SkDescriptor * desc,SkTypeface & proxyTypeface)919 SkScalerContext_FreeType::SkScalerContext_FreeType(const SkTypeface_FreeType& realTypeface,
920                                                    const SkScalerContextEffects& effects,
921                                                    const SkDescriptor* desc,
922                                                    SkTypeface& proxyTypeface)
923     : SkScalerContext(proxyTypeface, effects, desc)
924     , fFace(nullptr)
925     , fFTSize(nullptr)
926     , fStrikeIndex(-1)
927 {
928     SkAutoMutexExclusive  ac(f_t_mutex());
929     fFaceRec = realTypeface.getFaceRec();  // The proxyTypeface owns the realTypeface.
930 
931     // load the font file
932     if (nullptr == fFaceRec) {
933         LOG_INFO("Could not create FT_Face.\n");
934         return;
935     }
936 
937     fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
938 
939     // compute the flags we send to Load_Glyph
940     bool linearMetrics = this->isLinearMetrics();
941     {
942         FT_Int32 loadFlags = FT_LOAD_DEFAULT;
943 
944         if (SkMask::kBW_Format == fRec.fMaskFormat) {
945             // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
946             loadFlags = FT_LOAD_TARGET_MONO;
947             if (fRec.getHinting() == SkFontHinting::kNone) {
948                 loadFlags |= FT_LOAD_NO_HINTING;
949                 linearMetrics = true;
950             }
951         } else {
952             switch (fRec.getHinting()) {
953             case SkFontHinting::kNone:
954                 loadFlags = FT_LOAD_NO_HINTING;
955                 linearMetrics = true;
956                 break;
957             case SkFontHinting::kSlight:
958                 loadFlags = FT_LOAD_TARGET_LIGHT;  // This implies FORCE_AUTOHINT
959                 linearMetrics = true;
960                 break;
961             case SkFontHinting::kNormal:
962                 loadFlags = FT_LOAD_TARGET_NORMAL;
963                 break;
964             case SkFontHinting::kFull:
965                 loadFlags = FT_LOAD_TARGET_NORMAL;
966                 if (isLCD(fRec)) {
967                     if (fLCDIsVert) {
968                         loadFlags = FT_LOAD_TARGET_LCD_V;
969                     } else {
970                         loadFlags = FT_LOAD_TARGET_LCD;
971                     }
972                 }
973                 break;
974             default:
975                 LOG_INFO("---------- UNKNOWN hinting %d\n", fRec.getHinting());
976                 break;
977             }
978         }
979 
980         if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
981             loadFlags |= FT_LOAD_FORCE_AUTOHINT;
982 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
983         } else {
984             loadFlags |= FT_LOAD_NO_AUTOHINT;
985 #endif
986         }
987 
988         if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
989             loadFlags |= FT_LOAD_NO_BITMAP;
990         }
991 
992         // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
993         // advances, as fontconfig and cairo do.
994         // See http://code.google.com/p/skia/issues/detail?id=222.
995         loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
996 
997         // Use vertical layout if requested.
998         if (this->isVertical()) {
999             loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
1000         }
1001 
1002         fLoadGlyphFlags = loadFlags;
1003     }
1004 
1005     SkUniqueFTSize ftSize([this]() -> FT_Size {
1006         FT_Size size;
1007         FT_Error err = FT_New_Size(fFaceRec->fFace.get(), &size);
1008         if (err != 0) {
1009             SK_TRACEFTR(err, "FT_New_Size(%s) failed.", fFaceRec->fFace->family_name);
1010             return nullptr;
1011         }
1012         return size;
1013     }());
1014     if (nullptr == ftSize) {
1015         LOG_INFO("Could not create FT_Size.\n");
1016         return;
1017     }
1018 
1019     FT_Error err = FT_Activate_Size(ftSize.get());
1020     if (err != 0) {
1021         SK_TRACEFTR(err, "FT_Activate_Size(%s) failed.", fFaceRec->fFace->family_name);
1022         return;
1023     }
1024 
1025     fRec.computeMatrices(SkScalerContextRec::PreMatrixScale::kFull, &fScale, &fMatrix22Scalar);
1026     FT_F26Dot6 scaleX = SkScalarToFDot6(fScale.fX);
1027     FT_F26Dot6 scaleY = SkScalarToFDot6(fScale.fY);
1028 
1029     if (FT_IS_SCALABLE(fFaceRec->fFace)) {
1030         err = FT_Set_Char_Size(fFaceRec->fFace.get(), scaleX, scaleY, 72, 72);
1031         if (err != 0) {
1032             SK_TRACEFTR(err, "FT_Set_CharSize(%s, %f, %f) failed.",
1033                         fFaceRec->fFace->family_name, fScale.fX, fScale.fY);
1034             return;
1035         }
1036 
1037         // Adjust the matrix to reflect the actually chosen scale.
1038         // FreeType currently does not allow requesting sizes less than 1, this allow for scaling.
1039         // Don't do this at all sizes as that will interfere with hinting.
1040         if (fScale.fX < 1 || fScale.fY < 1) {
1041             SkScalar upem = fFaceRec->fFace->units_per_EM;
1042             FT_Size_Metrics& ftmetrics = fFaceRec->fFace->size->metrics;
1043             SkScalar x_ppem = upem * SkFT_FixedToScalar(ftmetrics.x_scale) / 64.0f;
1044             SkScalar y_ppem = upem * SkFT_FixedToScalar(ftmetrics.y_scale) / 64.0f;
1045             fMatrix22Scalar.preScale(fScale.x() / x_ppem, fScale.y() / y_ppem);
1046         }
1047 
1048         // FT_LOAD_COLOR with scalable fonts means allow SVG.
1049         // It also implies attempt to render COLR if available, but this is not used.
1050 #if defined(FT_CONFIG_OPTION_SVG)
1051         if (SkGraphics::GetOpenTypeSVGDecoderFactory()) {
1052             fLoadGlyphFlags |= FT_LOAD_COLOR;
1053         }
1054 #endif
1055     } else if (FT_HAS_FIXED_SIZES(fFaceRec->fFace)) {
1056         fStrikeIndex = chooseBitmapStrike(fFaceRec->fFace.get(), scaleY);
1057         if (fStrikeIndex == -1) {
1058             LOG_INFO("No glyphs for font \"%s\" size %f.\n",
1059                      fFaceRec->fFace->family_name, fScale.fY);
1060             return;
1061         }
1062 
1063         err = FT_Select_Size(fFaceRec->fFace.get(), fStrikeIndex);
1064         if (err != 0) {
1065             SK_TRACEFTR(err, "FT_Select_Size(%s, %d) failed.",
1066                         fFaceRec->fFace->family_name, fStrikeIndex);
1067             fStrikeIndex = -1;
1068             return;
1069         }
1070 
1071         // Adjust the matrix to reflect the actually chosen scale.
1072         // It is likely that the ppem chosen was not the one requested, this allows for scaling.
1073         fMatrix22Scalar.preScale(fScale.x() / fFaceRec->fFace->size->metrics.x_ppem,
1074                                  fScale.y() / fFaceRec->fFace->size->metrics.y_ppem);
1075 
1076         // FreeType does not provide linear metrics for bitmap fonts.
1077         linearMetrics = false;
1078 
1079         // FreeType documentation says:
1080         // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading.
1081         // Bitmap-only fonts ignore this flag.
1082         //
1083         // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag.
1084         // Force this flag off for bitmap only fonts.
1085         fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
1086 
1087         // Color bitmaps are supported.
1088         fLoadGlyphFlags |= FT_LOAD_COLOR;
1089     } else {
1090         LOG_INFO("Unknown kind of font \"%s\" size %f.\n", fFaceRec->fFace->family_name, fScale.fY);
1091         return;
1092     }
1093 
1094     fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
1095     fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
1096     fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
1097     fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
1098 
1099     fFTSize = ftSize.release();
1100     fFace = fFaceRec->fFace.get();
1101     fDoLinearMetrics = linearMetrics;
1102     fUtils.init(fRec.fForegroundColor, (SkScalerContext::Flags)fRec.fFlags);
1103 }
1104 
~SkScalerContext_FreeType()1105 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
1106     SkAutoMutexExclusive  ac(f_t_mutex());
1107 
1108     if (fFTSize != nullptr) {
1109         FT_Done_Size(fFTSize);
1110     }
1111 
1112     fFaceRec = nullptr;
1113 }
1114 
1115 /*  We call this before each use of the fFace, since we may be sharing
1116     this face with other context (at different sizes).
1117 */
setupSize()1118 FT_Error SkScalerContext_FreeType::setupSize() {
1119     f_t_mutex().assertHeld();
1120     FT_Error err = FT_Activate_Size(fFTSize);
1121     if (err != 0) {
1122         return err;
1123     }
1124     FT_Set_Transform(fFace, &fMatrix22, nullptr);
1125     return 0;
1126 }
1127 
getBoundsOfCurrentOutlineGlyph(FT_GlyphSlot glyph,SkRect * bounds)1128 bool SkScalerContext_FreeType::getBoundsOfCurrentOutlineGlyph(FT_GlyphSlot glyph, SkRect* bounds) {
1129     if (glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1130         SkASSERT(false);
1131         return false;
1132     }
1133     if (0 == glyph->outline.n_contours) {
1134         return false;
1135     }
1136 
1137     FT_BBox bbox;
1138     FT_Outline_Get_CBox(&glyph->outline, &bbox);
1139     *bounds = SkRect::MakeLTRB(SkFDot6ToScalar(bbox.xMin), -SkFDot6ToScalar(bbox.yMax),
1140                                SkFDot6ToScalar(bbox.xMax), -SkFDot6ToScalar(bbox.yMin));
1141     return true;
1142 }
1143 
getCBoxForLetter(char letter,FT_BBox * bbox)1144 bool SkScalerContext_FreeType::getCBoxForLetter(char letter, FT_BBox* bbox) {
1145     const FT_UInt glyph_id = FT_Get_Char_Index(fFace, letter);
1146     if (!glyph_id) {
1147         return false;
1148     }
1149     if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags)) {
1150         return false;
1151     }
1152     if (fFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1153         return false;
1154     }
1155     emboldenIfNeeded(fFace, fFace->glyph, SkTo<SkGlyphID>(glyph_id));
1156     FT_Outline_Get_CBox(&fFace->glyph->outline, bbox);
1157     return true;
1158 }
1159 
updateGlyphBoundsIfSubpixel(const SkGlyph & glyph,SkRect * bounds,bool subpixel)1160 void SkScalerContext_FreeType::updateGlyphBoundsIfSubpixel(const SkGlyph& glyph, SkRect* bounds,
1161                                                            bool subpixel) {
1162     if (subpixel && !bounds->isEmpty()) {
1163         bounds->offset(SkFixedToScalar(glyph.getSubXFixed()),
1164                        SkFixedToScalar(glyph.getSubYFixed()));
1165     }
1166 }
1167 
updateGlyphBoundsIfLCD(GlyphMetrics * mx)1168 void SkScalerContext_FreeType::updateGlyphBoundsIfLCD(GlyphMetrics* mx) {
1169     if (mx->maskFormat == SkMask::kLCD16_Format && !mx->bounds.isEmpty()) {
1170         mx->bounds.roundOut(&mx->bounds);
1171         if (fLCDIsVert) {
1172             mx->bounds.fBottom += 1;
1173             mx->bounds.fTop -= 1;
1174         } else {
1175             mx->bounds.fRight += 1;
1176             mx->bounds.fLeft -= 1;
1177         }
1178     }
1179 }
1180 
shouldSubpixelBitmap(const SkGlyph & glyph,const SkMatrix & matrix)1181 bool SkScalerContext_FreeType::shouldSubpixelBitmap(const SkGlyph& glyph, const SkMatrix& matrix) {
1182     // If subpixel rendering of a bitmap *can* be done.
1183     bool mechanism = fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP &&
1184                      this->isSubpixel() &&
1185                      (glyph.getSubXFixed() || glyph.getSubYFixed());
1186 
1187     // If subpixel rendering of a bitmap *should* be done.
1188     // 1. If the face is not scalable then always allow subpixel rendering.
1189     //    Otherwise, if the font has an 8ppem strike 7 will subpixel render but 8 won't.
1190     // 2. If the matrix is already not identity the bitmap will already be resampled,
1191     //    so resampling slightly differently shouldn't make much difference.
1192     bool policy = !FT_IS_SCALABLE(fFace) || !matrix.isIdentity();
1193 
1194     return mechanism && policy;
1195 }
1196 
generateMetrics(const SkGlyph & glyph,SkArenaAlloc * alloc)1197 SkScalerContext::GlyphMetrics SkScalerContext_FreeType::generateMetrics(const SkGlyph& glyph,
1198                                                                         SkArenaAlloc* alloc) {
1199     SkAutoMutexExclusive  ac(f_t_mutex());
1200 
1201     GlyphMetrics mx(glyph.maskFormat());
1202 
1203     if (this->setupSize()) {
1204         return mx;
1205     }
1206 
1207     FT_Bool haveLayers = false;
1208 #ifdef FT_COLOR_H
1209     // See https://skbug.com/12945, if the face isn't marked scalable then paths cannot be loaded.
1210     if (FT_IS_SCALABLE(fFace)) {
1211         SkRect bounds = SkRect::MakeEmpty();
1212 #ifdef TT_SUPPORT_COLRV1
1213         FT_OpaquePaint opaqueLayerPaint{nullptr, 1};
1214         if (FT_Get_Color_Glyph_Paint(fFace, glyph.getGlyphID(),
1215                                      FT_COLOR_INCLUDE_ROOT_TRANSFORM, &opaqueLayerPaint)) {
1216             haveLayers = true;
1217             mx.extraBits = ScalerContextBits::COLRv1;
1218 
1219             // COLRv1 optionally provides a ClipBox.
1220             FT_ClipBox clipBox;
1221             if (FT_Get_Color_Glyph_ClipBox(fFace, glyph.getGlyphID(), &clipBox)) {
1222                 // Find bounding box of clip box corner points, needed when clipbox is transformed.
1223                 FT_BBox bbox;
1224                 bbox.xMin = clipBox.bottom_left.x;
1225                 bbox.xMax = clipBox.bottom_left.x;
1226                 bbox.yMin = clipBox.bottom_left.y;
1227                 bbox.yMax = clipBox.bottom_left.y;
1228                 for (auto& corner : {clipBox.top_left, clipBox.top_right, clipBox.bottom_right}) {
1229                     bbox.xMin = std::min(bbox.xMin, corner.x);
1230                     bbox.yMin = std::min(bbox.yMin, corner.y);
1231                     bbox.xMax = std::max(bbox.xMax, corner.x);
1232                     bbox.yMax = std::max(bbox.yMax, corner.y);
1233                 }
1234                 bounds = SkRect::MakeLTRB(SkFDot6ToScalar(bbox.xMin), -SkFDot6ToScalar(bbox.yMax),
1235                                           SkFDot6ToScalar(bbox.xMax), -SkFDot6ToScalar(bbox.yMin));
1236             } else {
1237                 // Traverse the glyph graph with a focus on measuring the required bounding box.
1238                 // The call to computeColrV1GlyphBoundingBox may modify the face.
1239                 // Reset the face to load the base glyph for metrics.
1240                 if (!SkScalerContextFTUtils::computeColrV1GlyphBoundingBox(fFace,
1241                                                                            glyph.getGlyphID(),
1242                                                                            &bounds) ||
1243                     this->setupSize())
1244                 {
1245                     return mx;
1246                 }
1247             }
1248         }
1249 #endif // #TT_SUPPORT_COLRV1
1250 
1251         if (!haveLayers) {
1252             FT_LayerIterator layerIterator = { 0, 0, nullptr };
1253             FT_UInt layerGlyphIndex;
1254             FT_UInt layerColorIndex;
1255             FT_Int32 flags = fLoadGlyphFlags;
1256             flags |= FT_LOAD_BITMAP_METRICS_ONLY;  // Don't decode any bitmaps.
1257             flags |= FT_LOAD_NO_BITMAP; // Ignore embedded bitmaps.
1258             flags &= ~FT_LOAD_RENDER;  // Don't scan convert.
1259             flags &= ~FT_LOAD_COLOR;  // Ignore SVG.
1260             // For COLRv0 compute the glyph bounding box from the union of layer bounding boxes.
1261             while (FT_Get_Color_Glyph_Layer(fFace, glyph.getGlyphID(), &layerGlyphIndex,
1262                                             &layerColorIndex, &layerIterator)) {
1263                 haveLayers = true;
1264                 if (FT_Load_Glyph(fFace, layerGlyphIndex, flags)) {
1265                     return mx;
1266                 }
1267 
1268                 SkRect currentBounds;
1269                 if (getBoundsOfCurrentOutlineGlyph(fFace->glyph, &currentBounds)) {
1270                     bounds.join(currentBounds);
1271                 }
1272             }
1273             if (haveLayers) {
1274                 mx.extraBits = ScalerContextBits::COLRv0;
1275             }
1276         }
1277 
1278         if (haveLayers) {
1279             mx.maskFormat = SkMask::kARGB32_Format;
1280             mx.neverRequestPath = true;
1281             updateGlyphBoundsIfSubpixel(glyph, &bounds, this->isSubpixel());
1282             mx.bounds = bounds;
1283         }
1284     }
1285 #endif  //FT_COLOR_H
1286 
1287     // Even if haveLayers, the base glyph must be loaded to get the metrics.
1288     if (FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY)) {
1289         return mx;
1290     }
1291 
1292     if (!haveLayers) {
1293         emboldenIfNeeded(fFace, fFace->glyph, glyph.getGlyphID());
1294 
1295         if (fFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1296             getBoundsOfCurrentOutlineGlyph(fFace->glyph, &mx.bounds);
1297             updateGlyphBoundsIfSubpixel(glyph, &mx.bounds, this->isSubpixel());
1298             updateGlyphBoundsIfLCD(&mx);
1299 
1300         } else if (fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
1301             mx.neverRequestPath = true;
1302 
1303             if (this->isVertical()) {
1304                 FT_Vector vector;
1305                 vector.x =  fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1306                 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1307                 FT_Vector_Transform(&vector, &fMatrix22);
1308                 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1309                 fFace->glyph->bitmap_top  += SkFDot6Floor(vector.y);
1310             }
1311 
1312             if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
1313                 mx.maskFormat = SkMask::kARGB32_Format;
1314             }
1315 
1316             mx.bounds = SkRect::MakeXYWH(SkIntToScalar(fFace->glyph->bitmap_left ),
1317                                         -SkIntToScalar(fFace->glyph->bitmap_top  ),
1318                                          SkIntToScalar(fFace->glyph->bitmap.width),
1319                                          SkIntToScalar(fFace->glyph->bitmap.rows ));
1320             fMatrix22Scalar.mapRect(&mx.bounds);
1321             updateGlyphBoundsIfSubpixel(glyph, &mx.bounds,
1322                                         this->shouldSubpixelBitmap(glyph, fMatrix22Scalar));
1323 
1324 #if defined(FT_CONFIG_OPTION_SVG)
1325         } else if (fFace->glyph->format == FT_GLYPH_FORMAT_SVG) {
1326             mx.extraBits = ScalerContextBits::SVG;
1327             mx.maskFormat = SkMask::kARGB32_Format;
1328             mx.neverRequestPath = true;
1329 
1330             SkPictureRecorder recorder;
1331             SkRect infiniteRect = SkRect::MakeLTRB(-SK_ScalarInfinity, -SK_ScalarInfinity,
1332                                                     SK_ScalarInfinity,  SK_ScalarInfinity);
1333             sk_sp<SkBBoxHierarchy> bboxh = SkRTreeFactory()();
1334             SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
1335             SkCanvas* recordingCanvas = recorder.beginRecording(infiniteRect, bboxh);
1336             if (!fUtils.drawSVGGlyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1337                 return mx;
1338             }
1339             sk_sp<SkPicture> pic = recorder.finishRecordingAsPicture();
1340             mx.bounds = pic->cullRect();
1341             SkASSERT(mx.bounds.isFinite());
1342             // drawSVGGlyph already applied the subpixel positioning.
1343 #endif  // FT_CONFIG_OPTION_SVG
1344 
1345         } else {
1346             SkDEBUGFAIL("unknown glyph format");
1347             return mx;
1348         }
1349     }
1350 
1351     if (this->isVertical()) {
1352         if (fDoLinearMetrics) {
1353             const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->linearVertAdvance);
1354             mx.advance.fX = fMatrix22Scalar.getSkewX() * advanceScalar;
1355             mx.advance.fY = fMatrix22Scalar.getScaleY() * advanceScalar;
1356         } else {
1357             mx.advance.fX = -SkFDot6ToFloat(fFace->glyph->advance.x);
1358             mx.advance.fY =  SkFDot6ToFloat(fFace->glyph->advance.y);
1359         }
1360     } else {
1361         if (fDoLinearMetrics) {
1362             const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->linearHoriAdvance);
1363             mx.advance.fX = fMatrix22Scalar.getScaleX() * advanceScalar;
1364             mx.advance.fY = fMatrix22Scalar.getSkewY() * advanceScalar;
1365         } else {
1366             mx.advance.fX =  SkFDot6ToFloat(fFace->glyph->advance.x);
1367             mx.advance.fY = -SkFDot6ToFloat(fFace->glyph->advance.y);
1368         }
1369     }
1370 
1371 #ifdef ENABLE_GLYPH_SPEW
1372     LOG_INFO("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadGlyphFlags, glyph->width());
1373 #endif
1374     return mx;
1375 }
1376 
generateImage(const SkGlyph & glyph,void * imageBuffer)1377 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph, void* imageBuffer) {
1378     SkAutoMutexExclusive  ac(f_t_mutex());
1379 
1380     if (this->setupSize()) {
1381         sk_bzero(imageBuffer, glyph.imageSize());
1382         return;
1383     }
1384 
1385     if (glyph.extraBits() == ScalerContextBits::COLRv0 ||
1386         glyph.extraBits() == ScalerContextBits::COLRv1 ||
1387         glyph.extraBits() == ScalerContextBits::SVG     )
1388     {
1389         SkASSERT(glyph.maskFormat() == SkMask::kARGB32_Format);
1390         SkBitmap dstBitmap;
1391         // TODO: mark this as sRGB when the blits will be sRGB.
1392         dstBitmap.setInfo(SkImageInfo::Make(glyph.width(), glyph.height(),
1393                                             kN32_SkColorType,
1394                                             kPremul_SkAlphaType),
1395                                             glyph.rowBytes());
1396         dstBitmap.setPixels(imageBuffer);
1397 
1398         SkCanvas canvas(dstBitmap);
1399         if constexpr (kSkShowTextBlitCoverage) {
1400             canvas.clear(0x33FF0000);
1401         } else {
1402             canvas.clear(SK_ColorTRANSPARENT);
1403         }
1404         canvas.translate(-glyph.left(), -glyph.top());
1405 
1406         SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
1407         if (glyph.extraBits() == ScalerContextBits::COLRv0) {
1408 #ifdef FT_COLOR_H
1409             fUtils.drawCOLRv0Glyph(fFace, glyph, fLoadGlyphFlags, palette, &canvas);
1410 #endif
1411         } else if (glyph.extraBits() == ScalerContextBits::COLRv1) {
1412 #ifdef TT_SUPPORT_COLRV1
1413             fUtils.drawCOLRv1Glyph(fFace, glyph, fLoadGlyphFlags, palette, &canvas);
1414 #endif
1415         } else if (glyph.extraBits() == ScalerContextBits::SVG) {
1416 #if defined(FT_CONFIG_OPTION_SVG)
1417             if (FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags)) {
1418                 return;
1419             }
1420             fUtils.drawSVGGlyph(fFace, glyph, fLoadGlyphFlags, palette, &canvas);
1421 #endif
1422         }
1423         return;
1424     }
1425 
1426     if (FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags)) {
1427         sk_bzero(imageBuffer, glyph.imageSize());
1428         return;
1429     }
1430     emboldenIfNeeded(fFace, fFace->glyph, glyph.getGlyphID());
1431 
1432     SkMatrix* bitmapMatrix = &fMatrix22Scalar;
1433     SkMatrix subpixelBitmapMatrix;
1434     if (this->shouldSubpixelBitmap(glyph, *bitmapMatrix)) {
1435         subpixelBitmapMatrix = fMatrix22Scalar;
1436         subpixelBitmapMatrix.postTranslate(SkFixedToScalar(glyph.getSubXFixed()),
1437                                            SkFixedToScalar(glyph.getSubYFixed()));
1438         bitmapMatrix = &subpixelBitmapMatrix;
1439     }
1440 
1441     fUtils.generateGlyphImage(fFace, glyph, imageBuffer, *bitmapMatrix, fPreBlend);
1442 }
1443 
generateDrawable(const SkGlyph & glyph)1444 sk_sp<SkDrawable> SkScalerContext_FreeType::generateDrawable(const SkGlyph& glyph) {
1445     // Because FreeType's FT_Face is stateful (not thread safe) and the current design of this
1446     // SkTypeface and SkScalerContext does not work around this, it is necessary lock at least the
1447     // FT_Face when using it (this implementation currently locks the whole FT_Library).
1448     // It should be possible to draw the drawable straight out of the FT_Face. However, this would
1449     // mean locking each time any such drawable is drawn. To avoid locking, this implementation
1450     // creates drawables backed as pictures so that they can be played back later without locking.
1451     SkAutoMutexExclusive  ac(f_t_mutex());
1452 
1453     if (this->setupSize()) {
1454         return nullptr;
1455     }
1456 
1457 #if defined(FT_COLOR_H) || defined(TT_SUPPORT_COLRV1) || defined(FT_CONFIG_OPTION_SVG)
1458     if (glyph.extraBits() == ScalerContextBits::COLRv0 ||
1459         glyph.extraBits() == ScalerContextBits::COLRv1 ||
1460         glyph.extraBits() == ScalerContextBits::SVG     )
1461     {
1462         SkSpan<SkColor> palette(fFaceRec->fSkPalette.get(), fFaceRec->fFTPaletteEntryCount);
1463         SkPictureRecorder recorder;
1464         SkCanvas* recordingCanvas = recorder.beginRecording(SkRect::Make(glyph.mask().fBounds));
1465         if (glyph.extraBits() == ScalerContextBits::COLRv0) {
1466 #ifdef FT_COLOR_H
1467             if (!fUtils.drawCOLRv0Glyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1468                 return nullptr;
1469             }
1470 #else
1471             return nullptr;
1472 #endif
1473         } else if (glyph.extraBits() == ScalerContextBits::COLRv1) {
1474 #ifdef TT_SUPPORT_COLRV1
1475             if (!fUtils.drawCOLRv1Glyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1476                 return nullptr;
1477             }
1478 #else
1479             return nullptr;
1480 #endif
1481         } else if (glyph.extraBits() == ScalerContextBits::SVG) {
1482 #if defined(FT_CONFIG_OPTION_SVG)
1483             if (FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags)) {
1484                 return nullptr;
1485             }
1486             if (!fUtils.drawSVGGlyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1487                 return nullptr;
1488             }
1489 #else
1490             return nullptr;
1491 #endif
1492         }
1493         return recorder.finishRecordingAsDrawable();
1494     }
1495 #endif
1496     return nullptr;
1497 }
1498 
generatePath(const SkGlyph & glyph,SkPath * path,bool * modified)1499 bool SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path, bool* modified) {
1500     SkASSERT(path);
1501 
1502     SkAutoMutexExclusive  ac(f_t_mutex());
1503 
1504     SkGlyphID glyphID = glyph.getGlyphID();
1505     // FT_IS_SCALABLE is documented to mean the face contains outline glyphs.
1506     if (!FT_IS_SCALABLE(fFace) || this->setupSize()) {
1507         path->reset();
1508         return false;
1509     }
1510 
1511     uint32_t flags = fLoadGlyphFlags;
1512     flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
1513     flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
1514 
1515     FT_Error err = FT_Load_Glyph(fFace, glyphID, flags);
1516     if (err != 0 || fFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1517         path->reset();
1518         return false;
1519     }
1520     *modified |= emboldenIfNeeded(fFace, fFace->glyph, glyphID);
1521 
1522     if (!fUtils.generateGlyphPath(fFace, path)) {
1523         path->reset();
1524         return false;
1525     }
1526 
1527     // The path's origin from FreeType is always the horizontal layout origin.
1528     // Offset the path so that it is relative to the vertical origin if needed.
1529     if (this->isVertical()) {
1530         FT_Vector vector;
1531         vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1532         vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1533         FT_Vector_Transform(&vector, &fMatrix22);
1534         path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y));
1535         *modified = true;
1536     }
1537     return true;
1538 }
1539 
generateFontMetrics(SkFontMetrics * metrics)1540 void SkScalerContext_FreeType::generateFontMetrics(SkFontMetrics* metrics) {
1541     if (nullptr == metrics) {
1542         return;
1543     }
1544 
1545     SkAutoMutexExclusive ac(f_t_mutex());
1546 
1547     if (this->setupSize()) {
1548         sk_bzero(metrics, sizeof(*metrics));
1549         return;
1550     }
1551 
1552     FT_Face face = fFace;
1553     metrics->fFlags = 0;
1554 
1555     SkScalar upem = SkIntToScalar(SkTypeface_FreeType::GetUnitsPerEm(face));
1556 
1557     // use the os/2 table as a source of reasonable defaults.
1558     SkScalar x_height = 0.0f;
1559     SkScalar avgCharWidth = 0.0f;
1560     SkScalar cap_height = 0.0f;
1561     SkScalar strikeoutThickness = 0.0f, strikeoutPosition = 0.0f;
1562     TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1563     if (os2) {
1564         x_height = SkIntToScalar(os2->sxHeight) / upem * fScale.y();
1565         avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem;
1566         strikeoutThickness = SkIntToScalar(os2->yStrikeoutSize) / upem;
1567         strikeoutPosition = -SkIntToScalar(os2->yStrikeoutPosition) / upem;
1568         metrics->fFlags |= SkFontMetrics::kStrikeoutThicknessIsValid_Flag;
1569         metrics->fFlags |= SkFontMetrics::kStrikeoutPositionIsValid_Flag;
1570         if (os2->version != 0xFFFF && os2->version >= 2) {
1571             cap_height = SkIntToScalar(os2->sCapHeight) / upem * fScale.y();
1572         }
1573     }
1574 
1575     // pull from format-specific metrics as needed
1576     SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax;
1577     SkScalar underlineThickness, underlinePosition;
1578     if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font
1579         // FreeType will always use HHEA metrics if they're not zero.
1580         // It completely ignores the OS/2 fsSelection::UseTypoMetrics bit.
1581         // It also ignores the VDMX tables, which are also of interest here
1582         // (and override everything else when they apply).
1583         static const int kUseTypoMetricsMask = (1 << 7);
1584         if (os2 && os2->version != 0xFFFF && (os2->fsSelection & kUseTypoMetricsMask)) {
1585             ascent = -SkIntToScalar(os2->sTypoAscender) / upem;
1586             descent = -SkIntToScalar(os2->sTypoDescender) / upem;
1587             leading = SkIntToScalar(os2->sTypoLineGap) / upem;
1588         } else {
1589             ascent = -SkIntToScalar(face->ascender) / upem;
1590             descent = -SkIntToScalar(face->descender) / upem;
1591             leading = SkIntToScalar(face->height + (face->descender - face->ascender)) / upem;
1592         }
1593         xmin = SkIntToScalar(face->bbox.xMin) / upem;
1594         xmax = SkIntToScalar(face->bbox.xMax) / upem;
1595         ymin = -SkIntToScalar(face->bbox.yMin) / upem;
1596         ymax = -SkIntToScalar(face->bbox.yMax) / upem;
1597         underlineThickness = SkIntToScalar(face->underline_thickness) / upem;
1598         underlinePosition = -SkIntToScalar(face->underline_position +
1599                                            face->underline_thickness / 2) / upem;
1600 
1601         metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
1602         metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
1603 
1604         // we may be able to synthesize x_height and cap_height from outline
1605         if (!x_height) {
1606             FT_BBox bbox;
1607             if (getCBoxForLetter('x', &bbox)) {
1608                 x_height = SkIntToScalar(bbox.yMax) / 64.0f;
1609             }
1610         }
1611         if (!cap_height) {
1612             FT_BBox bbox;
1613             if (getCBoxForLetter('H', &bbox)) {
1614                 cap_height = SkIntToScalar(bbox.yMax) / 64.0f;
1615             }
1616         }
1617     } else if (fStrikeIndex != -1) { // bitmap strike metrics
1618         SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem);
1619         SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem);
1620         ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f);
1621         descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f);
1622         leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f)) + ascent - descent;
1623 
1624         xmin = 0.0f;
1625         xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
1626         ymin = descent;
1627         ymax = ascent;
1628         // The actual bitmaps may be any size and placed at any offset.
1629         metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
1630 
1631         underlineThickness = 0;
1632         underlinePosition = 0;
1633         metrics->fFlags &= ~SkFontMetrics::kUnderlineThicknessIsValid_Flag;
1634         metrics->fFlags &= ~SkFontMetrics::kUnderlinePositionIsValid_Flag;
1635 
1636         TT_Postscript* post = (TT_Postscript*) FT_Get_Sfnt_Table(face, ft_sfnt_post);
1637         if (post) {
1638             underlineThickness = SkIntToScalar(post->underlineThickness) / upem;
1639             underlinePosition = -SkIntToScalar(post->underlinePosition) / upem;
1640             metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
1641             metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
1642         }
1643     } else {
1644         sk_bzero(metrics, sizeof(*metrics));
1645         return;
1646     }
1647 
1648     // synthesize elements that were not provided by the os/2 table or format-specific metrics
1649     if (!x_height) {
1650         x_height = -ascent * fScale.y();
1651     }
1652     if (!avgCharWidth) {
1653         avgCharWidth = xmax - xmin;
1654     }
1655     if (!cap_height) {
1656       cap_height = -ascent * fScale.y();
1657     }
1658 
1659     // disallow negative linespacing
1660     if (leading < 0.0f) {
1661         leading = 0.0f;
1662     }
1663 
1664     metrics->fTop = ymax * fScale.y();
1665     metrics->fAscent = ascent * fScale.y();
1666     metrics->fDescent = descent * fScale.y();
1667     metrics->fBottom = ymin * fScale.y();
1668     metrics->fLeading = leading * fScale.y();
1669     metrics->fAvgCharWidth = avgCharWidth * fScale.y();
1670     metrics->fXMin = xmin * fScale.y();
1671     metrics->fXMax = xmax * fScale.y();
1672     metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
1673     metrics->fXHeight = x_height;
1674     metrics->fCapHeight = cap_height;
1675     metrics->fUnderlineThickness = underlineThickness * fScale.y();
1676     metrics->fUnderlinePosition = underlinePosition * fScale.y();
1677     metrics->fStrikeoutThickness = strikeoutThickness * fScale.y();
1678     metrics->fStrikeoutPosition = strikeoutPosition * fScale.y();
1679 
1680     if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS
1681 #if defined(FT_CONFIG_OPTION_SVG)
1682         || face->face_flags & FT_FACE_FLAG_SVG
1683 #endif  // FT_CONFIG_OPTION_SVG
1684     ) {
1685         // The bounds are only valid for the default variation of variable glyphs.
1686         // https://docs.microsoft.com/en-us/typography/opentype/spec/head
1687         // For SVG glyphs this number is often incorrect for its non-`glyf` points.
1688         // https://github.com/fonttools/fonttools/issues/2566
1689         metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
1690     }
1691 }
1692 
1693 ///////////////////////////////////////////////////////////////////////////////
1694 
1695 // hand-tuned value to reduce outline embolden strength
1696 #ifndef SK_OUTLINE_EMBOLDEN_DIVISOR
1697     #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1698         #define SK_OUTLINE_EMBOLDEN_DIVISOR   34
1699     #else
1700         #define SK_OUTLINE_EMBOLDEN_DIVISOR   24
1701     #endif
1702 #endif
1703 
1704 ///////////////////////////////////////////////////////////////////////////////
1705 
emboldenIfNeeded(FT_Face face,FT_GlyphSlot glyph,SkGlyphID gid)1706 bool SkScalerContext_FreeType::emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph, SkGlyphID gid) {
1707     // check to see if the embolden bit is set
1708     if (0 == (fRec.fFlags & SkScalerContext::kEmbolden_Flag)) {
1709         return false;
1710     }
1711 
1712     if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1713         const FT_Pos strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale)
1714                                 / SK_OUTLINE_EMBOLDEN_DIVISOR;
1715         return 0 == FT_Outline_Embolden(&glyph->outline, strength);
1716     } else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
1717         if (!fFace->glyph->bitmap.buffer) {
1718             FT_Load_Glyph(fFace, gid, fLoadGlyphFlags);
1719         }
1720         FT_GlyphSlot_Own_Bitmap(glyph);
1721         return 0 == FT_Bitmap_Embolden(glyph->library, &glyph->bitmap, kBitmapEmboldenStrength, 0);
1722     }
1723     return false;
1724 }
1725 
1726 ///////////////////////////////////////////////////////////////////////////////
1727 
SkTypeface_FreeType(const SkFontStyle & style,bool isFixedPitch)1728 SkTypeface_FreeType::SkTypeface_FreeType(const SkFontStyle& style, bool isFixedPitch)
1729     : INHERITED(style, isFixedPitch)
1730 {}
1731 
~SkTypeface_FreeType()1732 SkTypeface_FreeType::~SkTypeface_FreeType() {
1733     if (fFaceRec) {
1734         SkAutoMutexExclusive ac(f_t_mutex());
1735         fFaceRec.reset();
1736     }
1737 }
1738 
1739 // Just made up, so we don't end up storing 1000s of entries
1740 constexpr int kMaxC2GCacheCount = 512;
1741 
onCharsToGlyphs(const SkUnichar uni[],int count,SkGlyphID glyphs[]) const1742 void SkTypeface_FreeType::onCharsToGlyphs(const SkUnichar uni[], int count,
1743                                           SkGlyphID glyphs[]) const {
1744     // Try the cache first, *before* accessing freetype lib/face, as that
1745     // can be very slow. If we do need to compute a new glyphID, then
1746     // access those freetype objects and continue the loop.
1747 
1748     int i;
1749     {
1750         // Optimistically use a shared lock.
1751         SkAutoSharedMutexShared ama(fC2GCacheMutex);
1752         for (i = 0; i < count; ++i) {
1753             int index = fC2GCache.findGlyphIndex(uni[i]);
1754             if (index < 0) {
1755                 break;
1756             }
1757             glyphs[i] = SkTo<SkGlyphID>(index);
1758         }
1759         if (i == count) {
1760             // we're done, no need to access the freetype objects
1761             return;
1762         }
1763     }
1764 
1765     // Need to add more so grab an exclusive lock.
1766     SkAutoSharedMutexExclusive ama(fC2GCacheMutex);
1767     AutoFTAccess fta(this);
1768     FT_Face face = fta.face();
1769     if (!face) {
1770         sk_bzero(glyphs, count * sizeof(glyphs[0]));
1771         return;
1772     }
1773 
1774     for (; i < count; ++i) {
1775         SkUnichar c = uni[i];
1776         int index = fC2GCache.findGlyphIndex(c);
1777         if (index >= 0) {
1778             glyphs[i] = SkTo<SkGlyphID>(index);
1779         } else {
1780             glyphs[i] = SkTo<SkGlyphID>(FT_Get_Char_Index(face, c));
1781             fC2GCache.insertCharAndGlyph(~index, c, glyphs[i]);
1782         }
1783     }
1784 
1785     if (fC2GCache.count() > kMaxC2GCacheCount) {
1786         fC2GCache.reset();
1787     }
1788 }
1789 
onCountGlyphs() const1790 int SkTypeface_FreeType::onCountGlyphs() const {
1791     AutoFTAccess fta(this);
1792     FT_Face face = fta.face();
1793     return face ? face->num_glyphs : 0;
1794 }
1795 
onCreateFamilyNameIterator() const1796 SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() const {
1797     sk_sp<SkTypeface::LocalizedStrings> nameIter =
1798         SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
1799     if (!nameIter) {
1800         SkString familyName;
1801         this->getFamilyName(&familyName);
1802         SkString language("und"); //undetermined
1803         nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(familyName, language);
1804     }
1805     return nameIter.release();
1806 }
1807 
onGlyphMaskNeedsCurrentColor() const1808 bool SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const {
1809     fGlyphMasksMayNeedCurrentColorOnce([this]{
1810         static constexpr SkFourByteTag COLRTag = SkSetFourByteTag('C', 'O', 'L', 'R');
1811         fGlyphMasksMayNeedCurrentColor = this->getTableSize(COLRTag) > 0;
1812 #if defined(FT_CONFIG_OPTION_SVG)
1813         static constexpr SkFourByteTag SVGTag = SkSetFourByteTag('S', 'V', 'G', ' ');
1814         fGlyphMasksMayNeedCurrentColor |= this->getTableSize(SVGTag) > 0 ;
1815 #endif  // FT_CONFIG_OPTION_SVG
1816     });
1817     return fGlyphMasksMayNeedCurrentColor;
1818 }
1819 
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const1820 int SkTypeface_FreeType::onGetVariationDesignPosition(
1821     SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
1822 {
1823     AutoFTAccess fta(this);
1824     FT_Face face = fta.face();
1825     if (!face) {
1826         return -1;
1827     }
1828     return GetVariationDesignPosition(face, coordinates, coordinateCount);
1829 }
1830 
onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount) const1831 int SkTypeface_FreeType::onGetVariationDesignParameters(
1832     SkFontParameters::Variation::Axis parameters[], int parameterCount) const
1833 {
1834     AutoFTAccess fta(this);
1835     FT_Face face = fta.face();
1836     if (!face) {
1837         return -1;
1838     }
1839 
1840     if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
1841         return 0;
1842     }
1843 
1844     FT_MM_Var* variations = nullptr;
1845     if (FT_Get_MM_Var(face, &variations)) {
1846         return -1;
1847     }
1848     UniqueVoidPtr autoFreeVariations(variations);
1849 
1850     if (!parameters || parameterCount < SkToInt(variations->num_axis)) {
1851         return variations->num_axis;
1852     }
1853 
1854     for (FT_UInt i = 0; i < variations->num_axis; ++i) {
1855         parameters[i].tag = variations->axis[i].tag;
1856         parameters[i].min = SkFixedToScalar(variations->axis[i].minimum);
1857         parameters[i].def = SkFixedToScalar(variations->axis[i].def);
1858         parameters[i].max = SkFixedToScalar(variations->axis[i].maximum);
1859         FT_UInt flags = 0;
1860         bool hidden = !FT_Get_Var_Axis_Flags(variations, i, &flags) &&
1861                       (flags & FT_VAR_AXIS_FLAG_HIDDEN);
1862         parameters[i].setHidden(hidden);
1863     }
1864 
1865     return variations->num_axis;
1866 }
1867 
onGetTableTags(SkFontTableTag tags[]) const1868 int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const {
1869     AutoFTAccess fta(this);
1870     FT_Face face = fta.face();
1871     if (!face) {
1872         return 0;
1873     }
1874 
1875     FT_ULong tableCount = 0;
1876     FT_Error error;
1877 
1878     // When 'tag' is nullptr, returns number of tables in 'length'.
1879     error = FT_Sfnt_Table_Info(face, 0, nullptr, &tableCount);
1880     if (error) {
1881         return 0;
1882     }
1883 
1884     if (tags) {
1885         for (FT_ULong tableIndex = 0; tableIndex < tableCount; ++tableIndex) {
1886             FT_ULong tableTag;
1887             FT_ULong tablelength;
1888             error = FT_Sfnt_Table_Info(face, tableIndex, &tableTag, &tablelength);
1889             if (error) {
1890                 return 0;
1891             }
1892             tags[tableIndex] = static_cast<SkFontTableTag>(tableTag);
1893         }
1894     }
1895     return tableCount;
1896 }
1897 
onGetTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const1898 size_t SkTypeface_FreeType::onGetTableData(SkFontTableTag tag, size_t offset,
1899                                            size_t length, void* data) const
1900 {
1901     AutoFTAccess fta(this);
1902     FT_Face face = fta.face();
1903     if (!face) {
1904         return 0;
1905     }
1906 
1907     FT_ULong tableLength = 0;
1908     FT_Error error;
1909 
1910     // When 'length' is 0 it is overwritten with the full table length; 'offset' is ignored.
1911     error = FT_Load_Sfnt_Table(face, tag, 0, nullptr, &tableLength);
1912     if (error) {
1913         return 0;
1914     }
1915 
1916     if (offset > tableLength) {
1917         return 0;
1918     }
1919     FT_ULong size = std::min((FT_ULong)length, tableLength - (FT_ULong)offset);
1920     if (data) {
1921         error = FT_Load_Sfnt_Table(face, tag, offset, reinterpret_cast<FT_Byte*>(data), &size);
1922         if (error) {
1923             return 0;
1924         }
1925     }
1926 
1927     return size;
1928 }
1929 
onCopyTableData(SkFontTableTag tag) const1930 sk_sp<SkData> SkTypeface_FreeType::onCopyTableData(SkFontTableTag tag) const {
1931     AutoFTAccess fta(this);
1932     FT_Face face = fta.face();
1933     if (!face) {
1934         return nullptr;
1935     }
1936 
1937     FT_ULong tableLength = 0;
1938     FT_Error error;
1939 
1940     // When 'length' is 0 it is overwritten with the full table length; 'offset' is ignored.
1941     error = FT_Load_Sfnt_Table(face, tag, 0, nullptr, &tableLength);
1942     if (error) {
1943         return nullptr;
1944     }
1945 
1946     sk_sp<SkData> data = SkData::MakeUninitialized(tableLength);
1947     if (data) {
1948         error = FT_Load_Sfnt_Table(face, tag, 0,
1949                                    reinterpret_cast<FT_Byte*>(data->writable_data()), &tableLength);
1950         if (error) {
1951             data.reset();
1952         }
1953     }
1954     return data;
1955 }
1956 
getFaceRec() const1957 SkTypeface_FreeType::FaceRec* SkTypeface_FreeType::getFaceRec() const {
1958     f_t_mutex().assertHeld();
1959     fFTFaceOnce([this]{ fFaceRec = SkTypeface_FreeType::FaceRec::Make(this); });
1960     return fFaceRec.get();
1961 }
1962 
makeFontData() const1963 std::unique_ptr<SkFontData> SkTypeface_FreeType::makeFontData() const {
1964     return this->onMakeFontData();
1965 }
1966 
FontDataPaletteToDescriptorPalette(const SkFontData & fontData,SkFontDescriptor * desc)1967 void SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(const SkFontData& fontData,
1968                                                              SkFontDescriptor* desc) {
1969     desc->setPaletteIndex(fontData.getPaletteIndex());
1970     int paletteOverrideCount = fontData.getPaletteOverrideCount();
1971     auto overrides = desc->setPaletteEntryOverrides(paletteOverrideCount);
1972     for (int i = 0; i < paletteOverrideCount; ++i) {
1973         overrides[i] = fontData.getPaletteOverrides()[i];
1974     }
1975 }
1976 
1977 ///////////////////////////////////////////////////////////////////////////////
1978 ///////////////////////////////////////////////////////////////////////////////
1979 
SkTypeface_FreeTypeStream(std::unique_ptr<SkFontData> fontData,const SkString familyName,const SkFontStyle & style,bool isFixedPitch)1980 SkTypeface_FreeTypeStream::SkTypeface_FreeTypeStream(std::unique_ptr<SkFontData> fontData,
1981                                                      const SkString familyName,
1982                                                      const SkFontStyle& style, bool isFixedPitch)
1983     : SkTypeface_FreeType(style, isFixedPitch)
1984     , fFamilyName(std::move(familyName))
1985     , fData(std::move(fontData))
1986 { }
1987 
~SkTypeface_FreeTypeStream()1988 SkTypeface_FreeTypeStream::~SkTypeface_FreeTypeStream() {}
1989 
onGetFamilyName(SkString * familyName) const1990 void SkTypeface_FreeTypeStream::onGetFamilyName(SkString* familyName) const {
1991     *familyName = fFamilyName;
1992 }
1993 
onOpenStream(int * ttcIndex) const1994 std::unique_ptr<SkStreamAsset> SkTypeface_FreeTypeStream::onOpenStream(int* ttcIndex) const {
1995     *ttcIndex = fData->getIndex();
1996     return fData->getStream()->duplicate();
1997 }
1998 
onMakeFontData() const1999 std::unique_ptr<SkFontData> SkTypeface_FreeTypeStream::onMakeFontData() const {
2000     return std::make_unique<SkFontData>(*fData);
2001 }
2002 
onMakeClone(const SkFontArguments & args) const2003 sk_sp<SkTypeface> SkTypeface_FreeTypeStream::onMakeClone(const SkFontArguments& args) const {
2004     SkFontStyle style = this->fontStyle();
2005     std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style);
2006     if (!data) {
2007         return nullptr;
2008     }
2009 
2010     SkString familyName;
2011     this->getFamilyName(&familyName);
2012 
2013     return sk_make_sp<SkTypeface_FreeTypeStream>(
2014         std::move(data), familyName, style, this->isFixedPitch());
2015 }
2016 
onGetFontDescriptor(SkFontDescriptor * desc,bool * serialize) const2017 void SkTypeface_FreeTypeStream::onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const {
2018     desc->setFamilyName(fFamilyName.c_str());
2019     desc->setStyle(this->fontStyle());
2020     desc->setFactoryId(SkTypeface_FreeType::FactoryId);
2021     SkTypeface_FreeType::FontDataPaletteToDescriptorPalette(*fData, desc);
2022     *serialize = true;
2023 }
2024 
MakeFromStream(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args)2025 sk_sp<SkTypeface> SkTypeface_FreeType::MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
2026                                                       const SkFontArguments& args) {
2027     static SkFontScanner_FreeType scanner;
2028     bool isFixedPitch;
2029     SkFontStyle style;
2030     SkString name;
2031     SkFontScanner::AxisDefinitions axisDefinitions;
2032     SkFontScanner::VariationPosition current;
2033     if (!scanner.scanInstance(stream.get(), args.getCollectionIndex(), 0,
2034                               &name, &style, &isFixedPitch, &axisDefinitions, &current)) {
2035         return nullptr;
2036     }
2037 
2038     AutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.size());
2039     SkFontScanner_FreeType::computeAxisValues(
2040         axisDefinitions,
2041         SkFontArguments::VariationPosition{current.data(), current.size()},
2042         args.getVariationDesignPosition(),
2043         axisValues, name, &style);
2044 
2045     auto data = std::make_unique<SkFontData>(
2046         std::move(stream), args.getCollectionIndex(), args.getPalette().index,
2047         axisValues.get(), axisDefinitions.size(),
2048         args.getPalette().overrides, args.getPalette().overrideCount);
2049     return sk_make_sp<SkTypeface_FreeTypeStream>(std::move(data), name, style, isFixedPitch);
2050 }
2051 
SkFontScanner_FreeType()2052 SkFontScanner_FreeType::SkFontScanner_FreeType() : fLibrary(nullptr) {
2053     if (FT_New_Library(&gFTMemory, &fLibrary)) {
2054         return;
2055     }
2056     FT_Add_Default_Modules(fLibrary);
2057     FT_Set_Default_Properties(fLibrary);
2058 }
2059 
~SkFontScanner_FreeType()2060 SkFontScanner_FreeType::~SkFontScanner_FreeType() {
2061     if (fLibrary) {
2062         FT_Done_Library(fLibrary);
2063     }
2064 }
2065 
openFace(SkStreamAsset * stream,int ttcIndex,FT_Stream ftStream) const2066 FT_Face SkFontScanner_FreeType::openFace(SkStreamAsset* stream, int ttcIndex,
2067                                          FT_Stream ftStream) const
2068 {
2069     if (fLibrary == nullptr || stream == nullptr) {
2070         return nullptr;
2071     }
2072 
2073     FT_Open_Args args;
2074     memset(&args, 0, sizeof(args));
2075 
2076     const void* memoryBase = stream->getMemoryBase();
2077 
2078     if (memoryBase) {
2079         args.flags = FT_OPEN_MEMORY;
2080         args.memory_base = (const FT_Byte*)memoryBase;
2081         args.memory_size = stream->getLength();
2082     } else {
2083         memset(ftStream, 0, sizeof(*ftStream));
2084         ftStream->size = stream->getLength();
2085         ftStream->descriptor.pointer = stream;
2086         ftStream->read  = sk_ft_stream_io;
2087         ftStream->close = sk_ft_stream_close;
2088 
2089         args.flags = FT_OPEN_STREAM;
2090         args.stream = ftStream;
2091     }
2092 
2093     FT_Face face;
2094     if (FT_Open_Face(fLibrary, &args, ttcIndex, &face)) {
2095         return nullptr;
2096     }
2097     return face;
2098 }
2099 
scanFile(SkStreamAsset * stream,int * numFaces) const2100 bool SkFontScanner_FreeType::scanFile(SkStreamAsset* stream, int* numFaces) const {
2101     SkAutoMutexExclusive libraryLock(fLibraryMutex);
2102 
2103     FT_StreamRec streamRec;
2104     SkUniqueFTFace face(this->openFace(stream, -1, &streamRec));
2105     if (!face) {
2106         return false;
2107     }
2108     if (numFaces) {
2109         *numFaces = face->num_faces;
2110     }
2111     return true;
2112 }
2113 
scanFace(SkStreamAsset * stream,int faceIndex,int * numInstances) const2114 bool SkFontScanner_FreeType::scanFace(SkStreamAsset* stream,
2115                                       int faceIndex,
2116                                       int* numInstances) const {
2117     SkAutoMutexExclusive libraryLock(fLibraryMutex);
2118 
2119     FT_StreamRec streamRec;
2120     SkUniqueFTFace face(this->openFace(stream, -(faceIndex + 1), &streamRec));
2121     if (!face) {
2122         return false;
2123     }
2124     if (numInstances) {
2125         *numInstances = face->style_flags >> 16;
2126     }
2127     return true;
2128 }
2129 
scanInstance(SkStreamAsset * stream,int faceIndex,int instanceIndex,SkString * name,SkFontStyle * style,bool * isFixedPitch,AxisDefinitions * axes,VariationPosition * position) const2130 bool SkFontScanner_FreeType::scanInstance(SkStreamAsset* stream,
2131                                           int faceIndex,
2132                                           int instanceIndex,
2133                                           SkString* name,
2134                                           SkFontStyle* style,
2135                                           bool* isFixedPitch,
2136                                           AxisDefinitions* axes,
2137                                           VariationPosition* position) const {
2138 
2139     SkAutoMutexExclusive libraryLock(fLibraryMutex);
2140 
2141     FT_StreamRec streamRec;
2142     SkUniqueFTFace face(this->openFace(stream, (instanceIndex << 16) + faceIndex, &streamRec));
2143     if (!face) {
2144         return false;
2145     }
2146 
2147     int weight = SkFontStyle::kNormal_Weight;
2148     int width = SkFontStyle::kNormal_Width;
2149     SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
2150     if (face->style_flags & FT_STYLE_FLAG_BOLD) {
2151         weight = SkFontStyle::kBold_Weight;
2152     }
2153     if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
2154         slant = SkFontStyle::kItalic_Slant;
2155     }
2156 
2157     bool hasAxes = face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
2158     TT_OS2* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face.get(), ft_sfnt_os2));
2159     bool hasOs2 = os2 && os2->version != 0xffff;
2160 
2161     PS_FontInfoRec psFontInfo;
2162 
2163     if (hasOs2) {
2164         weight = os2->usWeightClass;
2165         width = os2->usWidthClass;
2166 
2167         // OS/2::fsSelection bit 9 indicates oblique.
2168         if (SkToBool(os2->fsSelection & (1u << 9))) {
2169             slant = SkFontStyle::kOblique_Slant;
2170         }
2171     }
2172 
2173     // Let variable axes override properties from the OS/2 table.
2174     if (hasAxes) {
2175         AxisDefinitions axisDefinitions;
2176         if (GetAxes(face.get(), &axisDefinitions)) {
2177             size_t numAxes = axisDefinitions.size();
2178             static constexpr SkFourByteTag wghtTag = SkSetFourByteTag('w', 'g', 'h', 't');
2179             static constexpr SkFourByteTag wdthTag = SkSetFourByteTag('w', 'd', 't', 'h');
2180             static constexpr SkFourByteTag slntTag = SkSetFourByteTag('s', 'l', 'n', 't');
2181             std::optional<size_t> wghtIndex;
2182             std::optional<size_t> wdthIndex;
2183             std::optional<size_t> slntIndex;
2184             for(size_t i = 0; i < numAxes; ++i) {
2185                 if (axisDefinitions[i].tag == wghtTag) {
2186                     // Rough validity check, sufficient spread and ranges within 0-1000.
2187                     SkScalar wghtRange = axisDefinitions[i].max - axisDefinitions[i].min;
2188                     if (wghtRange > 5 && wghtRange <= 1000 && axisDefinitions[i].max <= 1000) {
2189                         wghtIndex = i;
2190                     }
2191                 }
2192                 if (axisDefinitions[i].tag == wdthTag) {
2193                     // Rough validity check, sufficient spread and are ranges within 0-500.
2194                     SkScalar wdthRange = axisDefinitions[i].max - axisDefinitions[i].min;
2195                     if (wdthRange > 0 && wdthRange <= 500 && axisDefinitions[i].max <= 500) {
2196                         wdthIndex = i;
2197                     }
2198                 }
2199                 if (axisDefinitions[i].tag == slntTag) {
2200                     slntIndex = i;
2201                 }
2202             }
2203             AutoSTMalloc<4, FT_Fixed> coords(numAxes);
2204             if ((wghtIndex || wdthIndex || slntIndex) &&
2205                 !FT_Get_Var_Design_Coordinates(face.get(), numAxes, coords.get())) {
2206                 if (wghtIndex) {
2207                     SkASSERT(*wghtIndex < numAxes);
2208                     weight = SkFixedRoundToInt(coords[*wghtIndex]);
2209                 }
2210                 if (wdthIndex) {
2211                     SkASSERT(*wdthIndex < numAxes);
2212                     SkScalar wdthValue = SkFixedToScalar(coords[*wdthIndex]);
2213                     width = SkFontDescriptor::SkFontStyleWidthForWidthAxisValue(wdthValue);
2214                 }
2215                 if (slntIndex) {
2216                     SkASSERT(*slntIndex < numAxes);
2217                     // https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_slnt
2218                     // "Scale interpretation: Values can be interpreted as the angle,
2219                     // in counter-clockwise degrees, of oblique slant from whatever
2220                     // the designer considers to be upright for that font design."
2221                     if (SkFixedToScalar(coords[*slntIndex]) < 0) {
2222                         slant = SkFontStyle::kOblique_Slant;
2223                     }
2224                 }
2225             }
2226 
2227             if (position) {
2228                 position->reset(numAxes);
2229                 auto coordinates = position->data();
2230                 if (GetVariationDesignPosition(face.get(), coordinates, numAxes) != (int)numAxes) {
2231                     return false;
2232                 }
2233             }
2234         }
2235     }
2236 
2237     if (!hasOs2 && !hasAxes && 0 == FT_Get_PS_Font_Info(face.get(), &psFontInfo) && psFontInfo.weight) {
2238         static const struct {
2239             char const * const name;
2240             int const weight;
2241         } commonWeights [] = {
2242                 // There are probably more common names, but these are known to exist.
2243                 { "all", SkFontStyle::kNormal_Weight }, // Multiple Masters usually default to normal.
2244                 { "black", SkFontStyle::kBlack_Weight },
2245                 { "bold", SkFontStyle::kBold_Weight },
2246                 { "book", (SkFontStyle::kNormal_Weight + SkFontStyle::kLight_Weight)/2 },
2247                 { "demi", SkFontStyle::kSemiBold_Weight },
2248                 { "demibold", SkFontStyle::kSemiBold_Weight },
2249                 { "extra", SkFontStyle::kExtraBold_Weight },
2250                 { "extrabold", SkFontStyle::kExtraBold_Weight },
2251                 { "extralight", SkFontStyle::kExtraLight_Weight },
2252                 { "hairline", SkFontStyle::kThin_Weight },
2253                 { "heavy", SkFontStyle::kBlack_Weight },
2254                 { "light", SkFontStyle::kLight_Weight },
2255                 { "medium", SkFontStyle::kMedium_Weight },
2256                 { "normal", SkFontStyle::kNormal_Weight },
2257                 { "plain", SkFontStyle::kNormal_Weight },
2258                 { "regular", SkFontStyle::kNormal_Weight },
2259                 { "roman", SkFontStyle::kNormal_Weight },
2260                 { "semibold", SkFontStyle::kSemiBold_Weight },
2261                 { "standard", SkFontStyle::kNormal_Weight },
2262                 { "thin", SkFontStyle::kThin_Weight },
2263                 { "ultra", SkFontStyle::kExtraBold_Weight },
2264                 { "ultrablack", SkFontStyle::kExtraBlack_Weight },
2265                 { "ultrabold", SkFontStyle::kExtraBold_Weight },
2266                 { "ultraheavy", SkFontStyle::kExtraBlack_Weight },
2267                 { "ultralight", SkFontStyle::kExtraLight_Weight },
2268         };
2269         int const index = SkStrLCSearch(&commonWeights[0].name, std::size(commonWeights),
2270                                         psFontInfo.weight, sizeof(commonWeights[0]));
2271         if (index >= 0) {
2272             weight = commonWeights[index].weight;
2273         } else {
2274             LOG_INFO("Do not know weight for: %s (%s) \n", face->family_name, psFontInfo.weight);
2275         }
2276     }
2277 
2278     if (name != nullptr) {
2279         name->set(face->family_name);
2280     }
2281     if (style != nullptr) {
2282         *style = SkFontStyle(weight, width, slant);
2283     }
2284     if (isFixedPitch != nullptr) {
2285         *isFixedPitch = FT_IS_FIXED_WIDTH(face);
2286     }
2287 
2288     if (axes != nullptr && !GetAxes(face.get(), axes)) {
2289         return false;
2290     }
2291 
2292     return true;
2293 }
2294 
MakeFromStream(std::unique_ptr<SkStreamAsset> stream,const SkFontArguments & args) const2295 sk_sp<SkTypeface> SkFontScanner_FreeType::MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
2296                                                          const SkFontArguments& args) const {
2297     return SkTypeface_FreeType::MakeFromStream(std::move(stream), args);
2298 }
2299 
getFactoryId() const2300 SkTypeface::FactoryId SkFontScanner_FreeType::getFactoryId() const {
2301     return SkTypeface_FreeType::FactoryId;
2302 }
2303 
computeAxisValues(const AxisDefinitions & axisDefinitions,const SkFontArguments::VariationPosition current,const SkFontArguments::VariationPosition position,SkFixed * axisValues,const SkString & name,SkFontStyle * style)2304 /*static*/ void SkFontScanner_FreeType::computeAxisValues(
2305         const AxisDefinitions& axisDefinitions,
2306         const SkFontArguments::VariationPosition current,
2307         const SkFontArguments::VariationPosition position,
2308         SkFixed* axisValues,
2309         const SkString& name,
2310         SkFontStyle* style)
2311 {
2312     static constexpr SkFourByteTag wghtTag = SkSetFourByteTag('w', 'g', 'h', 't');
2313     static constexpr SkFourByteTag wdthTag = SkSetFourByteTag('w', 'd', 't', 'h');
2314     static constexpr SkFourByteTag slntTag = SkSetFourByteTag('s', 'l', 'n', 't');
2315     int weight = SkFontStyle::kNormal_Weight;
2316     int width = SkFontStyle::kNormal_Width;
2317     SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
2318     if (style) {
2319         weight = style->weight();
2320         width = style->width();
2321         slant = style->slant();
2322     }
2323 
2324     for (int i = 0; i < axisDefinitions.size(); ++i) {
2325         const SkFontParameters::Variation::Axis& axisDefinition = axisDefinitions[i];
2326         const SkScalar axisMin = axisDefinition.min;
2327         const SkScalar axisMax = axisDefinition.max;
2328 
2329         // Start with the default value.
2330         axisValues[i] = SkScalarToFixed(axisDefinition.def);
2331 
2332         // Then the current value.
2333         for (int j = current.coordinateCount; j --> 0;) {
2334             const auto& coordinate = current.coordinates[j];
2335             if (axisDefinition.tag == coordinate.axis) {
2336                 const SkScalar axisValue = SkTPin(coordinate.value, axisMin, axisMax);
2337                 if (coordinate.value != axisValue) {
2338                     LOG_INFO("Current font axis value out of range: "
2339                             "%s '%c%c%c%c' %f; pinned to %f.\n",
2340                             name.c_str(),
2341                             (axisDefinition.tag >> 24) & 0xFF,
2342                             (axisDefinition.tag >> 16) & 0xFF,
2343                             (axisDefinition.tag >>  8) & 0xFF,
2344                             (axisDefinition.tag      ) & 0xFF,
2345                             SkScalarToDouble(coordinate.value),
2346                             SkScalarToDouble(axisValue));
2347                 }
2348                 axisValues[i] = SkScalarToFixed(axisValue);
2349                 break;
2350             }
2351         }
2352 
2353         // Then the requested value.
2354         // The position may be over specified. If there are multiple values for a given axis,
2355         // use the last one since that's what css-fonts-4 requires.
2356         for (int j = position.coordinateCount; j --> 0;) {
2357             const auto& coordinate = position.coordinates[j];
2358             if (axisDefinition.tag == coordinate.axis) {
2359                 const SkScalar axisValue = SkTPin(coordinate.value, axisMin, axisMax);
2360                 if (coordinate.value != axisValue) {
2361                     LOG_INFO("Requested font axis value out of range: "
2362                             "%s '%c%c%c%c' %f; pinned to %f.\n",
2363                             name.c_str(),
2364                             (axisDefinition.tag >> 24) & 0xFF,
2365                             (axisDefinition.tag >> 16) & 0xFF,
2366                             (axisDefinition.tag >>  8) & 0xFF,
2367                             (axisDefinition.tag      ) & 0xFF,
2368                             SkScalarToDouble(coordinate.value),
2369                             SkScalarToDouble(axisValue));
2370                 }
2371                 axisValues[i] = SkScalarToFixed(axisValue);
2372                 break;
2373             }
2374         }
2375 
2376         if (style) {
2377             if (axisDefinition.tag == wghtTag) {
2378                 // Rough validity check, is there sufficient spread and are ranges within 0-1000.
2379                 SkScalar wghtRange = axisMax - axisMin;
2380                 if (wghtRange > 5 && wghtRange <= 1000 && axisMax <= 1000) {
2381                     weight = SkFixedRoundToInt(axisValues[i]);
2382                 }
2383             }
2384             if (axisDefinition.tag == wdthTag) {
2385                 // Rough validity check, is there a spread and are ranges within 0-500.
2386                 SkScalar wdthRange = axisMax - axisMin;
2387                 if (wdthRange > 0 && wdthRange <= 500 && axisMax <= 500) {
2388                     SkScalar wdthValue = SkFixedToScalar(axisValues[i]);
2389                     width = SkFontDescriptor::SkFontStyleWidthForWidthAxisValue(wdthValue);
2390                 }
2391             }
2392             if (axisDefinition.tag == slntTag && slant != SkFontStyle::kItalic_Slant) {
2393                 // https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_slnt
2394                 // "Scale interpretation: Values can be interpreted as the angle,
2395                 // in counter-clockwise degrees, of oblique slant from whatever
2396                 // the designer considers to be upright for that font design."
2397                 if (axisValues[i] == 0) {
2398                     slant = SkFontStyle::kUpright_Slant;
2399                 } else {
2400                     slant = SkFontStyle::kOblique_Slant;
2401                 }
2402             }
2403         }
2404         // TODO: warn on defaulted axis?
2405     }
2406 
2407     if (style) {
2408         *style = SkFontStyle(weight, width, slant);
2409     }
2410 
2411     SkDEBUGCODE(
2412         // Check for axis specified, but not matched in font.
2413         for (int i = 0; i < position.coordinateCount; ++i) {
2414             SkFourByteTag skTag = position.coordinates[i].axis;
2415             bool found = false;
2416             for (int j = 0; j < axisDefinitions.size(); ++j) {
2417                 if (skTag == axisDefinitions[j].tag) {
2418                     found = true;
2419                     break;
2420                 }
2421             }
2422             if (!found) {
2423                 LOG_INFO("Requested font axis not found: %s '%c%c%c%c'\n",
2424                          name.c_str(),
2425                          (skTag >> 24) & 0xFF,
2426                          (skTag >> 16) & 0xFF,
2427                          (skTag >>  8) & 0xFF,
2428                          (skTag)       & 0xFF);
2429             }
2430         }
2431     )
2432 }
2433 
SkFontScanner_Make_FreeType()2434 std::unique_ptr<SkFontScanner> SkFontScanner_Make_FreeType() {
2435     return std::make_unique<SkFontScanner_FreeType>();
2436 }
2437