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