| 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 |