Home | History | Annotate | Download | only in ports
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "SkAdvancedTypefaceMetrics.h"
     10 #include "SkBase64.h"
     11 #include "SkColorPriv.h"
     12 #include "SkData.h"
     13 #include "SkDescriptor.h"
     14 #include "SkFontDescriptor.h"
     15 #include "SkFontHost.h"
     16 #include "SkGlyph.h"
     17 #include "SkMaskGamma.h"
     18 #include "SkOTTable_maxp.h"
     19 #include "SkOTTable_name.h"
     20 #include "SkOTUtils.h"
     21 #include "SkPath.h"
     22 #include "SkSFNTHeader.h"
     23 #include "SkStream.h"
     24 #include "SkString.h"
     25 #include "SkTemplates.h"
     26 #include "SkThread.h"
     27 #include "SkTypeface_win.h"
     28 #include "SkTypefaceCache.h"
     29 #include "SkUtils.h"
     30 
     31 #include "SkTypes.h"
     32 #include <tchar.h>
     33 #include <usp10.h>
     34 #include <objbase.h>
     35 
     36 static void (*gEnsureLOGFONTAccessibleProc)(const LOGFONT&);
     37 
     38 void SkTypeface_SetEnsureLOGFONTAccessibleProc(void (*proc)(const LOGFONT&)) {
     39     gEnsureLOGFONTAccessibleProc = proc;
     40 }
     41 
     42 static void call_ensure_accessible(const LOGFONT& lf) {
     43     if (gEnsureLOGFONTAccessibleProc) {
     44         gEnsureLOGFONTAccessibleProc(lf);
     45     }
     46 }
     47 
     48 ///////////////////////////////////////////////////////////////////////////////
     49 
     50 // always packed xxRRGGBB
     51 typedef uint32_t SkGdiRGB;
     52 
     53 // define this in your Makefile or .gyp to enforce AA requests
     54 // which GDI ignores at small sizes. This flag guarantees AA
     55 // for rotated text, regardless of GDI's notions.
     56 //#define SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS
     57 
     58 static bool isLCD(const SkScalerContext::Rec& rec) {
     59     return SkMask::kLCD16_Format == rec.fMaskFormat ||
     60            SkMask::kLCD32_Format == rec.fMaskFormat;
     61 }
     62 
     63 static bool bothZero(SkScalar a, SkScalar b) {
     64     return 0 == a && 0 == b;
     65 }
     66 
     67 // returns false if there is any non-90-rotation or skew
     68 static bool isAxisAligned(const SkScalerContext::Rec& rec) {
     69     return 0 == rec.fPreSkewX &&
     70            (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
     71             bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
     72 }
     73 
     74 static bool needToRenderWithSkia(const SkScalerContext::Rec& rec) {
     75 #ifdef SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS
     76     // What we really want to catch is when GDI will ignore the AA request and give
     77     // us BW instead. Smallish rotated text is one heuristic, so this code is just
     78     // an approximation. We shouldn't need to do this for larger sizes, but at those
     79     // sizes, the quality difference gets less and less between our general
     80     // scanconverter and GDI's.
     81     if (SkMask::kA8_Format == rec.fMaskFormat && !isAxisAligned(rec)) {
     82         return true;
     83     }
     84 #endif
     85     return rec.getHinting() == SkPaint::kNo_Hinting || rec.getHinting() == SkPaint::kSlight_Hinting;
     86 }
     87 
     88 using namespace skia_advanced_typeface_metrics_utils;
     89 
     90 static void tchar_to_skstring(const TCHAR t[], SkString* s) {
     91 #ifdef UNICODE
     92     size_t sSize = WideCharToMultiByte(CP_UTF8, 0, t, -1, NULL, 0, NULL, NULL);
     93     s->resize(sSize);
     94     WideCharToMultiByte(CP_UTF8, 0, t, -1, s->writable_str(), sSize, NULL, NULL);
     95 #else
     96     s->set(t);
     97 #endif
     98 }
     99 
    100 static void dcfontname_to_skstring(HDC deviceContext, const LOGFONT& lf, SkString* familyName) {
    101     int fontNameLen; //length of fontName in TCHARS.
    102     if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
    103         call_ensure_accessible(lf);
    104         if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) {
    105             fontNameLen = 0;
    106         }
    107     }
    108 
    109     SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1);
    110     if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
    111         call_ensure_accessible(lf);
    112         if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) {
    113             fontName[0] = 0;
    114         }
    115     }
    116 
    117     tchar_to_skstring(fontName.get(), familyName);
    118 }
    119 
    120 static void make_canonical(LOGFONT* lf) {
    121     lf->lfHeight = -2048;
    122     lf->lfQuality = CLEARTYPE_QUALITY;//PROOF_QUALITY;
    123     lf->lfCharSet = DEFAULT_CHARSET;
    124 //    lf->lfClipPrecision = 64;
    125 }
    126 
    127 static SkTypeface::Style get_style(const LOGFONT& lf) {
    128     unsigned style = 0;
    129     if (lf.lfWeight >= FW_BOLD) {
    130         style |= SkTypeface::kBold;
    131     }
    132     if (lf.lfItalic) {
    133         style |= SkTypeface::kItalic;
    134     }
    135     return static_cast<SkTypeface::Style>(style);
    136 }
    137 
    138 static void setStyle(LOGFONT* lf, SkTypeface::Style style) {
    139     lf->lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
    140     lf->lfItalic = ((style & SkTypeface::kItalic) != 0);
    141 }
    142 
    143 static inline FIXED SkFixedToFIXED(SkFixed x) {
    144     return *(FIXED*)(&x);
    145 }
    146 static inline SkFixed SkFIXEDToFixed(FIXED x) {
    147     return *(SkFixed*)(&x);
    148 }
    149 
    150 static inline FIXED SkScalarToFIXED(SkScalar x) {
    151     return SkFixedToFIXED(SkScalarToFixed(x));
    152 }
    153 
    154 static unsigned calculateGlyphCount(HDC hdc, const LOGFONT& lf) {
    155     TEXTMETRIC textMetric;
    156     if (0 == GetTextMetrics(hdc, &textMetric)) {
    157         textMetric.tmPitchAndFamily = TMPF_VECTOR;
    158         call_ensure_accessible(lf);
    159         GetTextMetrics(hdc, &textMetric);
    160     }
    161 
    162     if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
    163         return textMetric.tmLastChar;
    164     }
    165 
    166     // The 'maxp' table stores the number of glyphs at offset 4, in 2 bytes.
    167     uint16_t glyphs;
    168     if (GDI_ERROR != GetFontData(hdc, SkOTTableMaximumProfile::TAG, 4, &glyphs, sizeof(glyphs))) {
    169         return SkEndian_SwapBE16(glyphs);
    170     }
    171 
    172     // Binary search for glyph count.
    173     static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
    174     int32_t max = SK_MaxU16 + 1;
    175     int32_t min = 0;
    176     GLYPHMETRICS gm;
    177     while (min < max) {
    178         int32_t mid = min + ((max - min) / 2);
    179         if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0,
    180                              NULL, &mat2) == GDI_ERROR) {
    181             max = mid;
    182         } else {
    183             min = mid + 1;
    184         }
    185     }
    186     SkASSERT(min == max);
    187     return min;
    188 }
    189 
    190 static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) {
    191     TEXTMETRIC textMetric;
    192     if (0 == GetTextMetrics(hdc, &textMetric)) {
    193         textMetric.tmPitchAndFamily = TMPF_VECTOR;
    194         call_ensure_accessible(lf);
    195         GetTextMetrics(hdc, &textMetric);
    196     }
    197 
    198     if (!(textMetric.tmPitchAndFamily & TMPF_VECTOR)) {
    199         return textMetric.tmMaxCharWidth;
    200     }
    201 
    202     OUTLINETEXTMETRIC otm;
    203     unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
    204     if (0 == otmRet) {
    205         call_ensure_accessible(lf);
    206         otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
    207     }
    208 
    209     return (0 == otmRet) ? 0 : otm.otmEMSquare;
    210 }
    211 
    212 class LogFontTypeface : public SkTypeface {
    213 public:
    214     LogFontTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, bool serializeAsStream = false) :
    215         SkTypeface(style, fontID, false), fLogFont(lf), fSerializeAsStream(serializeAsStream) {
    216 
    217         // If the font has cubic outlines, it will not be rendered with ClearType.
    218         HFONT font = CreateFontIndirect(&lf);
    219 
    220         HDC deviceContext = ::CreateCompatibleDC(NULL);
    221         HFONT savefont = (HFONT)SelectObject(deviceContext, font);
    222 
    223         TEXTMETRIC textMetric;
    224         if (0 == GetTextMetrics(deviceContext, &textMetric)) {
    225             call_ensure_accessible(lf);
    226             if (0 == GetTextMetrics(deviceContext, &textMetric)) {
    227                 textMetric.tmPitchAndFamily = TMPF_TRUETYPE;
    228             }
    229         }
    230         if (deviceContext) {
    231             ::SelectObject(deviceContext, savefont);
    232             ::DeleteDC(deviceContext);
    233         }
    234         if (font) {
    235             ::DeleteObject(font);
    236         }
    237 
    238         // The fixed pitch bit is set if the font is *not* fixed pitch.
    239         this->setIsFixedPitch((textMetric.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0);
    240 
    241         // Used a logfont on a memory context, should never get a device font.
    242         // Therefore all TMPF_DEVICE will be PostScript (cubic) fonts.
    243         fCanBeLCD = !((textMetric.tmPitchAndFamily & TMPF_VECTOR) &&
    244                       (textMetric.tmPitchAndFamily & TMPF_DEVICE));
    245     }
    246 
    247     LOGFONT fLogFont;
    248     bool fSerializeAsStream;
    249     bool fCanBeLCD;
    250 
    251     static LogFontTypeface* Create(const LOGFONT& lf) {
    252         SkTypeface::Style style = get_style(lf);
    253         SkFontID fontID = SkTypefaceCache::NewFontID();
    254         return new LogFontTypeface(style, fontID, lf);
    255     }
    256 
    257     static void EnsureAccessible(const SkTypeface* face) {
    258         call_ensure_accessible(static_cast<const LogFontTypeface*>(face)->fLogFont);
    259     }
    260 
    261 protected:
    262     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
    263     virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
    264     virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
    265     virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
    266                                 SkAdvancedTypefaceMetrics::PerGlyphInfo,
    267                                 const uint32_t*, uint32_t) const SK_OVERRIDE;
    268     virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
    269     virtual int onCountGlyphs() const SK_OVERRIDE;
    270     virtual int onGetUPEM() const SK_OVERRIDE;
    271     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
    272     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
    273     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
    274                                   size_t length, void* data) const SK_OVERRIDE;
    275     virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE;
    276 };
    277 
    278 class FontMemResourceTypeface : public LogFontTypeface {
    279 public:
    280     /**
    281      *  Takes ownership of fontMemResource.
    282      */
    283     FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, HANDLE fontMemResource) :
    284         LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResource) {
    285     }
    286 
    287     HANDLE fFontMemResource;
    288 
    289     /**
    290      *  The created FontMemResourceTypeface takes ownership of fontMemResource.
    291      */
    292     static FontMemResourceTypeface* Create(const LOGFONT& lf, HANDLE fontMemResource) {
    293         SkTypeface::Style style = get_style(lf);
    294         SkFontID fontID = SkTypefaceCache::NewFontID();
    295         return new FontMemResourceTypeface(style, fontID, lf, fontMemResource);
    296     }
    297 
    298 protected:
    299     virtual void weak_dispose() const SK_OVERRIDE {
    300         RemoveFontMemResourceEx(fFontMemResource);
    301         //SkTypefaceCache::Remove(this);
    302         INHERITED::weak_dispose();
    303     }
    304 
    305 private:
    306     typedef LogFontTypeface INHERITED;
    307 };
    308 
    309 static const LOGFONT& get_default_font() {
    310     static LOGFONT gDefaultFont;
    311     return gDefaultFont;
    312 }
    313 
    314 static bool FindByLogFont(SkTypeface* face, SkTypeface::Style requestedStyle, void* ctx) {
    315     LogFontTypeface* lface = static_cast<LogFontTypeface*>(face);
    316     const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx);
    317 
    318     return lface &&
    319            get_style(lface->fLogFont) == requestedStyle &&
    320            !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT));
    321 }
    322 
    323 /**
    324  *  This guy is public. It first searches the cache, and if a match is not found,
    325  *  it creates a new face.
    326  */
    327 SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) {
    328     LOGFONT lf = origLF;
    329     make_canonical(&lf);
    330     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf);
    331     if (NULL == face) {
    332         face = LogFontTypeface::Create(lf);
    333         SkTypefaceCache::Add(face, get_style(lf));
    334     }
    335     return face;
    336 }
    337 
    338 /**
    339  *  The created SkTypeface takes ownership of fontMemResource.
    340  */
    341 SkTypeface* SkCreateFontMemResourceTypefaceFromLOGFONT(const LOGFONT& origLF, HANDLE fontMemResource) {
    342     LOGFONT lf = origLF;
    343     make_canonical(&lf);
    344     FontMemResourceTypeface* face = FontMemResourceTypeface::Create(lf, fontMemResource);
    345     SkTypefaceCache::Add(face, get_style(lf), false);
    346     return face;
    347 }
    348 
    349 /**
    350  *  This guy is public
    351  */
    352 void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) {
    353     if (NULL == face) {
    354         *lf = get_default_font();
    355     } else {
    356         *lf = static_cast<const LogFontTypeface*>(face)->fLogFont;
    357     }
    358 }
    359 
    360 static void GetLogFontByID(SkFontID fontID, LOGFONT* lf) {
    361     LogFontTypeface* face = static_cast<LogFontTypeface*>(SkTypefaceCache::FindByID(fontID));
    362     if (face) {
    363         *lf = face->fLogFont;
    364     } else {
    365         sk_bzero(lf, sizeof(LOGFONT));
    366     }
    367 }
    368 
    369 // Construct Glyph to Unicode table.
    370 // Unicode code points that require conjugate pairs in utf16 are not
    371 // supported.
    372 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
    373 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead
    374 // of calling GetFontUnicodeRange().
    375 static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount,
    376                                       SkTDArray<SkUnichar>* glyphToUnicode) {
    377     DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, NULL);
    378     if (!glyphSetBufferSize) {
    379         return;
    380     }
    381 
    382     SkAutoTDeleteArray<BYTE> glyphSetBuffer(new BYTE[glyphSetBufferSize]);
    383     GLYPHSET* glyphSet =
    384         reinterpret_cast<LPGLYPHSET>(glyphSetBuffer.get());
    385     if (GetFontUnicodeRanges(fontHdc, glyphSet) != glyphSetBufferSize) {
    386         return;
    387     }
    388 
    389     glyphToUnicode->setCount(glyphCount);
    390     memset(glyphToUnicode->begin(), 0, glyphCount * sizeof(SkUnichar));
    391     for (DWORD i = 0; i < glyphSet->cRanges; ++i) {
    392         // There is no guarantee that within a Unicode range, the corresponding
    393         // glyph id in a font file are continuous. So, even if we have ranges,
    394         // we can't just use the first and last entry of the range to compute
    395         // result. We need to enumerate them one by one.
    396         int count = glyphSet->ranges[i].cGlyphs;
    397         SkAutoTArray<WCHAR> chars(count + 1);
    398         chars[count] = 0;  // termintate string
    399         SkAutoTArray<WORD> glyph(count);
    400         for (USHORT j = 0; j < count; ++j) {
    401             chars[j] = glyphSet->ranges[i].wcLow + j;
    402         }
    403         GetGlyphIndicesW(fontHdc, chars.get(), count, glyph.get(),
    404                          GGI_MARK_NONEXISTING_GLYPHS);
    405         // If the glyph ID is valid, and the glyph is not mapped, then we will
    406         // fill in the char id into the vector. If the glyph is mapped already,
    407         // skip it.
    408         // TODO(arthurhsu): better improve this. e.g. Get all used char ids from
    409         // font cache, then generate this mapping table from there. It's
    410         // unlikely to have collisions since glyph reuse happens mostly for
    411         // different Unicode pages.
    412         for (USHORT j = 0; j < count; ++j) {
    413             if (glyph[j] != 0xffff && glyph[j] < glyphCount &&
    414                 (*glyphToUnicode)[glyph[j]] == 0) {
    415                 (*glyphToUnicode)[glyph[j]] = chars[j];
    416             }
    417         }
    418     }
    419 }
    420 
    421 //////////////////////////////////////////////////////////////////////////////////////
    422 
    423 static int alignTo32(int n) {
    424     return (n + 31) & ~31;
    425 }
    426 
    427 struct MyBitmapInfo : public BITMAPINFO {
    428     RGBQUAD fMoreSpaceForColors[1];
    429 };
    430 
    431 class HDCOffscreen {
    432 public:
    433     HDCOffscreen() {
    434         fFont = 0;
    435         fDC = 0;
    436         fBM = 0;
    437         fBits = NULL;
    438         fWidth = fHeight = 0;
    439         fIsBW = false;
    440     }
    441 
    442     ~HDCOffscreen() {
    443         if (fDC) {
    444             DeleteDC(fDC);
    445         }
    446         if (fBM) {
    447             DeleteObject(fBM);
    448         }
    449     }
    450 
    451     void init(HFONT font, const XFORM& xform) {
    452         fFont = font;
    453         fXform = xform;
    454     }
    455 
    456     const void* draw(const SkGlyph&, bool isBW, size_t* srcRBPtr);
    457 
    458 private:
    459     HDC     fDC;
    460     HBITMAP fBM;
    461     HFONT   fFont;
    462     XFORM   fXform;
    463     void*   fBits;  // points into fBM
    464     int     fWidth;
    465     int     fHeight;
    466     bool    fIsBW;
    467 };
    468 
    469 const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW,
    470                                size_t* srcRBPtr) {
    471     // Can we share the scalercontext's fDDC, so we don't need to create
    472     // a separate fDC here?
    473     if (0 == fDC) {
    474         fDC = CreateCompatibleDC(0);
    475         if (0 == fDC) {
    476             return NULL;
    477         }
    478         SetGraphicsMode(fDC, GM_ADVANCED);
    479         SetBkMode(fDC, TRANSPARENT);
    480         SetTextAlign(fDC, TA_LEFT | TA_BASELINE);
    481         SelectObject(fDC, fFont);
    482 
    483         COLORREF color = 0x00FFFFFF;
    484         SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color);
    485         SkASSERT(prev != CLR_INVALID);
    486     }
    487 
    488     if (fBM && (fIsBW != isBW || fWidth < glyph.fWidth || fHeight < glyph.fHeight)) {
    489         DeleteObject(fBM);
    490         fBM = 0;
    491     }
    492     fIsBW = isBW;
    493 
    494     fWidth = SkMax32(fWidth, glyph.fWidth);
    495     fHeight = SkMax32(fHeight, glyph.fHeight);
    496 
    497     int biWidth = isBW ? alignTo32(fWidth) : fWidth;
    498 
    499     if (0 == fBM) {
    500         MyBitmapInfo info;
    501         sk_bzero(&info, sizeof(info));
    502         if (isBW) {
    503             RGBQUAD blackQuad = { 0, 0, 0, 0 };
    504             RGBQUAD whiteQuad = { 0xFF, 0xFF, 0xFF, 0 };
    505             info.bmiColors[0] = blackQuad;
    506             info.bmiColors[1] = whiteQuad;
    507         }
    508         info.bmiHeader.biSize = sizeof(info.bmiHeader);
    509         info.bmiHeader.biWidth = biWidth;
    510         info.bmiHeader.biHeight = fHeight;
    511         info.bmiHeader.biPlanes = 1;
    512         info.bmiHeader.biBitCount = isBW ? 1 : 32;
    513         info.bmiHeader.biCompression = BI_RGB;
    514         if (isBW) {
    515             info.bmiHeader.biClrUsed = 2;
    516         }
    517         fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0);
    518         if (0 == fBM) {
    519             return NULL;
    520         }
    521         SelectObject(fDC, fBM);
    522     }
    523 
    524     // erase
    525     size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2);
    526     size_t size = fHeight * srcRB;
    527     memset(fBits, 0, size);
    528 
    529     XFORM xform = fXform;
    530     xform.eDx = (float)-glyph.fLeft;
    531     xform.eDy = (float)-glyph.fTop;
    532     SetWorldTransform(fDC, &xform);
    533 
    534     uint16_t glyphID = glyph.getGlyphID();
    535     BOOL ret = ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, NULL, reinterpret_cast<LPCWSTR>(&glyphID), 1, NULL);
    536     GdiFlush();
    537     if (0 == ret) {
    538         return NULL;
    539     }
    540     *srcRBPtr = srcRB;
    541     // offset to the start of the image
    542     return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB;
    543 }
    544 
    545 //////////////////////////////////////////////////////////////////////////////
    546 #define BUFFERSIZE (1 << 13)
    547 
    548 class SkScalerContext_GDI : public SkScalerContext {
    549 public:
    550     SkScalerContext_GDI(SkTypeface*, const SkDescriptor* desc);
    551     virtual ~SkScalerContext_GDI();
    552 
    553     // Returns true if the constructor was able to complete all of its
    554     // initializations (which may include calling GDI).
    555     bool isValid() const;
    556 
    557 protected:
    558     virtual unsigned generateGlyphCount() SK_OVERRIDE;
    559     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE;
    560     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
    561     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
    562     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
    563     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
    564     virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
    565                                      SkPaint::FontMetrics* mY) SK_OVERRIDE;
    566 
    567 private:
    568     DWORD getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
    569                           SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf);
    570 
    571     HDCOffscreen fOffscreen;
    572     /** fGsA is the non-rotational part of total matrix without the text height scale.
    573      *  Used to find the magnitude of advances.
    574      */
    575     MAT2         fGsA;
    576     /** The total matrix without the textSize. */
    577     MAT2         fMat22;
    578     /** Scales font to EM size. */
    579     MAT2         fHighResMat22;
    580     HDC          fDDC;
    581     HFONT        fSavefont;
    582     HFONT        fFont;
    583     SCRIPT_CACHE fSC;
    584     int          fGlyphCount;
    585 
    586     /** The total matrix which also removes EM scale. */
    587     SkMatrix     fHiResMatrix;
    588     /** fG_inv is the inverse of the rotational part of the total matrix.
    589      *  Used to set the direction of advances.
    590      */
    591     SkMatrix     fG_inv;
    592     enum Type {
    593         kTrueType_Type, kBitmap_Type,
    594     } fType;
    595     TEXTMETRIC fTM;
    596 };
    597 
    598 static FIXED float2FIXED(float x) {
    599     return SkFixedToFIXED(SkFloatToFixed(x));
    600 }
    601 
    602 static BYTE compute_quality(const SkScalerContext::Rec& rec) {
    603     switch (rec.fMaskFormat) {
    604         case SkMask::kBW_Format:
    605             return NONANTIALIASED_QUALITY;
    606         case SkMask::kLCD16_Format:
    607         case SkMask::kLCD32_Format:
    608             return CLEARTYPE_QUALITY;
    609         default:
    610             if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) {
    611                 return CLEARTYPE_QUALITY;
    612             } else {
    613                 return ANTIALIASED_QUALITY;
    614             }
    615     }
    616 }
    617 
    618 SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface,
    619                                                  const SkDescriptor* desc)
    620         : SkScalerContext(rawTypeface, desc)
    621         , fDDC(0)
    622         , fSavefont(0)
    623         , fFont(0)
    624         , fSC(0)
    625         , fGlyphCount(-1)
    626 {
    627     LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface);
    628 
    629     fDDC = ::CreateCompatibleDC(NULL);
    630     if (!fDDC) {
    631         return;
    632     }
    633     SetGraphicsMode(fDDC, GM_ADVANCED);
    634     SetBkMode(fDDC, TRANSPARENT);
    635 
    636     SkPoint h = SkPoint::Make(SK_Scalar1, 0);
    637     // A is the total matrix.
    638     SkMatrix A;
    639     fRec.getSingleMatrix(&A);
    640     A.mapPoints(&h, 1);
    641 
    642     // Find the Given's matrix [[c, -s],[s, c]] which rotates the baseline vector h
    643     // (where the baseline is mapped to) to the positive horizontal axis.
    644     const SkScalar& a = h.fX;
    645     const SkScalar& b = h.fY;
    646     SkScalar c, s;
    647     if (0 == b) {
    648         c = SkDoubleToScalar(_copysign(SK_Scalar1, a));
    649         s = 0;
    650     } else if (0 == a) {
    651         c = 0;
    652         s = SkDoubleToScalar(-_copysign(SK_Scalar1, b));
    653     } else if (SkScalarAbs(b) > SkScalarAbs(a)) {
    654         SkScalar t = a / b;
    655         SkScalar u = SkDoubleToScalar(_copysign(SkScalarSqrt(SK_Scalar1 + t*t), b));
    656         s = -1 / u;
    657         c = -s * t;
    658     } else {
    659         SkScalar t = b / a;
    660         SkScalar u = SkDoubleToScalar(_copysign(SkScalarSqrt(SK_Scalar1 + t*t), a));
    661         c = 1 / u;
    662         s = -c * t;
    663     }
    664 
    665     // G is the Given's Matrix for A (rotational matrix such that GA[0][1] == 0).
    666     SkMatrix G;
    667     G.setAll(c, -s, 0,
    668              s,  c, 0,
    669              0,  0, SkScalarToPersp(SK_Scalar1));
    670 
    671     // GA is the matrix A with rotation removed.
    672     SkMatrix GA(G);
    673     GA.preConcat(A);
    674 
    675     // textSize is the actual device size we want (as opposed to the size the user requested).
    676     // If the scale is negative, this means the matrix will do the flip anyway.
    677     SkScalar textSize = SkScalarAbs(SkScalarRoundToScalar(GA.get(SkMatrix::kMScaleY)));
    678     if (textSize == 0) {
    679         textSize = SK_Scalar1;
    680     }
    681 
    682     // sA is the total matrix A without the textSize (so GDI knows the text size separately).
    683     // When this matrix is used with GetGlyphOutline, no further processing is needed.
    684     SkMatrix sA(A);
    685     SkScalar scale = SkScalarInvert(textSize);
    686     sA.preScale(scale, scale); //remove text size
    687 
    688     // GsA is the non-rotational part of A without the text height scale.
    689     // This is what is used to find the magnitude of advances.
    690     SkMatrix GsA(GA);
    691     GsA.preScale(scale, scale); //remove text size, G is rotational so reorders with the scale.
    692 
    693     fGsA.eM11 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleX));
    694     fGsA.eM12 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewY)); // This should be ~0.
    695     fGsA.eM21 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewX));
    696     fGsA.eM22 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleY));
    697 
    698     // fG_inv is G inverse, which is fairly simple since G is 2x2 rotational.
    699     fG_inv.setAll(G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(SkMatrix::kMTransX),
    700                   -G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(SkMatrix::kMTransY),
    701                   G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(SkMatrix::kMPersp2));
    702 
    703     LOGFONT lf = typeface->fLogFont;
    704     lf.lfHeight = -SkScalarTruncToInt(textSize);
    705     lf.lfQuality = compute_quality(fRec);
    706     fFont = CreateFontIndirect(&lf);
    707     if (!fFont) {
    708         return;
    709     }
    710 
    711     fSavefont = (HFONT)SelectObject(fDDC, fFont);
    712 
    713     if (0 == GetTextMetrics(fDDC, &fTM)) {
    714         call_ensure_accessible(lf);
    715         if (0 == GetTextMetrics(fDDC, &fTM)) {
    716             fTM.tmPitchAndFamily = TMPF_TRUETYPE;
    717         }
    718     }
    719     // Used a logfont on a memory context, should never get a device font.
    720     // Therefore all TMPF_DEVICE will be PostScript fonts.
    721 
    722     // If TMPF_VECTOR is set, one of TMPF_TRUETYPE or TMPF_DEVICE must be set,
    723     // otherwise we have a vector FON, which we don't support.
    724     // This was determined by testing with Type1 PFM/PFB and OpenTypeCFF OTF,
    725     // as well as looking at Wine bugs and sources.
    726     SkASSERT(!(fTM.tmPitchAndFamily & TMPF_VECTOR) ||
    727               (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE)));
    728 
    729     XFORM xform;
    730     if (fTM.tmPitchAndFamily & TMPF_VECTOR) {
    731         // Truetype or PostScript.
    732         // Stroked FON also gets here (TMPF_VECTOR), but we don't handle it.
    733         fType = SkScalerContext_GDI::kTrueType_Type;
    734 
    735         // fPost2x2 is column-major, left handed (y down).
    736         // XFORM 2x2 is row-major, left handed (y down).
    737         xform.eM11 = SkScalarToFloat(sA.get(SkMatrix::kMScaleX));
    738         xform.eM12 = SkScalarToFloat(sA.get(SkMatrix::kMSkewY));
    739         xform.eM21 = SkScalarToFloat(sA.get(SkMatrix::kMSkewX));
    740         xform.eM22 = SkScalarToFloat(sA.get(SkMatrix::kMScaleY));
    741         xform.eDx = 0;
    742         xform.eDy = 0;
    743 
    744         // MAT2 is row major, right handed (y up).
    745         fMat22.eM11 = float2FIXED(xform.eM11);
    746         fMat22.eM12 = float2FIXED(-xform.eM12);
    747         fMat22.eM21 = float2FIXED(-xform.eM21);
    748         fMat22.eM22 = float2FIXED(xform.eM22);
    749 
    750         if (needToRenderWithSkia(fRec)) {
    751             this->forceGenerateImageFromPath();
    752         }
    753 
    754         // Create a hires font if we need linear metrics.
    755         if (this->isSubpixel()) {
    756             OUTLINETEXTMETRIC otm;
    757             UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
    758             if (0 == success) {
    759                 call_ensure_accessible(lf);
    760                 success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
    761             }
    762             if (0 != success) {
    763                 SkScalar scale = SkIntToScalar(otm.otmEMSquare);
    764 
    765                 SkScalar textScale = scale / textSize;
    766                 fHighResMat22.eM11 = float2FIXED(textScale);
    767                 fHighResMat22.eM12 = float2FIXED(0);
    768                 fHighResMat22.eM21 = float2FIXED(0);
    769                 fHighResMat22.eM22 = float2FIXED(textScale);
    770 
    771                 SkScalar invScale = SkScalarInvert(scale);
    772                 fHiResMatrix = A;
    773                 fHiResMatrix.preScale(invScale, invScale);
    774             }
    775         }
    776 
    777     } else {
    778         // Assume bitmap
    779         fType = SkScalerContext_GDI::kBitmap_Type;
    780 
    781         xform.eM11 = 1.0f;
    782         xform.eM12 = 0.0f;
    783         xform.eM21 = 0.0f;
    784         xform.eM22 = 1.0f;
    785         xform.eDx = 0.0f;
    786         xform.eDy = 0.0f;
    787 
    788         // fPost2x2 is column-major, left handed (y down).
    789         // MAT2 is row major, right handed (y up).
    790         fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]);
    791         fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]);
    792         fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]);
    793         fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]);
    794     }
    795 
    796     fOffscreen.init(fFont, xform);
    797 }
    798 
    799 SkScalerContext_GDI::~SkScalerContext_GDI() {
    800     if (fDDC) {
    801         ::SelectObject(fDDC, fSavefont);
    802         ::DeleteDC(fDDC);
    803     }
    804     if (fFont) {
    805         ::DeleteObject(fFont);
    806     }
    807     if (fSC) {
    808         ::ScriptFreeCache(&fSC);
    809     }
    810 }
    811 
    812 bool SkScalerContext_GDI::isValid() const {
    813     return fDDC && fFont;
    814 }
    815 
    816 unsigned SkScalerContext_GDI::generateGlyphCount() {
    817     if (fGlyphCount < 0) {
    818         fGlyphCount = calculateGlyphCount(
    819                           fDDC, static_cast<const LogFontTypeface*>(this->getTypeface())->fLogFont);
    820     }
    821     return fGlyphCount;
    822 }
    823 
    824 uint16_t SkScalerContext_GDI::generateCharToGlyph(SkUnichar uni) {
    825     uint16_t index = 0;
    826     WCHAR c[2];
    827     // TODO(ctguil): Support characters that generate more than one glyph.
    828     if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) {
    829         // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0.
    830         SkAssertResult(GetGlyphIndicesW(fDDC, c, 1, &index, 0));
    831     } else {
    832         // Use uniscribe to detemine glyph index for non-BMP characters.
    833         // Need to add extra item to SCRIPT_ITEM to work around a bug in older
    834         // windows versions. https://bugzilla.mozilla.org/show_bug.cgi?id=366643
    835         SCRIPT_ITEM si[2 + 1];
    836         int items;
    837         SkAssertResult(
    838             SUCCEEDED(ScriptItemize(c, 2, 2, NULL, NULL, si, &items)));
    839 
    840         WORD log[2];
    841         SCRIPT_VISATTR vsa;
    842         int glyphs;
    843         SkAssertResult(SUCCEEDED(ScriptShape(
    844             fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs)));
    845     }
    846     return index;
    847 }
    848 
    849 void SkScalerContext_GDI::generateAdvance(SkGlyph* glyph) {
    850     this->generateMetrics(glyph);
    851 }
    852 
    853 void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) {
    854     SkASSERT(fDDC);
    855 
    856     if (fType == SkScalerContext_GDI::kBitmap_Type) {
    857         SIZE size;
    858         WORD glyphs = glyph->getGlyphID(0);
    859         if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) {
    860             glyph->fWidth = SkToS16(fTM.tmMaxCharWidth);
    861         } else {
    862             glyph->fWidth = SkToS16(size.cx);
    863         }
    864         glyph->fHeight = SkToS16(size.cy);
    865 
    866         glyph->fTop = SkToS16(-fTM.tmAscent);
    867         glyph->fLeft = SkToS16(0);
    868         glyph->fAdvanceX = SkIntToFixed(glyph->fWidth);
    869         glyph->fAdvanceY = 0;
    870 
    871         // Apply matrix to advance.
    872         glyph->fAdvanceY = SkFixedMul(SkFIXEDToFixed(fMat22.eM21), glyph->fAdvanceX);
    873         glyph->fAdvanceX = SkFixedMul(SkFIXEDToFixed(fMat22.eM11), glyph->fAdvanceX);
    874 
    875         return;
    876     }
    877 
    878     UINT glyphId = glyph->getGlyphID(0);
    879 
    880     GLYPHMETRICS gm;
    881     sk_bzero(&gm, sizeof(gm));
    882 
    883     DWORD status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
    884     if (GDI_ERROR == status) {
    885         LogFontTypeface::EnsureAccessible(this->getTypeface());
    886         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
    887         if (GDI_ERROR == status) {
    888             glyph->zeroMetrics();
    889             return;
    890         }
    891     }
    892 
    893     bool empty = false;
    894     // The black box is either the embedded bitmap size or the outline extent.
    895     // It is 1x1 if nothing is to be drawn, but will also be 1x1 if something very small
    896     // is to be drawn, like a '.'. We need to outset '.' but do not wish to outset ' '.
    897     if (1 == gm.gmBlackBoxX && 1 == gm.gmBlackBoxY) {
    898         // If GetGlyphOutline with GGO_NATIVE returns 0, we know there was no outline.
    899         DWORD bufferSize = GetGlyphOutlineW(fDDC, glyphId, GGO_NATIVE | GGO_GLYPH_INDEX, &gm, 0, NULL, &fMat22);
    900         empty = (0 == bufferSize);
    901     }
    902 
    903     glyph->fTop = SkToS16(-gm.gmptGlyphOrigin.y);
    904     glyph->fLeft = SkToS16(gm.gmptGlyphOrigin.x);
    905     if (empty) {
    906         glyph->fWidth = 0;
    907         glyph->fHeight = 0;
    908     } else {
    909         // Outset, since the image may bleed out of the black box.
    910         // For embedded bitmaps the black box should be exact.
    911         // For outlines we need to outset by 1 in all directions for bleed.
    912         // For ClearType we need to outset by 2 for bleed.
    913         glyph->fWidth = gm.gmBlackBoxX + 4;
    914         glyph->fHeight = gm.gmBlackBoxY + 4;
    915         glyph->fTop -= 2;
    916         glyph->fLeft -= 2;
    917     }
    918     glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX);
    919     glyph->fAdvanceY = SkIntToFixed(gm.gmCellIncY);
    920     glyph->fRsbDelta = 0;
    921     glyph->fLsbDelta = 0;
    922 
    923     if (this->isSubpixel()) {
    924         sk_bzero(&gm, sizeof(gm));
    925         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fHighResMat22);
    926         if (GDI_ERROR != status) {
    927             SkPoint advance;
    928             fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance);
    929             glyph->fAdvanceX = SkScalarToFixed(advance.fX);
    930             glyph->fAdvanceY = SkScalarToFixed(advance.fY);
    931         }
    932     } else if (!isAxisAligned(this->fRec)) {
    933         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, &fGsA);
    934         if (GDI_ERROR != status) {
    935             SkPoint advance;
    936             fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIncY), &advance);
    937             glyph->fAdvanceX = SkScalarToFixed(advance.fX);
    938             glyph->fAdvanceY = SkScalarToFixed(advance.fY);
    939         }
    940     }
    941 }
    942 
    943 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
    944 void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
    945     if (!(mx || my)) {
    946       return;
    947     }
    948 
    949     if (mx) {
    950         sk_bzero(mx, sizeof(*mx));
    951     }
    952     if (my) {
    953         sk_bzero(my, sizeof(*my));
    954     }
    955 
    956     SkASSERT(fDDC);
    957 
    958 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
    959     if (fType == SkScalerContext_GDI::kBitmap_Type) {
    960 #endif
    961         if (mx) {
    962             mx->fTop = SkIntToScalar(-fTM.tmAscent);
    963             mx->fAscent = SkIntToScalar(-fTM.tmAscent);
    964             mx->fDescent = SkIntToScalar(fTM.tmDescent);
    965             mx->fBottom = SkIntToScalar(fTM.tmDescent);
    966             mx->fLeading = SkIntToScalar(fTM.tmExternalLeading);
    967         }
    968 
    969         if (my) {
    970             my->fTop = SkIntToScalar(-fTM.tmAscent);
    971             my->fAscent = SkIntToScalar(-fTM.tmAscent);
    972             my->fDescent = SkIntToScalar(fTM.tmDescent);
    973             my->fBottom = SkIntToScalar(fTM.tmDescent);
    974             my->fLeading = SkIntToScalar(fTM.tmExternalLeading);
    975             my->fAvgCharWidth = SkIntToScalar(fTM.tmAveCharWidth);
    976             my->fMaxCharWidth = SkIntToScalar(fTM.tmMaxCharWidth);
    977             my->fXMin = 0;
    978             my->fXMax = my->fMaxCharWidth;
    979             //my->fXHeight = 0;
    980         }
    981 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
    982         return;
    983     }
    984 #endif
    985 
    986     OUTLINETEXTMETRIC otm;
    987 
    988     uint32_t ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
    989     if (0 == ret) {
    990         LogFontTypeface::EnsureAccessible(this->getTypeface());
    991         ret = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm);
    992     }
    993     if (0 == ret) {
    994         return;
    995     }
    996 
    997     if (mx) {
    998         mx->fTop = SkIntToScalar(-otm.otmrcFontBox.left);
    999         mx->fAscent = SkIntToScalar(-otm.otmAscent);
   1000         mx->fDescent = SkIntToScalar(-otm.otmDescent);
   1001         mx->fBottom = SkIntToScalar(otm.otmrcFontBox.right);
   1002         mx->fLeading = SkIntToScalar(otm.otmLineGap);
   1003     }
   1004 
   1005     if (my) {
   1006 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS
   1007         my->fTop = SkIntToScalar(-otm.otmrcFontBox.top);
   1008         my->fAscent = SkIntToScalar(-otm.otmAscent);
   1009         my->fDescent = SkIntToScalar(-otm.otmDescent);
   1010         my->fBottom = SkIntToScalar(-otm.otmrcFontBox.bottom);
   1011         my->fLeading = SkIntToScalar(otm.otmLineGap);
   1012         my->fAvgCharWidth = SkIntToScalar(otm.otmTextMetrics.tmAveCharWidth);
   1013         my->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
   1014         my->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
   1015         my->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
   1016 #endif
   1017         my->fXHeight = SkIntToScalar(otm.otmsXHeight);
   1018 
   1019         GLYPHMETRICS gm;
   1020         sk_bzero(&gm, sizeof(gm));
   1021         DWORD len = GetGlyphOutlineW(fDDC, 'x', GGO_METRICS, &gm, 0, 0, &gMat2Identity);
   1022         if (len != GDI_ERROR && gm.gmBlackBoxY > 0) {
   1023             my->fXHeight = SkIntToScalar(gm.gmBlackBoxY);
   1024         }
   1025     }
   1026 }
   1027 
   1028 ////////////////////////////////////////////////////////////////////////////////////////
   1029 
   1030 #define SK_SHOW_TEXT_BLIT_COVERAGE 0
   1031 
   1032 static void build_power_table(uint8_t table[], float ee) {
   1033     for (int i = 0; i < 256; i++) {
   1034         float x = i / 255.f;
   1035         x = sk_float_pow(x, ee);
   1036         int xx = SkScalarRound(SkFloatToScalar(x * 255));
   1037         table[i] = SkToU8(xx);
   1038     }
   1039 }
   1040 
   1041 /**
   1042  *  This will invert the gamma applied by GDI (gray-scale antialiased), so we
   1043  *  can get linear values.
   1044  *
   1045  *  GDI grayscale appears to use a hard-coded gamma of 2.3.
   1046  *
   1047  *  GDI grayscale appears to draw using the black and white rasterizer at four
   1048  *  times the size and then downsamples to compute the coverage mask. As a
   1049  *  result there are only seventeen total grays. This lack of fidelity means
   1050  *  that shifting into other color spaces is imprecise.
   1051  */
   1052 static const uint8_t* getInverseGammaTableGDI() {
   1053     // Since build_power_table is idempotent, many threads can build gTableGdi
   1054     // simultaneously.
   1055 
   1056     // Microsoft Specific:
   1057     // Making gInited volatile provides read-aquire and write-release in vc++.
   1058     // In VS2012, see compiler option /volatile:(ms|iso).
   1059     // Replace with C++11 atomics when possible.
   1060     static volatile bool gInited;
   1061     static uint8_t gTableGdi[256];
   1062     if (gInited) {
   1063         // Need a L/L (read) barrier (full acquire not needed). If gInited is observed
   1064         // true then gTableGdi is observable, but it must be requested.
   1065     } else {
   1066         build_power_table(gTableGdi, 2.3f);
   1067         // Need a S/S (write) barrier (full release not needed) here so that this
   1068         // write to gInited becomes observable after gTableGdi.
   1069         gInited = true;
   1070     }
   1071     return gTableGdi;
   1072 }
   1073 
   1074 /**
   1075  *  This will invert the gamma applied by GDI ClearType, so we can get linear
   1076  *  values.
   1077  *
   1078  *  GDI ClearType uses SPI_GETFONTSMOOTHINGCONTRAST / 1000 as the gamma value.
   1079  *  If this value is not specified, the default is a gamma of 1.4.
   1080  */
   1081 static const uint8_t* getInverseGammaTableClearType() {
   1082     // We don't expect SPI_GETFONTSMOOTHINGCONTRAST to ever change, so building
   1083     // gTableClearType with build_power_table is effectively idempotent.
   1084 
   1085     // Microsoft Specific:
   1086     // Making gInited volatile provides read-aquire and write-release in vc++.
   1087     // In VS2012, see compiler option /volatile:(ms|iso).
   1088     // Replace with C++11 atomics when possible.
   1089     static volatile bool gInited;
   1090     static uint8_t gTableClearType[256];
   1091     if (gInited) {
   1092         // Need a L/L (read) barrier (acquire not needed). If gInited is observed
   1093         // true then gTableClearType is observable, but it must be requested.
   1094     } else {
   1095         UINT level = 0;
   1096         if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &level, 0) || !level) {
   1097             // can't get the data, so use a default
   1098             level = 1400;
   1099         }
   1100         build_power_table(gTableClearType, level / 1000.0f);
   1101         // Need a S/S (write) barrier (release not needed) here so that this
   1102         // write to gInited becomes observable after gTableClearType.
   1103         gInited = true;
   1104     }
   1105     return gTableClearType;
   1106 }
   1107 
   1108 #include "SkColorPriv.h"
   1109 
   1110 //Cannot assume that the input rgb is gray due to possible setting of kGenA8FromLCD_Flag.
   1111 template<bool APPLY_PREBLEND>
   1112 static inline uint8_t rgb_to_a8(SkGdiRGB rgb, const uint8_t* table8) {
   1113     U8CPU r = (rgb >> 16) & 0xFF;
   1114     U8CPU g = (rgb >>  8) & 0xFF;
   1115     U8CPU b = (rgb >>  0) & 0xFF;
   1116     return sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), table8);
   1117 }
   1118 
   1119 template<bool APPLY_PREBLEND>
   1120 static inline uint16_t rgb_to_lcd16(SkGdiRGB rgb, const uint8_t* tableR,
   1121                                                   const uint8_t* tableG,
   1122                                                   const uint8_t* tableB) {
   1123     U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR);
   1124     U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  8) & 0xFF, tableG);
   1125     U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  0) & 0xFF, tableB);
   1126 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1127     r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
   1128 #endif
   1129     return SkPack888ToRGB16(r, g, b);
   1130 }
   1131 
   1132 template<bool APPLY_PREBLEND>
   1133 static inline SkPMColor rgb_to_lcd32(SkGdiRGB rgb, const uint8_t* tableR,
   1134                                                    const uint8_t* tableG,
   1135                                                    const uint8_t* tableB) {
   1136     U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR);
   1137     U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  8) & 0xFF, tableG);
   1138     U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >>  0) & 0xFF, tableB);
   1139 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1140     r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10);
   1141 #endif
   1142     return SkPackARGB32(0xFF, r, g, b);
   1143 }
   1144 
   1145 // Is this GDI color neither black nor white? If so, we have to keep this
   1146 // image as is, rather than smashing it down to a BW mask.
   1147 //
   1148 // returns int instead of bool, since we don't want/have to pay to convert
   1149 // the zero/non-zero value into a bool
   1150 static int is_not_black_or_white(SkGdiRGB c) {
   1151     // same as (but faster than)
   1152     //      c &= 0x00FFFFFF;
   1153     //      return 0 == c || 0x00FFFFFF == c;
   1154     return (c + (c & 1)) & 0x00FFFFFF;
   1155 }
   1156 
   1157 static bool is_rgb_really_bw(const SkGdiRGB* src, int width, int height, size_t srcRB) {
   1158     for (int y = 0; y < height; ++y) {
   1159         for (int x = 0; x < width; ++x) {
   1160             if (is_not_black_or_white(src[x])) {
   1161                 return false;
   1162             }
   1163         }
   1164         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
   1165     }
   1166     return true;
   1167 }
   1168 
   1169 // gdi's bitmap is upside-down, so we reverse dst walking in Y
   1170 // whenever we copy it into skia's buffer
   1171 static void rgb_to_bw(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
   1172                       const SkGlyph& glyph) {
   1173     const int width = glyph.fWidth;
   1174     const size_t dstRB = (width + 7) >> 3;
   1175     uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
   1176 
   1177     int byteCount = width >> 3;
   1178     int bitCount = width & 7;
   1179 
   1180     // adjust srcRB to skip the values in our byteCount loop,
   1181     // since we increment src locally there
   1182     srcRB -= byteCount * 8 * sizeof(SkGdiRGB);
   1183 
   1184     for (int y = 0; y < glyph.fHeight; ++y) {
   1185         if (byteCount > 0) {
   1186             for (int i = 0; i < byteCount; ++i) {
   1187                 unsigned byte = 0;
   1188                 byte |= src[0] & (1 << 7);
   1189                 byte |= src[1] & (1 << 6);
   1190                 byte |= src[2] & (1 << 5);
   1191                 byte |= src[3] & (1 << 4);
   1192                 byte |= src[4] & (1 << 3);
   1193                 byte |= src[5] & (1 << 2);
   1194                 byte |= src[6] & (1 << 1);
   1195                 byte |= src[7] & (1 << 0);
   1196                 dst[i] = byte;
   1197                 src += 8;
   1198             }
   1199         }
   1200         if (bitCount > 0) {
   1201             unsigned byte = 0;
   1202             unsigned mask = 0x80;
   1203             for (int i = 0; i < bitCount; i++) {
   1204                 byte |= src[i] & mask;
   1205                 mask >>= 1;
   1206             }
   1207             dst[byteCount] = byte;
   1208         }
   1209         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
   1210         dst -= dstRB;
   1211     }
   1212 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1213     if (glyph.fWidth > 0 && glyph.fHeight > 0) {
   1214         uint8_t* first = (uint8_t*)glyph.fImage;
   1215         uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.fHeight * dstRB - 1);
   1216         *first |= 1 << 7;
   1217         *last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
   1218     }
   1219 #endif
   1220 }
   1221 
   1222 template<bool APPLY_PREBLEND>
   1223 static void rgb_to_a8(const SkGdiRGB* SK_RESTRICT src, size_t srcRB,
   1224                       const SkGlyph& glyph, const uint8_t* table8) {
   1225     const size_t dstRB = glyph.rowBytes();
   1226     const int width = glyph.fWidth;
   1227     uint8_t* SK_RESTRICT dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
   1228 
   1229     for (int y = 0; y < glyph.fHeight; y++) {
   1230         for (int i = 0; i < width; i++) {
   1231             dst[i] = rgb_to_a8<APPLY_PREBLEND>(src[i], table8);
   1232 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1233             dst[i] = SkMax32(dst[i], 10);
   1234 #endif
   1235         }
   1236         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
   1237         dst -= dstRB;
   1238     }
   1239 }
   1240 
   1241 template<bool APPLY_PREBLEND>
   1242 static void rgb_to_lcd16(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
   1243                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
   1244     const size_t dstRB = glyph.rowBytes();
   1245     const int width = glyph.fWidth;
   1246     uint16_t* SK_RESTRICT dst = (uint16_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
   1247 
   1248     for (int y = 0; y < glyph.fHeight; y++) {
   1249         for (int i = 0; i < width; i++) {
   1250             dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(src[i], tableR, tableG, tableB);
   1251         }
   1252         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
   1253         dst = (uint16_t*)((char*)dst - dstRB);
   1254     }
   1255 }
   1256 
   1257 template<bool APPLY_PREBLEND>
   1258 static void rgb_to_lcd32(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const SkGlyph& glyph,
   1259                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
   1260     const size_t dstRB = glyph.rowBytes();
   1261     const int width = glyph.fWidth;
   1262     uint32_t* SK_RESTRICT dst = (uint32_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
   1263 
   1264     for (int y = 0; y < glyph.fHeight; y++) {
   1265         for (int i = 0; i < width; i++) {
   1266             dst[i] = rgb_to_lcd32<APPLY_PREBLEND>(src[i], tableR, tableG, tableB);
   1267         }
   1268         src = SkTAddOffset<const SkGdiRGB>(src, srcRB);
   1269         dst = (uint32_t*)((char*)dst - dstRB);
   1270     }
   1271 }
   1272 
   1273 static inline unsigned clamp255(unsigned x) {
   1274     SkASSERT(x <= 256);
   1275     return x - (x >> 8);
   1276 }
   1277 
   1278 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) {
   1279     SkASSERT(fDDC);
   1280 
   1281     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
   1282     const bool isAA = !isLCD(fRec);
   1283 
   1284     size_t srcRB;
   1285     const void* bits = fOffscreen.draw(glyph, isBW, &srcRB);
   1286     if (NULL == bits) {
   1287         LogFontTypeface::EnsureAccessible(this->getTypeface());
   1288         bits = fOffscreen.draw(glyph, isBW, &srcRB);
   1289         if (NULL == bits) {
   1290             sk_bzero(glyph.fImage, glyph.computeImageSize());
   1291             return;
   1292         }
   1293     }
   1294 
   1295     if (!isBW) {
   1296         const uint8_t* table;
   1297         //The offscreen contains a GDI blit if isAA and kGenA8FromLCD_Flag is not set.
   1298         //Otherwise the offscreen contains a ClearType blit.
   1299         if (isAA && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) {
   1300             table = getInverseGammaTableGDI();
   1301         } else {
   1302             table = getInverseGammaTableClearType();
   1303         }
   1304         //Note that the following cannot really be integrated into the
   1305         //pre-blend, since we may not be applying the pre-blend; when we aren't
   1306         //applying the pre-blend it means that a filter wants linear anyway.
   1307         //Other code may also be applying the pre-blend, so we'd need another
   1308         //one with this and one without.
   1309         SkGdiRGB* addr = (SkGdiRGB*)bits;
   1310         for (int y = 0; y < glyph.fHeight; ++y) {
   1311             for (int x = 0; x < glyph.fWidth; ++x) {
   1312                 int r = (addr[x] >> 16) & 0xFF;
   1313                 int g = (addr[x] >>  8) & 0xFF;
   1314                 int b = (addr[x] >>  0) & 0xFF;
   1315                 addr[x] = (table[r] << 16) | (table[g] << 8) | table[b];
   1316             }
   1317             addr = SkTAddOffset<SkGdiRGB>(addr, srcRB);
   1318         }
   1319     }
   1320 
   1321     int width = glyph.fWidth;
   1322     size_t dstRB = glyph.rowBytes();
   1323     if (isBW) {
   1324         const uint8_t* src = (const uint8_t*)bits;
   1325         uint8_t* dst = (uint8_t*)((char*)glyph.fImage + (glyph.fHeight - 1) * dstRB);
   1326         for (int y = 0; y < glyph.fHeight; y++) {
   1327             memcpy(dst, src, dstRB);
   1328             src += srcRB;
   1329             dst -= dstRB;
   1330         }
   1331 #if SK_SHOW_TEXT_BLIT_COVERAGE
   1332             if (glyph.fWidth > 0 && glyph.fHeight > 0) {
   1333                 int bitCount = width & 7;
   1334                 uint8_t* first = (uint8_t*)glyph.fImage;
   1335                 uint8_t* last = (uint8_t*)((char*)glyph.fImage + glyph.fHeight * dstRB - 1);
   1336                 *first |= 1 << 7;
   1337                 *last |= bitCount == 0 ? 1 : 1 << (8 - bitCount);
   1338             }
   1339 #endif
   1340     } else if (isAA) {
   1341         // since the caller may require A8 for maskfilters, we can't check for BW
   1342         // ... until we have the caller tell us that explicitly
   1343         const SkGdiRGB* src = (const SkGdiRGB*)bits;
   1344         if (fPreBlend.isApplicable()) {
   1345             rgb_to_a8<true>(src, srcRB, glyph, fPreBlend.fG);
   1346         } else {
   1347             rgb_to_a8<false>(src, srcRB, glyph, fPreBlend.fG);
   1348         }
   1349     } else {    // LCD16
   1350         const SkGdiRGB* src = (const SkGdiRGB*)bits;
   1351         if (is_rgb_really_bw(src, width, glyph.fHeight, srcRB)) {
   1352             rgb_to_bw(src, srcRB, glyph);
   1353             ((SkGlyph*)&glyph)->fMaskFormat = SkMask::kBW_Format;
   1354         } else {
   1355             if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
   1356                 if (fPreBlend.isApplicable()) {
   1357                     rgb_to_lcd16<true>(src, srcRB, glyph,
   1358                                        fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1359                 } else {
   1360                     rgb_to_lcd16<false>(src, srcRB, glyph,
   1361                                         fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1362                 }
   1363             } else {
   1364                 SkASSERT(SkMask::kLCD32_Format == glyph.fMaskFormat);
   1365                 if (fPreBlend.isApplicable()) {
   1366                     rgb_to_lcd32<true>(src, srcRB, glyph,
   1367                                        fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1368                 } else {
   1369                     rgb_to_lcd32<false>(src, srcRB, glyph,
   1370                                         fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1371                 }
   1372             }
   1373         }
   1374     }
   1375 }
   1376 
   1377 class GDIGlyphbufferPointIter {
   1378 public:
   1379     GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size)
   1380         : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter()
   1381     { }
   1382 
   1383     POINTFX next() {
   1384 nextHeader:
   1385         if (!fCurveIter.isSet()) {
   1386             const TTPOLYGONHEADER* header = fHeaderIter.next();
   1387             SkASSERT(header);
   1388             fCurveIter.set(header);
   1389             const TTPOLYCURVE* curve = fCurveIter.next();
   1390             SkASSERT(curve);
   1391             fPointIter.set(curve);
   1392             return header->pfxStart;
   1393         }
   1394 
   1395         const POINTFX* nextPoint = fPointIter.next();
   1396         if (NULL == nextPoint) {
   1397             const TTPOLYCURVE* curve = fCurveIter.next();
   1398             if (NULL == curve) {
   1399                 fCurveIter.set();
   1400                 goto nextHeader;
   1401             } else {
   1402                 fPointIter.set(curve);
   1403             }
   1404             nextPoint = fPointIter.next();
   1405             SkASSERT(nextPoint);
   1406         }
   1407         return *nextPoint;
   1408     }
   1409 
   1410     WORD currentCurveType() {
   1411         return fPointIter.fCurveType;
   1412     }
   1413 
   1414 private:
   1415     /** Iterates over all of the polygon headers in a glyphbuf. */
   1416     class GDIPolygonHeaderIter {
   1417     public:
   1418         GDIPolygonHeaderIter(const uint8_t* glyphbuf, DWORD total_size)
   1419             : fCurPolygon(reinterpret_cast<const TTPOLYGONHEADER*>(glyphbuf))
   1420             , fEndPolygon(SkTAddOffset<const TTPOLYGONHEADER>(glyphbuf, total_size))
   1421         { }
   1422 
   1423         const TTPOLYGONHEADER* next() {
   1424             if (fCurPolygon >= fEndPolygon) {
   1425                 return NULL;
   1426             }
   1427             const TTPOLYGONHEADER* thisPolygon = fCurPolygon;
   1428             fCurPolygon = SkTAddOffset<const TTPOLYGONHEADER>(fCurPolygon, fCurPolygon->cb);
   1429             return thisPolygon;
   1430         }
   1431     private:
   1432         const TTPOLYGONHEADER* fCurPolygon;
   1433         const TTPOLYGONHEADER* fEndPolygon;
   1434     };
   1435 
   1436     /** Iterates over all of the polygon curves in a polygon header. */
   1437     class GDIPolygonCurveIter {
   1438     public:
   1439         GDIPolygonCurveIter() : fCurCurve(NULL), fEndCurve(NULL) { }
   1440 
   1441         GDIPolygonCurveIter(const TTPOLYGONHEADER* curPolygon)
   1442             : fCurCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOLYGONHEADER)))
   1443             , fEndCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->cb))
   1444         { }
   1445 
   1446         bool isSet() { return fCurCurve != NULL; }
   1447 
   1448         void set(const TTPOLYGONHEADER* curPolygon) {
   1449             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOLYGONHEADER));
   1450             fEndCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->cb);
   1451         }
   1452         void set() {
   1453             fCurCurve = NULL;
   1454             fEndCurve = NULL;
   1455         }
   1456 
   1457         const TTPOLYCURVE* next() {
   1458             if (fCurCurve >= fEndCurve) {
   1459                 return NULL;
   1460             }
   1461             const TTPOLYCURVE* thisCurve = fCurCurve;
   1462             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(fCurCurve, size_of_TTPOLYCURVE(*fCurCurve));
   1463             return thisCurve;
   1464         }
   1465     private:
   1466         size_t size_of_TTPOLYCURVE(const TTPOLYCURVE& curve) {
   1467             return 2*sizeof(WORD) + curve.cpfx*sizeof(POINTFX);
   1468         }
   1469         const TTPOLYCURVE* fCurCurve;
   1470         const TTPOLYCURVE* fEndCurve;
   1471     };
   1472 
   1473     /** Iterates over all of the polygon points in a polygon curve. */
   1474     class GDIPolygonCurvePointIter {
   1475     public:
   1476         GDIPolygonCurvePointIter() : fCurveType(0), fCurPoint(NULL), fEndPoint(NULL) { }
   1477 
   1478         GDIPolygonCurvePointIter(const TTPOLYCURVE* curPolygon)
   1479             : fCurveType(curPolygon->wType)
   1480             , fCurPoint(&curPolygon->apfx[0])
   1481             , fEndPoint(&curPolygon->apfx[curPolygon->cpfx])
   1482         { }
   1483 
   1484         bool isSet() { return fCurPoint != NULL; }
   1485 
   1486         void set(const TTPOLYCURVE* curPolygon) {
   1487             fCurveType = curPolygon->wType;
   1488             fCurPoint = &curPolygon->apfx[0];
   1489             fEndPoint = &curPolygon->apfx[curPolygon->cpfx];
   1490         }
   1491         void set() {
   1492             fCurPoint = NULL;
   1493             fEndPoint = NULL;
   1494         }
   1495 
   1496         const POINTFX* next() {
   1497             if (fCurPoint >= fEndPoint) {
   1498                 return NULL;
   1499             }
   1500             const POINTFX* thisPoint = fCurPoint;
   1501             ++fCurPoint;
   1502             return thisPoint;
   1503         }
   1504 
   1505         WORD fCurveType;
   1506     private:
   1507         const POINTFX* fCurPoint;
   1508         const POINTFX* fEndPoint;
   1509     };
   1510 
   1511     GDIPolygonHeaderIter fHeaderIter;
   1512     GDIPolygonCurveIter fCurveIter;
   1513     GDIPolygonCurvePointIter fPointIter;
   1514 };
   1515 
   1516 static void sk_path_from_gdi_path(SkPath* path, const uint8_t* glyphbuf, DWORD total_size) {
   1517     const uint8_t* cur_glyph = glyphbuf;
   1518     const uint8_t* end_glyph = glyphbuf + total_size;
   1519 
   1520     while (cur_glyph < end_glyph) {
   1521         const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
   1522 
   1523         const uint8_t* end_poly = cur_glyph + th->cb;
   1524         const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
   1525 
   1526         path->moveTo(SkFixedToScalar( SkFIXEDToFixed(th->pfxStart.x)),
   1527                      SkFixedToScalar(-SkFIXEDToFixed(th->pfxStart.y)));
   1528 
   1529         while (cur_poly < end_poly) {
   1530             const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
   1531 
   1532             if (pc->wType == TT_PRIM_LINE) {
   1533                 for (uint16_t i = 0; i < pc->cpfx; i++) {
   1534                     path->lineTo(SkFixedToScalar( SkFIXEDToFixed(pc->apfx[i].x)),
   1535                                  SkFixedToScalar(-SkFIXEDToFixed(pc->apfx[i].y)));
   1536                 }
   1537             }
   1538 
   1539             if (pc->wType == TT_PRIM_QSPLINE) {
   1540                 for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
   1541                     POINTFX pnt_b = pc->apfx[u];    // B is always the current point
   1542                     POINTFX pnt_c = pc->apfx[u+1];
   1543 
   1544                     if (u < pc->cpfx - 2) {          // If not on last spline, compute C
   1545                         pnt_c.x = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.x),
   1546                                                             SkFIXEDToFixed(pnt_c.x)));
   1547                         pnt_c.y = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.y),
   1548                                                             SkFIXEDToFixed(pnt_c.y)));
   1549                     }
   1550 
   1551                     path->quadTo(SkFixedToScalar( SkFIXEDToFixed(pnt_b.x)),
   1552                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_b.y)),
   1553                                  SkFixedToScalar( SkFIXEDToFixed(pnt_c.x)),
   1554                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_c.y)));
   1555                 }
   1556             }
   1557             // Advance past this TTPOLYCURVE.
   1558             cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
   1559         }
   1560         cur_glyph += th->cb;
   1561         path->close();
   1562     }
   1563 }
   1564 
   1565 static void sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD total_size,
   1566                                    GDIGlyphbufferPointIter hintedYs) {
   1567     const uint8_t* cur_glyph = glyphbuf;
   1568     const uint8_t* end_glyph = glyphbuf + total_size;
   1569 
   1570     while (cur_glyph < end_glyph) {
   1571         const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph;
   1572 
   1573         const uint8_t* end_poly = cur_glyph + th->cb;
   1574         const uint8_t* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER);
   1575 
   1576         path->moveTo(SkFixedToScalar( SkFIXEDToFixed(th->pfxStart.x)),
   1577                      SkFixedToScalar(-SkFIXEDToFixed(hintedYs.next().y)));
   1578 
   1579         while (cur_poly < end_poly) {
   1580             const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly;
   1581 
   1582             if (pc->wType == TT_PRIM_LINE) {
   1583                 for (uint16_t i = 0; i < pc->cpfx; i++) {
   1584                     path->lineTo(SkFixedToScalar( SkFIXEDToFixed(pc->apfx[i].x)),
   1585                                  SkFixedToScalar(-SkFIXEDToFixed(hintedYs.next().y)));
   1586                 }
   1587             }
   1588 
   1589             if (pc->wType == TT_PRIM_QSPLINE) {
   1590                 POINTFX currentPoint = pc->apfx[0];
   1591                 POINTFX hintedY = hintedYs.next();
   1592                 // only take the hinted y if it wasn't flipped
   1593                 if (hintedYs.currentCurveType() == TT_PRIM_QSPLINE) {
   1594                     currentPoint.y = hintedY.y;
   1595                 }
   1596                 for (uint16_t u = 0; u < pc->cpfx - 1; u++) { // Walk through points in spline
   1597                     POINTFX pnt_b = currentPoint;//pc->apfx[u]; // B is always the current point
   1598                     POINTFX pnt_c = pc->apfx[u+1];
   1599                     POINTFX hintedY = hintedYs.next();
   1600                     // only take the hinted y if it wasn't flipped
   1601                     if (hintedYs.currentCurveType() == TT_PRIM_QSPLINE) {
   1602                         pnt_c.y = hintedY.y;
   1603                     }
   1604                     currentPoint.x = pnt_c.x;
   1605                     currentPoint.y = pnt_c.y;
   1606 
   1607                     if (u < pc->cpfx - 2) {          // If not on last spline, compute C
   1608                         pnt_c.x = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.x),
   1609                                                             SkFIXEDToFixed(pnt_c.x)));
   1610                         pnt_c.y = SkFixedToFIXED(SkFixedAve(SkFIXEDToFixed(pnt_b.y),
   1611                                                             SkFIXEDToFixed(pnt_c.y)));
   1612                     }
   1613 
   1614                     path->quadTo(SkFixedToScalar( SkFIXEDToFixed(pnt_b.x)),
   1615                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_b.y)),
   1616                                  SkFixedToScalar( SkFIXEDToFixed(pnt_c.x)),
   1617                                  SkFixedToScalar(-SkFIXEDToFixed(pnt_c.y)));
   1618                 }
   1619             }
   1620             // Advance past this TTPOLYCURVE.
   1621             cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx;
   1622         }
   1623         cur_glyph += th->cb;
   1624         path->close();
   1625     }
   1626 }
   1627 
   1628 DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags,
   1629                                                SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf)
   1630 {
   1631     GLYPHMETRICS gm;
   1632 
   1633     DWORD total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, BUFFERSIZE, glyphbuf->get(), &fMat22);
   1634     // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even if BUFFERSIZE > 0.
   1635     // It has been verified that this does not involve a buffer overrun.
   1636     if (GDI_ERROR == total_size || total_size > BUFFERSIZE) {
   1637         // GDI_ERROR because the BUFFERSIZE was too small, or because the data was not accessible.
   1638         // When the data is not accessable GetGlyphOutlineW fails rather quickly,
   1639         // so just try to get the size. If that fails then ensure the data is accessible.
   1640         total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, 0, NULL, &fMat22);
   1641         if (GDI_ERROR == total_size) {
   1642             LogFontTypeface::EnsureAccessible(this->getTypeface());
   1643             total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, 0, NULL, &fMat22);
   1644             if (GDI_ERROR == total_size) {
   1645                 SkASSERT(false);
   1646                 return 0;
   1647             }
   1648         }
   1649 
   1650         glyphbuf->reset(total_size);
   1651 
   1652         DWORD ret = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, total_size, glyphbuf->get(), &fMat22);
   1653         if (GDI_ERROR == ret) {
   1654             LogFontTypeface::EnsureAccessible(this->getTypeface());
   1655             ret = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, total_size, glyphbuf->get(), &fMat22);
   1656             if (GDI_ERROR == ret) {
   1657                 SkASSERT(false);
   1658                 return 0;
   1659             }
   1660         }
   1661     }
   1662     return total_size;
   1663 }
   1664 
   1665 void SkScalerContext_GDI::generatePath(const SkGlyph& glyph, SkPath* path) {
   1666     SkASSERT(&glyph && path);
   1667     SkASSERT(fDDC);
   1668 
   1669     path->reset();
   1670 
   1671     // Out of all the fonts on a typical Windows box,
   1672     // 25% of glyphs require more than 2KB.
   1673     // 1% of glyphs require more than 4KB.
   1674     // 0.01% of glyphs require more than 8KB.
   1675     // 8KB is less than 1% of the normal 1MB stack on Windows.
   1676     // Note that some web fonts glyphs require more than 20KB.
   1677     //static const DWORD BUFFERSIZE = (1 << 13);
   1678 
   1679     //GDI only uses hinted outlines when axis aligned.
   1680     UINT format = GGO_NATIVE | GGO_GLYPH_INDEX;
   1681     if (fRec.getHinting() == SkPaint::kNo_Hinting || fRec.getHinting() == SkPaint::kSlight_Hinting){
   1682         format |= GGO_UNHINTED;
   1683     }
   1684     SkAutoSTMalloc<BUFFERSIZE, uint8_t> glyphbuf(BUFFERSIZE);
   1685     DWORD total_size = getGDIGlyphPath(glyph, format, &glyphbuf);
   1686     if (0 == total_size) {
   1687         return;
   1688     }
   1689 
   1690     if (fRec.getHinting() != SkPaint::kSlight_Hinting) {
   1691         sk_path_from_gdi_path(path, glyphbuf, total_size);
   1692     } else {
   1693         //GDI only uses hinted outlines when axis aligned.
   1694         UINT format = GGO_NATIVE | GGO_GLYPH_INDEX;
   1695 
   1696         SkAutoSTMalloc<BUFFERSIZE, uint8_t> hintedGlyphbuf(BUFFERSIZE);
   1697         DWORD hinted_total_size = getGDIGlyphPath(glyph, format, &hintedGlyphbuf);
   1698         if (0 == hinted_total_size) {
   1699             return;
   1700         }
   1701 
   1702         sk_path_from_gdi_paths(path, glyphbuf, total_size,
   1703                                GDIGlyphbufferPointIter(hintedGlyphbuf, hinted_total_size));
   1704     }
   1705 }
   1706 
   1707 static void logfont_for_name(const char* familyName, LOGFONT* lf) {
   1708     sk_bzero(lf, sizeof(LOGFONT));
   1709 #ifdef UNICODE
   1710     // Get the buffer size needed first.
   1711     size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName,
   1712                                             -1, NULL, 0);
   1713     // Allocate a buffer (str_len already has terminating null
   1714     // accounted for).
   1715     wchar_t *wideFamilyName = new wchar_t[str_len];
   1716     // Now actually convert the string.
   1717     ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1,
   1718                             wideFamilyName, str_len);
   1719     ::wcsncpy(lf->lfFaceName, wideFamilyName, LF_FACESIZE - 1);
   1720     delete [] wideFamilyName;
   1721     lf->lfFaceName[LF_FACESIZE-1] = L'\0';
   1722 #else
   1723     ::strncpy(lf->lfFaceName, familyName, LF_FACESIZE - 1);
   1724     lf->lfFaceName[LF_FACESIZE - 1] = '\0';
   1725 #endif
   1726 }
   1727 
   1728 void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
   1729                                           bool* isLocalStream) const {
   1730     // Get the actual name of the typeface. The logfont may not know this.
   1731     HFONT font = CreateFontIndirect(&fLogFont);
   1732 
   1733     HDC deviceContext = ::CreateCompatibleDC(NULL);
   1734     HFONT savefont = (HFONT)SelectObject(deviceContext, font);
   1735 
   1736     SkString familyName;
   1737     dcfontname_to_skstring(deviceContext, fLogFont, &familyName);
   1738 
   1739     if (deviceContext) {
   1740         ::SelectObject(deviceContext, savefont);
   1741         ::DeleteDC(deviceContext);
   1742     }
   1743     if (font) {
   1744         ::DeleteObject(font);
   1745     }
   1746 
   1747     desc->setFamilyName(familyName.c_str());
   1748     *isLocalStream = this->fSerializeAsStream;
   1749 }
   1750 
   1751 static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
   1752     // Initialize the MAT2 structure to the identify transformation matrix.
   1753     static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0),
   1754                         SkScalarToFIXED(0), SkScalarToFIXED(1)};
   1755     int flags = GGO_METRICS | GGO_GLYPH_INDEX;
   1756     GLYPHMETRICS gm;
   1757     if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, NULL, &mat2)) {
   1758         return false;
   1759     }
   1760     SkASSERT(advance);
   1761     *advance = gm.gmCellIncX;
   1762     return true;
   1763 }
   1764 
   1765 SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics(
   1766         SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
   1767         const uint32_t* glyphIDs,
   1768         uint32_t glyphIDsCount) const {
   1769     LOGFONT lf = fLogFont;
   1770     SkAdvancedTypefaceMetrics* info = NULL;
   1771 
   1772     HDC hdc = CreateCompatibleDC(NULL);
   1773     HFONT font = CreateFontIndirect(&lf);
   1774     HFONT savefont = (HFONT)SelectObject(hdc, font);
   1775     HFONT designFont = NULL;
   1776 
   1777     const char stem_chars[] = {'i', 'I', '!', '1'};
   1778     int16_t min_width;
   1779     unsigned glyphCount;
   1780 
   1781     // To request design units, create a logical font whose height is specified
   1782     // as unitsPerEm.
   1783     OUTLINETEXTMETRIC otm;
   1784     unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
   1785     if (0 == otmRet) {
   1786         call_ensure_accessible(lf);
   1787         otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm);
   1788     }
   1789     if (!otmRet || !GetTextFace(hdc, LF_FACESIZE, lf.lfFaceName)) {
   1790         goto Error;
   1791     }
   1792     lf.lfHeight = -SkToS32(otm.otmEMSquare);
   1793     designFont = CreateFontIndirect(&lf);
   1794     SelectObject(hdc, designFont);
   1795     if (!GetOutlineTextMetrics(hdc, sizeof(otm), &otm)) {
   1796         goto Error;
   1797     }
   1798     glyphCount = calculateGlyphCount(hdc, fLogFont);
   1799 
   1800     info = new SkAdvancedTypefaceMetrics;
   1801     info->fEmSize = otm.otmEMSquare;
   1802     info->fMultiMaster = false;
   1803     info->fLastGlyphID = SkToU16(glyphCount - 1);
   1804     info->fStyle = 0;
   1805     tchar_to_skstring(lf.lfFaceName, &info->fFontName);
   1806 
   1807     if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
   1808         populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode));
   1809     }
   1810 
   1811     if (glyphCount > 0 &&
   1812         (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) {
   1813         info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
   1814     } else {
   1815         info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
   1816         info->fItalicAngle = 0;
   1817         info->fAscent = 0;
   1818         info->fDescent = 0;
   1819         info->fStemV = 0;
   1820         info->fCapHeight = 0;
   1821         info->fBBox = SkIRect::MakeEmpty();
   1822         goto ReturnInfo;
   1823     }
   1824 
   1825     // If this bit is clear the font is a fixed pitch font.
   1826     if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
   1827         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
   1828     }
   1829     if (otm.otmTextMetrics.tmItalic) {
   1830         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
   1831     }
   1832     if (otm.otmTextMetrics.tmPitchAndFamily & FF_ROMAN) {
   1833         info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
   1834     } else if (otm.otmTextMetrics.tmPitchAndFamily & FF_SCRIPT) {
   1835             info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
   1836     }
   1837 
   1838     // The main italic angle of the font, in tenths of a degree counterclockwise
   1839     // from vertical.
   1840     info->fItalicAngle = otm.otmItalicAngle / 10;
   1841     info->fAscent = SkToS16(otm.otmTextMetrics.tmAscent);
   1842     info->fDescent = SkToS16(-otm.otmTextMetrics.tmDescent);
   1843     // TODO(ctguil): Use alternate cap height calculation.
   1844     // MSDN says otmsCapEmHeight is not support but it is returning a value on
   1845     // my Win7 box.
   1846     info->fCapHeight = otm.otmsCapEmHeight;
   1847     info->fBBox =
   1848         SkIRect::MakeLTRB(otm.otmrcFontBox.left, otm.otmrcFontBox.top,
   1849                           otm.otmrcFontBox.right, otm.otmrcFontBox.bottom);
   1850 
   1851     // Figure out a good guess for StemV - Min width of i, I, !, 1.
   1852     // This probably isn't very good with an italic font.
   1853     min_width = SHRT_MAX;
   1854     info->fStemV = 0;
   1855     for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
   1856         ABC abcWidths;
   1857         if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
   1858             int16_t width = abcWidths.abcB;
   1859             if (width > 0 && width < min_width) {
   1860                 min_width = width;
   1861                 info->fStemV = min_width;
   1862             }
   1863         }
   1864     }
   1865 
   1866     // If bit 1 is set, the font may not be embedded in a document.
   1867     // If bit 1 is clear, the font can be embedded.
   1868     // If bit 2 is set, the embedding is read-only.
   1869     if (otm.otmfsType & 0x1) {
   1870         info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
   1871     } else if (perGlyphInfo &
   1872                SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
   1873         if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) {
   1874             appendRange(&info->fGlyphWidths, 0);
   1875             info->fGlyphWidths->fAdvance.append(1, &min_width);
   1876             finishRange(info->fGlyphWidths.get(), 0,
   1877                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
   1878         } else {
   1879             info->fGlyphWidths.reset(
   1880                 getAdvanceData(hdc,
   1881                                glyphCount,
   1882                                glyphIDs,
   1883                                glyphIDsCount,
   1884                                &getWidthAdvance));
   1885         }
   1886     }
   1887 
   1888 Error:
   1889 ReturnInfo:
   1890     SelectObject(hdc, savefont);
   1891     DeleteObject(designFont);
   1892     DeleteObject(font);
   1893     DeleteDC(hdc);
   1894 
   1895     return info;
   1896 }
   1897 
   1898 //Dummy representation of a Base64 encoded GUID from create_unique_font_name.
   1899 #define BASE64_GUID_ID "XXXXXXXXXXXXXXXXXXXXXXXX"
   1900 //Length of GUID representation from create_id, including NULL terminator.
   1901 #define BASE64_GUID_ID_LEN SK_ARRAY_COUNT(BASE64_GUID_ID)
   1902 
   1903 SK_COMPILE_ASSERT(BASE64_GUID_ID_LEN < LF_FACESIZE, GUID_longer_than_facesize);
   1904 
   1905 /**
   1906    NameID 6 Postscript names cannot have the character '/'.
   1907    It would be easier to hex encode the GUID, but that is 32 bytes,
   1908    and many systems have issues with names longer than 28 bytes.
   1909    The following need not be any standard base64 encoding.
   1910    The encoded value is never decoded.
   1911 */
   1912 static const char postscript_safe_base64_encode[] =
   1913     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   1914     "abcdefghijklmnopqrstuvwxyz"
   1915     "0123456789-_=";
   1916 
   1917 /**
   1918    Formats a GUID into Base64 and places it into buffer.
   1919    buffer should have space for at least BASE64_GUID_ID_LEN characters.
   1920    The string will always be null terminated.
   1921    XXXXXXXXXXXXXXXXXXXXXXXX0
   1922  */
   1923 static void format_guid_b64(const GUID& guid, char* buffer, size_t bufferSize) {
   1924     SkASSERT(bufferSize >= BASE64_GUID_ID_LEN);
   1925     size_t written = SkBase64::Encode(&guid, sizeof(guid), buffer, postscript_safe_base64_encode);
   1926     SkASSERT(written < LF_FACESIZE);
   1927     buffer[written] = '\0';
   1928 }
   1929 
   1930 /**
   1931    Creates a Base64 encoded GUID and places it into buffer.
   1932    buffer should have space for at least BASE64_GUID_ID_LEN characters.
   1933    The string will always be null terminated.
   1934    XXXXXXXXXXXXXXXXXXXXXXXX0
   1935  */
   1936 static HRESULT create_unique_font_name(char* buffer, size_t bufferSize) {
   1937     GUID guid = {};
   1938     if (FAILED(CoCreateGuid(&guid))) {
   1939         return E_UNEXPECTED;
   1940     }
   1941     format_guid_b64(guid, buffer, bufferSize);
   1942 
   1943     return S_OK;
   1944 }
   1945 
   1946 /**
   1947    Introduces a font to GDI. On failure will return NULL. The returned handle
   1948    should eventually be passed to RemoveFontMemResourceEx.
   1949 */
   1950 static HANDLE activate_font(SkData* fontData) {
   1951     DWORD numFonts = 0;
   1952     //AddFontMemResourceEx just copies the data, but does not specify const.
   1953     HANDLE fontHandle = AddFontMemResourceEx(const_cast<void*>(fontData->data()),
   1954                                              static_cast<DWORD>(fontData->size()),
   1955                                              0,
   1956                                              &numFonts);
   1957 
   1958     if (fontHandle != NULL && numFonts < 1) {
   1959         RemoveFontMemResourceEx(fontHandle);
   1960         return NULL;
   1961     }
   1962 
   1963     return fontHandle;
   1964 }
   1965 
   1966 static SkTypeface* create_from_stream(SkStream* stream) {
   1967     // Create a unique and unpredictable font name.
   1968     // Avoids collisions and access from CSS.
   1969     char familyName[BASE64_GUID_ID_LEN];
   1970     const int familyNameSize = SK_ARRAY_COUNT(familyName);
   1971     if (FAILED(create_unique_font_name(familyName, familyNameSize))) {
   1972         return NULL;
   1973     }
   1974 
   1975     // Change the name of the font.
   1976     SkAutoTUnref<SkData> rewrittenFontData(SkOTUtils::RenameFont(stream, familyName, familyNameSize-1));
   1977     if (NULL == rewrittenFontData.get()) {
   1978         return NULL;
   1979     }
   1980 
   1981     // Register the font with GDI.
   1982     HANDLE fontReference = activate_font(rewrittenFontData.get());
   1983     if (NULL == fontReference) {
   1984         return NULL;
   1985     }
   1986 
   1987     // Create the typeface.
   1988     LOGFONT lf;
   1989     logfont_for_name(familyName, &lf);
   1990 
   1991     return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference);
   1992 }
   1993 
   1994 SkStream* LogFontTypeface::onOpenStream(int* ttcIndex) const {
   1995     *ttcIndex = 0;
   1996 
   1997     const DWORD kTTCTag =
   1998         SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f'));
   1999     LOGFONT lf = fLogFont;
   2000 
   2001     HDC hdc = ::CreateCompatibleDC(NULL);
   2002     HFONT font = CreateFontIndirect(&lf);
   2003     HFONT savefont = (HFONT)SelectObject(hdc, font);
   2004 
   2005     SkMemoryStream* stream = NULL;
   2006     DWORD tables[2] = {kTTCTag, 0};
   2007     for (int i = 0; i < SK_ARRAY_COUNT(tables); i++) {
   2008         DWORD bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
   2009         if (bufferSize == GDI_ERROR) {
   2010             call_ensure_accessible(lf);
   2011             bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0);
   2012         }
   2013         if (bufferSize != GDI_ERROR) {
   2014             stream = new SkMemoryStream(bufferSize);
   2015             if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(), bufferSize)) {
   2016                 break;
   2017             } else {
   2018                 delete stream;
   2019                 stream = NULL;
   2020             }
   2021         }
   2022     }
   2023 
   2024     SelectObject(hdc, savefont);
   2025     DeleteObject(font);
   2026     DeleteDC(hdc);
   2027 
   2028     return stream;
   2029 }
   2030 
   2031 int LogFontTypeface::onCountGlyphs() const {
   2032     HDC hdc = ::CreateCompatibleDC(NULL);
   2033     HFONT font = CreateFontIndirect(&fLogFont);
   2034     HFONT savefont = (HFONT)SelectObject(hdc, font);
   2035 
   2036     unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont);
   2037 
   2038     SelectObject(hdc, savefont);
   2039     DeleteObject(font);
   2040     DeleteDC(hdc);
   2041 
   2042     return glyphCount;
   2043 }
   2044 
   2045 int LogFontTypeface::onGetUPEM() const {
   2046     HDC hdc = ::CreateCompatibleDC(NULL);
   2047     HFONT font = CreateFontIndirect(&fLogFont);
   2048     HFONT savefont = (HFONT)SelectObject(hdc, font);
   2049 
   2050     unsigned int upem = calculateUPEM(hdc, fLogFont);
   2051 
   2052     SelectObject(hdc, savefont);
   2053     DeleteObject(font);
   2054     DeleteDC(hdc);
   2055 
   2056     return upem;
   2057 }
   2058 
   2059 SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() const {
   2060     SkTypeface::LocalizedStrings* nameIter =
   2061         SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
   2062     if (NULL == nameIter) {
   2063         SkString familyName;
   2064         this->getFamilyName(&familyName);
   2065         SkString language("und"); //undetermined
   2066         nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, language);
   2067     }
   2068     return nameIter;
   2069 }
   2070 
   2071 int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
   2072     SkSFNTHeader header;
   2073     if (sizeof(header) != this->onGetTableData(0, 0, sizeof(header), &header)) {
   2074         return 0;
   2075     }
   2076 
   2077     int numTables = SkEndian_SwapBE16(header.numTables);
   2078 
   2079     if (tags) {
   2080         size_t size = numTables * sizeof(SkSFNTHeader::TableDirectoryEntry);
   2081         SkAutoSTMalloc<0x20, SkSFNTHeader::TableDirectoryEntry> dir(numTables);
   2082         if (size != this->onGetTableData(0, sizeof(header), size, dir.get())) {
   2083             return 0;
   2084         }
   2085 
   2086         for (int i = 0; i < numTables; ++i) {
   2087             tags[i] = SkEndian_SwapBE32(dir[i].tag);
   2088         }
   2089     }
   2090     return numTables;
   2091 }
   2092 
   2093 size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
   2094                                        size_t length, void* data) const
   2095 {
   2096     LOGFONT lf = fLogFont;
   2097 
   2098     HDC hdc = ::CreateCompatibleDC(NULL);
   2099     HFONT font = CreateFontIndirect(&lf);
   2100     HFONT savefont = (HFONT)SelectObject(hdc, font);
   2101 
   2102     tag = SkEndian_SwapBE32(tag);
   2103     if (NULL == data) {
   2104         length = 0;
   2105     }
   2106     DWORD bufferSize = GetFontData(hdc, tag, offset, data, length);
   2107     if (bufferSize == GDI_ERROR) {
   2108         call_ensure_accessible(lf);
   2109         bufferSize = GetFontData(hdc, tag, offset, data, length);
   2110     }
   2111 
   2112     SelectObject(hdc, savefont);
   2113     DeleteObject(font);
   2114     DeleteDC(hdc);
   2115 
   2116     return bufferSize == GDI_ERROR ? 0 : bufferSize;
   2117 }
   2118 
   2119 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
   2120     SkScalerContext_GDI* ctx = SkNEW_ARGS(SkScalerContext_GDI,
   2121                                                 (const_cast<LogFontTypeface*>(this), desc));
   2122     if (!ctx->isValid()) {
   2123         SkDELETE(ctx);
   2124         ctx = NULL;
   2125     }
   2126     return ctx;
   2127 }
   2128 
   2129 void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
   2130     if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
   2131         rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
   2132     {
   2133         rec->fMaskFormat = SkMask::kA8_Format;
   2134         rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag;
   2135     }
   2136 
   2137     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
   2138                                   SkScalerContext::kAutohinting_Flag |
   2139                                   SkScalerContext::kEmbeddedBitmapText_Flag |
   2140                                   SkScalerContext::kEmbolden_Flag |
   2141                                   SkScalerContext::kLCD_BGROrder_Flag |
   2142                                   SkScalerContext::kLCD_Vertical_Flag;
   2143     rec->fFlags &= ~flagsWeDontSupport;
   2144 
   2145     SkPaint::Hinting h = rec->getHinting();
   2146     switch (h) {
   2147         case SkPaint::kNo_Hinting:
   2148             break;
   2149         case SkPaint::kSlight_Hinting:
   2150             // Only do slight hinting when axis aligned.
   2151             // TODO: re-enable slight hinting when FontHostTest can pass.
   2152             //if (!isAxisAligned(*rec)) {
   2153                 h = SkPaint::kNo_Hinting;
   2154             //}
   2155             break;
   2156         case SkPaint::kNormal_Hinting:
   2157         case SkPaint::kFull_Hinting:
   2158             // TODO: need to be able to distinguish subpixel positioned glyphs
   2159             // and linear metrics.
   2160             //rec->fFlags &= ~SkScalerContext::kSubpixelPositioning_Flag;
   2161             h = SkPaint::kNormal_Hinting;
   2162             break;
   2163         default:
   2164             SkDEBUGFAIL("unknown hinting");
   2165     }
   2166     //TODO: if this is a bitmap font, squash hinting and subpixel.
   2167     rec->setHinting(h);
   2168 
   2169 // turn this off since GDI might turn A8 into BW! Need a bigger fix.
   2170 #if 0
   2171     // Disable LCD when rotated, since GDI's output is ugly
   2172     if (isLCD(*rec) && !isAxisAligned(*rec)) {
   2173         rec->fMaskFormat = SkMask::kA8_Format;
   2174     }
   2175 #endif
   2176 
   2177     if (!fCanBeLCD && isLCD(*rec)) {
   2178         rec->fMaskFormat = SkMask::kA8_Format;
   2179         rec->fFlags &= ~SkScalerContext::kGenA8FromLCD_Flag;
   2180     }
   2181 }
   2182 
   2183 static SkTypeface* create_typeface(const SkTypeface* familyFace,
   2184                                    const char familyName[],
   2185                                    unsigned styleBits) {
   2186     LOGFONT lf;
   2187     if (NULL == familyFace && NULL == familyName) {
   2188         lf = get_default_font();
   2189     } else if (familyFace) {
   2190         LogFontTypeface* face = (LogFontTypeface*)familyFace;
   2191         lf = face->fLogFont;
   2192     } else {
   2193         logfont_for_name(familyName, &lf);
   2194     }
   2195     setStyle(&lf, (SkTypeface::Style)styleBits);
   2196     return SkCreateTypefaceFromLOGFONT(lf);
   2197 }
   2198 
   2199 SkTypeface* LogFontTypeface::onRefMatchingStyle(Style style) const {
   2200     return create_typeface(this, NULL, style);
   2201 }
   2202 
   2203 ///////////////////////////////////////////////////////////////////////////////
   2204 
   2205 #include "SkFontMgr.h"
   2206 #include "SkDataTable.h"
   2207 
   2208 static bool valid_logfont_for_enum(const LOGFONT& lf) {
   2209     // TODO: Vector FON is unsupported and should not be listed.
   2210     return
   2211         // Ignore implicit vertical variants.
   2212         lf.lfFaceName[0] && lf.lfFaceName[0] != '@'
   2213 
   2214         // DEFAULT_CHARSET is used to get all fonts, but also implies all
   2215         // character sets. Filter assuming all fonts support ANSI_CHARSET.
   2216         && ANSI_CHARSET == lf.lfCharSet
   2217     ;
   2218 }
   2219 
   2220 /** An EnumFontFamExProc implementation which interprets builderParam as
   2221  *  an SkTDArray<ENUMLOGFONTEX>* and appends logfonts which
   2222  *  pass the valid_logfont_for_enum predicate.
   2223  */
   2224 static int CALLBACK enum_family_proc(const LOGFONT* lf, const TEXTMETRIC*,
   2225                                      DWORD fontType, LPARAM builderParam) {
   2226     if (valid_logfont_for_enum(*lf)) {
   2227         SkTDArray<ENUMLOGFONTEX>* array = (SkTDArray<ENUMLOGFONTEX>*)builderParam;
   2228         *array->append() = *(ENUMLOGFONTEX*)lf;
   2229     }
   2230     return 1; // non-zero means continue
   2231 }
   2232 
   2233 static SkFontStyle compute_fontstyle(const LOGFONT& lf) {
   2234     return SkFontStyle(lf.lfWeight, SkFontStyle::kNormal_Width,
   2235                        lf.lfItalic ? SkFontStyle::kItalic_Slant
   2236                                    : SkFontStyle::kUpright_Slant);
   2237 }
   2238 
   2239 class SkFontStyleSetGDI : public SkFontStyleSet {
   2240 public:
   2241     SkFontStyleSetGDI(const TCHAR familyName[]) {
   2242         LOGFONT lf;
   2243         sk_bzero(&lf, sizeof(lf));
   2244         lf.lfCharSet = DEFAULT_CHARSET;
   2245         _tcscpy_s(lf.lfFaceName, familyName);
   2246 
   2247         HDC hdc = ::CreateCompatibleDC(NULL);
   2248         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0);
   2249         ::DeleteDC(hdc);
   2250     }
   2251 
   2252     virtual int count() SK_OVERRIDE {
   2253         return fArray.count();
   2254     }
   2255 
   2256     virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OVERRIDE {
   2257         if (fs) {
   2258             *fs = compute_fontstyle(fArray[index].elfLogFont);
   2259         }
   2260         if (styleName) {
   2261             const ENUMLOGFONTEX& ref = fArray[index];
   2262             // For some reason, ENUMLOGFONTEX and LOGFONT disagree on their type in the
   2263             // non-unicode version.
   2264             //      ENUMLOGFONTEX uses BYTE
   2265             //      LOGFONT uses CHAR
   2266             // Here we assert they that the style name is logically the same (size) as
   2267             // a TCHAR, so we can use the same converter function.
   2268             SkASSERT(sizeof(TCHAR) == sizeof(ref.elfStyle[0]));
   2269             tchar_to_skstring((const TCHAR*)ref.elfStyle, styleName);
   2270         }
   2271     }
   2272 
   2273     virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
   2274         return SkCreateTypefaceFromLOGFONT(fArray[index].elfLogFont);
   2275     }
   2276 
   2277     virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
   2278         // todo:
   2279         return SkCreateTypefaceFromLOGFONT(fArray[0].elfLogFont);
   2280     }
   2281 
   2282 private:
   2283     SkTDArray<ENUMLOGFONTEX> fArray;
   2284 };
   2285 
   2286 class SkFontMgrGDI : public SkFontMgr {
   2287 public:
   2288     SkFontMgrGDI() {
   2289         LOGFONT lf;
   2290         sk_bzero(&lf, sizeof(lf));
   2291         lf.lfCharSet = DEFAULT_CHARSET;
   2292 
   2293         HDC hdc = ::CreateCompatibleDC(NULL);
   2294         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fLogFontArray, 0);
   2295         ::DeleteDC(hdc);
   2296     }
   2297 
   2298 protected:
   2299     virtual int onCountFamilies() SK_OVERRIDE {
   2300         return fLogFontArray.count();
   2301     }
   2302 
   2303     virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE {
   2304         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
   2305         tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName);
   2306     }
   2307 
   2308     virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE {
   2309         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count());
   2310         return SkNEW_ARGS(SkFontStyleSetGDI, (fLogFontArray[index].elfLogFont.lfFaceName));
   2311     }
   2312 
   2313     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE {
   2314         if (NULL == familyName) {
   2315             familyName = "";    // do we need this check???
   2316         }
   2317         LOGFONT lf;
   2318         logfont_for_name(familyName, &lf);
   2319         return SkNEW_ARGS(SkFontStyleSetGDI, (lf.lfFaceName));
   2320     }
   2321 
   2322     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
   2323                                            const SkFontStyle& fontstyle) SK_OVERRIDE {
   2324         // could be in base impl
   2325         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
   2326         return sset->matchStyle(fontstyle);
   2327     }
   2328 
   2329     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
   2330                                          const SkFontStyle& fontstyle) SK_OVERRIDE {
   2331         // could be in base impl
   2332         SkString familyName;
   2333         ((LogFontTypeface*)familyMember)->getFamilyName(&familyName);
   2334         return this->matchFamilyStyle(familyName.c_str(), fontstyle);
   2335     }
   2336 
   2337     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OVERRIDE {
   2338         return create_from_stream(stream);
   2339     }
   2340 
   2341     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE {
   2342         // could be in base impl
   2343         SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
   2344         return this->createFromStream(stream);
   2345     }
   2346 
   2347     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVERRIDE {
   2348         // could be in base impl
   2349         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
   2350         return this->createFromStream(stream);
   2351     }
   2352 
   2353     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
   2354                                                unsigned styleBits) SK_OVERRIDE {
   2355         return create_typeface(NULL, familyName, styleBits);
   2356     }
   2357 
   2358 private:
   2359     SkTDArray<ENUMLOGFONTEX> fLogFontArray;
   2360 };
   2361 
   2362 ///////////////////////////////////////////////////////////////////////////////
   2363 
   2364 #ifndef SK_FONTHOST_USES_FONTMGR
   2365 
   2366 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
   2367                                        const char familyName[],
   2368                                        SkTypeface::Style styleBits) {
   2369     return create_typeface(familyFace, familyName, styleBits);
   2370 }
   2371 
   2372 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
   2373     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
   2374     return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
   2375 }
   2376 
   2377 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
   2378     return create_from_stream(stream);
   2379 }
   2380 
   2381 #endif
   2382 
   2383 SkFontMgr* SkFontMgr::Factory() {
   2384     return SkNEW(SkFontMgrGDI);
   2385 }
   2386