| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2006 The Android Open Source Project | 2  * Copyright 2006 The Android Open Source Project | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkAdvancedTypefaceMetrics.h" | 8 #include "SkAdvancedTypefaceMetrics.h" | 
| 9 #include "SkBase64.h" | 9 #include "SkBase64.h" | 
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 80         return true; | 80         return true; | 
| 81     } | 81     } | 
| 82 #endif | 82 #endif | 
| 83     return rec.getHinting() == SkPaint::kNo_Hinting || rec.getHinting() == SkPai
      nt::kSlight_Hinting; | 83     return rec.getHinting() == SkPaint::kNo_Hinting || rec.getHinting() == SkPai
      nt::kSlight_Hinting; | 
| 84 } | 84 } | 
| 85 | 85 | 
| 86 using namespace skia_advanced_typeface_metrics_utils; | 86 using namespace skia_advanced_typeface_metrics_utils; | 
| 87 | 87 | 
| 88 static void tchar_to_skstring(const TCHAR t[], SkString* s) { | 88 static void tchar_to_skstring(const TCHAR t[], SkString* s) { | 
| 89 #ifdef UNICODE | 89 #ifdef UNICODE | 
| 90     size_t sSize = WideCharToMultiByte(CP_UTF8, 0, t, -1, NULL, 0, NULL, NULL); | 90     size_t sSize = WideCharToMultiByte(CP_UTF8, 0, t, -1, nullptr, 0, nullptr, n
      ullptr); | 
| 91     s->resize(sSize); | 91     s->resize(sSize); | 
| 92     WideCharToMultiByte(CP_UTF8, 0, t, -1, s->writable_str(), sSize, NULL, NULL)
      ; | 92     WideCharToMultiByte(CP_UTF8, 0, t, -1, s->writable_str(), sSize, nullptr, nu
      llptr); | 
| 93 #else | 93 #else | 
| 94     s->set(t); | 94     s->set(t); | 
| 95 #endif | 95 #endif | 
| 96 } | 96 } | 
| 97 | 97 | 
| 98 static void dcfontname_to_skstring(HDC deviceContext, const LOGFONT& lf, SkStrin
      g* familyName) { | 98 static void dcfontname_to_skstring(HDC deviceContext, const LOGFONT& lf, SkStrin
      g* familyName) { | 
| 99     int fontNameLen; //length of fontName in TCHARS. | 99     int fontNameLen; //length of fontName in TCHARS. | 
| 100     if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) { | 100     if (0 == (fontNameLen = GetTextFace(deviceContext, 0, nullptr))) { | 
| 101         call_ensure_accessible(lf); | 101         call_ensure_accessible(lf); | 
| 102         if (0 == (fontNameLen = GetTextFace(deviceContext, 0, NULL))) { | 102         if (0 == (fontNameLen = GetTextFace(deviceContext, 0, nullptr))) { | 
| 103             fontNameLen = 0; | 103             fontNameLen = 0; | 
| 104         } | 104         } | 
| 105     } | 105     } | 
| 106 | 106 | 
| 107     SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1); | 107     SkAutoSTArray<LF_FULLFACESIZE, TCHAR> fontName(fontNameLen+1); | 
| 108     if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) { | 108     if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) { | 
| 109         call_ensure_accessible(lf); | 109         call_ensure_accessible(lf); | 
| 110         if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) { | 110         if (0 == GetTextFace(deviceContext, fontNameLen, fontName.get())) { | 
| 111             fontName[0] = 0; | 111             fontName[0] = 0; | 
| 112         } | 112         } | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 162     } | 162     } | 
| 163 | 163 | 
| 164     // Binary search for glyph count. | 164     // Binary search for glyph count. | 
| 165     static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; | 165     static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; | 
| 166     int32_t max = SK_MaxU16 + 1; | 166     int32_t max = SK_MaxU16 + 1; | 
| 167     int32_t min = 0; | 167     int32_t min = 0; | 
| 168     GLYPHMETRICS gm; | 168     GLYPHMETRICS gm; | 
| 169     while (min < max) { | 169     while (min < max) { | 
| 170         int32_t mid = min + ((max - min) / 2); | 170         int32_t mid = min + ((max - min) / 2); | 
| 171         if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, | 171         if (GetGlyphOutlineW(hdc, mid, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, | 
| 172                              NULL, &mat2) == GDI_ERROR) { | 172                              nullptr, &mat2) == GDI_ERROR) { | 
| 173             max = mid; | 173             max = mid; | 
| 174         } else { | 174         } else { | 
| 175             min = mid + 1; | 175             min = mid + 1; | 
| 176         } | 176         } | 
| 177     } | 177     } | 
| 178     SkASSERT(min == max); | 178     SkASSERT(min == max); | 
| 179     return min; | 179     return min; | 
| 180 } | 180 } | 
| 181 | 181 | 
| 182 static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) { | 182 static unsigned calculateUPEM(HDC hdc, const LOGFONT& lf) { | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 205 public: | 205 public: | 
| 206     LogFontTypeface(const SkFontStyle& style, const LOGFONT& lf, bool serializeA
      sStream) | 206     LogFontTypeface(const SkFontStyle& style, const LOGFONT& lf, bool serializeA
      sStream) | 
| 207         : SkTypeface(style, SkTypefaceCache::NewFontID(), false) | 207         : SkTypeface(style, SkTypefaceCache::NewFontID(), false) | 
| 208         , fLogFont(lf) | 208         , fLogFont(lf) | 
| 209         , fSerializeAsStream(serializeAsStream) | 209         , fSerializeAsStream(serializeAsStream) | 
| 210     { | 210     { | 
| 211 | 211 | 
| 212         // If the font has cubic outlines, it will not be rendered with ClearTyp
      e. | 212         // If the font has cubic outlines, it will not be rendered with ClearTyp
      e. | 
| 213         HFONT font = CreateFontIndirect(&lf); | 213         HFONT font = CreateFontIndirect(&lf); | 
| 214 | 214 | 
| 215         HDC deviceContext = ::CreateCompatibleDC(NULL); | 215         HDC deviceContext = ::CreateCompatibleDC(nullptr); | 
| 216         HFONT savefont = (HFONT)SelectObject(deviceContext, font); | 216         HFONT savefont = (HFONT)SelectObject(deviceContext, font); | 
| 217 | 217 | 
| 218         TEXTMETRIC textMetric; | 218         TEXTMETRIC textMetric; | 
| 219         if (0 == GetTextMetrics(deviceContext, &textMetric)) { | 219         if (0 == GetTextMetrics(deviceContext, &textMetric)) { | 
| 220             call_ensure_accessible(lf); | 220             call_ensure_accessible(lf); | 
| 221             if (0 == GetTextMetrics(deviceContext, &textMetric)) { | 221             if (0 == GetTextMetrics(deviceContext, &textMetric)) { | 
| 222                 textMetric.tmPitchAndFamily = TMPF_TRUETYPE; | 222                 textMetric.tmPitchAndFamily = TMPF_TRUETYPE; | 
| 223             } | 223             } | 
| 224         } | 224         } | 
| 225         if (deviceContext) { | 225         if (deviceContext) { | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 313 } | 313 } | 
| 314 | 314 | 
| 315 /** | 315 /** | 
| 316  *  This guy is public. It first searches the cache, and if a match is not found
      , | 316  *  This guy is public. It first searches the cache, and if a match is not found
      , | 
| 317  *  it creates a new face. | 317  *  it creates a new face. | 
| 318  */ | 318  */ | 
| 319 SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) { | 319 SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT& origLF) { | 
| 320     LOGFONT lf = origLF; | 320     LOGFONT lf = origLF; | 
| 321     make_canonical(&lf); | 321     make_canonical(&lf); | 
| 322     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf); | 322     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf); | 
| 323     if (NULL == face) { | 323     if (nullptr == face) { | 
| 324         face = LogFontTypeface::Create(lf); | 324         face = LogFontTypeface::Create(lf); | 
| 325         SkTypefaceCache::Add(face, get_style(lf)); | 325         SkTypefaceCache::Add(face, get_style(lf)); | 
| 326     } | 326     } | 
| 327     return face; | 327     return face; | 
| 328 } | 328 } | 
| 329 | 329 | 
| 330 /** | 330 /** | 
| 331  *  The created SkTypeface takes ownership of fontMemResource. | 331  *  The created SkTypeface takes ownership of fontMemResource. | 
| 332  */ | 332  */ | 
| 333 SkTypeface* SkCreateFontMemResourceTypefaceFromLOGFONT(const LOGFONT& origLF, HA
      NDLE fontMemResource) { | 333 SkTypeface* SkCreateFontMemResourceTypefaceFromLOGFONT(const LOGFONT& origLF, HA
      NDLE fontMemResource) { | 
| 334     LOGFONT lf = origLF; | 334     LOGFONT lf = origLF; | 
| 335     make_canonical(&lf); | 335     make_canonical(&lf); | 
| 336     // We'll never get a cache hit, so no point in putting this in SkTypefaceCac
      he. | 336     // We'll never get a cache hit, so no point in putting this in SkTypefaceCac
      he. | 
| 337     return FontMemResourceTypeface::Create(lf, fontMemResource); | 337     return FontMemResourceTypeface::Create(lf, fontMemResource); | 
| 338 } | 338 } | 
| 339 | 339 | 
| 340 /** | 340 /** | 
| 341  *  This guy is public | 341  *  This guy is public | 
| 342  */ | 342  */ | 
| 343 void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) { | 343 void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) { | 
| 344     if (NULL == face) { | 344     if (nullptr == face) { | 
| 345         *lf = get_default_font(); | 345         *lf = get_default_font(); | 
| 346     } else { | 346     } else { | 
| 347         *lf = static_cast<const LogFontTypeface*>(face)->fLogFont; | 347         *lf = static_cast<const LogFontTypeface*>(face)->fLogFont; | 
| 348     } | 348     } | 
| 349 } | 349 } | 
| 350 | 350 | 
| 351 // Construct Glyph to Unicode table. | 351 // Construct Glyph to Unicode table. | 
| 352 // Unicode code points that require conjugate pairs in utf16 are not | 352 // Unicode code points that require conjugate pairs in utf16 are not | 
| 353 // supported. | 353 // supported. | 
| 354 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may | 354 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may | 
| 355 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead | 355 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead | 
| 356 // of calling GetFontUnicodeRange(). | 356 // of calling GetFontUnicodeRange(). | 
| 357 static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount, | 357 static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount, | 
| 358                                       SkTDArray<SkUnichar>* glyphToUnicode) { | 358                                       SkTDArray<SkUnichar>* glyphToUnicode) { | 
| 359     DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, NULL); | 359     DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, nullptr); | 
| 360     if (!glyphSetBufferSize) { | 360     if (!glyphSetBufferSize) { | 
| 361         return; | 361         return; | 
| 362     } | 362     } | 
| 363 | 363 | 
| 364     SkAutoTDeleteArray<BYTE> glyphSetBuffer(new BYTE[glyphSetBufferSize]); | 364     SkAutoTDeleteArray<BYTE> glyphSetBuffer(new BYTE[glyphSetBufferSize]); | 
| 365     GLYPHSET* glyphSet = | 365     GLYPHSET* glyphSet = | 
| 366         reinterpret_cast<LPGLYPHSET>(glyphSetBuffer.get()); | 366         reinterpret_cast<LPGLYPHSET>(glyphSetBuffer.get()); | 
| 367     if (GetFontUnicodeRanges(fontHdc, glyphSet) != glyphSetBufferSize) { | 367     if (GetFontUnicodeRanges(fontHdc, glyphSet) != glyphSetBufferSize) { | 
| 368         return; | 368         return; | 
| 369     } | 369     } | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 409 struct MyBitmapInfo : public BITMAPINFO { | 409 struct MyBitmapInfo : public BITMAPINFO { | 
| 410     RGBQUAD fMoreSpaceForColors[1]; | 410     RGBQUAD fMoreSpaceForColors[1]; | 
| 411 }; | 411 }; | 
| 412 | 412 | 
| 413 class HDCOffscreen { | 413 class HDCOffscreen { | 
| 414 public: | 414 public: | 
| 415     HDCOffscreen() { | 415     HDCOffscreen() { | 
| 416         fFont = 0; | 416         fFont = 0; | 
| 417         fDC = 0; | 417         fDC = 0; | 
| 418         fBM = 0; | 418         fBM = 0; | 
| 419         fBits = NULL; | 419         fBits = nullptr; | 
| 420         fWidth = fHeight = 0; | 420         fWidth = fHeight = 0; | 
| 421         fIsBW = false; | 421         fIsBW = false; | 
| 422     } | 422     } | 
| 423 | 423 | 
| 424     ~HDCOffscreen() { | 424     ~HDCOffscreen() { | 
| 425         if (fDC) { | 425         if (fDC) { | 
| 426             DeleteDC(fDC); | 426             DeleteDC(fDC); | 
| 427         } | 427         } | 
| 428         if (fBM) { | 428         if (fBM) { | 
| 429             DeleteObject(fBM); | 429             DeleteObject(fBM); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 448     bool    fIsBW; | 448     bool    fIsBW; | 
| 449 }; | 449 }; | 
| 450 | 450 | 
| 451 const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW, | 451 const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW, | 
| 452                                size_t* srcRBPtr) { | 452                                size_t* srcRBPtr) { | 
| 453     // Can we share the scalercontext's fDDC, so we don't need to create | 453     // Can we share the scalercontext's fDDC, so we don't need to create | 
| 454     // a separate fDC here? | 454     // a separate fDC here? | 
| 455     if (0 == fDC) { | 455     if (0 == fDC) { | 
| 456         fDC = CreateCompatibleDC(0); | 456         fDC = CreateCompatibleDC(0); | 
| 457         if (0 == fDC) { | 457         if (0 == fDC) { | 
| 458             return NULL; | 458             return nullptr; | 
| 459         } | 459         } | 
| 460         SetGraphicsMode(fDC, GM_ADVANCED); | 460         SetGraphicsMode(fDC, GM_ADVANCED); | 
| 461         SetBkMode(fDC, TRANSPARENT); | 461         SetBkMode(fDC, TRANSPARENT); | 
| 462         SetTextAlign(fDC, TA_LEFT | TA_BASELINE); | 462         SetTextAlign(fDC, TA_LEFT | TA_BASELINE); | 
| 463         SelectObject(fDC, fFont); | 463         SelectObject(fDC, fFont); | 
| 464 | 464 | 
| 465         COLORREF color = 0x00FFFFFF; | 465         COLORREF color = 0x00FFFFFF; | 
| 466         SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color); | 466         SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color); | 
| 467         SkASSERT(prev != CLR_INVALID); | 467         SkASSERT(prev != CLR_INVALID); | 
| 468     } | 468     } | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 491         info.bmiHeader.biWidth = biWidth; | 491         info.bmiHeader.biWidth = biWidth; | 
| 492         info.bmiHeader.biHeight = fHeight; | 492         info.bmiHeader.biHeight = fHeight; | 
| 493         info.bmiHeader.biPlanes = 1; | 493         info.bmiHeader.biPlanes = 1; | 
| 494         info.bmiHeader.biBitCount = isBW ? 1 : 32; | 494         info.bmiHeader.biBitCount = isBW ? 1 : 32; | 
| 495         info.bmiHeader.biCompression = BI_RGB; | 495         info.bmiHeader.biCompression = BI_RGB; | 
| 496         if (isBW) { | 496         if (isBW) { | 
| 497             info.bmiHeader.biClrUsed = 2; | 497             info.bmiHeader.biClrUsed = 2; | 
| 498         } | 498         } | 
| 499         fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0); | 499         fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0); | 
| 500         if (0 == fBM) { | 500         if (0 == fBM) { | 
| 501             return NULL; | 501             return nullptr; | 
| 502         } | 502         } | 
| 503         SelectObject(fDC, fBM); | 503         SelectObject(fDC, fBM); | 
| 504     } | 504     } | 
| 505 | 505 | 
| 506     // erase | 506     // erase | 
| 507     size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2); | 507     size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2); | 
| 508     size_t size = fHeight * srcRB; | 508     size_t size = fHeight * srcRB; | 
| 509     memset(fBits, 0, size); | 509     memset(fBits, 0, size); | 
| 510 | 510 | 
| 511     XFORM xform = fXform; | 511     XFORM xform = fXform; | 
| 512     xform.eDx = (float)-glyph.fLeft; | 512     xform.eDx = (float)-glyph.fLeft; | 
| 513     xform.eDy = (float)-glyph.fTop; | 513     xform.eDy = (float)-glyph.fTop; | 
| 514     SetWorldTransform(fDC, &xform); | 514     SetWorldTransform(fDC, &xform); | 
| 515 | 515 | 
| 516     uint16_t glyphID = glyph.getGlyphID(); | 516     uint16_t glyphID = glyph.getGlyphID(); | 
| 517     BOOL ret = ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, NULL, reinterpret_cast<LP
      CWSTR>(&glyphID), 1, NULL); | 517     BOOL ret = ExtTextOutW(fDC, 0, 0, ETO_GLYPH_INDEX, nullptr, reinterpret_cast
      <LPCWSTR>(&glyphID), 1, nullptr); | 
