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 |