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