| 518     GdiFlush(); | 518     GdiFlush(); | 
| 519     if (0 == ret) { | 519     if (0 == ret) { | 
| 520         return NULL; | 520         return nullptr; | 
| 521     } | 521     } | 
| 522     *srcRBPtr = srcRB; | 522     *srcRBPtr = srcRB; | 
| 523     // offset to the start of the image | 523     // offset to the start of the image | 
| 524     return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB; | 524     return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB; | 
| 525 } | 525 } | 
| 526 | 526 | 
| 527 ////////////////////////////////////////////////////////////////////////////// | 527 ////////////////////////////////////////////////////////////////////////////// | 
| 528 #define BUFFERSIZE (1 << 13) | 528 #define BUFFERSIZE (1 << 13) | 
| 529 | 529 | 
| 530 class SkScalerContext_GDI : public SkScalerContext { | 530 class SkScalerContext_GDI : public SkScalerContext { | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 599                                                  const SkDescriptor* desc) | 599                                                  const SkDescriptor* desc) | 
| 600         : SkScalerContext(rawTypeface, desc) | 600         : SkScalerContext(rawTypeface, desc) | 
| 601         , fDDC(0) | 601         , fDDC(0) | 
| 602         , fSavefont(0) | 602         , fSavefont(0) | 
| 603         , fFont(0) | 603         , fFont(0) | 
| 604         , fSC(0) | 604         , fSC(0) | 
| 605         , fGlyphCount(-1) | 605         , fGlyphCount(-1) | 
| 606 { | 606 { | 
| 607     LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); | 607     LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); | 
| 608 | 608 | 
| 609     fDDC = ::CreateCompatibleDC(NULL); | 609     fDDC = ::CreateCompatibleDC(nullptr); | 
| 610     if (!fDDC) { | 610     if (!fDDC) { | 
| 611         return; | 611         return; | 
| 612     } | 612     } | 
| 613     SetGraphicsMode(fDDC, GM_ADVANCED); | 613     SetGraphicsMode(fDDC, GM_ADVANCED); | 
| 614     SetBkMode(fDDC, TRANSPARENT); | 614     SetBkMode(fDDC, TRANSPARENT); | 
| 615 | 615 | 
| 616     // When GDI hinting, remove the entire Y scale from sA and GsA. (Prevents 'l
      inear' metrics.) | 616     // When GDI hinting, remove the entire Y scale from sA and GsA. (Prevents 'l
      inear' metrics.) | 
| 617     // When not hinting, remove only the integer Y scale from sA and GsA. (Appli
      ed by GDI.) | 617     // When not hinting, remove only the integer Y scale from sA and GsA. (Appli
      ed by GDI.) | 
| 618     SkScalerContextRec::PreMatrixScale scaleConstraints = | 618     SkScalerContextRec::PreMatrixScale scaleConstraints = | 
| 619         (fRec.getHinting() == SkPaint::kNo_Hinting || fRec.getHinting() == SkPai
      nt::kSlight_Hinting) | 619         (fRec.getHinting() == SkPaint::kNo_Hinting || fRec.getHinting() == SkPai
      nt::kSlight_Hinting) | 
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 799                 fType == SkScalerContext_GDI::kLine_Type) | 799                 fType == SkScalerContext_GDI::kLine_Type) | 
| 800                /*&& winVer < Vista */) | 800                /*&& winVer < Vista */) | 
| 801            ) | 801            ) | 
| 802         { | 802         { | 
| 803             index = 0; | 803             index = 0; | 
| 804         } | 804         } | 
| 805     } else { | 805     } else { | 
| 806         // Use uniscribe to detemine glyph index for non-BMP characters. | 806         // Use uniscribe to detemine glyph index for non-BMP characters. | 
| 807         static const int numWCHAR = 2; | 807         static const int numWCHAR = 2; | 
| 808         static const int maxItems = 2; | 808         static const int maxItems = 2; | 
| 809         // MSDN states that this can be NULL, but some things don't work then. | 809         // MSDN states that this can be nullptr, but some things don't work then
      . | 
| 810         SCRIPT_CONTROL sc = { 0 }; | 810         SCRIPT_CONTROL sc = { 0 }; | 
| 811         // Add extra item to SCRIPT_ITEM to work around a bug (now documented). | 811         // Add extra item to SCRIPT_ITEM to work around a bug (now documented). | 
| 812         // https://bugzilla.mozilla.org/show_bug.cgi?id=366643 | 812         // https://bugzilla.mozilla.org/show_bug.cgi?id=366643 | 
| 813         SCRIPT_ITEM si[maxItems + 1]; | 813         SCRIPT_ITEM si[maxItems + 1]; | 
| 814         int numItems; | 814         int numItems; | 
| 815         HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &sc, NULL, si, &numItems), | 815         HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &sc, nullptr, si, &numItem
      s), | 
| 816              "Could not itemize character."); | 816              "Could not itemize character."); | 
| 817 | 817 | 
| 818         // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2
       space glyphs. | 818         // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2
       space glyphs. | 
| 819         static const int maxGlyphs = 2; | 819         static const int maxGlyphs = 2; | 
| 820         SCRIPT_VISATTR vsa[maxGlyphs]; | 820         SCRIPT_VISATTR vsa[maxGlyphs]; | 
| 821         WORD outGlyphs[maxGlyphs]; | 821         WORD outGlyphs[maxGlyphs]; | 
| 822         WORD logClust[numWCHAR]; | 822         WORD logClust[numWCHAR]; | 
| 823         int numGlyphs; | 823         int numGlyphs; | 
| 824         HRZM(ScriptShape(fDDC, &fSC, utf16, numWCHAR, maxGlyphs, &si[0].a, | 824         HRZM(ScriptShape(fDDC, &fSC, utf16, numWCHAR, maxGlyphs, &si[0].a, | 
| 825                          outGlyphs, logClust, vsa, &numGlyphs), | 825                          outGlyphs, logClust, vsa, &numGlyphs), | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 876         glyph->fAdvanceX = SkFixedMul(SkFIXEDToFixed(fMat22.eM11), glyph->fAdvan
      ceX); | 876         glyph->fAdvanceX = SkFixedMul(SkFIXEDToFixed(fMat22.eM11), glyph->fAdvan
      ceX); | 
| 877 | 877 | 
| 878         return; | 878         return; | 
| 879     } | 879     } | 
| 880 | 880 | 
| 881     UINT glyphId = glyph->getGlyphID(); | 881     UINT glyphId = glyph->getGlyphID(); | 
| 882 | 882 | 
| 883     GLYPHMETRICS gm; | 883     GLYPHMETRICS gm; | 
| 884     sk_bzero(&gm, sizeof(gm)); | 884     sk_bzero(&gm, sizeof(gm)); | 
| 885 | 885 | 
| 886     DWORD status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX
      , &gm, 0, NULL, &fMat22); | 886     DWORD status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX
      , &gm, 0, nullptr, &fMat22); | 
