• 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/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkData.h"
11 #include "include/core/SkFontMetrics.h"
12 #include "include/core/SkPath.h"
13 #include "include/core/SkStream.h"
14 #include "include/core/SkString.h"
15 #include "include/private/SkColorData.h"
16 #include "include/private/SkMalloc.h"
17 #include "include/private/SkMutex.h"
18 #include "include/private/SkTPin.h"
19 #include "include/private/SkTemplates.h"
20 #include "include/private/SkTo.h"
21 #include "src/core/SkAdvancedTypefaceMetrics.h"
22 #include "src/core/SkDescriptor.h"
23 #include "src/core/SkFDot6.h"
24 #include "src/core/SkFontDescriptor.h"
25 #include "src/core/SkGlyph.h"
26 #include "src/core/SkMask.h"
27 #include "src/core/SkMaskGamma.h"
28 #include "src/core/SkScalerContext.h"
29 #include "src/core/SkTSearch.h"
30 #include "src/ports/SkFontHost_FreeType_common.h"
31 #include "src/sfnt/SkOTUtils.h"
32 #include "src/utils/SkCallableTraits.h"
33 #include "src/utils/SkMatrix22.h"
34 
35 #include <memory>
36 #include <tuple>
37 
38 #include <ft2build.h>
39 #include <freetype/ftadvanc.h>
40 #include <freetype/ftimage.h>
41 #include <freetype/ftbitmap.h>
42 #ifdef FT_COLOR_H  // 2.10.0
43 #   include <freetype/ftcolor.h>
44 #endif
45 #include <freetype/freetype.h>
46 #include <freetype/ftlcdfil.h>
47 #include <freetype/ftmodapi.h>
48 #include <freetype/ftmm.h>
49 #include <freetype/ftoutln.h>
50 #include <freetype/ftsizes.h>
51 #include <freetype/ftsystem.h>
52 #include <freetype/tttables.h>
53 #include <freetype/t1tables.h>
54 #include <freetype/ftfntfmt.h>
55 
56 // SK_FREETYPE_MINIMUM_RUNTIME_VERSION 0x<major><minor><patch><flags>
57 // Flag SK_FREETYPE_DLOPEN: also try dlopen to get newer features.
58 #define SK_FREETYPE_DLOPEN (0x1)
59 #ifndef SK_FREETYPE_MINIMUM_RUNTIME_VERSION
60 #  if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || defined (SK_BUILD_FOR_GOOGLE3)
61 #    define SK_FREETYPE_MINIMUM_RUNTIME_VERSION (((FREETYPE_MAJOR) << 24) | ((FREETYPE_MINOR) << 16) | ((FREETYPE_PATCH) << 8))
62 #  else
63 #    define SK_FREETYPE_MINIMUM_RUNTIME_VERSION ((2 << 24) | (8 << 16) | (1 << 8) | (SK_FREETYPE_DLOPEN))
64 #  endif
65 #endif
66 #if SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN
67 #  include <dlfcn.h>
68 #endif
69 
70 //#define ENABLE_GLYPH_SPEW     // for tracing calls
71 //#define DUMP_STRIKE_CREATION
72 //#define SK_FONTHOST_FREETYPE_RUNTIME_VERSION
73 //#define SK_GAMMA_APPLY_TO_A8
74 
75 #if 1
76     #define LOG_INFO(...)
77 #else
78     #define LOG_INFO SkDEBUGF
79 #endif
80 
isLCD(const SkScalerContextRec & rec)81 static bool isLCD(const SkScalerContextRec& rec) {
82     return SkMask::kLCD16_Format == rec.fMaskFormat;
83 }
84 
SkFT_FixedToScalar(FT_Fixed x)85 static SkScalar SkFT_FixedToScalar(FT_Fixed x) {
86   return SkFixedToScalar(x);
87 }
88 
89 using SkUniqueFTFace =
90         std::unique_ptr<FT_FaceRec, SkFunctionWrapper<decltype(FT_Done_Face), FT_Done_Face>>;
91 
92 //////////////////////////////////////////////////////////////////////////
93 
94 using FT_Alloc_size_t = SkCallableTraits<FT_Alloc_Func>::argument<1>::type;
95 static_assert(std::is_same<FT_Alloc_size_t, long  >::value ||
96               std::is_same<FT_Alloc_size_t, size_t>::value,"");
97 
98 extern "C" {
sk_ft_alloc(FT_Memory,FT_Alloc_size_t size)99     static void* sk_ft_alloc(FT_Memory, FT_Alloc_size_t size) {
100         return sk_malloc_throw(size);
101     }
sk_ft_free(FT_Memory,void * block)102     static void sk_ft_free(FT_Memory, void* block) {
103         sk_free(block);
104     }
sk_ft_realloc(FT_Memory,FT_Alloc_size_t cur_size,FT_Alloc_size_t new_size,void * block)105     static void* sk_ft_realloc(FT_Memory, FT_Alloc_size_t cur_size,
106                                           FT_Alloc_size_t new_size, void* block) {
107         return sk_realloc_throw(block, new_size);
108     }
109 };
110 FT_MemoryRec_ gFTMemory = { nullptr, sk_ft_alloc, sk_ft_free, sk_ft_realloc };
111 
112 class FreeTypeLibrary : SkNoncopyable {
113 public:
FreeTypeLibrary()114     FreeTypeLibrary() : fLibrary(nullptr) {
115         if (FT_New_Library(&gFTMemory, &fLibrary)) {
116             return;
117         }
118         FT_Add_Default_Modules(fLibrary);
119         FT_Set_Default_Properties(fLibrary);
120 
121         // Subpixel anti-aliasing may be unfiltered until the LCD filter is set.
122         // Newer versions may still need this, so this test with side effects must come first.
123         // The default has changed over time, so this doesn't mean the same thing to all users.
124         FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT);
125     }
~FreeTypeLibrary()126     ~FreeTypeLibrary() {
127         if (fLibrary) {
128             FT_Done_Library(fLibrary);
129         }
130     }
131 
library()132     FT_Library library() { return fLibrary; }
133 
134 private:
135     FT_Library fLibrary;
136 
137     // FT_Library_SetLcdFilterWeights 2.4.0
138     // FT_LOAD_COLOR 2.5.0
139     // FT_Pixel_Mode::FT_PIXEL_MODE_BGRA 2.5.0
140     // Thread safety in 2.6.0
141     // freetype/ftfntfmt.h (rename) 2.6.0
142     // Direct header inclusion 2.6.1
143     // FT_Get_Var_Design_Coordinates 2.7.1
144     // FT_LOAD_BITMAP_METRICS_ONLY 2.7.1
145     // FT_Set_Default_Properties 2.7.2
146     // The 'light' hinting is vertical only from 2.8.0
147     // FT_Get_Var_Axis_Flags 2.8.1
148     // FT_VAR_AXIS_FLAG_HIDDEN was introduced in FreeType 2.8.1
149     // --------------------
150     // FT_Done_MM_Var 2.9.0 (Currenty setting ft_free to a known allocator.)
151     // freetype/ftcolor.h 2.10.0 (Currently assuming if compiled with FT_COLOR_H runtime available.)
152 
153     // Ubuntu 18.04       2.8.1
154     // Debian 10          2.9.1
155     // openSUSE Leap 15.2 2.10.1
156     // Fedora 32          2.10.4
157     // RHEL 8             2.9.1
158 };
159 
f_t_mutex()160 static SkMutex& f_t_mutex() {
161     static SkMutex& mutex = *(new SkMutex);
162     return mutex;
163 }
164 
165 static FreeTypeLibrary* gFTLibrary;
166 
167 ///////////////////////////////////////////////////////////////////////////
168 
169 class SkTypeface_FreeType::FaceRec {
170 public:
171     SkUniqueFTFace fFace;
172     FT_StreamRec fFTStream;
173     std::unique_ptr<SkStreamAsset> fSkStream;
174 
175     static std::unique_ptr<FaceRec> Make(const SkTypeface_FreeType* typeface);
176     ~FaceRec();
177 
178 private:
179     FaceRec(std::unique_ptr<SkStreamAsset> stream);
180     void setupAxes(const SkFontData& data);
181 
182     // Private to ref_ft_library and unref_ft_library
183     static int gFTCount;
184 
185     // Caller must lock f_t_mutex() before calling this function.
ref_ft_library()186     static bool ref_ft_library() {
187         f_t_mutex().assertHeld();
188         SkASSERT(gFTCount >= 0);
189 
190         if (0 == gFTCount) {
191             SkASSERT(nullptr == gFTLibrary);
192             gFTLibrary = new FreeTypeLibrary;
193         }
194         ++gFTCount;
195         return gFTLibrary->library();
196     }
197 
198     // Caller must lock f_t_mutex() before calling this function.
unref_ft_library()199     static void unref_ft_library() {
200         f_t_mutex().assertHeld();
201         SkASSERT(gFTCount > 0);
202 
203         --gFTCount;
204         if (0 == gFTCount) {
205             SkASSERT(nullptr != gFTLibrary);
206             delete gFTLibrary;
207             SkDEBUGCODE(gFTLibrary = nullptr;)
208         }
209     }
210 };
211 int SkTypeface_FreeType::FaceRec::gFTCount;
212 
213 extern "C" {
sk_ft_stream_io(FT_Stream ftStream,unsigned long offset,unsigned char * buffer,unsigned long count)214     static unsigned long sk_ft_stream_io(FT_Stream ftStream,
215                                          unsigned long offset,
216                                          unsigned char* buffer,
217                                          unsigned long count)
218     {
219         SkStreamAsset* stream = static_cast<SkStreamAsset*>(ftStream->descriptor.pointer);
220 
221         if (count) {
222             if (!stream->seek(offset)) {
223                 return 0;
224             }
225             count = stream->read(buffer, count);
226         }
227         return count;
228     }
229 
sk_ft_stream_close(FT_Stream)230     static void sk_ft_stream_close(FT_Stream) {}
231 }
232 
FaceRec(std::unique_ptr<SkStreamAsset> stream)233 SkTypeface_FreeType::FaceRec::FaceRec(std::unique_ptr<SkStreamAsset> stream)
234         : fSkStream(std::move(stream))
235 {
236     sk_bzero(&fFTStream, sizeof(fFTStream));
237     fFTStream.size = fSkStream->getLength();
238     fFTStream.descriptor.pointer = fSkStream.get();
239     fFTStream.read  = sk_ft_stream_io;
240     fFTStream.close = sk_ft_stream_close;
241 
242     f_t_mutex().assertHeld();
243     ref_ft_library();
244 }
245 
~FaceRec()246 SkTypeface_FreeType::FaceRec::~FaceRec() {
247     f_t_mutex().assertHeld();
248     fFace.reset(); // Must release face before the library, the library frees existing faces.
249     unref_ft_library();
250 }
251 
setupAxes(const SkFontData & data)252 void SkTypeface_FreeType::FaceRec::setupAxes(const SkFontData& data) {
253     if (!(fFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
254         return;
255     }
256 
257     // If a named variation is requested, don't overwrite the named variation's position.
258     if (data.getIndex() > 0xFFFF) {
259         return;
260     }
261 
262     SkDEBUGCODE(
263         FT_MM_Var* variations = nullptr;
264         if (FT_Get_MM_Var(fFace.get(), &variations)) {
265             LOG_INFO("INFO: font %s claims variations, but none found.\n",
266                      rec->fFace->family_name);
267             return;
268         }
269         SkAutoFree autoFreeVariations(variations);
270 
271         if (static_cast<FT_UInt>(data.getAxisCount()) != variations->num_axis) {
272             LOG_INFO("INFO: font %s has %d variations, but %d were specified.\n",
273                      rec->fFace->family_name, variations->num_axis, data.getAxisCount());
274             return;
275         }
276     )
277 
278     SkAutoSTMalloc<4, FT_Fixed> coords(data.getAxisCount());
279     for (int i = 0; i < data.getAxisCount(); ++i) {
280         coords[i] = data.getAxis()[i];
281     }
282     if (FT_Set_Var_Design_Coordinates(fFace.get(), data.getAxisCount(), coords.get())) {
283         LOG_INFO("INFO: font %s has variations, but specified variations could not be set.\n",
284                  rec->fFace->family_name);
285         return;
286     }
287 }
288 
289 // Will return nullptr on failure
290 // Caller must lock f_t_mutex() before calling this function.
291 std::unique_ptr<SkTypeface_FreeType::FaceRec>
Make(const SkTypeface_FreeType * typeface)292 SkTypeface_FreeType::FaceRec::Make(const SkTypeface_FreeType* typeface) {
293     f_t_mutex().assertHeld();
294 
295     std::unique_ptr<SkFontData> data = typeface->makeFontData();
296     if (nullptr == data || !data->hasStream()) {
297         return nullptr;
298     }
299 
300     std::unique_ptr<FaceRec> rec(new FaceRec(data->detachStream()));
301 
302     FT_Open_Args args;
303     memset(&args, 0, sizeof(args));
304     const void* memoryBase = rec->fSkStream->getMemoryBase();
305     if (memoryBase) {
306         args.flags = FT_OPEN_MEMORY;
307         args.memory_base = (const FT_Byte*)memoryBase;
308         args.memory_size = rec->fSkStream->getLength();
309     } else {
310         args.flags = FT_OPEN_STREAM;
311         args.stream = &rec->fFTStream;
312     }
313 
314     {
315         FT_Face rawFace;
316         FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(), &rawFace);
317         if (err) {
318             SK_TRACEFTR(err, "unable to open font '%x'", typeface->uniqueID());
319             return nullptr;
320         }
321         rec->fFace.reset(rawFace);
322     }
323     SkASSERT(rec->fFace);
324 
325     rec->setupAxes(*data);
326 
327     // FreeType will set the charmap to the "most unicode" cmap if it exists.
328     // If there are no unicode cmaps, the charmap is set to nullptr.
329     // However, "symbol" cmaps should also be considered "fallback unicode" cmaps
330     // because they are effectively private use area only (even if they aren't).
331     // This is the last on the fallback list at
332     // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
333     if (!rec->fFace->charmap) {
334         FT_Select_Charmap(rec->fFace.get(), FT_ENCODING_MS_SYMBOL);
335     }
336 
337     return rec;
338 }
339 
340 class AutoFTAccess {
341 public:
AutoFTAccess(const SkTypeface_FreeType * tf)342     AutoFTAccess(const SkTypeface_FreeType* tf) : fFaceRec(nullptr) {
343         f_t_mutex().acquire();
344         fFaceRec = tf->getFaceRec();
345     }
346 
~AutoFTAccess()347     ~AutoFTAccess() {
348         f_t_mutex().release();
349     }
350 
face()351     FT_Face face() { return fFaceRec ? fFaceRec->fFace.get() : nullptr; }
352 
353 private:
354     SkTypeface_FreeType::FaceRec* fFaceRec;
355 };
356 
357 ///////////////////////////////////////////////////////////////////////////
358 
359 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base {
360 public:
361     SkScalerContext_FreeType(sk_sp<SkTypeface_FreeType>,
362                              const SkScalerContextEffects&,
363                              const SkDescriptor* desc);
364     ~SkScalerContext_FreeType() override;
365 
success() const366     bool success() const {
367         return fFTSize != nullptr && fFace != nullptr;
368     }
369 
370 protected:
371     bool generateAdvance(SkGlyph* glyph) override;
372     void generateMetrics(SkGlyph* glyph) override;
373     void generateImage(const SkGlyph& glyph) override;
374     bool generatePath(SkGlyphID glyphID, SkPath* path) override;
375     void generateFontMetrics(SkFontMetrics*) override;
376 
377 private:
378     SkTypeface_FreeType::FaceRec* fFaceRec; // Borrowed face from the typeface's FaceRec.
379     FT_Face   fFace;  // Borrowed face from fFaceRec.
380     FT_Size   fFTSize;  // The size to apply to the fFace.
381     FT_Int    fStrikeIndex; // The bitmap strike for the fFace (or -1 if none).
382 
383     /** The rest of the matrix after FreeType handles the size.
384      *  With outline font rasterization this is handled by FreeType with FT_Set_Transform.
385      *  With bitmap only fonts this matrix must be applied to scale the bitmap.
386      */
387     SkMatrix  fMatrix22Scalar;
388     /** Same as fMatrix22Scalar, but in FreeType units and space. */
389     FT_Matrix fMatrix22;
390     /** The actual size requested. */
391     SkVector  fScale;
392 
393     uint32_t  fLoadGlyphFlags;
394     bool      fDoLinearMetrics;
395     bool      fLCDIsVert;
396 
397     FT_Error setupSize();
398     void getBBoxForCurrentGlyph(const SkGlyph* glyph, FT_BBox* bbox,
399                                 bool snapToPixelBoundary = false);
400     bool getCBoxForLetter(char letter, FT_BBox* bbox);
401     // Caller must lock f_t_mutex() before calling this function.
402     void updateGlyphIfLCD(SkGlyph* glyph);
403     // Caller must lock f_t_mutex() before calling this function.
404     // update FreeType2 glyph slot with glyph emboldened
405     void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph, SkGlyphID gid);
406     bool shouldSubpixelBitmap(const SkGlyph&, const SkMatrix&);
407 };
408 
409 ///////////////////////////////////////////////////////////////////////////
410 
canEmbed(FT_Face face)411 static bool canEmbed(FT_Face face) {
412     FT_UShort fsType = FT_Get_FSType_Flags(face);
413     return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
414                       FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0;
415 }
416 
canSubset(FT_Face face)417 static bool canSubset(FT_Face face) {
418     FT_UShort fsType = FT_Get_FSType_Flags(face);
419     return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0;
420 }
421 
get_font_type(FT_Face face)422 static SkAdvancedTypefaceMetrics::FontType get_font_type(FT_Face face) {
423     const char* fontType = FT_Get_X11_Font_Format(face);
424     static struct { const char* s; SkAdvancedTypefaceMetrics::FontType t; } values[] = {
425         { "Type 1",     SkAdvancedTypefaceMetrics::kType1_Font    },
426         { "CID Type 1", SkAdvancedTypefaceMetrics::kType1CID_Font },
427         { "CFF",        SkAdvancedTypefaceMetrics::kCFF_Font      },
428         { "TrueType",   SkAdvancedTypefaceMetrics::kTrueType_Font },
429     };
430     for(const auto& v : values) { if (strcmp(fontType, v.s) == 0) { return v.t; } }
431     return SkAdvancedTypefaceMetrics::kOther_Font;
432 }
433 
onGetAdvancedMetrics() const434 std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_FreeType::onGetAdvancedMetrics() const {
435     AutoFTAccess fta(this);
436     FT_Face face = fta.face();
437     if (!face) {
438         return nullptr;
439     }
440 
441     std::unique_ptr<SkAdvancedTypefaceMetrics> info(new SkAdvancedTypefaceMetrics);
442     info->fPostScriptName.set(FT_Get_Postscript_Name(face));
443     info->fFontName = info->fPostScriptName;
444 
445     if (FT_HAS_MULTIPLE_MASTERS(face)) {
446         info->fFlags |= SkAdvancedTypefaceMetrics::kVariable_FontFlag;
447     }
448     if (!canEmbed(face)) {
449         info->fFlags |= SkAdvancedTypefaceMetrics::kNotEmbeddable_FontFlag;
450     }
451     if (!canSubset(face)) {
452         info->fFlags |= SkAdvancedTypefaceMetrics::kNotSubsettable_FontFlag;
453     }
454 
455     info->fType = get_font_type(face);
456     info->fStyle = (SkAdvancedTypefaceMetrics::StyleFlags)0;
457     if (FT_IS_FIXED_WIDTH(face)) {
458         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
459     }
460     if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
461         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
462     }
463 
464     PS_FontInfoRec psFontInfo;
465     TT_Postscript* postTable;
466     if (FT_Get_PS_Font_Info(face, &psFontInfo) == 0) {
467         info->fItalicAngle = psFontInfo.italic_angle;
468     } else if ((postTable = (TT_Postscript*)FT_Get_Sfnt_Table(face, ft_sfnt_post)) != nullptr) {
469         info->fItalicAngle = SkFixedFloorToInt(postTable->italicAngle);
470     } else {
471         info->fItalicAngle = 0;
472     }
473 
474     info->fAscent = face->ascender;
475     info->fDescent = face->descender;
476 
477     TT_PCLT* pcltTable;
478     TT_OS2* os2Table;
479     if ((pcltTable = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != nullptr) {
480         info->fCapHeight = pcltTable->CapHeight;
481         uint8_t serif_style = pcltTable->SerifStyle & 0x3F;
482         if (2 <= serif_style && serif_style <= 6) {
483             info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
484         } else if (9 <= serif_style && serif_style <= 12) {
485             info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
486         }
487     } else if (((os2Table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != nullptr) &&
488                // sCapHeight is available only when version 2 or later.
489                os2Table->version != 0xFFFF &&
490                os2Table->version >= 2)
491     {
492         info->fCapHeight = os2Table->sCapHeight;
493     }
494     info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax,
495                                     face->bbox.xMax, face->bbox.yMin);
496     return info;
497 }
498 
getGlyphToUnicodeMap(SkUnichar * dstArray) const499 void SkTypeface_FreeType::getGlyphToUnicodeMap(SkUnichar* dstArray) const {
500     AutoFTAccess fta(this);
501     FT_Face face = fta.face();
502     if (!face) {
503         return;
504     }
505 
506     FT_Long numGlyphs = face->num_glyphs;
507     if (!dstArray) { SkASSERT(numGlyphs == 0); }
508     sk_bzero(dstArray, sizeof(SkUnichar) * numGlyphs);
509 
510     FT_UInt glyphIndex;
511     SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
512     while (glyphIndex) {
513         SkASSERT(glyphIndex < SkToUInt(numGlyphs));
514         // Use the first character that maps to this glyphID. https://crbug.com/359065
515         if (0 == dstArray[glyphIndex]) {
516             dstArray[glyphIndex] = charCode;
517         }
518         charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
519     }
520 }
521 
getPostScriptGlyphNames(SkString * dstArray) const522 void SkTypeface_FreeType::getPostScriptGlyphNames(SkString* dstArray) const {
523     AutoFTAccess fta(this);
524     FT_Face face = fta.face();
525     if (!face) {
526         return;
527     }
528 
529     FT_Long numGlyphs = face->num_glyphs;
530     if (!dstArray) { SkASSERT(numGlyphs == 0); }
531 
532     if (FT_HAS_GLYPH_NAMES(face)) {
533         for (int gID = 0; gID < numGlyphs; ++gID) {
534             char glyphName[128];  // PS limit for names is 127 bytes.
535             FT_Get_Glyph_Name(face, gID, glyphName, 128);
536             dstArray[gID] = glyphName;
537         }
538     }
539 }
540 
onGetPostScriptName(SkString * skPostScriptName) const541 bool SkTypeface_FreeType::onGetPostScriptName(SkString* skPostScriptName) const {
542     AutoFTAccess fta(this);
543     FT_Face face = fta.face();
544     if (!face) {
545         return false;
546     }
547 
548     const char* ftPostScriptName = FT_Get_Postscript_Name(face);
549     if (!ftPostScriptName) {
550         return false;
551     }
552     if (skPostScriptName) {
553         *skPostScriptName = ftPostScriptName;
554     }
555     return true;
556 }
557 
558 ///////////////////////////////////////////////////////////////////////////
559 
bothZero(SkScalar a,SkScalar b)560 static bool bothZero(SkScalar a, SkScalar b) {
561     return 0 == a && 0 == b;
562 }
563 
564 // returns false if there is any non-90-rotation or skew
isAxisAligned(const SkScalerContextRec & rec)565 static bool isAxisAligned(const SkScalerContextRec& rec) {
566     return 0 == rec.fPreSkewX &&
567            (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
568             bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
569 }
570 
onCreateScalerContext(const SkScalerContextEffects & effects,const SkDescriptor * desc) const571 std::unique_ptr<SkScalerContext> SkTypeface_FreeType::onCreateScalerContext(
572     const SkScalerContextEffects& effects, const SkDescriptor* desc) const
573 {
574     auto c = std::make_unique<SkScalerContext_FreeType>(
575             sk_ref_sp(const_cast<SkTypeface_FreeType*>(this)), effects, desc);
576     if (c->success()) {
577         return std::move(c);
578     }
579     return SkScalerContext::MakeEmpty(
580             sk_ref_sp(const_cast<SkTypeface_FreeType*>(this)), effects, desc);
581 }
582 
583 /** Copy the design variation coordinates into 'coordinates'.
584  *
585  *  @param coordinates the buffer into which to write the design variation coordinates.
586  *  @param coordinateCount the number of entries available through 'coordinates'.
587  *
588  *  @return The number of axes, or -1 if there is an error.
589  *  If 'coordinates != nullptr' and 'coordinateCount >= numAxes' then 'coordinates' will be
590  *  filled with the variation coordinates describing the position of this typeface in design
591  *  variation space. It is possible the number of axes can be retrieved but actual position
592  *  cannot.
593  */
GetVariationDesignPosition(AutoFTAccess & fta,SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount)594 static int GetVariationDesignPosition(AutoFTAccess& fta,
595     SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount)
596 {
597     FT_Face face = fta.face();
598     if (!face) {
599         return -1;
600     }
601 
602     if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
603         return 0;
604     }
605 
606     FT_MM_Var* variations = nullptr;
607     if (FT_Get_MM_Var(face, &variations)) {
608         return -1;
609     }
610     SkAutoFree autoFreeVariations(variations);
611 
612     if (!coordinates || coordinateCount < SkToInt(variations->num_axis)) {
613         return variations->num_axis;
614     }
615 
616     SkAutoSTMalloc<4, FT_Fixed> coords(variations->num_axis);
617     if (FT_Get_Var_Design_Coordinates(face, variations->num_axis, coords.get())) {
618         return -1;
619     }
620     for (FT_UInt i = 0; i < variations->num_axis; ++i) {
621         coordinates[i].axis = variations->axis[i].tag;
622         coordinates[i].value = SkFixedToScalar(coords[i]);
623     }
624 
625     return variations->num_axis;
626 }
627 
cloneFontData(const SkFontArguments & args) const628 std::unique_ptr<SkFontData> SkTypeface_FreeType::cloneFontData(const SkFontArguments& args) const {
629     AutoFTAccess fta(this);
630     FT_Face face = fta.face();
631     if (!face) {
632         return nullptr;
633     }
634 
635     Scanner::AxisDefinitions axisDefinitions;
636     if (!Scanner::GetAxes(face, &axisDefinitions)) {
637         return nullptr;
638     }
639     int axisCount = axisDefinitions.count();
640 
641     SkAutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate> currentPosition(axisCount);
642     int currentAxisCount = GetVariationDesignPosition(fta, currentPosition, axisCount);
643 
644     SkString name;
645     SkAutoSTMalloc<4, SkFixed> axisValues(axisCount);
646     Scanner::computeAxisValues(axisDefinitions, args.getVariationDesignPosition(), axisValues, name,
647                                currentAxisCount == axisCount ? currentPosition.get() : nullptr);
648     int ttcIndex;
649     std::unique_ptr<SkStreamAsset> stream = this->openStream(&ttcIndex);
650     return std::make_unique<SkFontData>(std::move(stream), ttcIndex, axisValues.get(), axisCount);
651 }
652 
onFilterRec(SkScalerContextRec * rec) const653 void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
654     //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119
655     //Cap the requested size as larger sizes give bogus values.
656     //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed.
657     //Note that this also currently only protects against large text size requests,
658     //the total matrix is not taken into account here.
659     if (rec->fTextSize > SkIntToScalar(1 << 14)) {
660         rec->fTextSize = SkIntToScalar(1 << 14);
661     }
662 
663     SkFontHinting h = rec->getHinting();
664     if (SkFontHinting::kFull == h && !isLCD(*rec)) {
665         // collapse full->normal hinting if we're not doing LCD
666         h = SkFontHinting::kNormal;
667     }
668 
669     // rotated text looks bad with hinting, so we disable it as needed
670     if (!isAxisAligned(*rec)) {
671         h = SkFontHinting::kNone;
672     }
673     rec->setHinting(h);
674 
675 #ifndef SK_GAMMA_APPLY_TO_A8
676     if (!isLCD(*rec)) {
677         // SRGBTODO: Is this correct? Do we want contrast boost?
678         rec->ignorePreBlend();
679     }
680 #endif
681 }
682 
GetUnitsPerEm(FT_Face face)683 int SkTypeface_FreeType::GetUnitsPerEm(FT_Face face) {
684     SkASSERT(face);
685 
686     SkScalar upem = SkIntToScalar(face->units_per_EM);
687     // At least some versions of FreeType set face->units_per_EM to 0 for bitmap only fonts.
688     if (upem == 0) {
689         TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
690         if (ttHeader) {
691             upem = SkIntToScalar(ttHeader->Units_Per_EM);
692         }
693     }
694     return upem;
695 }
696 
onGetUPEM() const697 int SkTypeface_FreeType::onGetUPEM() const {
698     AutoFTAccess fta(this);
699     FT_Face face = fta.face();
700     if (!face) {
701         return 0;
702     }
703     return GetUnitsPerEm(face);
704 }
705 
onGetKerningPairAdjustments(const uint16_t glyphs[],int count,int32_t adjustments[]) const706 bool SkTypeface_FreeType::onGetKerningPairAdjustments(const uint16_t glyphs[],
707                                       int count, int32_t adjustments[]) const {
708     AutoFTAccess fta(this);
709     FT_Face face = fta.face();
710     if (!face || !FT_HAS_KERNING(face)) {
711         return false;
712     }
713 
714     for (int i = 0; i < count - 1; ++i) {
715         FT_Vector delta;
716         FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1],
717                                       FT_KERNING_UNSCALED, &delta);
718         if (err) {
719             return false;
720         }
721         adjustments[i] = delta.x;
722     }
723     return true;
724 }
725 
726 /** Returns the bitmap strike equal to or just larger than the requested size. */
chooseBitmapStrike(FT_Face face,FT_F26Dot6 scaleY)727 static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) {
728     if (face == nullptr) {
729         LOG_INFO("chooseBitmapStrike aborted due to nullptr face.\n");
730         return -1;
731     }
732 
733     FT_Pos requestedPPEM = scaleY;  // FT_Bitmap_Size::y_ppem is in 26.6 format.
734     FT_Int chosenStrikeIndex = -1;
735     FT_Pos chosenPPEM = 0;
736     for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIndex) {
737         FT_Pos strikePPEM = face->available_sizes[strikeIndex].y_ppem;
738         if (strikePPEM == requestedPPEM) {
739             // exact match - our search stops here
740             return strikeIndex;
741         } else if (chosenPPEM < requestedPPEM) {
742             // attempt to increase chosenPPEM
743             if (chosenPPEM < strikePPEM) {
744                 chosenPPEM = strikePPEM;
745                 chosenStrikeIndex = strikeIndex;
746             }
747         } else {
748             // attempt to decrease chosenPPEM, but not below requestedPPEM
749             if (requestedPPEM < strikePPEM && strikePPEM < chosenPPEM) {
750                 chosenPPEM = strikePPEM;
751                 chosenStrikeIndex = strikeIndex;
752             }
753         }
754     }
755     return chosenStrikeIndex;
756 }
757 
SkScalerContext_FreeType(sk_sp<SkTypeface_FreeType> typeface,const SkScalerContextEffects & effects,const SkDescriptor * desc)758 SkScalerContext_FreeType::SkScalerContext_FreeType(sk_sp<SkTypeface_FreeType> typeface,
759                                                    const SkScalerContextEffects& effects,
760                                                    const SkDescriptor* desc)
761     : SkScalerContext_FreeType_Base(std::move(typeface), effects, desc)
762     , fFace(nullptr)
763     , fFTSize(nullptr)
764     , fStrikeIndex(-1)
765 {
766     SkAutoMutexExclusive  ac(f_t_mutex());
767     fFaceRec = static_cast<SkTypeface_FreeType*>(this->getTypeface())->getFaceRec();
768 
769     // load the font file
770     if (nullptr == fFaceRec) {
771         LOG_INFO("Could not create FT_Face.\n");
772         return;
773     }
774 
775     fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
776 
777     // compute the flags we send to Load_Glyph
778     bool linearMetrics = this->isLinearMetrics();
779     {
780         FT_Int32 loadFlags = FT_LOAD_DEFAULT;
781 
782         if (SkMask::kBW_Format == fRec.fMaskFormat) {
783             // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
784             loadFlags = FT_LOAD_TARGET_MONO;
785             if (fRec.getHinting() == SkFontHinting::kNone) {
786                 loadFlags = FT_LOAD_NO_HINTING;
787                 linearMetrics = true;
788             }
789         } else {
790             switch (fRec.getHinting()) {
791             case SkFontHinting::kNone:
792                 loadFlags = FT_LOAD_NO_HINTING;
793                 linearMetrics = true;
794                 break;
795             case SkFontHinting::kSlight:
796                 loadFlags = FT_LOAD_TARGET_LIGHT;  // This implies FORCE_AUTOHINT
797                 linearMetrics = true;
798                 break;
799             case SkFontHinting::kNormal:
800                 loadFlags = FT_LOAD_TARGET_NORMAL;
801                 break;
802             case SkFontHinting::kFull:
803                 loadFlags = FT_LOAD_TARGET_NORMAL;
804                 if (isLCD(fRec)) {
805                     if (fLCDIsVert) {
806                         loadFlags = FT_LOAD_TARGET_LCD_V;
807                     } else {
808                         loadFlags = FT_LOAD_TARGET_LCD;
809                     }
810                 }
811                 break;
812             default:
813                 LOG_INFO("---------- UNKNOWN hinting %d\n", fRec.getHinting());
814                 break;
815             }
816         }
817 
818         if (fRec.fFlags & SkScalerContext::kForceAutohinting_Flag) {
819             loadFlags |= FT_LOAD_FORCE_AUTOHINT;
820 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
821         } else {
822             loadFlags |= FT_LOAD_NO_AUTOHINT;
823 #endif
824         }
825 
826         if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) {
827             loadFlags |= FT_LOAD_NO_BITMAP;
828         }
829 
830         // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
831         // advances, as fontconfig and cairo do.
832         // See http://code.google.com/p/skia/issues/detail?id=222.
833         loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
834 
835         // Use vertical layout if requested.
836         if (this->isVertical()) {
837             loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
838         }
839 
840         loadFlags |= FT_LOAD_COLOR;
841 
842         fLoadGlyphFlags = loadFlags;
843     }
844 
845     using DoneFTSize = SkFunctionWrapper<decltype(FT_Done_Size), FT_Done_Size>;
846     std::unique_ptr<std::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([this]() -> FT_Size {
847         FT_Size size;
848         FT_Error err = FT_New_Size(fFaceRec->fFace.get(), &size);
849         if (err != 0) {
850             SK_TRACEFTR(err, "FT_New_Size(%s) failed.", fFaceRec->fFace->family_name);
851             return nullptr;
852         }
853         return size;
854     }());
855     if (nullptr == ftSize) {
856         LOG_INFO("Could not create FT_Size.\n");
857         return;
858     }
859 
860     FT_Error err = FT_Activate_Size(ftSize.get());
861     if (err != 0) {
862         SK_TRACEFTR(err, "FT_Activate_Size(%s) failed.", fFaceRec->fFace->family_name);
863         return;
864     }
865 
866     fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMatrix22Scalar);
867     FT_F26Dot6 scaleX = SkScalarToFDot6(fScale.fX);
868     FT_F26Dot6 scaleY = SkScalarToFDot6(fScale.fY);
869 
870     if (FT_IS_SCALABLE(fFaceRec->fFace)) {
871         err = FT_Set_Char_Size(fFaceRec->fFace.get(), scaleX, scaleY, 72, 72);
872         if (err != 0) {
873             SK_TRACEFTR(err, "FT_Set_CharSize(%s, %f, %f) failed.",
874                         fFaceRec->fFace->family_name, fScale.fX, fScale.fY);
875             return;
876         }
877 
878         // Adjust the matrix to reflect the actually chosen scale.
879         // FreeType currently does not allow requesting sizes less than 1, this allow for scaling.
880         // Don't do this at all sizes as that will interfere with hinting.
881         if (fScale.fX < 1 || fScale.fY < 1) {
882             SkScalar upem = fFaceRec->fFace->units_per_EM;
883             FT_Size_Metrics& ftmetrics = fFaceRec->fFace->size->metrics;
884             SkScalar x_ppem = upem * SkFT_FixedToScalar(ftmetrics.x_scale) / 64.0f;
885             SkScalar y_ppem = upem * SkFT_FixedToScalar(ftmetrics.y_scale) / 64.0f;
886             fMatrix22Scalar.preScale(fScale.x() / x_ppem, fScale.y() / y_ppem);
887         }
888 
889     } else if (FT_HAS_FIXED_SIZES(fFaceRec->fFace)) {
890         fStrikeIndex = chooseBitmapStrike(fFaceRec->fFace.get(), scaleY);
891         if (fStrikeIndex == -1) {
892             LOG_INFO("No glyphs for font \"%s\" size %f.\n",
893                      fFaceRec->fFace->family_name, fScale.fY);
894             return;
895         }
896 
897         err = FT_Select_Size(fFaceRec->fFace.get(), fStrikeIndex);
898         if (err != 0) {
899             SK_TRACEFTR(err, "FT_Select_Size(%s, %d) failed.",
900                         fFaceRec->fFace->family_name, fStrikeIndex);
901             fStrikeIndex = -1;
902             return;
903         }
904 
905         // Adjust the matrix to reflect the actually chosen scale.
906         // It is likely that the ppem chosen was not the one requested, this allows for scaling.
907         fMatrix22Scalar.preScale(fScale.x() / fFaceRec->fFace->size->metrics.x_ppem,
908                                  fScale.y() / fFaceRec->fFace->size->metrics.y_ppem);
909 
910         // FreeType does not provide linear metrics for bitmap fonts.
911         linearMetrics = false;
912 
913         // FreeType documentation says:
914         // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading.
915         // Bitmap-only fonts ignore this flag.
916         //
917         // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag.
918         // Force this flag off for bitmap only fonts.
919         fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
920     } else {
921         LOG_INFO("Unknown kind of font \"%s\" size %f.\n", fFaceRec->fFace->family_name, fScale.fY);
922         return;
923     }
924 
925     fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
926     fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
927     fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
928     fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
929 
930 #ifdef FT_COLOR_H
931     FT_Palette_Select(fFaceRec->fFace.get(), 0, nullptr);
932 #endif
933 
934     fFTSize = ftSize.release();
935     fFace = fFaceRec->fFace.get();
936     fDoLinearMetrics = linearMetrics;
937 }
938 
~SkScalerContext_FreeType()939 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
940     SkAutoMutexExclusive  ac(f_t_mutex());
941 
942     if (fFTSize != nullptr) {
943         FT_Done_Size(fFTSize);
944     }
945 
946     fFaceRec = nullptr;
947 }
948 
949 /*  We call this before each use of the fFace, since we may be sharing
950     this face with other context (at different sizes).
951 */
setupSize()952 FT_Error SkScalerContext_FreeType::setupSize() {
953     f_t_mutex().assertHeld();
954     FT_Error err = FT_Activate_Size(fFTSize);
955     if (err != 0) {
956         return err;
957     }
958     FT_Set_Transform(fFace, &fMatrix22, nullptr);
959     return 0;
960 }
961 
generateAdvance(SkGlyph * glyph)962 bool SkScalerContext_FreeType::generateAdvance(SkGlyph* glyph) {
963    /* unhinted and light hinted text have linearly scaled advances
964     * which are very cheap to compute with some font formats...
965     */
966     if (!fDoLinearMetrics) {
967         return false;
968     }
969 
970     SkAutoMutexExclusive  ac(f_t_mutex());
971 
972     if (this->setupSize()) {
973         glyph->zeroMetrics();
974         return true;
975     }
976 
977     FT_Error    error;
978     FT_Fixed    advance;
979 
980     error = FT_Get_Advance( fFace, glyph->getGlyphID(),
981                             fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY,
982                             &advance );
983 
984     if (error != 0) {
985         return false;
986     }
987 
988     const SkScalar advanceScalar = SkFT_FixedToScalar(advance);
989     glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * advanceScalar);
990     glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getSkewY() * advanceScalar);
991     return true;
992 }
993 
getBBoxForCurrentGlyph(const SkGlyph * glyph,FT_BBox * bbox,bool snapToPixelBoundary)994 void SkScalerContext_FreeType::getBBoxForCurrentGlyph(const SkGlyph* glyph,
995                                                       FT_BBox* bbox,
996                                                       bool snapToPixelBoundary) {
997 
998     FT_Outline_Get_CBox(&fFace->glyph->outline, bbox);
999 
1000     if (this->isSubpixel()) {
1001         int dx = SkFixedToFDot6(glyph->getSubXFixed());
1002         int dy = SkFixedToFDot6(glyph->getSubYFixed());
1003         // negate dy since freetype-y-goes-up and skia-y-goes-down
1004         bbox->xMin += dx;
1005         bbox->yMin -= dy;
1006         bbox->xMax += dx;
1007         bbox->yMax -= dy;
1008     }
1009 
1010     // outset the box to integral boundaries
1011     if (snapToPixelBoundary) {
1012         bbox->xMin &= ~63;
1013         bbox->yMin &= ~63;
1014         bbox->xMax  = (bbox->xMax + 63) & ~63;
1015         bbox->yMax  = (bbox->yMax + 63) & ~63;
1016     }
1017 
1018     // Must come after snapToPixelBoundary so that the width and height are
1019     // consistent. Otherwise asserts will fire later on when generating the
1020     // glyph image.
1021     if (this->isVertical()) {
1022         FT_Vector vector;
1023         vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1024         vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1025         FT_Vector_Transform(&vector, &fMatrix22);
1026         bbox->xMin += vector.x;
1027         bbox->xMax += vector.x;
1028         bbox->yMin += vector.y;
1029         bbox->yMax += vector.y;
1030     }
1031 }
1032 
getCBoxForLetter(char letter,FT_BBox * bbox)1033 bool SkScalerContext_FreeType::getCBoxForLetter(char letter, FT_BBox* bbox) {
1034     const FT_UInt glyph_id = FT_Get_Char_Index(fFace, letter);
1035     if (!glyph_id) {
1036         return false;
1037     }
1038     if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags) != 0) {
1039         return false;
1040     }
1041     emboldenIfNeeded(fFace, fFace->glyph, SkTo<SkGlyphID>(glyph_id));
1042     FT_Outline_Get_CBox(&fFace->glyph->outline, bbox);
1043     return true;
1044 }
1045 
updateGlyphIfLCD(SkGlyph * glyph)1046 void SkScalerContext_FreeType::updateGlyphIfLCD(SkGlyph* glyph) {
1047     if (glyph->fMaskFormat == SkMask::kLCD16_Format) {
1048         if (fLCDIsVert) {
1049             glyph->fHeight += 2;
1050             glyph->fTop -= 1;
1051         } else {
1052             glyph->fWidth += 2;
1053             glyph->fLeft -= 1;
1054         }
1055     }
1056 }
1057 
shouldSubpixelBitmap(const SkGlyph & glyph,const SkMatrix & matrix)1058 bool SkScalerContext_FreeType::shouldSubpixelBitmap(const SkGlyph& glyph, const SkMatrix& matrix) {
1059     // If subpixel rendering of a bitmap *can* be done.
1060     bool mechanism = fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP &&
1061                      this->isSubpixel() &&
1062                      (glyph.getSubXFixed() || glyph.getSubYFixed());
1063 
1064     // If subpixel rendering of a bitmap *should* be done.
1065     // 1. If the face is not scalable then always allow subpixel rendering.
1066     //    Otherwise, if the font has an 8ppem strike 7 will subpixel render but 8 won't.
1067     // 2. If the matrix is already not identity the bitmap will already be resampled,
1068     //    so resampling slightly differently shouldn't make much difference.
1069     bool policy = !FT_IS_SCALABLE(fFace) || !matrix.isIdentity();
1070 
1071     return mechanism && policy;
1072 }
1073 
generateMetrics(SkGlyph * glyph)1074 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1075     SkAutoMutexExclusive  ac(f_t_mutex());
1076 
1077     glyph->fMaskFormat = fRec.fMaskFormat;
1078 
1079     if (this->setupSize()) {
1080         glyph->zeroMetrics();
1081         return;
1082     }
1083 
1084     FT_Error    err;
1085     err = FT_Load_Glyph( fFace, glyph->getGlyphID(),
1086                          fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY );
1087     if (err != 0) {
1088         glyph->zeroMetrics();
1089         return;
1090     }
1091     emboldenIfNeeded(fFace, fFace->glyph, glyph->getGlyphID());
1092 
1093     if (fFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1094         using FT_PosLimits = std::numeric_limits<FT_Pos>;
1095         FT_BBox bounds = { FT_PosLimits::max(), FT_PosLimits::max(),
1096                            FT_PosLimits::min(), FT_PosLimits::min() };
1097 #ifdef FT_COLOR_H
1098         FT_Bool haveLayers = false;
1099         FT_LayerIterator layerIterator = { 0, 0, nullptr };
1100         FT_UInt layerGlyphIndex;
1101         FT_UInt layerColorIndex;
1102 
1103 #ifdef TT_SUPPORT_COLRV1
1104         FT_OpaquePaint opaqueLayerPaint;
1105         opaqueLayerPaint.p = nullptr;
1106         if (FT_Get_Color_Glyph_Paint(fFace, glyph->getGlyphID(),
1107                                      FT_COLOR_INCLUDE_ROOT_TRANSFORM, &opaqueLayerPaint)) {
1108             haveLayers = true;
1109 
1110             FT_ClipBox colrGlyphBbox;
1111 
1112             // COLRv1 optionally provides a ClipBox that we can use for allocation.
1113             if (FT_Get_Color_Glyph_ClipBox(fFace, glyph->getGlyphID(), &colrGlyphBbox)) {
1114                 // Find enclosing bounding box of clip box corner points, needed
1115                 // when clipbox is transformed.
1116                 bounds.xMin = colrGlyphBbox.bottom_left.x;
1117                 bounds.xMax = colrGlyphBbox.bottom_left.x;
1118                 bounds.yMin = colrGlyphBbox.bottom_left.y;
1119                 bounds.yMax = colrGlyphBbox.bottom_left.y;
1120 
1121                 for (auto& corner : {colrGlyphBbox.top_left,
1122                                      colrGlyphBbox.top_right,
1123                                      colrGlyphBbox.bottom_right}) {
1124                     if (corner.x < bounds.xMin) {
1125                         bounds.xMin = corner.x;
1126                     }
1127                     if (corner.y < bounds.yMin) {
1128                         bounds.yMin = corner.y;
1129                     }
1130                     if (corner.x > bounds.xMax) {
1131                         bounds.xMax = corner.x;
1132                     }
1133                     if (corner.y > bounds.yMax) {
1134                         bounds.yMax = corner.y;
1135                     }
1136                 }
1137           } else {
1138               // Otherwise we need to traverse the glyph graph with a focus on measuring the
1139               // required bounding box.
1140               FT_BBox computed_bounds;
1141               if (!computeColrV1GlyphBoundingBox(fFace, glyph->getGlyphID(), &computed_bounds)) {
1142                   glyph->zeroMetrics();
1143                   return;
1144               }
1145 
1146               // Reset face so the main glyph slot contains information about the
1147               // base glyph again, for usage for computing and copying horizontal
1148               // metrics from FreeType to Skia below.
1149               if (this->setupSize()) {
1150                   glyph->zeroMetrics();
1151                   return;
1152               }
1153 
1154               err = FT_Load_Glyph(
1155                       fFace, glyph->getGlyphID(), fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY);
1156               if (err != 0) {
1157                   glyph->zeroMetrics();
1158                   return;
1159               }
1160 
1161               bounds = computed_bounds;
1162           }
1163         }
1164 #endif // #TT_SUPPORT_COLRV1
1165 
1166         if (!haveLayers) {
1167             // For COLRv0 compute the glyph bounding box from the union of layer bounding boxes.
1168             while (FT_Get_Color_Glyph_Layer(fFace, glyph->getGlyphID(), &layerGlyphIndex,
1169                                             &layerColorIndex, &layerIterator)) {
1170                 haveLayers = true;
1171                 err = FT_Load_Glyph(fFace, layerGlyphIndex,
1172                                     fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY);
1173                 if (err != 0) {
1174                     glyph->zeroMetrics();
1175                     return;
1176                 }
1177                 emboldenIfNeeded(fFace, fFace->glyph, layerGlyphIndex);
1178 
1179                 if (0 < fFace->glyph->outline.n_contours) {
1180                     FT_BBox bbox;
1181                     getBBoxForCurrentGlyph(glyph, &bbox, true);
1182 
1183                     // Union
1184                     bounds.xMin = std::min(bbox.xMin, bounds.xMin);
1185                     bounds.yMin = std::min(bbox.yMin, bounds.yMin);
1186                     bounds.xMax = std::max(bbox.xMax, bounds.xMax);
1187                     bounds.yMax = std::max(bbox.yMax, bounds.yMax);
1188                 }
1189             }
1190         }
1191 
1192         if (haveLayers) {
1193             glyph->fMaskFormat = SkMask::kARGB32_Format;
1194             if (!(bounds.xMin < bounds.xMax && bounds.yMin < bounds.yMax)) {
1195                 bounds = { 0, 0, 0, 0 };
1196             }
1197         } else {
1198 #endif
1199             if (0 < fFace->glyph->outline.n_contours) {
1200                 getBBoxForCurrentGlyph(glyph, &bounds, true);
1201             } else {
1202                 bounds = { 0, 0, 0, 0 };
1203             }
1204 #ifdef FT_COLOR_H
1205         }
1206 #endif
1207         // Round out, no longer dot6.
1208         bounds.xMin = SkFDot6Floor(bounds.xMin);
1209         bounds.yMin = SkFDot6Floor(bounds.yMin);
1210         bounds.xMax = SkFDot6Ceil (bounds.xMax);
1211         bounds.yMax = SkFDot6Ceil (bounds.yMax);
1212 
1213         FT_Pos width  =  bounds.xMax - bounds.xMin;
1214         FT_Pos height =  bounds.yMax - bounds.yMin;
1215         FT_Pos top    = -bounds.yMax;  // Freetype y-up, Skia y-down.
1216         FT_Pos left   =  bounds.xMin;
1217         if (!SkTFitsIn<decltype(glyph->fWidth )>(width ) ||
1218             !SkTFitsIn<decltype(glyph->fHeight)>(height) ||
1219             !SkTFitsIn<decltype(glyph->fTop   )>(top   ) ||
1220             !SkTFitsIn<decltype(glyph->fLeft  )>(left  )  )
1221         {
1222             width = height = top = left = 0;
1223         }
1224 
1225         glyph->fWidth  = SkToU16(width );
1226         glyph->fHeight = SkToU16(height);
1227         glyph->fTop    = SkToS16(top   );
1228         glyph->fLeft   = SkToS16(left  );
1229         updateGlyphIfLCD(glyph);
1230 
1231     } else if (fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
1232         if (this->isVertical()) {
1233             FT_Vector vector;
1234             vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1235             vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1236             FT_Vector_Transform(&vector, &fMatrix22);
1237             fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1238             fFace->glyph->bitmap_top  += SkFDot6Floor(vector.y);
1239         }
1240 
1241         if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
1242             glyph->fMaskFormat = SkMask::kARGB32_Format;
1243         }
1244 
1245         {
1246             SkRect rect = SkRect::MakeXYWH(SkIntToScalar(fFace->glyph->bitmap_left),
1247                                           -SkIntToScalar(fFace->glyph->bitmap_top),
1248                                            SkIntToScalar(fFace->glyph->bitmap.width),
1249                                            SkIntToScalar(fFace->glyph->bitmap.rows));
1250             fMatrix22Scalar.mapRect(&rect);
1251             if (this->shouldSubpixelBitmap(*glyph, fMatrix22Scalar)) {
1252                 rect.offset(SkFixedToScalar(glyph->getSubXFixed()),
1253                             SkFixedToScalar(glyph->getSubYFixed()));
1254             }
1255             SkIRect irect = rect.roundOut();
1256             glyph->fWidth   = SkToU16(irect.width());
1257             glyph->fHeight  = SkToU16(irect.height());
1258             glyph->fTop     = SkToS16(irect.top());
1259             glyph->fLeft    = SkToS16(irect.left());
1260         }
1261     } else {
1262         SkDEBUGFAIL("unknown glyph format");
1263         glyph->zeroMetrics();
1264         return;
1265     }
1266 
1267     if (this->isVertical()) {
1268         if (fDoLinearMetrics) {
1269             const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->linearVertAdvance);
1270             glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getSkewX() * advanceScalar);
1271             glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getScaleY() * advanceScalar);
1272         } else {
1273             glyph->fAdvanceX = -SkFDot6ToFloat(fFace->glyph->advance.x);
1274             glyph->fAdvanceY = SkFDot6ToFloat(fFace->glyph->advance.y);
1275         }
1276     } else {
1277         if (fDoLinearMetrics) {
1278             const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->linearHoriAdvance);
1279             glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * advanceScalar);
1280             glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getSkewY() * advanceScalar);
1281         } else {
1282             glyph->fAdvanceX = SkFDot6ToFloat(fFace->glyph->advance.x);
1283             glyph->fAdvanceY = -SkFDot6ToFloat(fFace->glyph->advance.y);
1284         }
1285     }
1286 
1287 #ifdef ENABLE_GLYPH_SPEW
1288     LOG_INFO("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadGlyphFlags, glyph->fWidth);
1289 #endif
1290 }
1291 
generateImage(const SkGlyph & glyph)1292 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1293     SkAutoMutexExclusive  ac(f_t_mutex());
1294 
1295     if (this->setupSize()) {
1296         sk_bzero(glyph.fImage, glyph.imageSize());
1297         return;
1298     }
1299 
1300     FT_Error err = FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags);
1301     if (err != 0) {
1302         SK_TRACEFTR(err, "SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph:%d "
1303                      "width:%d height:%d rb:%zu flags:%d) failed.",
1304                      glyph.getGlyphID(), glyph.width(), glyph.height(), glyph.rowBytes(),
1305                      fLoadGlyphFlags);
1306         sk_bzero(glyph.fImage, glyph.imageSize());
1307         return;
1308     }
1309 
1310     emboldenIfNeeded(fFace, fFace->glyph, glyph.getGlyphID());
1311     SkMatrix* bitmapMatrix = &fMatrix22Scalar;
1312     SkMatrix subpixelBitmapMatrix;
1313     if (this->shouldSubpixelBitmap(glyph, *bitmapMatrix)) {
1314         subpixelBitmapMatrix = fMatrix22Scalar;
1315         subpixelBitmapMatrix.postTranslate(SkFixedToScalar(glyph.getSubXFixed()),
1316                                            SkFixedToScalar(glyph.getSubYFixed()));
1317         bitmapMatrix = &subpixelBitmapMatrix;
1318     }
1319     generateGlyphImage(fFace, glyph, *bitmapMatrix);
1320 }
1321 
1322 
generatePath(SkGlyphID glyphID,SkPath * path)1323 bool SkScalerContext_FreeType::generatePath(SkGlyphID glyphID, SkPath* path) {
1324     SkASSERT(path);
1325 
1326     SkAutoMutexExclusive  ac(f_t_mutex());
1327 
1328     // FT_IS_SCALABLE is documented to mean the face contains outline glyphs.
1329     if (!FT_IS_SCALABLE(fFace) || this->setupSize()) {
1330         path->reset();
1331         return false;
1332     }
1333 
1334     uint32_t flags = fLoadGlyphFlags;
1335     flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
1336     flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
1337 
1338     FT_Error err = FT_Load_Glyph(fFace, glyphID, flags);
1339     if (err != 0 || fFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1340         path->reset();
1341         return false;
1342     }
1343     emboldenIfNeeded(fFace, fFace->glyph, glyphID);
1344 
1345     if (!generateGlyphPath(fFace, path)) {
1346         path->reset();
1347         return false;
1348     }
1349 
1350     // The path's origin from FreeType is always the horizontal layout origin.
1351     // Offset the path so that it is relative to the vertical origin if needed.
1352     if (this->isVertical()) {
1353         FT_Vector vector;
1354         vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1355         vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1356         FT_Vector_Transform(&vector, &fMatrix22);
1357         path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y));
1358     }
1359     return true;
1360 }
1361 
generateFontMetrics(SkFontMetrics * metrics)1362 void SkScalerContext_FreeType::generateFontMetrics(SkFontMetrics* metrics) {
1363     if (nullptr == metrics) {
1364         return;
1365     }
1366 
1367     SkAutoMutexExclusive ac(f_t_mutex());
1368 
1369     if (this->setupSize()) {
1370         sk_bzero(metrics, sizeof(*metrics));
1371         return;
1372     }
1373 
1374     FT_Face face = fFace;
1375     metrics->fFlags = 0;
1376 
1377     SkScalar upem = SkIntToScalar(SkTypeface_FreeType::GetUnitsPerEm(face));
1378 
1379     // use the os/2 table as a source of reasonable defaults.
1380     SkScalar x_height = 0.0f;
1381     SkScalar avgCharWidth = 0.0f;
1382     SkScalar cap_height = 0.0f;
1383     SkScalar strikeoutThickness = 0.0f, strikeoutPosition = 0.0f;
1384     TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1385     if (os2) {
1386         x_height = SkIntToScalar(os2->sxHeight) / upem * fScale.y();
1387         avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem;
1388         strikeoutThickness = SkIntToScalar(os2->yStrikeoutSize) / upem;
1389         strikeoutPosition = -SkIntToScalar(os2->yStrikeoutPosition) / upem;
1390         metrics->fFlags |= SkFontMetrics::kStrikeoutThicknessIsValid_Flag;
1391         metrics->fFlags |= SkFontMetrics::kStrikeoutPositionIsValid_Flag;
1392         if (os2->version != 0xFFFF && os2->version >= 2) {
1393             cap_height = SkIntToScalar(os2->sCapHeight) / upem * fScale.y();
1394         }
1395     }
1396 
1397     // pull from format-specific metrics as needed
1398     SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax;
1399     SkScalar underlineThickness, underlinePosition;
1400     if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font
1401         // FreeType will always use HHEA metrics if they're not zero.
1402         // It completely ignores the OS/2 fsSelection::UseTypoMetrics bit.
1403         // It also ignores the VDMX tables, which are also of interest here
1404         // (and override everything else when they apply).
1405         static const int kUseTypoMetricsMask = (1 << 7);
1406         if (os2 && os2->version != 0xFFFF && (os2->fsSelection & kUseTypoMetricsMask)) {
1407             ascent = -SkIntToScalar(os2->sTypoAscender) / upem;
1408             descent = -SkIntToScalar(os2->sTypoDescender) / upem;
1409             leading = SkIntToScalar(os2->sTypoLineGap) / upem;
1410         } else {
1411             ascent = -SkIntToScalar(face->ascender) / upem;
1412             descent = -SkIntToScalar(face->descender) / upem;
1413             leading = SkIntToScalar(face->height + (face->descender - face->ascender)) / upem;
1414         }
1415         xmin = SkIntToScalar(face->bbox.xMin) / upem;
1416         xmax = SkIntToScalar(face->bbox.xMax) / upem;
1417         ymin = -SkIntToScalar(face->bbox.yMin) / upem;
1418         ymax = -SkIntToScalar(face->bbox.yMax) / upem;
1419         underlineThickness = SkIntToScalar(face->underline_thickness) / upem;
1420         underlinePosition = -SkIntToScalar(face->underline_position +
1421                                            face->underline_thickness / 2) / upem;
1422 
1423         metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
1424         metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
1425 
1426         // we may be able to synthesize x_height and cap_height from outline
1427         if (!x_height) {
1428             FT_BBox bbox;
1429             if (getCBoxForLetter('x', &bbox)) {
1430                 x_height = SkIntToScalar(bbox.yMax) / 64.0f;
1431             }
1432         }
1433         if (!cap_height) {
1434             FT_BBox bbox;
1435             if (getCBoxForLetter('H', &bbox)) {
1436                 cap_height = SkIntToScalar(bbox.yMax) / 64.0f;
1437             }
1438         }
1439     } else if (fStrikeIndex != -1) { // bitmap strike metrics
1440         SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem);
1441         SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem);
1442         ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f);
1443         descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f);
1444         leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f)) + ascent - descent;
1445 
1446         xmin = 0.0f;
1447         xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
1448         ymin = descent;
1449         ymax = ascent;
1450         // The actual bitmaps may be any size and placed at any offset.
1451         metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
1452 
1453         underlineThickness = 0;
1454         underlinePosition = 0;
1455         metrics->fFlags &= ~SkFontMetrics::kUnderlineThicknessIsValid_Flag;
1456         metrics->fFlags &= ~SkFontMetrics::kUnderlinePositionIsValid_Flag;
1457 
1458         TT_Postscript* post = (TT_Postscript*) FT_Get_Sfnt_Table(face, ft_sfnt_post);
1459         if (post) {
1460             underlineThickness = SkIntToScalar(post->underlineThickness) / upem;
1461             underlinePosition = -SkIntToScalar(post->underlinePosition) / upem;
1462             metrics->fFlags |= SkFontMetrics::kUnderlineThicknessIsValid_Flag;
1463             metrics->fFlags |= SkFontMetrics::kUnderlinePositionIsValid_Flag;
1464         }
1465     } else {
1466         sk_bzero(metrics, sizeof(*metrics));
1467         return;
1468     }
1469 
1470     // synthesize elements that were not provided by the os/2 table or format-specific metrics
1471     if (!x_height) {
1472         x_height = -ascent * fScale.y();
1473     }
1474     if (!avgCharWidth) {
1475         avgCharWidth = xmax - xmin;
1476     }
1477     if (!cap_height) {
1478       cap_height = -ascent * fScale.y();
1479     }
1480 
1481     // disallow negative linespacing
1482     if (leading < 0.0f) {
1483         leading = 0.0f;
1484     }
1485 
1486     metrics->fTop = ymax * fScale.y();
1487     metrics->fAscent = ascent * fScale.y();
1488     metrics->fDescent = descent * fScale.y();
1489     metrics->fBottom = ymin * fScale.y();
1490     metrics->fLeading = leading * fScale.y();
1491     metrics->fAvgCharWidth = avgCharWidth * fScale.y();
1492     metrics->fXMin = xmin * fScale.y();
1493     metrics->fXMax = xmax * fScale.y();
1494     metrics->fMaxCharWidth = metrics->fXMax - metrics->fXMin;
1495     metrics->fXHeight = x_height;
1496     metrics->fCapHeight = cap_height;
1497     metrics->fUnderlineThickness = underlineThickness * fScale.y();
1498     metrics->fUnderlinePosition = underlinePosition * fScale.y();
1499     metrics->fStrikeoutThickness = strikeoutThickness * fScale.y();
1500     metrics->fStrikeoutPosition = strikeoutPosition * fScale.y();
1501 
1502     if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
1503         // The bounds are only valid for the default variation.
1504         metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
1505     }
1506 }
1507 
1508 ///////////////////////////////////////////////////////////////////////////////
1509 
1510 // hand-tuned value to reduce outline embolden strength
1511 #ifndef SK_OUTLINE_EMBOLDEN_DIVISOR
1512     #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1513         #define SK_OUTLINE_EMBOLDEN_DIVISOR   34
1514     #else
1515         #define SK_OUTLINE_EMBOLDEN_DIVISOR   24
1516     #endif
1517 #endif
1518 
1519 ///////////////////////////////////////////////////////////////////////////////
1520 
emboldenIfNeeded(FT_Face face,FT_GlyphSlot glyph,SkGlyphID gid)1521 void SkScalerContext_FreeType::emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph, SkGlyphID gid) {
1522     // check to see if the embolden bit is set
1523     if (0 == (fRec.fFlags & SkScalerContext::kEmbolden_Flag)) {
1524         return;
1525     }
1526 
1527     switch (glyph->format) {
1528         case FT_GLYPH_FORMAT_OUTLINE:
1529             FT_Pos strength;
1530             strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale)
1531                        / SK_OUTLINE_EMBOLDEN_DIVISOR;
1532             FT_Outline_Embolden(&glyph->outline, strength);
1533             break;
1534         case FT_GLYPH_FORMAT_BITMAP:
1535             if (!fFace->glyph->bitmap.buffer) {
1536                 FT_Load_Glyph(fFace, gid, fLoadGlyphFlags);
1537             }
1538             FT_GlyphSlot_Own_Bitmap(glyph);
1539             FT_Bitmap_Embolden(glyph->library, &glyph->bitmap, kBitmapEmboldenStrength, 0);
1540             break;
1541         default:
1542             SkDEBUGFAIL("unknown glyph format");
1543     }
1544 }
1545 
1546 ///////////////////////////////////////////////////////////////////////////////
1547 
1548 #include "src/core/SkUtils.h"
1549 
SkTypeface_FreeType(const SkFontStyle & style,bool isFixedPitch)1550 SkTypeface_FreeType::SkTypeface_FreeType(const SkFontStyle& style, bool isFixedPitch)
1551     : INHERITED(style, isFixedPitch)
1552 {}
1553 
~SkTypeface_FreeType()1554 SkTypeface_FreeType::~SkTypeface_FreeType() {
1555     if (fFaceRec) {
1556         SkAutoMutexExclusive ac(f_t_mutex());
1557         fFaceRec.reset();
1558     }
1559 }
1560 
1561 // Just made up, so we don't end up storing 1000s of entries
1562 constexpr int kMaxC2GCacheCount = 512;
1563 
onCharsToGlyphs(const SkUnichar uni[],int count,SkGlyphID glyphs[]) const1564 void SkTypeface_FreeType::onCharsToGlyphs(const SkUnichar uni[], int count,
1565                                           SkGlyphID glyphs[]) const {
1566     // Try the cache first, *before* accessing freetype lib/face, as that
1567     // can be very slow. If we do need to compute a new glyphID, then
1568     // access those freetype objects and continue the loop.
1569 
1570     int i;
1571     {
1572         // Optimistically use a shared lock.
1573         SkAutoSharedMutexShared ama(fC2GCacheMutex);
1574         for (i = 0; i < count; ++i) {
1575             int index = fC2GCache.findGlyphIndex(uni[i]);
1576             if (index < 0) {
1577                 break;
1578             }
1579             glyphs[i] = SkToU16(index);
1580         }
1581         if (i == count) {
1582             // we're done, no need to access the freetype objects
1583             return;
1584         }
1585     }
1586 
1587     // Need to add more so grab an exclusive lock.
1588     SkAutoSharedMutexExclusive ama(fC2GCacheMutex);
1589     AutoFTAccess fta(this);
1590     FT_Face face = fta.face();
1591     if (!face) {
1592         sk_bzero(glyphs, count * sizeof(glyphs[0]));
1593         return;
1594     }
1595 
1596     for (; i < count; ++i) {
1597         SkUnichar c = uni[i];
1598         int index = fC2GCache.findGlyphIndex(c);
1599         if (index >= 0) {
1600             glyphs[i] = SkToU16(index);
1601         } else {
1602             glyphs[i] = SkToU16(FT_Get_Char_Index(face, c));
1603             fC2GCache.insertCharAndGlyph(~index, c, glyphs[i]);
1604         }
1605     }
1606 
1607     if (fC2GCache.count() > kMaxC2GCacheCount) {
1608         fC2GCache.reset();
1609     }
1610 }
1611 
onCountGlyphs() const1612 int SkTypeface_FreeType::onCountGlyphs() const {
1613     AutoFTAccess fta(this);
1614     FT_Face face = fta.face();
1615     return face ? face->num_glyphs : 0;
1616 }
1617 
onCreateFamilyNameIterator() const1618 SkTypeface::LocalizedStrings* SkTypeface_FreeType::onCreateFamilyNameIterator() const {
1619     sk_sp<SkTypeface::LocalizedStrings> nameIter =
1620         SkOTUtils::LocalizedStrings_NameTable::MakeForFamilyNames(*this);
1621     if (!nameIter) {
1622         SkString familyName;
1623         this->getFamilyName(&familyName);
1624         SkString language("und"); //undetermined
1625         nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(familyName, language);
1626     }
1627     return nameIter.release();
1628 }
1629 
onGlyphMaskNeedsCurrentColor() const1630 bool SkTypeface_FreeType::onGlyphMaskNeedsCurrentColor() const {
1631     return this->getTableSize(SkSetFourByteTag('C', 'O', 'L', 'R')) > 0;
1632 }
1633 
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount) const1634 int SkTypeface_FreeType::onGetVariationDesignPosition(
1635     SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
1636 {
1637     AutoFTAccess fta(this);
1638     return GetVariationDesignPosition(fta, coordinates, coordinateCount);
1639 }
1640 
onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],int parameterCount) const1641 int SkTypeface_FreeType::onGetVariationDesignParameters(
1642     SkFontParameters::Variation::Axis parameters[], int parameterCount) const
1643 {
1644     AutoFTAccess fta(this);
1645     FT_Face face = fta.face();
1646     if (!face) {
1647         return -1;
1648     }
1649 
1650     if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
1651         return 0;
1652     }
1653 
1654     FT_MM_Var* variations = nullptr;
1655     if (FT_Get_MM_Var(face, &variations)) {
1656         return -1;
1657     }
1658     SkAutoFree autoFreeVariations(variations);
1659 
1660     if (!parameters || parameterCount < SkToInt(variations->num_axis)) {
1661         return variations->num_axis;
1662     }
1663 
1664     for (FT_UInt i = 0; i < variations->num_axis; ++i) {
1665         parameters[i].tag = variations->axis[i].tag;
1666         parameters[i].min = SkFixedToScalar(variations->axis[i].minimum);
1667         parameters[i].def = SkFixedToScalar(variations->axis[i].def);
1668         parameters[i].max = SkFixedToScalar(variations->axis[i].maximum);
1669         FT_UInt flags = 0;
1670         bool hidden = !FT_Get_Var_Axis_Flags(variations, i, &flags) &&
1671                       (flags & FT_VAR_AXIS_FLAG_HIDDEN);
1672         parameters[i].setHidden(hidden);
1673     }
1674 
1675     return variations->num_axis;
1676 }
1677 
onGetTableTags(SkFontTableTag tags[]) const1678 int SkTypeface_FreeType::onGetTableTags(SkFontTableTag tags[]) const {
1679     AutoFTAccess fta(this);
1680     FT_Face face = fta.face();
1681     if (!face) {
1682         return 0;
1683     }
1684 
1685     FT_ULong tableCount = 0;
1686     FT_Error error;
1687 
1688     // When 'tag' is nullptr, returns number of tables in 'length'.
1689     error = FT_Sfnt_Table_Info(face, 0, nullptr, &tableCount);
1690     if (error) {
1691         return 0;
1692     }
1693 
1694     if (tags) {
1695         for (FT_ULong tableIndex = 0; tableIndex < tableCount; ++tableIndex) {
1696             FT_ULong tableTag;
1697             FT_ULong tablelength;
1698             error = FT_Sfnt_Table_Info(face, tableIndex, &tableTag, &tablelength);
1699             if (error) {
1700                 return 0;
1701             }
1702             tags[tableIndex] = static_cast<SkFontTableTag>(tableTag);
1703         }
1704     }
1705     return tableCount;
1706 }
1707 
onGetTableData(SkFontTableTag tag,size_t offset,size_t length,void * data) const1708 size_t SkTypeface_FreeType::onGetTableData(SkFontTableTag tag, size_t offset,
1709                                            size_t length, void* data) const
1710 {
1711     AutoFTAccess fta(this);
1712     FT_Face face = fta.face();
1713     if (!face) {
1714         return 0;
1715     }
1716 
1717     FT_ULong tableLength = 0;
1718     FT_Error error;
1719 
1720     // When 'length' is 0 it is overwritten with the full table length; 'offset' is ignored.
1721     error = FT_Load_Sfnt_Table(face, tag, 0, nullptr, &tableLength);
1722     if (error) {
1723         return 0;
1724     }
1725 
1726     if (offset > tableLength) {
1727         return 0;
1728     }
1729     FT_ULong size = std::min((FT_ULong)length, tableLength - (FT_ULong)offset);
1730     if (data) {
1731         error = FT_Load_Sfnt_Table(face, tag, offset, reinterpret_cast<FT_Byte*>(data), &size);
1732         if (error) {
1733             return 0;
1734         }
1735     }
1736 
1737     return size;
1738 }
1739 
onCopyTableData(SkFontTableTag tag) const1740 sk_sp<SkData> SkTypeface_FreeType::onCopyTableData(SkFontTableTag tag) const {
1741     AutoFTAccess fta(this);
1742     FT_Face face = fta.face();
1743     if (!face) {
1744         return nullptr;
1745     }
1746 
1747     FT_ULong tableLength = 0;
1748     FT_Error error;
1749 
1750     // When 'length' is 0 it is overwritten with the full table length; 'offset' is ignored.
1751     error = FT_Load_Sfnt_Table(face, tag, 0, nullptr, &tableLength);
1752     if (error) {
1753         return nullptr;
1754     }
1755 
1756     sk_sp<SkData> data = SkData::MakeUninitialized(tableLength);
1757     if (data) {
1758         error = FT_Load_Sfnt_Table(face, tag, 0,
1759                                    reinterpret_cast<FT_Byte*>(data->writable_data()), &tableLength);
1760         if (error) {
1761             data.reset();
1762         }
1763     }
1764     return data;
1765 }
1766 
getFaceRec() const1767 SkTypeface_FreeType::FaceRec* SkTypeface_FreeType::getFaceRec() const {
1768     f_t_mutex().assertHeld();
1769     fFTFaceOnce([this]{ fFaceRec = SkTypeface_FreeType::FaceRec::Make(this); });
1770     return fFaceRec.get();
1771 }
1772 
makeFontData() const1773 std::unique_ptr<SkFontData> SkTypeface_FreeType::makeFontData() const {
1774     return this->onMakeFontData();
1775 }
1776 
1777 ///////////////////////////////////////////////////////////////////////////////
1778 ///////////////////////////////////////////////////////////////////////////////
1779 
Scanner()1780 SkTypeface_FreeType::Scanner::Scanner() : fLibrary(nullptr) {
1781     if (FT_New_Library(&gFTMemory, &fLibrary)) {
1782         return;
1783     }
1784     FT_Add_Default_Modules(fLibrary);
1785     FT_Set_Default_Properties(fLibrary);
1786 }
~Scanner()1787 SkTypeface_FreeType::Scanner::~Scanner() {
1788     if (fLibrary) {
1789         FT_Done_Library(fLibrary);
1790     }
1791 }
1792 
openFace(SkStreamAsset * stream,int ttcIndex,FT_Stream ftStream) const1793 FT_Face SkTypeface_FreeType::Scanner::openFace(SkStreamAsset* stream, int ttcIndex,
1794                                                FT_Stream ftStream) const
1795 {
1796     if (fLibrary == nullptr || stream == nullptr) {
1797         return nullptr;
1798     }
1799 
1800     FT_Open_Args args;
1801     memset(&args, 0, sizeof(args));
1802 
1803     const void* memoryBase = stream->getMemoryBase();
1804 
1805     if (memoryBase) {
1806         args.flags = FT_OPEN_MEMORY;
1807         args.memory_base = (const FT_Byte*)memoryBase;
1808         args.memory_size = stream->getLength();
1809     } else {
1810         memset(ftStream, 0, sizeof(*ftStream));
1811         ftStream->size = stream->getLength();
1812         ftStream->descriptor.pointer = stream;
1813         ftStream->read  = sk_ft_stream_io;
1814         ftStream->close = sk_ft_stream_close;
1815 
1816         args.flags = FT_OPEN_STREAM;
1817         args.stream = ftStream;
1818     }
1819 
1820     FT_Face face;
1821     if (FT_Open_Face(fLibrary, &args, ttcIndex, &face)) {
1822         return nullptr;
1823     }
1824     return face;
1825 }
1826 
recognizedFont(SkStreamAsset * stream,int * numFaces) const1827 bool SkTypeface_FreeType::Scanner::recognizedFont(SkStreamAsset* stream, int* numFaces) const {
1828     SkAutoMutexExclusive libraryLock(fLibraryMutex);
1829 
1830     FT_StreamRec streamRec;
1831     SkUniqueFTFace face(this->openFace(stream, -1, &streamRec));
1832     if (!face) {
1833         return false;
1834     }
1835 
1836     *numFaces = face->num_faces;
1837     return true;
1838 }
1839 
scanFont(SkStreamAsset * stream,int ttcIndex,SkString * name,SkFontStyle * style,bool * isFixedPitch,AxisDefinitions * axes) const1840 bool SkTypeface_FreeType::Scanner::scanFont(
1841     SkStreamAsset* stream, int ttcIndex,
1842     SkString* name, SkFontStyle* style, bool* isFixedPitch, AxisDefinitions* axes) const
1843 {
1844     SkAutoMutexExclusive libraryLock(fLibraryMutex);
1845 
1846     FT_StreamRec streamRec;
1847     SkUniqueFTFace face(this->openFace(stream, ttcIndex, &streamRec));
1848     if (!face) {
1849         return false;
1850     }
1851 
1852     int weight = SkFontStyle::kNormal_Weight;
1853     int width = SkFontStyle::kNormal_Width;
1854     SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
1855     if (face->style_flags & FT_STYLE_FLAG_BOLD) {
1856         weight = SkFontStyle::kBold_Weight;
1857     }
1858     if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
1859         slant = SkFontStyle::kItalic_Slant;
1860     }
1861 
1862     PS_FontInfoRec psFontInfo;
1863     TT_OS2* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face.get(), ft_sfnt_os2));
1864     if (os2 && os2->version != 0xffff) {
1865         weight = os2->usWeightClass;
1866         width = os2->usWidthClass;
1867 
1868         // OS/2::fsSelection bit 9 indicates oblique.
1869         if (SkToBool(os2->fsSelection & (1u << 9))) {
1870             slant = SkFontStyle::kOblique_Slant;
1871         }
1872     } else if (0 == FT_Get_PS_Font_Info(face.get(), &psFontInfo) && psFontInfo.weight) {
1873         static const struct {
1874             char const * const name;
1875             int const weight;
1876         } commonWeights [] = {
1877             // There are probably more common names, but these are known to exist.
1878             { "all", SkFontStyle::kNormal_Weight }, // Multiple Masters usually default to normal.
1879             { "black", SkFontStyle::kBlack_Weight },
1880             { "bold", SkFontStyle::kBold_Weight },
1881             { "book", (SkFontStyle::kNormal_Weight + SkFontStyle::kLight_Weight)/2 },
1882             { "demi", SkFontStyle::kSemiBold_Weight },
1883             { "demibold", SkFontStyle::kSemiBold_Weight },
1884             { "extra", SkFontStyle::kExtraBold_Weight },
1885             { "extrabold", SkFontStyle::kExtraBold_Weight },
1886             { "extralight", SkFontStyle::kExtraLight_Weight },
1887             { "hairline", SkFontStyle::kThin_Weight },
1888             { "heavy", SkFontStyle::kBlack_Weight },
1889             { "light", SkFontStyle::kLight_Weight },
1890             { "medium", SkFontStyle::kMedium_Weight },
1891             { "normal", SkFontStyle::kNormal_Weight },
1892             { "plain", SkFontStyle::kNormal_Weight },
1893             { "regular", SkFontStyle::kNormal_Weight },
1894             { "roman", SkFontStyle::kNormal_Weight },
1895             { "semibold", SkFontStyle::kSemiBold_Weight },
1896             { "standard", SkFontStyle::kNormal_Weight },
1897             { "thin", SkFontStyle::kThin_Weight },
1898             { "ultra", SkFontStyle::kExtraBold_Weight },
1899             { "ultrablack", SkFontStyle::kExtraBlack_Weight },
1900             { "ultrabold", SkFontStyle::kExtraBold_Weight },
1901             { "ultraheavy", SkFontStyle::kExtraBlack_Weight },
1902             { "ultralight", SkFontStyle::kExtraLight_Weight },
1903         };
1904         int const index = SkStrLCSearch(&commonWeights[0].name, SK_ARRAY_COUNT(commonWeights),
1905                                         psFontInfo.weight, sizeof(commonWeights[0]));
1906         if (index >= 0) {
1907             weight = commonWeights[index].weight;
1908         } else {
1909             LOG_INFO("Do not know weight for: %s (%s) \n", face->family_name, psFontInfo.weight);
1910         }
1911     }
1912 
1913     if (name != nullptr) {
1914         name->set(face->family_name);
1915     }
1916     if (style != nullptr) {
1917         *style = SkFontStyle(weight, width, slant);
1918     }
1919     if (isFixedPitch != nullptr) {
1920         *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1921     }
1922 
1923     if (axes != nullptr && !GetAxes(face.get(), axes)) {
1924         return false;
1925     }
1926     return true;
1927 }
1928 
GetAxes(FT_Face face,AxisDefinitions * axes)1929 bool SkTypeface_FreeType::Scanner::GetAxes(FT_Face face, AxisDefinitions* axes) {
1930     SkASSERT(face && axes);
1931     if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
1932         FT_MM_Var* variations = nullptr;
1933         FT_Error err = FT_Get_MM_Var(face, &variations);
1934         if (err) {
1935             LOG_INFO("INFO: font %s claims to have variations, but none found.\n",
1936                      face->family_name);
1937             return false;
1938         }
1939         SkAutoFree autoFreeVariations(variations);
1940 
1941         axes->reset(variations->num_axis);
1942         for (FT_UInt i = 0; i < variations->num_axis; ++i) {
1943             const FT_Var_Axis& ftAxis = variations->axis[i];
1944             (*axes)[i].fTag = ftAxis.tag;
1945             (*axes)[i].fMinimum = ftAxis.minimum;
1946             (*axes)[i].fDefault = ftAxis.def;
1947             (*axes)[i].fMaximum = ftAxis.maximum;
1948         }
1949     }
1950     return true;
1951 }
1952 
computeAxisValues(AxisDefinitions axisDefinitions,const SkFontArguments::VariationPosition position,SkFixed * axisValues,const SkString & name,const SkFontArguments::VariationPosition::Coordinate * current)1953 /*static*/ void SkTypeface_FreeType::Scanner::computeAxisValues(
1954     AxisDefinitions axisDefinitions,
1955     const SkFontArguments::VariationPosition position,
1956     SkFixed* axisValues,
1957     const SkString& name,
1958     const SkFontArguments::VariationPosition::Coordinate* current)
1959 {
1960     for (int i = 0; i < axisDefinitions.count(); ++i) {
1961         const Scanner::AxisDefinition& axisDefinition = axisDefinitions[i];
1962         const SkScalar axisMin = SkFixedToScalar(axisDefinition.fMinimum);
1963         const SkScalar axisMax = SkFixedToScalar(axisDefinition.fMaximum);
1964 
1965         // Start with the default value.
1966         axisValues[i] = axisDefinition.fDefault;
1967 
1968         // Then the current value.
1969         if (current) {
1970             for (int j = 0; j < axisDefinitions.count(); ++j) {
1971                 const auto& coordinate = current[j];
1972                 if (axisDefinition.fTag == coordinate.axis) {
1973                     const SkScalar axisValue = SkTPin(coordinate.value, axisMin, axisMax);
1974                     axisValues[i] = SkScalarToFixed(axisValue);
1975                     break;
1976                 }
1977             }
1978         }
1979 
1980         // Then the requested value.
1981         // The position may be over specified. If there are multiple values for a given axis,
1982         // use the last one since that's what css-fonts-4 requires.
1983         for (int j = position.coordinateCount; j --> 0;) {
1984             const auto& coordinate = position.coordinates[j];
1985             if (axisDefinition.fTag == coordinate.axis) {
1986                 const SkScalar axisValue = SkTPin(coordinate.value, axisMin, axisMax);
1987                 if (coordinate.value != axisValue) {
1988                     LOG_INFO("Requested font axis value out of range: "
1989                              "%s '%c%c%c%c' %f; pinned to %f.\n",
1990                              name.c_str(),
1991                              (axisDefinition.fTag >> 24) & 0xFF,
1992                              (axisDefinition.fTag >> 16) & 0xFF,
1993                              (axisDefinition.fTag >>  8) & 0xFF,
1994                              (axisDefinition.fTag      ) & 0xFF,
1995                              SkScalarToDouble(coordinate.value),
1996                              SkScalarToDouble(axisValue));
1997                 }
1998                 axisValues[i] = SkScalarToFixed(axisValue);
1999                 break;
2000             }
2001         }
2002         // TODO: warn on defaulted axis?
2003     }
2004 
2005     SkDEBUGCODE(
2006         // Check for axis specified, but not matched in font.
2007         for (int i = 0; i < position.coordinateCount; ++i) {
2008             SkFourByteTag skTag = position.coordinates[i].axis;
2009             bool found = false;
2010             for (int j = 0; j < axisDefinitions.count(); ++j) {
2011                 if (skTag == axisDefinitions[j].fTag) {
2012                     found = true;
2013                     break;
2014                 }
2015             }
2016             if (!found) {
2017                 LOG_INFO("Requested font axis not found: %s '%c%c%c%c'\n",
2018                          name.c_str(),
2019                          (skTag >> 24) & 0xFF,
2020                          (skTag >> 16) & 0xFF,
2021                          (skTag >>  8) & 0xFF,
2022                          (skTag)       & 0xFF);
2023             }
2024         }
2025     )
2026 }
2027