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