| 887     if (GDI_ERROR == status) { | 887     if (GDI_ERROR == status) { | 
| 888         LogFontTypeface::EnsureAccessible(this->getTypeface()); | 888         LogFontTypeface::EnsureAccessible(this->getTypeface()); | 
| 889         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, 
      &gm, 0, NULL, &fMat22); | 889         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, 
      &gm, 0, nullptr, &fMat22); | 
| 890         if (GDI_ERROR == status) { | 890         if (GDI_ERROR == status) { | 
| 891             glyph->zeroMetrics(); | 891             glyph->zeroMetrics(); | 
| 892             return; | 892             return; | 
| 893         } | 893         } | 
| 894     } | 894     } | 
| 895 | 895 | 
| 896     bool empty = false; | 896     bool empty = false; | 
| 897     // The black box is either the embedded bitmap size or the outline extent. | 897     // The black box is either the embedded bitmap size or the outline extent. | 
| 898     // It is 1x1 if nothing is to be drawn, but will also be 1x1 if something ve
      ry small | 898     // It is 1x1 if nothing is to be drawn, but will also be 1x1 if something ve
      ry small | 
| 899     // is to be drawn, like a '.'. We need to outset '.' but do not wish to outs
      et ' '. | 899     // is to be drawn, like a '.'. We need to outset '.' but do not wish to outs
      et ' '. | 
| 900     if (1 == gm.gmBlackBoxX && 1 == gm.gmBlackBoxY) { | 900     if (1 == gm.gmBlackBoxX && 1 == gm.gmBlackBoxY) { | 
| 901         // If GetGlyphOutline with GGO_NATIVE returns 0, we know there was no ou
      tline. | 901         // If GetGlyphOutline with GGO_NATIVE returns 0, we know there was no ou
      tline. | 
| 902         DWORD bufferSize = GetGlyphOutlineW(fDDC, glyphId, GGO_NATIVE | GGO_GLYP
      H_INDEX, &gm, 0, NULL, &fMat22); | 902         DWORD bufferSize = GetGlyphOutlineW(fDDC, glyphId, GGO_NATIVE | GGO_GLYP
      H_INDEX, &gm, 0, nullptr, &fMat22); | 
| 903         empty = (0 == bufferSize); | 903         empty = (0 == bufferSize); | 
| 904     } | 904     } | 
| 905 | 905 | 
| 906     glyph->fTop = SkToS16(-gm.gmptGlyphOrigin.y); | 906     glyph->fTop = SkToS16(-gm.gmptGlyphOrigin.y); | 
| 907     glyph->fLeft = SkToS16(gm.gmptGlyphOrigin.x); | 907     glyph->fLeft = SkToS16(gm.gmptGlyphOrigin.x); | 
| 908     if (empty) { | 908     if (empty) { | 
| 909         glyph->fWidth = 0; | 909         glyph->fWidth = 0; | 
| 910         glyph->fHeight = 0; | 910         glyph->fHeight = 0; | 
| 911     } else { | 911     } else { | 
| 912         // Outset, since the image may bleed out of the black box. | 912         // Outset, since the image may bleed out of the black box. | 
| 913         // For embedded bitmaps the black box should be exact. | 913         // For embedded bitmaps the black box should be exact. | 
| 914         // For outlines we need to outset by 1 in all directions for bleed. | 914         // For outlines we need to outset by 1 in all directions for bleed. | 
| 915         // For ClearType we need to outset by 2 for bleed. | 915         // For ClearType we need to outset by 2 for bleed. | 
| 916         glyph->fWidth = gm.gmBlackBoxX + 4; | 916         glyph->fWidth = gm.gmBlackBoxX + 4; | 
| 917         glyph->fHeight = gm.gmBlackBoxY + 4; | 917         glyph->fHeight = gm.gmBlackBoxY + 4; | 
| 918         glyph->fTop -= 2; | 918         glyph->fTop -= 2; | 
| 919         glyph->fLeft -= 2; | 919         glyph->fLeft -= 2; | 
| 920     } | 920     } | 
| 921     glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX); | 921     glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX); | 
| 922     glyph->fAdvanceY = SkIntToFixed(gm.gmCellIncY); | 922     glyph->fAdvanceY = SkIntToFixed(gm.gmCellIncY); | 
| 923     glyph->fRsbDelta = 0; | 923     glyph->fRsbDelta = 0; | 
| 924     glyph->fLsbDelta = 0; | 924     glyph->fLsbDelta = 0; | 
| 925 | 925 | 
| 926     if (this->isSubpixel()) { | 926     if (this->isSubpixel()) { | 
| 927         sk_bzero(&gm, sizeof(gm)); | 927         sk_bzero(&gm, sizeof(gm)); | 
| 928         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, 
      &gm, 0, NULL, &fHighResMat22); | 928         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, 
      &gm, 0, nullptr, &fHighResMat22); | 
| 929         if (GDI_ERROR != status) { | 929         if (GDI_ERROR != status) { | 
| 930             SkPoint advance; | 930             SkPoint advance; | 
| 931             fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gm
      CellIncY), &advance); | 931             fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gm
      CellIncY), &advance); | 
| 932             glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 932             glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 
| 933             glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 933             glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 
| 934         } | 934         } | 
| 935     } else if (!isAxisAligned(this->fRec)) { | 935     } else if (!isAxisAligned(this->fRec)) { | 
| 936         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, 
      &gm, 0, NULL, &fGsA); | 936         status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX, 
      &gm, 0, nullptr, &fGsA); | 
| 937         if (GDI_ERROR != status) { | 937         if (GDI_ERROR != status) { | 
| 938             SkPoint advance; | 938             SkPoint advance; | 
| 939             fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIn
      cY), &advance); | 939             fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIn
      cY), &advance); | 
| 940             glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 940             glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 
| 941             glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 941             glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 
| 942         } | 942         } | 
| 943     } | 943     } | 
| 944 } | 944 } | 
| 945 | 945 | 
| 946 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; | 946 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; | 
| 947 void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 947 void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* metrics) { | 
| 948     if (NULL == metrics) { | 948     if (nullptr == metrics) { | 
| 949         return; | 949         return; | 
| 950     } | 950     } | 
| 951     sk_bzero(metrics, sizeof(*metrics)); | 951     sk_bzero(metrics, sizeof(*metrics)); | 
| 952 | 952 | 
| 953     SkASSERT(fDDC); | 953     SkASSERT(fDDC); | 
| 954 | 954 | 
| 955 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS | 955 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS | 
| 956     if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_G
      DI::kLine_Type) { | 956     if (fType == SkScalerContext_GDI::kBitmap_Type || fType == SkScalerContext_G
      DI::kLine_Type) { | 
| 957 #endif | 957 #endif | 
| 958         metrics->fTop = SkIntToScalar(-fTM.tmAscent); | 958         metrics->fTop = SkIntToScalar(-fTM.tmAscent); | 
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1224 } | 1224 } | 
| 1225 | 1225 | 
| 1226 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) { | 1226 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) { | 
| 1227     SkASSERT(fDDC); | 1227     SkASSERT(fDDC); | 
| 1228 | 1228 | 
| 1229     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | 1229     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | 
| 1230     const bool isAA = !isLCD(fRec); | 1230     const bool isAA = !isLCD(fRec); | 
| 1231 | 1231 | 
| 1232     size_t srcRB; | 1232     size_t srcRB; | 
| 1233     const void* bits = fOffscreen.draw(glyph, isBW, &srcRB); | 1233     const void* bits = fOffscreen.draw(glyph, isBW, &srcRB); | 
| 1234     if (NULL == bits) { | 1234     if (nullptr == bits) { | 
| 1235         LogFontTypeface::EnsureAccessible(this->getTypeface()); | 1235         LogFontTypeface::EnsureAccessible(this->getTypeface()); | 
| 1236         bits = fOffscreen.draw(glyph, isBW, &srcRB); | 1236         bits = fOffscreen.draw(glyph, isBW, &srcRB); | 
| 1237         if (NULL == bits) { | 1237         if (nullptr == bits) { | 
| 1238             sk_bzero(glyph.fImage, glyph.computeImageSize()); | 1238             sk_bzero(glyph.fImage, glyph.computeImageSize()); | 
| 1239             return; | 1239             return; | 
| 1240         } | 1240         } | 
| 1241     } | 1241     } | 
| 1242 | 1242 | 
| 1243     if (!isBW) { | 1243     if (!isBW) { | 
| 1244         const uint8_t* table; | 1244         const uint8_t* table; | 
| 1245         //The offscreen contains a GDI blit if isAA and kGenA8FromLCD_Flag is no
      t set. | 1245         //The offscreen contains a GDI blit if isAA and kGenA8FromLCD_Flag is no
      t set. | 
| 1246         //Otherwise the offscreen contains a ClearType blit. | 1246         //Otherwise the offscreen contains a ClearType blit. | 
| 1247         if (isAA && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) { | 1247         if (isAA && !(fRec.fFlags & SkScalerContext::kGenA8FromLCD_Flag)) { | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1315 class GDIGlyphbufferPointIter { | 1315 class GDIGlyphbufferPointIter { | 
| 1316 public: | 1316 public: | 
| 1317     GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size) | 1317     GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size) | 
| 1318         : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter() | 1318         : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter() | 
| 1319     { } | 1319     { } | 
| 1320 | 1320 | 
| 1321     POINTFX const * next() { | 1321     POINTFX const * next() { | 
| 1322 nextHeader: | 1322 nextHeader: | 
| 1323         if (!fCurveIter.isSet()) { | 1323         if (!fCurveIter.isSet()) { | 
| 1324             const TTPOLYGONHEADER* header = fHeaderIter.next(); | 1324             const TTPOLYGONHEADER* header = fHeaderIter.next(); | 
| 1325             if (NULL == header) { | 1325             if (nullptr == header) { | 
| 1326                 return NULL; | 1326                 return nullptr; | 
| 1327             } | 1327             } | 
| 1328             fCurveIter.set(header); | 1328             fCurveIter.set(header); | 
| 1329             const TTPOLYCURVE* curve = fCurveIter.next(); | 1329             const TTPOLYCURVE* curve = fCurveIter.next(); | 
| 1330             if (NULL == curve) { | 1330             if (nullptr == curve) { | 
| 1331                 return NULL; | 1331                 return nullptr; | 
| 1332             } | 1332             } | 
| 1333             fPointIter.set(curve); | 1333             fPointIter.set(curve); | 
| 1334             return &header->pfxStart; | 1334             return &header->pfxStart; | 
| 1335         } | 1335         } | 
| 1336 | 1336 | 
| 1337         const POINTFX* nextPoint = fPointIter.next(); | 1337         const POINTFX* nextPoint = fPointIter.next(); | 
| 1338         if (NULL == nextPoint) { | 1338         if (nullptr == nextPoint) { | 
| 1339             const TTPOLYCURVE* curve = fCurveIter.next(); | 1339             const TTPOLYCURVE* curve = fCurveIter.next(); | 
| 1340             if (NULL == curve) { | 1340             if (nullptr == curve) { | 
| 1341                 fCurveIter.set(); | 1341                 fCurveIter.set(); | 
| 1342                 goto nextHeader; | 1342                 goto nextHeader; | 
| 1343             } else { | 1343             } else { | 
| 1344                 fPointIter.set(curve); | 1344                 fPointIter.set(curve); | 
| 1345             } | 1345             } | 
| 1346             nextPoint = fPointIter.next(); | 1346             nextPoint = fPointIter.next(); | 
| 1347         } | 1347         } | 
| 1348         return nextPoint; | 1348         return nextPoint; | 
| 1349     } | 1349     } | 
| 1350 | 1350 | 
| 1351     WORD currentCurveType() { | 1351     WORD currentCurveType() { | 
| 1352         return fPointIter.fCurveType; | 1352         return fPointIter.fCurveType; | 
| 1353     } | 1353     } | 
| 1354 | 1354 | 
| 1355 private: | 1355 private: | 
| 1356     /** Iterates over all of the polygon headers in a glyphbuf. */ | 1356     /** Iterates over all of the polygon headers in a glyphbuf. */ | 
| 1357     class GDIPolygonHeaderIter { | 1357     class GDIPolygonHeaderIter { | 
| 1358     public: | 1358     public: | 
| 1359         GDIPolygonHeaderIter(const uint8_t* glyphbuf, DWORD total_size) | 1359         GDIPolygonHeaderIter(const uint8_t* glyphbuf, DWORD total_size) | 
| 1360             : fCurPolygon(reinterpret_cast<const TTPOLYGONHEADER*>(glyphbuf)) | 1360             : fCurPolygon(reinterpret_cast<const TTPOLYGONHEADER*>(glyphbuf)) | 
| 1361             , fEndPolygon(SkTAddOffset<const TTPOLYGONHEADER>(glyphbuf, total_si
      ze)) | 1361             , fEndPolygon(SkTAddOffset<const TTPOLYGONHEADER>(glyphbuf, total_si
      ze)) | 
| 1362         { } | 1362         { } | 
| 1363 | 1363 | 
| 1364         const TTPOLYGONHEADER* next() { | 1364         const TTPOLYGONHEADER* next() { | 
| 1365             if (fCurPolygon >= fEndPolygon) { | 1365             if (fCurPolygon >= fEndPolygon) { | 
| 1366                 return NULL; | 1366                 return nullptr; | 
| 1367             } | 1367             } | 
| 1368             const TTPOLYGONHEADER* thisPolygon = fCurPolygon; | 1368             const TTPOLYGONHEADER* thisPolygon = fCurPolygon; | 
| 1369             fCurPolygon = SkTAddOffset<const TTPOLYGONHEADER>(fCurPolygon, fCurP
      olygon->cb); | 1369             fCurPolygon = SkTAddOffset<const TTPOLYGONHEADER>(fCurPolygon, fCurP
      olygon->cb); | 
| 1370             return thisPolygon; | 1370             return thisPolygon; | 
| 1371         } | 1371         } | 
| 1372     private: | 1372     private: | 
| 1373         const TTPOLYGONHEADER* fCurPolygon; | 1373         const TTPOLYGONHEADER* fCurPolygon; | 
| 1374         const TTPOLYGONHEADER* fEndPolygon; | 1374         const TTPOLYGONHEADER* fEndPolygon; | 
| 1375     }; | 1375     }; | 
| 1376 | 1376 | 
| 1377     /** Iterates over all of the polygon curves in a polygon header. */ | 1377     /** Iterates over all of the polygon curves in a polygon header. */ | 
| 1378     class GDIPolygonCurveIter { | 1378     class GDIPolygonCurveIter { | 
| 1379     public: | 1379     public: | 
| 1380         GDIPolygonCurveIter() : fCurCurve(NULL), fEndCurve(NULL) { } | 1380         GDIPolygonCurveIter() : fCurCurve(nullptr), fEndCurve(nullptr) { } | 
| 1381 | 1381 | 
| 1382         GDIPolygonCurveIter(const TTPOLYGONHEADER* curPolygon) | 1382         GDIPolygonCurveIter(const TTPOLYGONHEADER* curPolygon) | 
| 1383             : fCurCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOL
      YGONHEADER))) | 1383             : fCurCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOL
      YGONHEADER))) | 
| 1384             , fEndCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->
      cb)) | 1384             , fEndCurve(SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->
      cb)) | 
