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