| 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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 protected: | 243 protected: |
| 244 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; | 244 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; |
| 245 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; | 245 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; |
| 246 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; | 246 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; |
| 247 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( | 247 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( |
| 248 SkAdvancedTypefaceMetrics::PerGlyphInfo, | 248 SkAdvancedTypefaceMetrics::PerGlyphInfo, |
| 249 const uint32_t*, uint32_t) const SK_OVERRIDE; | 249 const uint32_t*, uint32_t) const SK_OVERRIDE; |
| 250 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
; | 250 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
; |
| 251 virtual int onCountGlyphs() const SK_OVERRIDE; | 251 virtual int onCountGlyphs() const SK_OVERRIDE; |
| 252 virtual int onGetUPEM() const SK_OVERRIDE; | 252 virtual int onGetUPEM() const SK_OVERRIDE; |
| 253 virtual SkTypeface* onRefMatchingStyle(Style) const SK_OVERRIDE; |
| 253 }; | 254 }; |
| 254 | 255 |
| 255 class FontMemResourceTypeface : public LogFontTypeface { | 256 class FontMemResourceTypeface : public LogFontTypeface { |
| 256 public: | 257 public: |
| 257 /** | 258 /** |
| 258 * Takes ownership of fontMemResource. | 259 * Takes ownership of fontMemResource. |
| 259 */ | 260 */ |
| 260 FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGF
ONT& lf, HANDLE fontMemResource) : | 261 FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGF
ONT& lf, HANDLE fontMemResource) : |
| 261 LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResour
ce) { | 262 LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResour
ce) { |
| 262 } | 263 } |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 return NULL; | 516 return NULL; |
| 516 } | 517 } |
| 517 *srcRBPtr = srcRB; | 518 *srcRBPtr = srcRB; |
| 518 // offset to the start of the image | 519 // offset to the start of the image |
| 519 return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB; | 520 return (const char*)fBits + (fHeight - glyph.fHeight) * srcRB; |
| 520 } | 521 } |
| 521 | 522 |
| 522 ////////////////////////////////////////////////////////////////////////////// | 523 ////////////////////////////////////////////////////////////////////////////// |
| 523 #define BUFFERSIZE (1 << 13) | 524 #define BUFFERSIZE (1 << 13) |
| 524 | 525 |
| 525 class SkScalerContext_Windows : public SkScalerContext { | 526 class SkScalerContext_GDI : public SkScalerContext { |
| 526 public: | 527 public: |
| 527 SkScalerContext_Windows(SkTypeface*, const SkDescriptor* desc); | 528 SkScalerContext_GDI(SkTypeface*, const SkDescriptor* desc); |
| 528 virtual ~SkScalerContext_Windows(); | 529 virtual ~SkScalerContext_GDI(); |
| 529 | 530 |
| 530 // Returns true if the constructor was able to complete all of its | 531 // Returns true if the constructor was able to complete all of its |
| 531 // initializations (which may include calling GDI). | 532 // initializations (which may include calling GDI). |
| 532 bool isValid() const; | 533 bool isValid() const; |
| 533 | 534 |
| 534 protected: | 535 protected: |
| 535 virtual unsigned generateGlyphCount() SK_OVERRIDE; | 536 virtual unsigned generateGlyphCount() SK_OVERRIDE; |
| 536 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; | 537 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; |
| 537 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; | 538 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; |
| 538 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; | 539 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 return CLEARTYPE_QUALITY; | 586 return CLEARTYPE_QUALITY; |
| 586 default: | 587 default: |
| 587 if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) { | 588 if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) { |
| 588 return CLEARTYPE_QUALITY; | 589 return CLEARTYPE_QUALITY; |
| 589 } else { | 590 } else { |
| 590 return ANTIALIASED_QUALITY; | 591 return ANTIALIASED_QUALITY; |
| 591 } | 592 } |
| 592 } | 593 } |
| 593 } | 594 } |
| 594 | 595 |
| 595 SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface, | 596 SkScalerContext_GDI::SkScalerContext_GDI(SkTypeface* rawTypeface, |
| 596 const SkDescriptor* desc) | 597 const SkDescriptor* desc) |
| 597 : SkScalerContext(rawTypeface, desc) | 598 : SkScalerContext(rawTypeface, desc) |
| 598 , fDDC(0) | 599 , fDDC(0) |
| 599 , fSavefont(0) | 600 , fSavefont(0) |
| 600 , fFont(0) | 601 , fFont(0) |
| 601 , fSC(0) | 602 , fSC(0) |
| 602 , fGlyphCount(-1) | 603 , fGlyphCount(-1) |
| 603 { | 604 { |
| 604 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); | 605 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); |
| 605 | 606 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 // otherwise we have a vector FON, which we don't support. | 701 // otherwise we have a vector FON, which we don't support. |
| 701 // This was determined by testing with Type1 PFM/PFB and OpenTypeCFF OTF, | 702 // This was determined by testing with Type1 PFM/PFB and OpenTypeCFF OTF, |
| 702 // as well as looking at Wine bugs and sources. | 703 // as well as looking at Wine bugs and sources. |
| 703 SkASSERT(!(fTM.tmPitchAndFamily & TMPF_VECTOR) || | 704 SkASSERT(!(fTM.tmPitchAndFamily & TMPF_VECTOR) || |
| 704 (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE))); | 705 (fTM.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_DEVICE))); |
| 705 | 706 |
| 706 XFORM xform; | 707 XFORM xform; |
| 707 if (fTM.tmPitchAndFamily & TMPF_VECTOR) { | 708 if (fTM.tmPitchAndFamily & TMPF_VECTOR) { |
| 708 // Truetype or PostScript. | 709 // Truetype or PostScript. |
| 709 // Stroked FON also gets here (TMPF_VECTOR), but we don't handle it. | 710 // Stroked FON also gets here (TMPF_VECTOR), but we don't handle it. |
| 710 fType = SkScalerContext_Windows::kTrueType_Type; | 711 fType = SkScalerContext_GDI::kTrueType_Type; |
| 711 | 712 |
| 712 // fPost2x2 is column-major, left handed (y down). | 713 // fPost2x2 is column-major, left handed (y down). |
| 713 // XFORM 2x2 is row-major, left handed (y down). | 714 // XFORM 2x2 is row-major, left handed (y down). |
| 714 xform.eM11 = SkScalarToFloat(sA.get(SkMatrix::kMScaleX)); | 715 xform.eM11 = SkScalarToFloat(sA.get(SkMatrix::kMScaleX)); |
| 715 xform.eM12 = SkScalarToFloat(sA.get(SkMatrix::kMSkewY)); | 716 xform.eM12 = SkScalarToFloat(sA.get(SkMatrix::kMSkewY)); |
| 716 xform.eM21 = SkScalarToFloat(sA.get(SkMatrix::kMSkewX)); | 717 xform.eM21 = SkScalarToFloat(sA.get(SkMatrix::kMSkewX)); |
| 717 xform.eM22 = SkScalarToFloat(sA.get(SkMatrix::kMScaleY)); | 718 xform.eM22 = SkScalarToFloat(sA.get(SkMatrix::kMScaleY)); |
| 718 xform.eDx = 0; | 719 xform.eDx = 0; |
| 719 xform.eDy = 0; | 720 xform.eDy = 0; |
| 720 | 721 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 746 fHighResMat22.eM22 = float2FIXED(textScale); | 747 fHighResMat22.eM22 = float2FIXED(textScale); |
| 747 | 748 |
| 748 SkScalar invScale = SkScalarInvert(scale); | 749 SkScalar invScale = SkScalarInvert(scale); |
| 749 fHiResMatrix = A; | 750 fHiResMatrix = A; |
| 750 fHiResMatrix.preScale(invScale, invScale); | 751 fHiResMatrix.preScale(invScale, invScale); |
| 751 } | 752 } |
| 752 } | 753 } |
| 753 | 754 |
| 754 } else { | 755 } else { |
| 755 // Assume bitmap | 756 // Assume bitmap |
| 756 fType = SkScalerContext_Windows::kBitmap_Type; | 757 fType = SkScalerContext_GDI::kBitmap_Type; |
| 757 | 758 |
| 758 xform.eM11 = 1.0f; | 759 xform.eM11 = 1.0f; |
| 759 xform.eM12 = 0.0f; | 760 xform.eM12 = 0.0f; |
| 760 xform.eM21 = 0.0f; | 761 xform.eM21 = 0.0f; |
| 761 xform.eM22 = 1.0f; | 762 xform.eM22 = 1.0f; |
| 762 xform.eDx = 0.0f; | 763 xform.eDx = 0.0f; |
| 763 xform.eDy = 0.0f; | 764 xform.eDy = 0.0f; |
| 764 | 765 |
| 765 // fPost2x2 is column-major, left handed (y down). | 766 // fPost2x2 is column-major, left handed (y down). |
| 766 // MAT2 is row major, right handed (y up). | 767 // MAT2 is row major, right handed (y up). |
| 767 fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]); | 768 fMat22.eM11 = SkScalarToFIXED(fRec.fPost2x2[0][0]); |
| 768 fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]); | 769 fMat22.eM12 = SkScalarToFIXED(-fRec.fPost2x2[1][0]); |
| 769 fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]); | 770 fMat22.eM21 = SkScalarToFIXED(-fRec.fPost2x2[0][1]); |
| 770 fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]); | 771 fMat22.eM22 = SkScalarToFIXED(fRec.fPost2x2[1][1]); |
| 771 } | 772 } |
| 772 | 773 |
| 773 fOffscreen.init(fFont, xform); | 774 fOffscreen.init(fFont, xform); |
| 774 } | 775 } |
| 775 | 776 |
| 776 SkScalerContext_Windows::~SkScalerContext_Windows() { | 777 SkScalerContext_GDI::~SkScalerContext_GDI() { |
| 777 if (fDDC) { | 778 if (fDDC) { |
| 778 ::SelectObject(fDDC, fSavefont); | 779 ::SelectObject(fDDC, fSavefont); |
| 779 ::DeleteDC(fDDC); | 780 ::DeleteDC(fDDC); |
| 780 } | 781 } |
| 781 if (fFont) { | 782 if (fFont) { |
| 782 ::DeleteObject(fFont); | 783 ::DeleteObject(fFont); |
| 783 } | 784 } |
| 784 if (fSC) { | 785 if (fSC) { |
| 785 ::ScriptFreeCache(&fSC); | 786 ::ScriptFreeCache(&fSC); |
| 786 } | 787 } |
| 787 } | 788 } |
| 788 | 789 |
| 789 bool SkScalerContext_Windows::isValid() const { | 790 bool SkScalerContext_GDI::isValid() const { |
| 790 return fDDC && fFont; | 791 return fDDC && fFont; |
| 791 } | 792 } |
| 792 | 793 |
| 793 unsigned SkScalerContext_Windows::generateGlyphCount() { | 794 unsigned SkScalerContext_GDI::generateGlyphCount() { |
| 794 if (fGlyphCount < 0) { | 795 if (fGlyphCount < 0) { |
| 795 fGlyphCount = calculateGlyphCount( | 796 fGlyphCount = calculateGlyphCount( |
| 796 fDDC, static_cast<const LogFontTypeface*>(this->getTyp
eface())->fLogFont); | 797 fDDC, static_cast<const LogFontTypeface*>(this->getTyp
eface())->fLogFont); |
| 797 } | 798 } |
| 798 return fGlyphCount; | 799 return fGlyphCount; |
| 799 } | 800 } |
| 800 | 801 |
| 801 uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) { | 802 uint16_t SkScalerContext_GDI::generateCharToGlyph(SkUnichar uni) { |
| 802 uint16_t index = 0; | 803 uint16_t index = 0; |
| 803 WCHAR c[2]; | 804 WCHAR c[2]; |
| 804 // TODO(ctguil): Support characters that generate more than one glyph. | 805 // TODO(ctguil): Support characters that generate more than one glyph. |
| 805 if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) { | 806 if (SkUTF16_FromUnichar(uni, (uint16_t*)c) == 1) { |
| 806 // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0. | 807 // Type1 fonts fail with uniscribe API. Use GetGlyphIndices for plane 0. |
| 807 SkAssertResult(GetGlyphIndicesW(fDDC, c, 1, &index, 0)); | 808 SkAssertResult(GetGlyphIndicesW(fDDC, c, 1, &index, 0)); |
| 808 } else { | 809 } else { |
| 809 // Use uniscribe to detemine glyph index for non-BMP characters. | 810 // Use uniscribe to detemine glyph index for non-BMP characters. |
| 810 // Need to add extra item to SCRIPT_ITEM to work around a bug in older | 811 // Need to add extra item to SCRIPT_ITEM to work around a bug in older |
| 811 // windows versions. https://bugzilla.mozilla.org/show_bug.cgi?id=366643 | 812 // windows versions. https://bugzilla.mozilla.org/show_bug.cgi?id=366643 |
| 812 SCRIPT_ITEM si[2 + 1]; | 813 SCRIPT_ITEM si[2 + 1]; |
| 813 int items; | 814 int items; |
| 814 SkAssertResult( | 815 SkAssertResult( |
| 815 SUCCEEDED(ScriptItemize(c, 2, 2, NULL, NULL, si, &items))); | 816 SUCCEEDED(ScriptItemize(c, 2, 2, NULL, NULL, si, &items))); |
| 816 | 817 |
| 817 WORD log[2]; | 818 WORD log[2]; |
| 818 SCRIPT_VISATTR vsa; | 819 SCRIPT_VISATTR vsa; |
| 819 int glyphs; | 820 int glyphs; |
| 820 SkAssertResult(SUCCEEDED(ScriptShape( | 821 SkAssertResult(SUCCEEDED(ScriptShape( |
| 821 fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs))); | 822 fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs))); |
| 822 } | 823 } |
| 823 return index; | 824 return index; |
| 824 } | 825 } |
| 825 | 826 |
| 826 void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) { | 827 void SkScalerContext_GDI::generateAdvance(SkGlyph* glyph) { |
| 827 this->generateMetrics(glyph); | 828 this->generateMetrics(glyph); |
| 828 } | 829 } |
| 829 | 830 |
| 830 void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) { | 831 void SkScalerContext_GDI::generateMetrics(SkGlyph* glyph) { |
| 831 SkASSERT(fDDC); | 832 SkASSERT(fDDC); |
| 832 | 833 |
| 833 if (fType == SkScalerContext_Windows::kBitmap_Type) { | 834 if (fType == SkScalerContext_GDI::kBitmap_Type) { |
| 834 SIZE size; | 835 SIZE size; |
| 835 WORD glyphs = glyph->getGlyphID(0); | 836 WORD glyphs = glyph->getGlyphID(0); |
| 836 if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) { | 837 if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) { |
| 837 glyph->fWidth = SkToS16(fTM.tmMaxCharWidth); | 838 glyph->fWidth = SkToS16(fTM.tmMaxCharWidth); |
| 838 } else { | 839 } else { |
| 839 glyph->fWidth = SkToS16(size.cx); | 840 glyph->fWidth = SkToS16(size.cx); |
| 840 } | 841 } |
| 841 glyph->fHeight = SkToS16(size.cy); | 842 glyph->fHeight = SkToS16(size.cy); |
| 842 | 843 |
| 843 glyph->fTop = SkToS16(-fTM.tmAscent); | 844 glyph->fTop = SkToS16(-fTM.tmAscent); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 if (GDI_ERROR != status) { | 912 if (GDI_ERROR != status) { |
| 912 SkPoint advance; | 913 SkPoint advance; |
| 913 fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIn
cY), &advance); | 914 fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIn
cY), &advance); |
| 914 glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 915 glyph->fAdvanceX = SkScalarToFixed(advance.fX); |
| 915 glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 916 glyph->fAdvanceY = SkScalarToFixed(advance.fY); |
| 916 } | 917 } |
| 917 } | 918 } |
| 918 } | 919 } |
| 919 | 920 |
| 920 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; | 921 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; |
| 921 void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
int::FontMetrics* my) { | 922 void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint:
:FontMetrics* my) { |
| 922 if (!(mx || my)) { | 923 if (!(mx || my)) { |
| 923 return; | 924 return; |
| 924 } | 925 } |
| 925 | 926 |
| 926 if (mx) { | 927 if (mx) { |
| 927 sk_bzero(mx, sizeof(*mx)); | 928 sk_bzero(mx, sizeof(*mx)); |
| 928 } | 929 } |
| 929 if (my) { | 930 if (my) { |
| 930 sk_bzero(my, sizeof(*my)); | 931 sk_bzero(my, sizeof(*my)); |
| 931 } | 932 } |
| 932 | 933 |
| 933 SkASSERT(fDDC); | 934 SkASSERT(fDDC); |
| 934 | 935 |
| 935 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS | 936 #ifndef SK_GDI_ALWAYS_USE_TEXTMETRICS_FOR_FONT_METRICS |
| 936 if (fType == SkScalerContext_Windows::kBitmap_Type) { | 937 if (fType == SkScalerContext_GDI::kBitmap_Type) { |
| 937 #endif | 938 #endif |
| 938 if (mx) { | 939 if (mx) { |
| 939 mx->fTop = SkIntToScalar(-fTM.tmAscent); | 940 mx->fTop = SkIntToScalar(-fTM.tmAscent); |
| 940 mx->fAscent = SkIntToScalar(-fTM.tmAscent); | 941 mx->fAscent = SkIntToScalar(-fTM.tmAscent); |
| 941 mx->fDescent = SkIntToScalar(fTM.tmDescent); | 942 mx->fDescent = SkIntToScalar(fTM.tmDescent); |
| 942 mx->fBottom = SkIntToScalar(fTM.tmDescent); | 943 mx->fBottom = SkIntToScalar(fTM.tmDescent); |
| 943 mx->fLeading = SkIntToScalar(fTM.tmExternalLeading); | 944 mx->fLeading = SkIntToScalar(fTM.tmExternalLeading); |
| 944 } | 945 } |
| 945 | 946 |
| 946 if (my) { | 947 if (my) { |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1245 src = SkTAddOffset<const SkGdiRGB>(src, srcRB); | 1246 src = SkTAddOffset<const SkGdiRGB>(src, srcRB); |
| 1246 dst = (uint32_t*)((char*)dst - dstRB); | 1247 dst = (uint32_t*)((char*)dst - dstRB); |
| 1247 } | 1248 } |
| 1248 } | 1249 } |
| 1249 | 1250 |
| 1250 static inline unsigned clamp255(unsigned x) { | 1251 static inline unsigned clamp255(unsigned x) { |
| 1251 SkASSERT(x <= 256); | 1252 SkASSERT(x <= 256); |
| 1252 return x - (x >> 8); | 1253 return x - (x >> 8); |
| 1253 } | 1254 } |
| 1254 | 1255 |
| 1255 void SkScalerContext_Windows::generateImage(const SkGlyph& glyph) { | 1256 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) { |
| 1256 SkASSERT(fDDC); | 1257 SkASSERT(fDDC); |
| 1257 | 1258 |
| 1258 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | 1259 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; |
| 1259 const bool isAA = !isLCD(fRec); | 1260 const bool isAA = !isLCD(fRec); |
| 1260 | 1261 |
| 1261 size_t srcRB; | 1262 size_t srcRB; |
| 1262 const void* bits = fOffscreen.draw(glyph, isBW, &srcRB); | 1263 const void* bits = fOffscreen.draw(glyph, isBW, &srcRB); |
| 1263 if (NULL == bits) { | 1264 if (NULL == bits) { |
| 1264 LogFontTypeface::EnsureAccessible(this->getTypeface()); | 1265 LogFontTypeface::EnsureAccessible(this->getTypeface()); |
| 1265 bits = fOffscreen.draw(glyph, isBW, &srcRB); | 1266 bits = fOffscreen.draw(glyph, isBW, &srcRB); |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 } | 1596 } |
| 1596 } | 1597 } |
| 1597 // Advance past this TTPOLYCURVE. | 1598 // Advance past this TTPOLYCURVE. |
| 1598 cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; | 1599 cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; |
| 1599 } | 1600 } |
| 1600 cur_glyph += th->cb; | 1601 cur_glyph += th->cb; |
| 1601 path->close(); | 1602 path->close(); |
| 1602 } | 1603 } |
| 1603 } | 1604 } |
| 1604 | 1605 |
| 1605 DWORD SkScalerContext_Windows::getGDIGlyphPath(const SkGlyph& glyph, UINT flags, | 1606 DWORD SkScalerContext_GDI::getGDIGlyphPath(const SkGlyph& glyph, UINT flags, |
| 1606 SkAutoSTMalloc<BUFFERSIZE, uint8_
t>* glyphbuf) | 1607 SkAutoSTMalloc<BUFFERSIZE, uint8_
t>* glyphbuf) |
| 1607 { | 1608 { |
| 1608 GLYPHMETRICS gm; | 1609 GLYPHMETRICS gm; |
| 1609 | 1610 |
| 1610 DWORD total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, BUFFERSIZE,
glyphbuf->get(), &fMat22); | 1611 DWORD total_size = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, BUFFERSIZE,
glyphbuf->get(), &fMat22); |
| 1611 // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even i
f BUFFERSIZE > 0. | 1612 // Sometimes GetGlyphOutlineW returns a number larger than BUFFERSIZE even i
f BUFFERSIZE > 0. |
| 1612 // It has been verified that this does not involve a buffer overrun. | 1613 // It has been verified that this does not involve a buffer overrun. |
| 1613 if (GDI_ERROR == total_size || total_size > BUFFERSIZE) { | 1614 if (GDI_ERROR == total_size || total_size > BUFFERSIZE) { |
| 1614 // GDI_ERROR because the BUFFERSIZE was too small, or because the data w
as not accessible. | 1615 // GDI_ERROR because the BUFFERSIZE was too small, or because the data w
as not accessible. |
| 1615 // When the data is not accessable GetGlyphOutlineW fails rather quickly
, | 1616 // When the data is not accessable GetGlyphOutlineW fails rather quickly
, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1632 ret = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, total_size, glyp
hbuf->get(), &fMat22); | 1633 ret = GetGlyphOutlineW(fDDC, glyph.fID, flags, &gm, total_size, glyp
hbuf->get(), &fMat22); |
| 1633 if (GDI_ERROR == ret) { | 1634 if (GDI_ERROR == ret) { |
| 1634 SkASSERT(false); | 1635 SkASSERT(false); |
| 1635 return 0; | 1636 return 0; |
| 1636 } | 1637 } |
| 1637 } | 1638 } |
| 1638 } | 1639 } |
| 1639 return total_size; | 1640 return total_size; |
| 1640 } | 1641 } |
| 1641 | 1642 |
| 1642 void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) { | 1643 void SkScalerContext_GDI::generatePath(const SkGlyph& glyph, SkPath* path) { |
| 1643 SkASSERT(&glyph && path); | 1644 SkASSERT(&glyph && path); |
| 1644 SkASSERT(fDDC); | 1645 SkASSERT(fDDC); |
| 1645 | 1646 |
| 1646 path->reset(); | 1647 path->reset(); |
| 1647 | 1648 |
| 1648 // Out of all the fonts on a typical Windows box, | 1649 // Out of all the fonts on a typical Windows box, |
| 1649 // 25% of glyphs require more than 2KB. | 1650 // 25% of glyphs require more than 2KB. |
| 1650 // 1% of glyphs require more than 4KB. | 1651 // 1% of glyphs require more than 4KB. |
| 1651 // 0.01% of glyphs require more than 8KB. | 1652 // 0.01% of glyphs require more than 8KB. |
| 1652 // 8KB is less than 1% of the normal 1MB stack on Windows. | 1653 // 8KB is less than 1% of the normal 1MB stack on Windows. |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1977 return NULL; | 1978 return NULL; |
| 1978 } | 1979 } |
| 1979 | 1980 |
| 1980 // Create the typeface. | 1981 // Create the typeface. |
| 1981 LOGFONT lf; | 1982 LOGFONT lf; |
| 1982 logfont_for_name(familyName, &lf); | 1983 logfont_for_name(familyName, &lf); |
| 1983 | 1984 |
| 1984 return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference); | 1985 return SkCreateFontMemResourceTypefaceFromLOGFONT(lf, fontReference); |
| 1985 } | 1986 } |
| 1986 | 1987 |
| 1987 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { | |
| 1988 return create_from_stream(stream); | |
| 1989 } | |
| 1990 | |
| 1991 SkStream* LogFontTypeface::onOpenStream(int* ttcIndex) const { | 1988 SkStream* LogFontTypeface::onOpenStream(int* ttcIndex) const { |
| 1992 *ttcIndex = 0; | 1989 *ttcIndex = 0; |
| 1993 | 1990 |
| 1994 const DWORD kTTCTag = | 1991 const DWORD kTTCTag = |
| 1995 SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f')); | 1992 SkEndian_SwapBE32(SkSetFourByteTag('t', 't', 'c', 'f')); |
| 1996 LOGFONT lf = fLogFont; | 1993 LOGFONT lf = fLogFont; |
| 1997 | 1994 |
| 1998 HDC hdc = ::CreateCompatibleDC(NULL); | 1995 HDC hdc = ::CreateCompatibleDC(NULL); |
| 1999 HFONT font = CreateFontIndirect(&lf); | 1996 HFONT font = CreateFontIndirect(&lf); |
| 2000 HFONT savefont = (HFONT)SelectObject(hdc, font); | 1997 HFONT savefont = (HFONT)SelectObject(hdc, font); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2047 unsigned int upem = calculateUPEM(hdc, fLogFont); | 2044 unsigned int upem = calculateUPEM(hdc, fLogFont); |
| 2048 | 2045 |
| 2049 SelectObject(hdc, savefont); | 2046 SelectObject(hdc, savefont); |
| 2050 DeleteObject(font); | 2047 DeleteObject(font); |
| 2051 DeleteDC(hdc); | 2048 DeleteDC(hdc); |
| 2052 | 2049 |
| 2053 return upem; | 2050 return upem; |
| 2054 } | 2051 } |
| 2055 | 2052 |
| 2056 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc
) const { | 2053 SkScalerContext* LogFontTypeface::onCreateScalerContext(const SkDescriptor* desc
) const { |
| 2057 SkScalerContext_Windows* ctx = SkNEW_ARGS(SkScalerContext_Windows, | 2054 SkScalerContext_GDI* ctx = SkNEW_ARGS(SkScalerContext_GDI, |
| 2058 (const_cast<LogFontTypeface*>(th
is), desc)); | 2055 (const_cast<LogFontTypeface*>(th
is), desc)); |
| 2059 if (!ctx->isValid()) { | 2056 if (!ctx->isValid()) { |
| 2060 SkDELETE(ctx); | 2057 SkDELETE(ctx); |
| 2061 ctx = NULL; | 2058 ctx = NULL; |
| 2062 } | 2059 } |
| 2063 return ctx; | 2060 return ctx; |
| 2064 } | 2061 } |
| 2065 | 2062 |
| 2066 /** Return the closest matching typeface given either an existing family | |
| 2067 (specified by a typeface in that family) or by a familyName, and a | |
| 2068 requested style. | |
| 2069 1) If familyFace is null, use familyName. | |
| 2070 2) If familyName is null, use familyFace. | |
| 2071 3) If both are null, return the default font that best matches style | |
| 2072 This MUST not return NULL. | |
| 2073 */ | |
| 2074 | |
| 2075 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, | |
| 2076 const char familyName[], | |
| 2077 SkTypeface::Style style) { | |
| 2078 LOGFONT lf; | |
| 2079 if (NULL == familyFace && NULL == familyName) { | |
| 2080 lf = get_default_font(); | |
| 2081 } else if (familyFace) { | |
| 2082 LogFontTypeface* face = (LogFontTypeface*)familyFace; | |
| 2083 lf = face->fLogFont; | |
| 2084 } else { | |
| 2085 logfont_for_name(familyName, &lf); | |
| 2086 } | |
| 2087 setStyle(&lf, style); | |
| 2088 return SkCreateTypefaceFromLOGFONT(lf); | |
| 2089 } | |
| 2090 | |
| 2091 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { | |
| 2092 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | |
| 2093 return stream.get() ? CreateTypefaceFromStream(stream) : NULL; | |
| 2094 } | |
| 2095 | |
| 2096 void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const { | 2063 void LogFontTypeface::onFilterRec(SkScalerContextRec* rec) const { |
| 2097 if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag || | 2064 if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag || |
| 2098 rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) | 2065 rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) |
| 2099 { | 2066 { |
| 2100 rec->fMaskFormat = SkMask::kA8_Format; | 2067 rec->fMaskFormat = SkMask::kA8_Format; |
| 2101 rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag; | 2068 rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag; |
| 2102 } | 2069 } |
| 2103 | 2070 |
| 2104 unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag | | 2071 unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag | |
| 2105 SkScalerContext::kAutohinting_Flag | | 2072 SkScalerContext::kAutohinting_Flag | |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2140 rec->fMaskFormat = SkMask::kA8_Format; | 2107 rec->fMaskFormat = SkMask::kA8_Format; |
| 2141 } | 2108 } |
| 2142 #endif | 2109 #endif |
| 2143 | 2110 |
| 2144 if (!fCanBeLCD && isLCD(*rec)) { | 2111 if (!fCanBeLCD && isLCD(*rec)) { |
| 2145 rec->fMaskFormat = SkMask::kA8_Format; | 2112 rec->fMaskFormat = SkMask::kA8_Format; |
| 2146 rec->fFlags &= ~SkScalerContext::kGenA8FromLCD_Flag; | 2113 rec->fFlags &= ~SkScalerContext::kGenA8FromLCD_Flag; |
| 2147 } | 2114 } |
| 2148 } | 2115 } |
| 2149 | 2116 |
| 2117 static SkTypeface* create_typeface(const SkTypeface* familyFace, |
| 2118 const char familyName[], |
| 2119 unsigned styleBits) { |
| 2120 LOGFONT lf; |
| 2121 if (NULL == familyFace && NULL == familyName) { |
| 2122 lf = get_default_font(); |
| 2123 } else if (familyFace) { |
| 2124 LogFontTypeface* face = (LogFontTypeface*)familyFace; |
| 2125 lf = face->fLogFont; |
| 2126 } else { |
| 2127 logfont_for_name(familyName, &lf); |
| 2128 } |
| 2129 setStyle(&lf, (SkTypeface::Style)styleBits); |
| 2130 return SkCreateTypefaceFromLOGFONT(lf); |
| 2131 } |
| 2132 |
| 2133 SkTypeface* LogFontTypeface::onRefMatchingStyle(Style style) const { |
| 2134 return create_typeface(this, NULL, style); |
| 2135 } |
| 2136 |
| 2150 /////////////////////////////////////////////////////////////////////////////// | 2137 /////////////////////////////////////////////////////////////////////////////// |
| 2151 | 2138 |
| 2152 #include "SkFontMgr.h" | 2139 #include "SkFontMgr.h" |
| 2153 #include "SkDataTable.h" | 2140 #include "SkDataTable.h" |
| 2154 | 2141 |
| 2155 static bool valid_logfont_for_enum(const LOGFONT& lf, DWORD fontType) { | 2142 static bool valid_logfont_for_enum(const LOGFONT& lf, DWORD fontType) { |
| 2156 return TRUETYPE_FONTTYPE == fontType | 2143 return TRUETYPE_FONTTYPE == fontType |
| 2157 && lf.lfFaceName[0] | 2144 && lf.lfFaceName[0] |
| 2158 && lf.lfFaceName[0] != '@' | 2145 && lf.lfFaceName[0] != '@' |
| 2159 && OUT_STROKE_PRECIS == lf.lfOutPrecision | 2146 && OUT_STROKE_PRECIS == lf.lfOutPrecision |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2307 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data))); | 2294 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data))); |
| 2308 return this->createFromStream(stream); | 2295 return this->createFromStream(stream); |
| 2309 } | 2296 } |
| 2310 | 2297 |
| 2311 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVE
RRIDE { | 2298 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVE
RRIDE { |
| 2312 // could be in base impl | 2299 // could be in base impl |
| 2313 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); | 2300 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
| 2314 return this->createFromStream(stream); | 2301 return this->createFromStream(stream); |
| 2315 } | 2302 } |
| 2316 | 2303 |
| 2304 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], |
| 2305 unsigned styleBits) SK_OVERRIDE { |
| 2306 return create_typeface(NULL, familyName, styleBits); |
| 2307 } |
| 2308 |
| 2317 private: | 2309 private: |
| 2318 SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 2310 SkTDArray<ENUMLOGFONTEX> fLogFontArray; |
| 2319 }; | 2311 }; |
| 2320 | 2312 |
| 2313 /////////////////////////////////////////////////////////////////////////////// |
| 2314 |
| 2315 #ifndef SK_FONTHOST_USES_FONTMGR |
| 2316 |
| 2317 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, |
| 2318 const char familyName[], |
| 2319 SkTypeface::Style style) { |
| 2320 return create_typeface(familyFace, familyName, styleBits); |
| 2321 } |
| 2322 |
| 2323 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { |
| 2324 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
| 2325 return stream.get() ? CreateTypefaceFromStream(stream) : NULL; |
| 2326 } |
| 2327 |
| 2328 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { |
| 2329 return create_from_stream(stream); |
| 2330 } |
| 2331 |
| 2332 #endif |
| 2333 |
| 2321 SkFontMgr* SkFontMgr::Factory() { | 2334 SkFontMgr* SkFontMgr::Factory() { |
| 2322 return SkNEW(SkFontMgrGDI); | 2335 return SkNEW(SkFontMgrGDI); |
| 2323 } | 2336 } |
| OLD | NEW |