| 1385         { } | 1385         { } | 
| 1386 | 1386 | 
| 1387         bool isSet() { return fCurCurve != NULL; } | 1387         bool isSet() { return fCurCurve != nullptr; } | 
| 1388 | 1388 | 
| 1389         void set(const TTPOLYGONHEADER* curPolygon) { | 1389         void set(const TTPOLYGONHEADER* curPolygon) { | 
| 1390             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOL
      YGONHEADER)); | 1390             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, sizeof(TTPOL
      YGONHEADER)); | 
| 1391             fEndCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->
      cb); | 1391             fEndCurve = SkTAddOffset<const TTPOLYCURVE>(curPolygon, curPolygon->
      cb); | 
| 1392         } | 1392         } | 
| 1393         void set() { | 1393         void set() { | 
| 1394             fCurCurve = NULL; | 1394             fCurCurve = nullptr; | 
| 1395             fEndCurve = NULL; | 1395             fEndCurve = nullptr; | 
| 1396         } | 1396         } | 
| 1397 | 1397 | 
| 1398         const TTPOLYCURVE* next() { | 1398         const TTPOLYCURVE* next() { | 
| 1399             if (fCurCurve >= fEndCurve) { | 1399             if (fCurCurve >= fEndCurve) { | 
| 1400                 return NULL; | 1400                 return nullptr; | 
| 1401             } | 1401             } | 
| 1402             const TTPOLYCURVE* thisCurve = fCurCurve; | 1402             const TTPOLYCURVE* thisCurve = fCurCurve; | 
| 1403             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(fCurCurve, size_of_TTPOL
      YCURVE(*fCurCurve)); | 1403             fCurCurve = SkTAddOffset<const TTPOLYCURVE>(fCurCurve, size_of_TTPOL
      YCURVE(*fCurCurve)); | 
| 1404             return thisCurve; | 1404             return thisCurve; | 
| 1405         } | 1405         } | 
| 1406     private: | 1406     private: | 
| 1407         size_t size_of_TTPOLYCURVE(const TTPOLYCURVE& curve) { | 1407         size_t size_of_TTPOLYCURVE(const TTPOLYCURVE& curve) { | 
| 1408             return 2*sizeof(WORD) + curve.cpfx*sizeof(POINTFX); | 1408             return 2*sizeof(WORD) + curve.cpfx*sizeof(POINTFX); | 
| 1409         } | 1409         } | 
| 1410         const TTPOLYCURVE* fCurCurve; | 1410         const TTPOLYCURVE* fCurCurve; | 
| 1411         const TTPOLYCURVE* fEndCurve; | 1411         const TTPOLYCURVE* fEndCurve; | 
| 1412     }; | 1412     }; | 
| 1413 | 1413 | 
| 1414     /** Iterates over all of the polygon points in a polygon curve. */ | 1414     /** Iterates over all of the polygon points in a polygon curve. */ | 
| 1415     class GDIPolygonCurvePointIter { | 1415     class GDIPolygonCurvePointIter { | 
| 1416     public: | 1416     public: | 
| 1417         GDIPolygonCurvePointIter() : fCurveType(0), fCurPoint(NULL), fEndPoint(N
      ULL) { } | 1417         GDIPolygonCurvePointIter() : fCurveType(0), fCurPoint(nullptr), fEndPoin
      t(nullptr) { } | 
| 1418 | 1418 | 
| 1419         GDIPolygonCurvePointIter(const TTPOLYCURVE* curPolygon) | 1419         GDIPolygonCurvePointIter(const TTPOLYCURVE* curPolygon) | 
| 1420             : fCurveType(curPolygon->wType) | 1420             : fCurveType(curPolygon->wType) | 
| 1421             , fCurPoint(&curPolygon->apfx[0]) | 1421             , fCurPoint(&curPolygon->apfx[0]) | 
| 1422             , fEndPoint(&curPolygon->apfx[curPolygon->cpfx]) | 1422             , fEndPoint(&curPolygon->apfx[curPolygon->cpfx]) | 
| 1423         { } | 1423         { } | 
| 1424 | 1424 | 
| 1425         bool isSet() { return fCurPoint != NULL; } | 1425         bool isSet() { return fCurPoint != nullptr; } | 
| 1426 | 1426 | 
| 1427         void set(const TTPOLYCURVE* curPolygon) { | 1427         void set(const TTPOLYCURVE* curPolygon) { | 
| 1428             fCurveType = curPolygon->wType; | 1428             fCurveType = curPolygon->wType; | 
| 1429             fCurPoint = &curPolygon->apfx[0]; | 1429             fCurPoint = &curPolygon->apfx[0]; | 
| 1430             fEndPoint = &curPolygon->apfx[curPolygon->cpfx]; | 1430             fEndPoint = &curPolygon->apfx[curPolygon->cpfx]; | 
| 1431         } | 1431         } | 
| 1432         void set() { | 1432         void set() { | 
| 1433             fCurPoint = NULL; | 1433             fCurPoint = nullptr; | 
| 1434             fEndPoint = NULL; | 1434             fEndPoint = nullptr; | 
| 1435         } | 1435         } | 
| 1436 | 1436 | 
| 1437         const POINTFX* next() { | 1437         const POINTFX* next() { | 
| 1438             if (fCurPoint >= fEndPoint) { | 1438             if (fCurPoint >= fEndPoint) { | 
| 1439                 return NULL; | 1439                 return nullptr; | 
| 1440             } | 1440             } | 
| 1441             const POINTFX* thisPoint = fCurPoint; | 1441             const POINTFX* thisPoint = fCurPoint; | 
| 1442             ++fCurPoint; | 1442             ++fCurPoint; | 
| 1443             return thisPoint; | 1443             return thisPoint; | 
| 1444         } | 1444         } | 
| 1445 | 1445 | 
| 1446         WORD fCurveType; | 1446         WORD fCurveType; | 
| 1447     private: | 1447     private: | 
| 1448         const POINTFX* fCurPoint; | 1448         const POINTFX* fCurPoint; | 
| 1449         const POINTFX* fEndPoint; | 1449         const POINTFX* fEndPoint; | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1498             // Advance past this TTPOLYCURVE. | 1498             // Advance past this TTPOLYCURVE. | 
| 1499             cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; | 1499             cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; | 
| 1500         } | 1500         } | 
| 1501         cur_glyph += th->cb; | 1501         cur_glyph += th->cb; | 
| 1502         path->close(); | 1502         path->close(); | 
| 1503     } | 1503     } | 
| 1504 } | 1504 } | 
| 1505 | 1505 | 
| 1506 #define move_next_expected_hinted_point(iter, pElem) do {\ | 1506 #define move_next_expected_hinted_point(iter, pElem) do {\ | 
| 1507     pElem = iter.next(); \ | 1507     pElem = iter.next(); \ | 
| 1508     if (NULL == pElem) return false; \ | 1508     if (nullptr == pElem) return false; \ | 
| 1509 } while(0) | 1509 } while(0) | 
| 1510 | 1510 | 
| 1511 // It is possible for the hinted and unhinted versions of the same path to have | 1511 // It is possible for the hinted and unhinted versions of the same path to have | 
| 1512 // a different number of points due to GDI's handling of flipped points. | 1512 // a different number of points due to GDI's handling of flipped points. | 
| 1513 // If this is detected, this will return false. | 1513 // If this is detected, this will return false. | 
| 1514 static bool sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD 
      total_size, | 1514 static bool sk_path_from_gdi_paths(SkPath* path, const uint8_t* glyphbuf, DWORD 
      total_size, | 
| 1515                                    GDIGlyphbufferPointIter hintedYs) { | 1515                                    GDIGlyphbufferPointIter hintedYs) { | 
| 1516     const uint8_t* cur_glyph = glyphbuf; | 1516     const uint8_t* cur_glyph = glyphbuf; | 
| 1517     const uint8_t* end_glyph = glyphbuf + total_size; | 1517     const uint8_t* end_glyph = glyphbuf + total_size; | 
| 1518 | 1518 | 
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1584 { | 1584 { | 
| 1585     GLYPHMETRICS gm; | 1585     GLYPHMETRICS gm; | 
| 1586 | 1586 | 
| 1587     DWORD total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, BU
      FFERSIZE, glyphbuf->get(), &fMat22); | 1587     DWORD total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, BU
      FFERSIZE, glyphbuf->get(), &fMat22); | 
| 1588     // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even i
      f BUFFERSIZE > 0. | 1588     // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even i
      f BUFFERSIZE > 0. | 
| 1589     // It has been verified that this does not involve a buffer overrun. | 1589     // It has been verified that this does not involve a buffer overrun. | 
| 1590     if (GDI_ERROR == total_size || total_size > BUFFERSIZE) { | 1590     if (GDI_ERROR == total_size || total_size > BUFFERSIZE) { | 
| 1591         // GDI_ERROR because the BUFFERSIZE was too small, or because the data w
      as not accessible. | 1591         // GDI_ERROR because the BUFFERSIZE was too small, or because the data w
      as not accessible. | 
| 1592         // When the data is not accessable GetGlyphOutlineW fails rather quickly
      , | 1592         // When the data is not accessable GetGlyphOutlineW fails rather quickly
      , | 
| 1593         // so just try to get the size. If that fails then ensure the data is ac
      cessible. | 1593         // so just try to get the size. If that fails then ensure the data is ac
      cessible. | 
| 1594         total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, 0, N
      ULL, &fMat22); | 1594         total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, 0, n
      ullptr, &fMat22); | 
| 1595         if (GDI_ERROR == total_size) { | 1595         if (GDI_ERROR == total_size) { | 
| 1596             LogFontTypeface::EnsureAccessible(this->getTypeface()); | 1596             LogFontTypeface::EnsureAccessible(this->getTypeface()); | 
| 1597             total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, 
      0, NULL, &fMat22); | 1597             total_size = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, 
      0, nullptr, &fMat22); | 
| 1598             if (GDI_ERROR == total_size) { | 1598             if (GDI_ERROR == total_size) { | 
| 1599                 // GetGlyphOutlineW is known to fail for some characters, such a
      s spaces. | 1599                 // GetGlyphOutlineW is known to fail for some characters, such a
      s spaces. | 
| 1600                 // In these cases, just return that the glyph does not have a sh
      ape. | 1600                 // In these cases, just return that the glyph does not have a sh
      ape. | 
| 1601                 return 0; | 1601                 return 0; | 
| 1602             } | 1602             } | 
| 1603         } | 1603         } | 
| 1604 | 1604 | 
| 1605         glyphbuf->reset(total_size); | 1605         glyphbuf->reset(total_size); | 
| 1606 | 1606 | 
| 1607         DWORD ret = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, total
      _size, glyphbuf->get(), &fMat22); | 1607         DWORD ret = GetGlyphOutlineW(fDDC, glyph.getGlyphID(), flags, &gm, total
      _size, glyphbuf->get(), &fMat22); | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1661             sk_path_from_gdi_path(path, glyphbuf, total_size); | 1661             sk_path_from_gdi_path(path, glyphbuf, total_size); | 
