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