OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkAdvancedTypefaceMetrics.h" | 9 #include "SkAdvancedTypefaceMetrics.h" |
10 #include "SkBase64.h" | 10 #include "SkBase64.h" |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 enum { | 423 enum { |
424 // will always trigger us to reset the color, since we | 424 // will always trigger us to reset the color, since we |
425 // should only store 0 or 0x00FFFFFF or gray (0x007F7F7F) | 425 // should only store 0 or 0x00FFFFFF or gray (0x007F7F7F) |
426 kInvalid_Color = 12345 | 426 kInvalid_Color = 12345 |
427 }; | 427 }; |
428 }; | 428 }; |
429 | 429 |
430 const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW, | 430 const void* HDCOffscreen::draw(const SkGlyph& glyph, bool isBW, |
431 size_t* srcRBPtr) { | 431 size_t* srcRBPtr) { |
432 if (0 == fDC) { | 432 if (0 == fDC) { |
433 fDC = CreateCompatibleDC(0); | 433 fDC = CreateCompatibleDC(0); |
bungeman-skia
2013/07/09 22:45:37
We do check creation of this guy, and just return
reed1
2013/07/10 13:59:04
Good optimization -- may do in a 2nd CL
bungeman-skia
2013/07/10 14:58:25
Changing this so this guy is part of initializatio
| |
434 if (0 == fDC) { | 434 if (0 == fDC) { |
435 return NULL; | 435 return NULL; |
436 } | 436 } |
437 SetGraphicsMode(fDC, GM_ADVANCED); | 437 SetGraphicsMode(fDC, GM_ADVANCED); |
438 SetBkMode(fDC, TRANSPARENT); | 438 SetBkMode(fDC, TRANSPARENT); |
439 SetTextAlign(fDC, TA_LEFT | TA_BASELINE); | 439 SetTextAlign(fDC, TA_LEFT | TA_BASELINE); |
440 SelectObject(fDC, fFont); | 440 SelectObject(fDC, fFont); |
441 | 441 |
442 COLORREF color = 0x00FFFFFF; | 442 COLORREF color = 0x00FFFFFF; |
443 SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color); | 443 SkDEBUGCODE(COLORREF prev =) SetTextColor(fDC, color); |
(...skipping 22 matching lines...) Expand all Loading... | |
466 } | 466 } |
467 info.bmiHeader.biSize = sizeof(info.bmiHeader); | 467 info.bmiHeader.biSize = sizeof(info.bmiHeader); |
468 info.bmiHeader.biWidth = biWidth; | 468 info.bmiHeader.biWidth = biWidth; |
469 info.bmiHeader.biHeight = fHeight; | 469 info.bmiHeader.biHeight = fHeight; |
470 info.bmiHeader.biPlanes = 1; | 470 info.bmiHeader.biPlanes = 1; |
471 info.bmiHeader.biBitCount = isBW ? 1 : 32; | 471 info.bmiHeader.biBitCount = isBW ? 1 : 32; |
472 info.bmiHeader.biCompression = BI_RGB; | 472 info.bmiHeader.biCompression = BI_RGB; |
473 if (isBW) { | 473 if (isBW) { |
474 info.bmiHeader.biClrUsed = 2; | 474 info.bmiHeader.biClrUsed = 2; |
475 } | 475 } |
476 fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0); | 476 fBM = CreateDIBSection(fDC, &info, DIB_RGB_COLORS, &fBits, 0, 0); |
bungeman-skia
2013/07/09 22:45:37
This is an HBITMAP, so this could fail too. This o
| |
477 if (0 == fBM) { | 477 if (0 == fBM) { |
478 return NULL; | 478 return NULL; |
479 } | 479 } |
480 SelectObject(fDC, fBM); | 480 SelectObject(fDC, fBM); |
481 } | 481 } |
482 | 482 |
483 // erase | 483 // erase |
484 size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2); | 484 size_t srcRB = isBW ? (biWidth >> 3) : (fWidth << 2); |
485 size_t size = fHeight * srcRB; | 485 size_t size = fHeight * srcRB; |
486 memset(fBits, 0, size); | 486 memset(fBits, 0, size); |
(...skipping 14 matching lines...) Expand all Loading... | |
501 return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB; | 501 return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB; |
502 } | 502 } |
503 | 503 |
504 ////////////////////////////////////////////////////////////////////////////// | 504 ////////////////////////////////////////////////////////////////////////////// |
505 | 505 |
506 class SkScalerContext_Windows : public SkScalerContext { | 506 class SkScalerContext_Windows : public SkScalerContext { |
507 public: | 507 public: |
508 SkScalerContext_Windows(SkTypeface*, const SkDescriptor* desc); | 508 SkScalerContext_Windows(SkTypeface*, const SkDescriptor* desc); |
509 virtual ~SkScalerContext_Windows(); | 509 virtual ~SkScalerContext_Windows(); |
510 | 510 |
511 // Returns true if the constructor was able to complete all of its | |
512 // initializations (which may include calling GDI). | |
513 bool isValid() const; | |
514 | |
511 protected: | 515 protected: |
512 virtual unsigned generateGlyphCount() SK_OVERRIDE; | 516 virtual unsigned generateGlyphCount() SK_OVERRIDE; |
513 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; | 517 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; |
514 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; | 518 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; |
515 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; | 519 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; |
516 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; | 520 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; |
517 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; | 521 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; |
518 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, | 522 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, |
519 SkPaint::FontMetrics* mY) SK_OVERRIDE; | 523 SkPaint::FontMetrics* mY) SK_OVERRIDE; |
520 | 524 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 : SkScalerContext(rawTypeface, desc) | 580 : SkScalerContext(rawTypeface, desc) |
577 , fDDC(0) | 581 , fDDC(0) |
578 , fFont(0) | 582 , fFont(0) |
579 , fSavefont(0) | 583 , fSavefont(0) |
580 , fSC(0) | 584 , fSC(0) |
581 , fGlyphCount(-1) | 585 , fGlyphCount(-1) |
582 { | 586 { |
583 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); | 587 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); |
584 | 588 |
585 fDDC = ::CreateCompatibleDC(NULL); | 589 fDDC = ::CreateCompatibleDC(NULL); |
590 if (!fDDC) { | |
591 return; | |
592 } | |
593 | |
586 SetGraphicsMode(fDDC, GM_ADVANCED); | 594 SetGraphicsMode(fDDC, GM_ADVANCED); |
587 SetBkMode(fDDC, TRANSPARENT); | 595 SetBkMode(fDDC, TRANSPARENT); |
588 | 596 |
589 // Scaling by the DPI is inconsistent with how Skia draws elsewhere | 597 // Scaling by the DPI is inconsistent with how Skia draws elsewhere |
590 //SkScalar height = -(fRec.fTextSize * GetDeviceCaps(ddc, LOGPIXELSY) / 72); | 598 //SkScalar height = -(fRec.fTextSize * GetDeviceCaps(ddc, LOGPIXELSY) / 72); |
591 LOGFONT lf = typeface->fLogFont; | 599 LOGFONT lf = typeface->fLogFont; |
592 lf.lfHeight = -gCanonicalTextSize; | 600 lf.lfHeight = -gCanonicalTextSize; |
593 lf.lfQuality = compute_quality(fRec); | 601 lf.lfQuality = compute_quality(fRec); |
594 fFont = CreateFontIndirect(&lf); | 602 fFont = CreateFontIndirect(&lf); |
603 if (!fFont) { | |
604 return; | |
605 } | |
595 | 606 |
596 // if we're rotated, or want fractional widths, create a hires font | 607 // if we're rotated, or want fractional widths, create a hires font |
597 fHiResFont = 0; | 608 fHiResFont = 0; |
598 if (needHiResMetrics(fRec.fPost2x2)) { | 609 if (needHiResMetrics(fRec.fPost2x2)) { |
599 lf.lfHeight = -HIRES_TEXTSIZE; | 610 lf.lfHeight = -HIRES_TEXTSIZE; |
600 fHiResFont = CreateFontIndirect(&lf); | 611 fHiResFont = CreateFontIndirect(&lf); |
bungeman-skia
2013/07/09 22:45:37
fHiResFont? I suppose things should still work wit
reed1
2013/07/10 13:59:04
Done.
| |
601 | 612 |
602 fMat22Identity.eM11 = fMat22Identity.eM22 = SkFixedToFIXED(SK_Fixed1); | 613 fMat22Identity.eM11 = fMat22Identity.eM22 = SkFixedToFIXED(SK_Fixed1); |
603 fMat22Identity.eM12 = fMat22Identity.eM21 = SkFixedToFIXED(0); | 614 fMat22Identity.eM12 = fMat22Identity.eM21 = SkFixedToFIXED(0); |
604 | 615 |
605 // construct a matrix to go from HIRES logical units to our device units | 616 // construct a matrix to go from HIRES logical units to our device units |
606 fRec.getSingleMatrix(&fHiResMatrix); | 617 fRec.getSingleMatrix(&fHiResMatrix); |
607 SkScalar scale = SkScalarInvert(SkIntToScalar(HIRES_TEXTSIZE)); | 618 SkScalar scale = SkScalarInvert(SkIntToScalar(HIRES_TEXTSIZE)); |
608 fHiResMatrix.preScale(scale, scale); | 619 fHiResMatrix.preScale(scale, scale); |
609 } | 620 } |
610 fSavefont = (HFONT)SelectObject(fDDC, fFont); | 621 fSavefont = (HFONT)SelectObject(fDDC, fFont); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
664 xform.eDy = 0.0f; | 675 xform.eDy = 0.0f; |
665 | 676 |
666 // fPost2x2 is column-major, left handed (y down). | 677 // fPost2x2 is column-major, left handed (y down). |
667 // MAT2 is row major, right handed (y up). | 678 // MAT2 is row major, right handed (y up). |
668 fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]); | 679 fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]); |
669 fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]); | 680 fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]); |
670 fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]); | 681 fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]); |
671 fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]); | 682 fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]); |
672 | 683 |
673 lf.lfHeight = -SkScalarCeilToInt(fRec.fTextSize); | 684 lf.lfHeight = -SkScalarCeilToInt(fRec.fTextSize); |
674 HFONT bitmapFont = CreateFontIndirect(&lf); | 685 HFONT bitmapFont = CreateFontIndirect(&lf); |
bungeman-skia
2013/07/09 22:45:37
here (though this replaces fFont, so we could remo
reed1
2013/07/10 13:59:04
I think this guy just works. If bitmapFont is 0, t
| |
675 SelectObject(fDDC, bitmapFont); | 686 SelectObject(fDDC, bitmapFont); |
676 ::DeleteObject(fFont); | 687 ::DeleteObject(fFont); |
677 fFont = bitmapFont; | 688 fFont = bitmapFont; |
678 | 689 |
679 if (0 == GetTextMetrics(fDDC, &fTM)) { | 690 if (0 == GetTextMetrics(fDDC, &fTM)) { |
680 call_ensure_accessible(lf); | 691 call_ensure_accessible(lf); |
681 //if the following fails, we'll just draw at gCanonicalTextSize. | 692 //if the following fails, we'll just draw at gCanonicalTextSize. |
682 GetTextMetrics(fDDC, &fTM); | 693 GetTextMetrics(fDDC, &fTM); |
683 } | 694 } |
684 } | 695 } |
(...skipping 10 matching lines...) Expand all Loading... | |
695 ::DeleteObject(fFont); | 706 ::DeleteObject(fFont); |
696 } | 707 } |
697 if (fHiResFont) { | 708 if (fHiResFont) { |
698 ::DeleteObject(fHiResFont); | 709 ::DeleteObject(fHiResFont); |
699 } | 710 } |
700 if (fSC) { | 711 if (fSC) { |
701 ::ScriptFreeCache(&fSC); | 712 ::ScriptFreeCache(&fSC); |
702 } | 713 } |
703 } | 714 } |
704 | 715 |
716 bool SkScalerContext_Windows::isValid() const { | |
717 return fDDC && fFont; | |
718 } | |
719 | |
705 unsigned SkScalerContext_Windows::generateGlyphCount() { | 720 unsigned SkScalerContext_Windows::generateGlyphCount() { |
706 if (fGlyphCount < 0) { | 721 if (fGlyphCount < 0) { |
707 if (fType == SkScalerContext_Windows::kBitmap_Type) { | 722 if (fType == SkScalerContext_Windows::kBitmap_Type) { |
708 return fTM.tmLastChar; | 723 return fTM.tmLastChar; |
709 } | 724 } |
710 fGlyphCount = calculateOutlineGlyphCount(fDDC); | 725 fGlyphCount = calculateOutlineGlyphCount(fDDC); |
711 } | 726 } |
712 return fGlyphCount; | 727 return fGlyphCount; |
713 } | 728 } |
714 | 729 |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1658 } | 1673 } |
1659 | 1674 |
1660 SelectObject(hdc, savefont); | 1675 SelectObject(hdc, savefont); |
1661 DeleteObject(font); | 1676 DeleteObject(font); |
1662 DeleteDC(hdc); | 1677 DeleteDC(hdc); |
1663 | 1678 |
1664 return stream; | 1679 return stream; |
1665 } | 1680 } |
1666 | 1681 |
1667 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc ) const { | 1682 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc ) const { |
1668 return SkNEW_ARGS(SkScalerContext_Windows, (const_cast<LogFontTypeface*>(thi s), desc)); | 1683 SkScalerContext_Windows* ctx = SkNEW_ARGS(SkScalerContext_Windows, |
bungeman-skia
2013/07/09 22:45:37
It may be easier to understand the intent with som
reed1
2013/07/10 13:59:04
Probably a matter of taste, as I find the current
| |
1684 (const_cast<LogFontTypeface*>(th is), desc)); | |
1685 if (!ctx->isValid()) { | |
1686 SkDELETE(ctx); | |
1687 ctx = NULL; | |
1688 } | |
1689 return ctx; | |
1669 } | 1690 } |
1670 | 1691 |
1671 /** Return the closest matching typeface given either an existing family | 1692 /** Return the closest matching typeface given either an existing family |
1672 (specified by a typeface in that family) or by a familyName, and a | 1693 (specified by a typeface in that family) or by a familyName, and a |
1673 requested style. | 1694 requested style. |
1674 1) If familyFace is null, use familyName. | 1695 1) If familyFace is null, use familyName. |
1675 2) If familyName is null, use familyFace. | 1696 2) If familyName is null, use familyFace. |
1676 3) If both are null, return the default font that best matches style | 1697 3) If both are null, return the default font that best matches style |
1677 This MUST not return NULL. | 1698 This MUST not return NULL. |
1678 */ | 1699 */ |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1918 return this->createFromStream(stream); | 1939 return this->createFromStream(stream); |
1919 } | 1940 } |
1920 | 1941 |
1921 private: | 1942 private: |
1922 SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 1943 SkTDArray<ENUMLOGFONTEX> fLogFontArray; |
1923 }; | 1944 }; |
1924 | 1945 |
1925 SkFontMgr* SkFontMgr::Factory() { | 1946 SkFontMgr* SkFontMgr::Factory() { |
1926 return SkNEW(SkFontMgrGDI); | 1947 return SkNEW(SkFontMgrGDI); |
1927 } | 1948 } |
OLD | NEW |