| 1662         } | 1662         } | 
| 1663     } | 1663     } | 
| 1664 } | 1664 } | 
| 1665 | 1665 | 
| 1666 static void logfont_for_name(const char* familyName, LOGFONT* lf) { | 1666 static void logfont_for_name(const char* familyName, LOGFONT* lf) { | 
| 1667     sk_bzero(lf, sizeof(LOGFONT)); | 1667     sk_bzero(lf, sizeof(LOGFONT)); | 
| 1668 #ifdef UNICODE | 1668 #ifdef UNICODE | 
| 1669     // Get the buffer size needed first. | 1669     // Get the buffer size needed first. | 
| 1670     size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName, | 1670     size_t str_len = ::MultiByteToWideChar(CP_UTF8, 0, familyName, | 
| 1671                                             -1, NULL, 0); | 1671                                             -1, nullptr, 0); | 
| 1672     // Allocate a buffer (str_len already has terminating null | 1672     // Allocate a buffer (str_len already has terminating null | 
| 1673     // accounted for). | 1673     // accounted for). | 
| 1674     wchar_t *wideFamilyName = new wchar_t[str_len]; | 1674     wchar_t *wideFamilyName = new wchar_t[str_len]; | 
| 1675     // Now actually convert the string. | 1675     // Now actually convert the string. | 
| 1676     ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1, | 1676     ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1, | 
| 1677                             wideFamilyName, str_len); | 1677                             wideFamilyName, str_len); | 
| 1678     ::wcsncpy(lf->lfFaceName, wideFamilyName, LF_FACESIZE - 1); | 1678     ::wcsncpy(lf->lfFaceName, wideFamilyName, LF_FACESIZE - 1); | 
| 1679     delete [] wideFamilyName; | 1679     delete [] wideFamilyName; | 
| 1680     lf->lfFaceName[LF_FACESIZE-1] = L'\0'; | 1680     lf->lfFaceName[LF_FACESIZE-1] = L'\0'; | 
| 1681 #else | 1681 #else | 
| 1682     ::strncpy(lf->lfFaceName, familyName, LF_FACESIZE - 1); | 1682     ::strncpy(lf->lfFaceName, familyName, LF_FACESIZE - 1); | 
| 1683     lf->lfFaceName[LF_FACESIZE - 1] = '\0'; | 1683     lf->lfFaceName[LF_FACESIZE - 1] = '\0'; | 
| 1684 #endif | 1684 #endif | 
| 1685 } | 1685 } | 
| 1686 | 1686 | 
| 1687 void LogFontTypeface::onGetFamilyName(SkString* familyName) const { | 1687 void LogFontTypeface::onGetFamilyName(SkString* familyName) const { | 
| 1688     // Get the actual name of the typeface. The logfont may not know this. | 1688     // Get the actual name of the typeface. The logfont may not know this. | 
| 1689     HFONT font = CreateFontIndirect(&fLogFont); | 1689     HFONT font = CreateFontIndirect(&fLogFont); | 
| 1690 | 1690 | 
| 1691     HDC deviceContext = ::CreateCompatibleDC(NULL); | 1691     HDC deviceContext = ::CreateCompatibleDC(nullptr); | 
| 1692     HFONT savefont = (HFONT)SelectObject(deviceContext, font); | 1692     HFONT savefont = (HFONT)SelectObject(deviceContext, font); | 
| 1693 | 1693 | 
| 1694     dcfontname_to_skstring(deviceContext, fLogFont, familyName); | 1694     dcfontname_to_skstring(deviceContext, fLogFont, familyName); | 
| 1695 | 1695 | 
| 1696     if (deviceContext) { | 1696     if (deviceContext) { | 
| 1697         ::SelectObject(deviceContext, savefont); | 1697         ::SelectObject(deviceContext, savefont); | 
| 1698         ::DeleteDC(deviceContext); | 1698         ::DeleteDC(deviceContext); | 
| 1699     } | 1699     } | 
| 1700     if (font) { | 1700     if (font) { | 
| 1701         ::DeleteObject(font); | 1701         ::DeleteObject(font); | 
| 1702     } | 1702     } | 
| 1703 } | 1703 } | 
| 1704 | 1704 | 
| 1705 void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, | 1705 void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, | 
| 1706                                           bool* isLocalStream) const { | 1706                                           bool* isLocalStream) const { | 
| 1707     SkString familyName; | 1707     SkString familyName; | 
| 1708     this->onGetFamilyName(&familyName); | 1708     this->onGetFamilyName(&familyName); | 
| 1709     desc->setFamilyName(familyName.c_str()); | 1709     desc->setFamilyName(familyName.c_str()); | 
| 1710     *isLocalStream = this->fSerializeAsStream; | 1710     *isLocalStream = this->fSerializeAsStream; | 
| 1711 } | 1711 } | 
| 1712 | 1712 | 
| 1713 static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) { | 1713 static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) { | 
| 1714     // Initialize the MAT2 structure to the identify transformation matrix. | 1714     // Initialize the MAT2 structure to the identify transformation matrix. | 
| 1715     static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0), | 1715     static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0), | 
| 1716                         SkScalarToFIXED(0), SkScalarToFIXED(1)}; | 1716                         SkScalarToFIXED(0), SkScalarToFIXED(1)}; | 
| 1717     int flags = GGO_METRICS | GGO_GLYPH_INDEX; | 1717     int flags = GGO_METRICS | GGO_GLYPH_INDEX; | 
| 1718     GLYPHMETRICS gm; | 1718     GLYPHMETRICS gm; | 
| 1719     if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, NULL, &mat2)) { | 1719     if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, nullptr, &mat2)) { | 
| 1720         return false; | 1720         return false; | 
| 1721     } | 1721     } | 
| 1722     SkASSERT(advance); | 1722     SkASSERT(advance); | 
| 1723     *advance = gm.gmCellIncX; | 1723     *advance = gm.gmCellIncX; | 
| 1724     return true; | 1724     return true; | 
| 1725 } | 1725 } | 
| 1726 | 1726 | 
| 1727 SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics( | 1727 SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics( | 
| 1728         PerGlyphInfo perGlyphInfo, | 1728         PerGlyphInfo perGlyphInfo, | 
| 1729         const uint32_t* glyphIDs, | 1729         const uint32_t* glyphIDs, | 
| 1730         uint32_t glyphIDsCount) const { | 1730         uint32_t glyphIDsCount) const { | 
| 1731     LOGFONT lf = fLogFont; | 1731     LOGFONT lf = fLogFont; | 
| 1732     SkAdvancedTypefaceMetrics* info = NULL; | 1732     SkAdvancedTypefaceMetrics* info = nullptr; | 
| 1733 | 1733 | 
| 1734     HDC hdc = CreateCompatibleDC(NULL); | 1734     HDC hdc = CreateCompatibleDC(nullptr); | 
| 1735     HFONT font = CreateFontIndirect(&lf); | 1735     HFONT font = CreateFontIndirect(&lf); | 
| 1736     HFONT savefont = (HFONT)SelectObject(hdc, font); | 1736     HFONT savefont = (HFONT)SelectObject(hdc, font); | 
| 1737     HFONT designFont = NULL; | 1737     HFONT designFont = nullptr; | 
| 1738 | 1738 | 
| 1739     const char stem_chars[] = {'i', 'I', '!', '1'}; | 1739     const char stem_chars[] = {'i', 'I', '!', '1'}; | 
| 1740     int16_t min_width; | 1740     int16_t min_width; | 
| 1741     unsigned glyphCount; | 1741     unsigned glyphCount; | 
| 1742 | 1742 | 
| 1743     // To request design units, create a logical font whose height is specified | 1743     // To request design units, create a logical font whose height is specified | 
| 1744     // as unitsPerEm. | 1744     // as unitsPerEm. | 
| 1745     OUTLINETEXTMETRIC otm; | 1745     OUTLINETEXTMETRIC otm; | 
| 1746     unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm); | 1746     unsigned int otmRet = GetOutlineTextMetrics(hdc, sizeof(otm), &otm); | 
| 1747     if (0 == otmRet) { | 1747     if (0 == otmRet) { | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1845     SelectObject(hdc, savefont); | 1845     SelectObject(hdc, savefont); | 
| 1846     DeleteObject(designFont); | 1846     DeleteObject(designFont); | 
| 1847     DeleteObject(font); | 1847     DeleteObject(font); | 
| 1848     DeleteDC(hdc); | 1848     DeleteDC(hdc); | 
| 1849 | 1849 | 
| 1850     return info; | 1850     return info; | 
| 1851 } | 1851 } | 
| 1852 | 1852 | 
| 1853 //Dummy representation of a Base64 encoded GUID from create_unique_font_name. | 1853 //Dummy representation of a Base64 encoded GUID from create_unique_font_name. | 
| 1854 #define BASE64_GUID_ID "XXXXXXXXXXXXXXXXXXXXXXXX" | 1854 #define BASE64_GUID_ID "XXXXXXXXXXXXXXXXXXXXXXXX" | 
| 1855 //Length of GUID representation from create_id, including NULL terminator. | 1855 //Length of GUID representation from create_id, including nullptr terminator. | 
| 1856 #define BASE64_GUID_ID_LEN SK_ARRAY_COUNT(BASE64_GUID_ID) | 1856 #define BASE64_GUID_ID_LEN SK_ARRAY_COUNT(BASE64_GUID_ID) | 
| 1857 | 1857 | 
| 1858 static_assert(BASE64_GUID_ID_LEN < LF_FACESIZE, "GUID_longer_than_facesize"); | 1858 static_assert(BASE64_GUID_ID_LEN < LF_FACESIZE, "GUID_longer_than_facesize"); | 
| 1859 | 1859 | 
| 1860 /** | 1860 /** | 
| 1861    NameID 6 Postscript names cannot have the character '/'. | 1861    NameID 6 Postscript names cannot have the character '/'. | 
| 1862    It would be easier to hex encode the GUID, but that is 32 bytes, | 1862    It would be easier to hex encode the GUID, but that is 32 bytes, | 
| 1863    and many systems have issues with names longer than 28 bytes. | 1863    and many systems have issues with names longer than 28 bytes. | 
| 1864    The following need not be any standard base64 encoding. | 1864    The following need not be any standard base64 encoding. | 
| 1865    The encoded value is never decoded. | 1865    The encoded value is never decoded. | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 1892     GUID guid = {}; | 1892     GUID guid = {}; | 
| 1893     if (FAILED(CoCreateGuid(&guid))) { | 1893     if (FAILED(CoCreateGuid(&guid))) { | 
| 1894         return E_UNEXPECTED; | 1894         return E_UNEXPECTED; | 
| 1895     } | 1895     } | 
| 1896     format_guid_b64(guid, buffer, bufferSize); | 1896     format_guid_b64(guid, buffer, bufferSize); | 
| 1897 | 1897 | 
| 1898     return S_OK; | 1898     return S_OK; | 
| 1899 } | 1899 } | 
| 1900 | 1900 | 
| 1901 /** | 1901 /** | 
| 1902    Introduces a font to GDI. On failure will return NULL. The returned handle | 1902    Introduces a font to GDI. On failure will return nullptr. The returned handle | 
| 1903    should eventually be passed to RemoveFontMemResourceEx. | 1903    should eventually be passed to RemoveFontMemResourceEx. | 
| 1904 */ | 1904 */ | 
| 1905 static HANDLE activate_font(SkData* fontData) { | 1905 static HANDLE activate_font(SkData* fontData) { | 
| 1906     DWORD numFonts = 0; | 1906     DWORD numFonts = 0; | 
| 1907     //AddFontMemResourceEx just copies the data, but does not specify const. | 1907     //AddFontMemResourceEx just copies the data, but does not specify const. | 
| 1908     HANDLE fontHandle = AddFontMemResourceEx(const_cast<void*>(fontData->data())
      , | 1908     HANDLE fontHandle = AddFontMemResourceEx(const_cast<void*>(fontData->data())
      , | 
| 1909                                              static_cast<DWORD>(fontData->size()
      ), | 1909                                              static_cast<DWORD>(fontData->size()
      ), | 
| 1910                                              0, | 1910                                              0, | 
| 1911                                              &numFonts); | 1911                                              &numFonts); | 
| 1912 | 1912 | 
| 1913     if (fontHandle != NULL && numFonts < 1) { | 1913     if (fontHandle != nullptr && numFonts < 1) { | 
| 1914         RemoveFontMemResourceEx(fontHandle); | 1914         RemoveFontMemResourceEx(fontHandle); | 
| 1915         return NULL; | 1915         return nullptr; | 
| 1916     } | 1916     } | 
| 1917 | 1917 | 
| 1918     return fontHandle; | 1918     return fontHandle; | 
| 1919 } | 1919 } | 
| 1920 | 1920 | 
| 1921 // Does not affect ownership of stream. | 1921 // Does not affect ownership of stream. | 
| 1922 static SkTypeface* create_from_stream(SkStreamAsset* stream) { | 1922 static SkTypeface* create_from_stream(SkStreamAsset* stream) { | 
| 1923     // Create a unique and unpredictable font name. | 1923     // Create a unique and unpredictable font name. | 
| 1924     // Avoids collisions and access from CSS. | 1924     // Avoids collisions and access from CSS. | 
| 1925     char familyName[BASE64_GUID_ID_LEN]; | 1925     char familyName[BASE64_GUID_ID_LEN]; | 
| 1926     const int familyNameSize = SK_ARRAY_COUNT(familyName); | 1926     const int familyNameSize = SK_ARRAY_COUNT(familyName); | 
| 1927     if (FAILED(create_unique_font_name(familyName, familyNameSize))) { | 1927     if (FAILED(create_unique_font_name(familyName, familyNameSize))) { | 
| 1928         return NULL; | 1928         return nullptr; | 
| 1929     } | 1929     } | 
| 1930 | 1930 | 
| 1931     // Change the name of the font. | 1931     // Change the name of the font. | 
| 1932     SkAutoTUnref<SkData> rewrittenFontData(SkOTUtils::RenameFont(stream, familyN
      ame, familyNameSize-1)); | 1932     SkAutoTUnref<SkData> rewrittenFontData(SkOTUtils::RenameFont(stream, familyN
      ame, familyNameSize-1)); | 
| 1933     if (NULL == rewrittenFontData.get()) { | 1933     if (nullptr == rewrittenFontData.get()) { | 
| 1934         return NULL; | 1934         return nullptr; | 
| 1935     } | 1935     } | 
| 1936 | 1936 | 
| 1937     // Register the font with GDI. | 1937     // Register the font with GDI. | 
| 1938     HANDLE fontReference = activate_font(rewrittenFontData.get()); | 1938     HANDLE fontReference = activate_font(rewrittenFontData.get()); | 
| 1939     if (NULL == fontReference) { | 1939     if (nullptr == fontReference) { | 
| 1940         return NULL; | 1940         return nullptr; | 
| 1941     } | 1941     } | 
| 1942 | 1942 | 
| 1943     // Create the typeface. | 1943     // Create the typeface. | 
| 1944     LOGFONT lf; | 1944     LOGFONT lf; | 
| 1945     logfont_for_name(familyName, &lf); | 1945     logfont_for_name(familyName, &lf); | 
| 1946 | 1946 | 
| 1947     return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference); | 1947     return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference); | 
| 1948 } | 1948 } | 
| 1949 | 1949 | 
| 1950 SkStreamAsset* LogFontTypeface::onOpenStream(int* ttcIndex) const { | 1950 SkStreamAsset* LogFontTypeface::onOpenStream(int* ttcIndex) const { | 
| 1951     *ttcIndex = 0; | 1951     *ttcIndex = 0; | 
| 1952 | 1952 | 
| 1953     const DWORD kTTCTag = | 1953     const DWORD kTTCTag = | 
| 1954         SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f')); | 1954         SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f')); | 
| 1955     LOGFONT lf = fLogFont; | 1955     LOGFONT lf = fLogFont; | 
| 1956 | 1956 | 
| 1957     HDC hdc = ::CreateCompatibleDC(NULL); | 1957     HDC hdc = ::CreateCompatibleDC(nullptr); | 
| 1958     HFONT font = CreateFontIndirect(&lf); | 1958     HFONT font = CreateFontIndirect(&lf); | 
| 1959     HFONT savefont = (HFONT)SelectObject(hdc, font); | 1959     HFONT savefont = (HFONT)SelectObject(hdc, font); | 
| 1960 | 1960 | 
| 1961     SkMemoryStream* stream = NULL; | 1961     SkMemoryStream* stream = nullptr; | 
| 1962     DWORD tables[2] = {kTTCTag, 0}; | 1962     DWORD tables[2] = {kTTCTag, 0}; | 
| 1963     for (int i = 0; i < SK_ARRAY_COUNT(tables); i++) { | 1963     for (int i = 0; i < SK_ARRAY_COUNT(tables); i++) { | 
| 1964         DWORD bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0); | 1964         DWORD bufferSize = GetFontData(hdc, tables[i], 0, nullptr, 0); | 
| 1965         if (bufferSize == GDI_ERROR) { | 1965         if (bufferSize == GDI_ERROR) { | 
| 1966             call_ensure_accessible(lf); | 1966             call_ensure_accessible(lf); | 
| 1967             bufferSize = GetFontData(hdc, tables[i], 0, NULL, 0); | 1967             bufferSize = GetFontData(hdc, tables[i], 0, nullptr, 0); | 
| 1968         } | 1968         } | 
| 1969         if (bufferSize != GDI_ERROR) { | 1969         if (bufferSize != GDI_ERROR) { | 
| 1970             stream = new SkMemoryStream(bufferSize); | 1970             stream = new SkMemoryStream(bufferSize); | 
| 1971             if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(), b
      ufferSize)) { | 1971             if (GetFontData(hdc, tables[i], 0, (void*)stream->getMemoryBase(), b
      ufferSize)) { | 
| 1972                 break; | 1972                 break; | 
| 1973             } else { | 1973             } else { | 
| 1974                 delete stream; | 1974                 delete stream; | 
| 1975                 stream = NULL; | 1975                 stream = nullptr; | 
| 1976             } | 1976             } | 
| 1977         } | 1977         } | 
| 1978     } | 1978     } | 
| 1979 | 1979 | 
| 1980     SelectObject(hdc, savefont); | 1980     SelectObject(hdc, savefont); | 
| 1981     DeleteObject(font); | 1981     DeleteObject(font); | 
| 1982     DeleteDC(hdc); | 1982     DeleteDC(hdc); | 
| 1983 | 1983 | 
| 1984     return stream; | 1984     return stream; | 
| 1985 } | 1985 } | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 2008             } | 2008             } | 
| 2009         } | 2009         } | 
| 2010     } | 2010     } | 
| 2011 } | 2011 } | 
| 2012 | 2012 | 
| 2013 static uint16_t nonBmpCharToGlyph(HDC hdc, SCRIPT_CACHE* scriptCache, const WCHA
      R utf16[2]) { | 2013 static uint16_t nonBmpCharToGlyph(HDC hdc, SCRIPT_CACHE* scriptCache, const WCHA
      R utf16[2]) { | 
| 2014     uint16_t index = 0; | 2014     uint16_t index = 0; | 
| 2015     // Use uniscribe to detemine glyph index for non-BMP characters. | 2015     // Use uniscribe to detemine glyph index for non-BMP characters. | 
| 2016     static const int numWCHAR = 2; | 2016     static const int numWCHAR = 2; | 
| 2017     static const int maxItems = 2; | 2017     static const int maxItems = 2; | 
| 2018     // MSDN states that this can be NULL, but some things don't work then. | 2018     // MSDN states that this can be nullptr, but some things don't work then. | 
| 2019     SCRIPT_CONTROL scriptControl = { 0 }; | 2019     SCRIPT_CONTROL scriptControl = { 0 }; | 
| 2020     // Add extra item to SCRIPT_ITEM to work around a bug (now documented). | 2020     // Add extra item to SCRIPT_ITEM to work around a bug (now documented). | 
| 2021     // https://bugzilla.mozilla.org/show_bug.cgi?id=366643 | 2021     // https://bugzilla.mozilla.org/show_bug.cgi?id=366643 | 
| 2022     SCRIPT_ITEM si[maxItems + 1]; | 2022     SCRIPT_ITEM si[maxItems + 1]; | 
| 2023     int numItems; | 2023     int numItems; | 
| 2024     HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &scriptControl, NULL, si, &num
      Items), | 2024     HRZM(ScriptItemize(utf16, numWCHAR, maxItems, &scriptControl, nullptr, si, &
      numItems), | 
| 2025          "Could not itemize character."); | 2025          "Could not itemize character."); | 
| 2026 | 2026 | 
| 2027     // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 spa
      ce glyphs. | 2027     // Sometimes ScriptShape cannot find a glyph for a non-BMP and returns 2 spa
      ce glyphs. | 
| 2028     static const int maxGlyphs = 2; | 2028     static const int maxGlyphs = 2; | 
| 2029     SCRIPT_VISATTR vsa[maxGlyphs]; | 2029     SCRIPT_VISATTR vsa[maxGlyphs]; | 
| 2030     WORD outGlyphs[maxGlyphs]; | 2030     WORD outGlyphs[maxGlyphs]; | 
| 2031     WORD logClust[numWCHAR]; | 2031     WORD logClust[numWCHAR]; | 
| 2032     int numGlyphs; | 2032     int numGlyphs; | 
| 2033     HRZM(ScriptShape(hdc, scriptCache, utf16, numWCHAR, maxGlyphs, &si[0].a, | 2033     HRZM(ScriptShape(hdc, scriptCache, utf16, numWCHAR, maxGlyphs, &si[0].a, | 
| 2034                      outGlyphs, logClust, vsa, &numGlyphs), | 2034                      outGlyphs, logClust, vsa, &numGlyphs), | 
| 2035          "Could not shape character."); | 2035          "Could not shape character."); | 
| 2036     if (1 == numGlyphs) { | 2036     if (1 == numGlyphs) { | 
| 2037         index = outGlyphs[0]; | 2037         index = outGlyphs[0]; | 
| 2038     } | 2038     } | 
| 2039     return index; | 2039     return index; | 
| 2040 } | 2040 } | 
| 2041 | 2041 | 
| 2042 class SkAutoHDC { | 2042 class SkAutoHDC { | 
| 2043 public: | 2043 public: | 
| 2044     SkAutoHDC(const LOGFONT& lf) | 2044     SkAutoHDC(const LOGFONT& lf) | 
| 2045         : fHdc(::CreateCompatibleDC(NULL)) | 2045         : fHdc(::CreateCompatibleDC(nullptr)) | 
| 2046         , fFont(::CreateFontIndirect(&lf)) | 2046         , fFont(::CreateFontIndirect(&lf)) | 
| 2047         , fSavefont((HFONT)SelectObject(fHdc, fFont)) | 2047         , fSavefont((HFONT)SelectObject(fHdc, fFont)) | 
| 2048     { } | 2048     { } | 
| 2049     ~SkAutoHDC() { | 2049     ~SkAutoHDC() { | 
| 2050         SelectObject(fHdc, fSavefont); | 2050         SelectObject(fHdc, fSavefont); | 
| 2051         DeleteObject(fFont); | 2051         DeleteObject(fFont); | 
| 2052         DeleteDC(fHdc); | 2052         DeleteDC(fHdc); | 
| 2053     } | 2053     } | 
| 2054     operator HDC() { return fHdc; } | 2054     operator HDC() { return fHdc; } | 
| 2055 private: | 2055 private: | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 2068     if (0 == GetTextMetrics(hdc, &tm)) { | 2068     if (0 == GetTextMetrics(hdc, &tm)) { | 
| 2069         call_ensure_accessible(fLogFont); | 2069         call_ensure_accessible(fLogFont); | 
| 2070         if (0 == GetTextMetrics(hdc, &tm)) { | 2070         if (0 == GetTextMetrics(hdc, &tm)) { | 
| 2071             tm.tmPitchAndFamily = TMPF_TRUETYPE; | 2071             tm.tmPitchAndFamily = TMPF_TRUETYPE; | 
| 2072         } | 2072         } | 
| 2073     } | 2073     } | 
| 2074     bool Ox1FHack = !(tm.tmPitchAndFamily & TMPF_VECTOR) /*&& winVer < Vista */; | 2074     bool Ox1FHack = !(tm.tmPitchAndFamily & TMPF_VECTOR) /*&& winVer < Vista */; | 
| 2075 | 2075 | 
| 2076     SkAutoSTMalloc<256, uint16_t> scratchGlyphs; | 2076     SkAutoSTMalloc<256, uint16_t> scratchGlyphs; | 
| 2077     uint16_t* glyphs; | 2077     uint16_t* glyphs; | 
| 2078     if (userGlyphs != NULL) { | 2078     if (userGlyphs != nullptr) { | 
| 2079         glyphs = userGlyphs; | 2079         glyphs = userGlyphs; | 
| 2080     } else { | 2080     } else { | 
| 2081         glyphs = scratchGlyphs.reset(glyphCount); | 2081         glyphs = scratchGlyphs.reset(glyphCount); | 
| 2082     } | 2082     } | 
| 2083 | 2083 | 
| 2084     SCRIPT_CACHE sc = 0; | 2084     SCRIPT_CACHE sc = 0; | 
| 2085     switch (encoding) { | 2085     switch (encoding) { | 
| 2086     case SkTypeface::kUTF8_Encoding: { | 2086     case SkTypeface::kUTF8_Encoding: { | 
| 2087         static const int scratchCount = 256; | 2087         static const int scratchCount = 256; | 
| 2088         WCHAR scratch[scratchCount]; | 2088         WCHAR scratch[scratchCount]; | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2182 | 2182 | 
| 2183     for (int i = 0; i < glyphCount; ++i) { | 2183     for (int i = 0; i < glyphCount; ++i) { | 
| 2184         if (0 == glyphs[i]) { | 2184         if (0 == glyphs[i]) { | 
| 2185             return i; | 2185             return i; | 
| 2186         } | 2186         } | 
| 2187     } | 2187     } | 
| 2188     return glyphCount; | 2188     return glyphCount; | 
| 2189 } | 2189 } | 
| 2190 | 2190 | 
| 2191 int LogFontTypeface::onCountGlyphs() const { | 2191 int LogFontTypeface::onCountGlyphs() const { | 
| 2192     HDC hdc = ::CreateCompatibleDC(NULL); | 2192     HDC hdc = ::CreateCompatibleDC(nullptr); | 
| 2193     HFONT font = CreateFontIndirect(&fLogFont); | 2193     HFONT font = CreateFontIndirect(&fLogFont); | 
| 2194     HFONT savefont = (HFONT)SelectObject(hdc, font); | 2194     HFONT savefont = (HFONT)SelectObject(hdc, font); | 
| 2195 | 2195 | 
| 2196     unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont); | 2196     unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont); | 
| 2197 | 2197 | 
| 2198     SelectObject(hdc, savefont); | 2198     SelectObject(hdc, savefont); | 
| 2199     DeleteObject(font); | 2199     DeleteObject(font); | 
| 2200     DeleteDC(hdc); | 2200     DeleteDC(hdc); | 
| 2201 | 2201 | 
| 2202     return glyphCount; | 2202     return glyphCount; | 
| 2203 } | 2203 } | 
| 2204 | 2204 | 
| 2205 int LogFontTypeface::onGetUPEM() const { | 2205 int LogFontTypeface::onGetUPEM() const { | 
| 2206     HDC hdc = ::CreateCompatibleDC(NULL); | 2206     HDC hdc = ::CreateCompatibleDC(nullptr); | 
| 2207     HFONT font = CreateFontIndirect(&fLogFont); | 2207     HFONT font = CreateFontIndirect(&fLogFont); | 
| 2208     HFONT savefont = (HFONT)SelectObject(hdc, font); | 2208     HFONT savefont = (HFONT)SelectObject(hdc, font); | 
| 2209 | 2209 | 
| 2210     unsigned int upem = calculateUPEM(hdc, fLogFont); | 2210     unsigned int upem = calculateUPEM(hdc, fLogFont); | 
| 2211 | 2211 | 
| 2212     SelectObject(hdc, savefont); | 2212     SelectObject(hdc, savefont); | 
| 2213     DeleteObject(font); | 2213     DeleteObject(font); | 
| 2214     DeleteDC(hdc); | 2214     DeleteDC(hdc); | 
| 2215 | 2215 | 
| 2216     return upem; | 2216     return upem; | 
| 2217 } | 2217 } | 
| 2218 | 2218 | 
| 2219 SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() cons
      t { | 2219 SkTypeface::LocalizedStrings* LogFontTypeface::onCreateFamilyNameIterator() cons
      t { | 
| 2220     SkTypeface::LocalizedStrings* nameIter = | 2220     SkTypeface::LocalizedStrings* nameIter = | 
| 2221         SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); | 2221         SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this); | 
| 2222     if (NULL == nameIter) { | 2222     if (nullptr == nameIter) { | 
| 2223         SkString familyName; | 2223         SkString familyName; | 
| 2224         this->getFamilyName(&familyName); | 2224         this->getFamilyName(&familyName); | 
| 2225         SkString language("und"); //undetermined | 2225         SkString language("und"); //undetermined | 
| 2226         nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, langua
      ge); | 2226         nameIter = new SkOTUtils::LocalizedStrings_SingleName(familyName, langua
      ge); | 
| 2227     } | 2227     } | 
| 2228     return nameIter; | 2228     return nameIter; | 
| 2229 } | 2229 } | 
| 2230 | 2230 | 
| 2231 int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const { | 2231 int LogFontTypeface::onGetTableTags(SkFontTableTag tags[]) const { | 
| 2232     SkSFNTHeader header; | 2232     SkSFNTHeader header; | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 2248         } | 2248         } | 
| 2249     } | 2249     } | 
| 2250     return numTables; | 2250     return numTables; | 
| 2251 } | 2251 } | 
| 2252 | 2252 | 
| 2253 size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, | 2253 size_t LogFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, | 
| 2254                                        size_t length, void* data) const | 2254                                        size_t length, void* data) const | 
| 2255 { | 2255 { | 
| 2256     LOGFONT lf = fLogFont; | 2256     LOGFONT lf = fLogFont; | 
| 2257 | 2257 | 
| 2258     HDC hdc = ::CreateCompatibleDC(NULL); | 2258     HDC hdc = ::CreateCompatibleDC(nullptr); | 
| 2259     HFONT font = CreateFontIndirect(&lf); | 2259     HFONT font = CreateFontIndirect(&lf); | 
| 2260     HFONT savefont = (HFONT)SelectObject(hdc, font); | 2260     HFONT savefont = (HFONT)SelectObject(hdc, font); | 
| 2261 | 2261 | 
| 2262     tag = SkEndian_SwapBE32(tag); | 2262     tag = SkEndian_SwapBE32(tag); | 
| 2263     if (NULL == data) { | 2263     if (nullptr == data) { | 
| 2264         length = 0; | 2264         length = 0; | 
| 2265     } | 2265     } | 
| 2266     DWORD bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) lengt
      h); | 2266     DWORD bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) lengt
      h); | 
| 2267     if (bufferSize == GDI_ERROR) { | 2267     if (bufferSize == GDI_ERROR) { | 
| 2268         call_ensure_accessible(lf); | 2268         call_ensure_accessible(lf); | 
| 2269         bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) length)
      ; | 2269         bufferSize = GetFontData(hdc, tag, (DWORD) offset, data, (DWORD) length)
      ; | 
| 2270     } | 2270     } | 
| 2271 | 2271 | 
| 2272     SelectObject(hdc, savefont); | 2272     SelectObject(hdc, savefont); | 
| 2273     DeleteObject(font); | 2273     DeleteObject(font); | 
| 2274     DeleteDC(hdc); | 2274     DeleteDC(hdc); | 
| 2275 | 2275 | 
| 2276     return bufferSize == GDI_ERROR ? 0 : bufferSize; | 2276     return bufferSize == GDI_ERROR ? 0 : bufferSize; | 
| 2277 } | 2277 } | 
| 2278 | 2278 | 
| 2279 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc
      ) const { | 2279 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc
      ) const { | 
| 2280     SkScalerContext_GDI* ctx = new SkScalerContext_GDI(const_cast<LogFontTypefac
      e*>(this), desc); | 2280     SkScalerContext_GDI* ctx = new SkScalerContext_GDI(const_cast<LogFontTypefac
      e*>(this), desc); | 
| 2281     if (!ctx->isValid()) { | 2281     if (!ctx->isValid()) { | 
| 2282         delete ctx; | 2282         delete ctx; | 
| 2283         ctx = NULL; | 2283         ctx = nullptr; | 
| 2284     } | 2284     } | 
| 2285     return ctx; | 2285     return ctx; | 
| 2286 } | 2286 } | 
| 2287 | 2287 | 
| 2288 void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const { | 2288 void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const { | 
| 2289     if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag || | 2289     if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag || | 
| 2290         rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) | 2290         rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) | 
| 2291     { | 2291     { | 
| 2292         rec->fMaskFormat = SkMask::kA8_Format; | 2292         rec->fMaskFormat = SkMask::kA8_Format; | 
| 2293         rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag; | 2293         rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag; | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2371 } | 2371 } | 
| 2372 | 2372 | 
| 2373 class SkFontStyleSetGDI : public SkFontStyleSet { | 2373 class SkFontStyleSetGDI : public SkFontStyleSet { | 
| 2374 public: | 2374 public: | 
| 2375     SkFontStyleSetGDI(const TCHAR familyName[]) { | 2375     SkFontStyleSetGDI(const TCHAR familyName[]) { | 
| 2376         LOGFONT lf; | 2376         LOGFONT lf; | 
| 2377         sk_bzero(&lf, sizeof(lf)); | 2377         sk_bzero(&lf, sizeof(lf)); | 
| 2378         lf.lfCharSet = DEFAULT_CHARSET; | 2378         lf.lfCharSet = DEFAULT_CHARSET; | 
| 2379         _tcscpy_s(lf.lfFaceName, familyName); | 2379         _tcscpy_s(lf.lfFaceName, familyName); | 
| 2380 | 2380 | 
| 2381         HDC hdc = ::CreateCompatibleDC(NULL); | 2381         HDC hdc = ::CreateCompatibleDC(nullptr); | 
| 2382         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0); | 2382         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fArray, 0); | 
| 2383         ::DeleteDC(hdc); | 2383         ::DeleteDC(hdc); | 
| 2384     } | 2384     } | 
| 2385 | 2385 | 
| 2386     int count() override { | 2386     int count() override { | 
| 2387         return fArray.count(); | 2387         return fArray.count(); | 
| 2388     } | 2388     } | 
| 2389 | 2389 | 
| 2390     void getStyle(int index, SkFontStyle* fs, SkString* styleName) override { | 2390     void getStyle(int index, SkFontStyle* fs, SkString* styleName) override { | 
| 2391         if (fs) { | 2391         if (fs) { | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 2417     SkTDArray<ENUMLOGFONTEX> fArray; | 2417     SkTDArray<ENUMLOGFONTEX> fArray; | 
| 2418 }; | 2418 }; | 
| 2419 | 2419 | 
| 2420 class SkFontMgrGDI : public SkFontMgr { | 2420 class SkFontMgrGDI : public SkFontMgr { | 
| 2421 public: | 2421 public: | 
| 2422     SkFontMgrGDI() { | 2422     SkFontMgrGDI() { | 
| 2423         LOGFONT lf; | 2423         LOGFONT lf; | 
| 2424         sk_bzero(&lf, sizeof(lf)); | 2424         sk_bzero(&lf, sizeof(lf)); | 
| 2425         lf.lfCharSet = DEFAULT_CHARSET; | 2425         lf.lfCharSet = DEFAULT_CHARSET; | 
| 2426 | 2426 | 
| 2427         HDC hdc = ::CreateCompatibleDC(NULL); | 2427         HDC hdc = ::CreateCompatibleDC(nullptr); | 
| 2428         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fLogFontArray,
       0); | 2428         ::EnumFontFamiliesEx(hdc, &lf, enum_family_proc, (LPARAM)&fLogFontArray,
       0); | 
| 2429         ::DeleteDC(hdc); | 2429         ::DeleteDC(hdc); | 
| 2430     } | 2430     } | 
| 2431 | 2431 | 
| 2432 protected: | 2432 protected: | 
| 2433     int onCountFamilies() const override { | 2433     int onCountFamilies() const override { | 
| 2434         return fLogFontArray.count(); | 2434         return fLogFontArray.count(); | 
| 2435     } | 2435     } | 
| 2436 | 2436 | 
| 2437     void onGetFamilyName(int index, SkString* familyName) const override { | 2437     void onGetFamilyName(int index, SkString* familyName) const override { | 
| 2438         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count()); | 2438         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count()); | 
| 2439         tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName
      ); | 2439         tchar_to_skstring(fLogFontArray[index].elfLogFont.lfFaceName, familyName
      ); | 
| 2440     } | 2440     } | 
| 2441 | 2441 | 
| 2442     SkFontStyleSet* onCreateStyleSet(int index) const override { | 2442     SkFontStyleSet* onCreateStyleSet(int index) const override { | 
| 2443         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count()); | 2443         SkASSERT((unsigned)index < (unsigned)fLogFontArray.count()); | 
| 2444         return new SkFontStyleSetGDI(fLogFontArray[index].elfLogFont.lfFaceName)
      ; | 2444         return new SkFontStyleSetGDI(fLogFontArray[index].elfLogFont.lfFaceName)
      ; | 
| 2445     } | 2445     } | 
| 2446 | 2446 | 
| 2447     SkFontStyleSet* onMatchFamily(const char familyName[]) const override { | 2447     SkFontStyleSet* onMatchFamily(const char familyName[]) const override { | 
| 2448         if (NULL == familyName) { | 2448         if (nullptr == familyName) { | 
| 2449             familyName = "";    // do we need this check??? | 2449             familyName = "";    // do we need this check??? | 
| 2450         } | 2450         } | 
| 2451         LOGFONT lf; | 2451         LOGFONT lf; | 
| 2452         logfont_for_name(familyName, &lf); | 2452         logfont_for_name(familyName, &lf); | 
| 2453         return new SkFontStyleSetGDI(lf.lfFaceName); | 2453         return new SkFontStyleSetGDI(lf.lfFaceName); | 
| 2454     } | 2454     } | 
| 2455 | 2455 | 
| 2456     virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 2456     virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 
| 2457                                            const SkFontStyle& fontstyle) const o
      verride { | 2457                                            const SkFontStyle& fontstyle) const o
      verride { | 
| 2458         // could be in base impl | 2458         // could be in base impl | 
| 2459         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); | 2459         SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); | 
| 2460         return sset->matchStyle(fontstyle); | 2460         return sset->matchStyle(fontstyle); | 
| 2461     } | 2461     } | 
| 2462 | 2462 | 
| 2463     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], con
      st SkFontStyle&, | 2463     virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], con
      st SkFontStyle&, | 
| 2464                                                     const char* bcp47[], int bcp
      47Count, | 2464                                                     const char* bcp47[], int bcp
      47Count, | 
| 2465                                                     SkUnichar character) const o
      verride { | 2465                                                     SkUnichar character) const o
      verride { | 
| 2466         return NULL; | 2466         return nullptr; | 
| 2467     } | 2467     } | 
| 2468 | 2468 | 
| 2469     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, | 2469     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, | 
| 2470                                          const SkFontStyle& fontstyle) const ove
      rride { | 2470                                          const SkFontStyle& fontstyle) const ove
      rride { | 
| 2471         // could be in base impl | 2471         // could be in base impl | 
| 2472         SkString familyName; | 2472         SkString familyName; | 
| 2473         ((LogFontTypeface*)familyMember)->getFamilyName(&familyName); | 2473         ((LogFontTypeface*)familyMember)->getFamilyName(&familyName); | 
| 2474         return this->matchFamilyStyle(familyName.c_str(), fontstyle); | 2474         return this->matchFamilyStyle(familyName.c_str(), fontstyle); | 
| 2475     } | 2475     } | 
| 2476 | 2476 | 
| 2477     SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) cons
      t override { | 2477     SkTypeface* onCreateFromStream(SkStreamAsset* bareStream, int ttcIndex) cons
      t override { | 
| 2478         SkAutoTDelete<SkStreamAsset> stream(bareStream); | 2478         SkAutoTDelete<SkStreamAsset> stream(bareStream); | 
| 2479         return create_from_stream(stream); | 2479         return create_from_stream(stream); | 
| 2480     } | 2480     } | 
| 2481 | 2481 | 
| 2482     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { | 2482     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override { | 
| 2483         // could be in base impl | 2483         // could be in base impl | 
| 2484         return this->createFromStream(new SkMemoryStream(data)); | 2484         return this->createFromStream(new SkMemoryStream(data)); | 
| 2485     } | 2485     } | 
| 2486 | 2486 | 
| 2487     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
       { | 2487     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
       { | 
| 2488         // could be in base impl | 2488         // could be in base impl | 
| 2489         return this->createFromStream(SkStream::NewFromFile(path)); | 2489         return this->createFromStream(SkStream::NewFromFile(path)); | 
| 2490     } | 2490     } | 
| 2491 | 2491 | 
| 2492     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 2492     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 
| 2493                                                unsigned styleBits) const overrid
      e { | 2493                                                unsigned styleBits) const overrid
      e { | 
| 2494         LOGFONT lf; | 2494         LOGFONT lf; | 
| 2495         if (NULL == familyName) { | 2495         if (nullptr == familyName) { | 
| 2496             lf = get_default_font(); | 2496             lf = get_default_font(); | 
| 2497         } else { | 2497         } else { | 
| 2498             logfont_for_name(familyName, &lf); | 2498             logfont_for_name(familyName, &lf); | 
| 2499         } | 2499         } | 
| 2500 | 2500 | 
| 2501         SkTypeface::Style style = (SkTypeface::Style)styleBits; | 2501         SkTypeface::Style style = (SkTypeface::Style)styleBits; | 
| 2502         lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL; | 2502         lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL; | 
| 2503         lf.lfItalic = ((style & SkTypeface::kItalic) != 0); | 2503         lf.lfItalic = ((style & SkTypeface::kItalic) != 0); | 
| 2504         return SkCreateTypefaceFromLOGFONT(lf); | 2504         return SkCreateTypefaceFromLOGFONT(lf); | 
| 2505     } | 2505     } | 
| 2506 | 2506 | 
| 2507 private: | 2507 private: | 
| 2508     SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 2508     SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 
| 2509 }; | 2509 }; | 
| 2510 | 2510 | 
| 2511 /////////////////////////////////////////////////////////////////////////////// | 2511 /////////////////////////////////////////////////////////////////////////////// | 
| 2512 | 2512 | 
| 2513 SkFontMgr* SkFontMgr_New_GDI() { return new SkFontMgrGDI; } | 2513 SkFontMgr* SkFontMgr_New_GDI() { return new SkFontMgrGDI; } | 
| OLD | NEW | 
|---|