OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
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 "SkTypes.h" | 8 #include "SkTypes.h" |
9 #undef GetGlyphIndices | 9 #undef GetGlyphIndices |
10 | 10 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE; | 116 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE; |
117 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE; | 117 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE; |
118 | 118 |
119 private: | 119 private: |
120 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr; | 120 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr; |
121 SkTScopedComPtr<IDWriteFontFamily> fFontFamily; | 121 SkTScopedComPtr<IDWriteFontFamily> fFontFamily; |
122 }; | 122 }; |
123 | 123 |
124 /////////////////////////////////////////////////////////////////////////////// | 124 /////////////////////////////////////////////////////////////////////////////// |
125 | 125 |
126 class DWriteOffscreen { | |
127 public: | |
128 DWriteOffscreen() : fWidth(0), fHeight(0) { } | |
129 | |
130 void init(IDWriteFactory* factory, IDWriteFontFace* fontFace, | |
131 const DWRITE_MATRIX& xform, FLOAT fontSize) | |
132 { | |
133 fFactory = factory; | |
134 fFontFace = fontFace; | |
135 fFontSize = fontSize; | |
136 fXform = xform; | |
137 } | |
138 | |
139 const void* draw(const SkGlyph&, bool isBW); | |
140 | |
141 private: | |
142 uint16_t fWidth; | |
143 uint16_t fHeight; | |
144 IDWriteFactory* fFactory; | |
145 IDWriteFontFace* fFontFace; | |
146 FLOAT fFontSize; | |
147 DWRITE_MATRIX fXform; | |
148 SkTDArray<uint8_t> fBits; | |
149 }; | |
150 | |
151 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) { | |
152 if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) { | |
153 fWidth = SkMax32(fWidth, glyph.fWidth); | |
154 fHeight = SkMax32(fHeight, glyph.fHeight); | |
155 | |
156 if (isBW) { | |
157 fBits.setCount(fWidth * fHeight); | |
158 } else { | |
159 fBits.setCount(fWidth * fHeight * 3); | |
160 } | |
161 } | |
162 | |
163 // erase | |
164 memset(fBits.begin(), 0, fBits.count()); | |
165 | |
166 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); | |
167 fXform.dy = SkFixedToFloat(glyph.getSubYFixed()); | |
168 | |
169 FLOAT advance = 0.0f; | |
170 | |
171 UINT16 index = glyph.getGlyphID(); | |
172 | |
173 DWRITE_GLYPH_OFFSET offset; | |
174 offset.advanceOffset = 0.0f; | |
175 offset.ascenderOffset = 0.0f; | |
176 | |
177 DWRITE_GLYPH_RUN run; | |
178 run.glyphCount = 1; | |
179 run.glyphAdvances = &advance; | |
180 run.fontFace = fFontFace; | |
181 run.fontEmSize = fFontSize; | |
182 run.bidiLevel = 0; | |
183 run.glyphIndices = &index; | |
184 run.isSideways = FALSE; | |
185 run.glyphOffsets = &offset; | |
186 | |
187 DWRITE_RENDERING_MODE renderingMode; | |
188 DWRITE_TEXTURE_TYPE textureType; | |
189 if (isBW) { | |
190 renderingMode = DWRITE_RENDERING_MODE_ALIASED; | |
191 textureType = DWRITE_TEXTURE_ALIASED_1x1; | |
192 } else { | |
193 renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | |
194 textureType = DWRITE_TEXTURE_CLEARTYPE_3x1; | |
195 } | |
196 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | |
197 HRNM(fFactory->CreateGlyphRunAnalysis(&run, | |
198 1.0f, // pixelsPerDip, | |
199 &fXform, | |
200 renderingMode, | |
201 DWRITE_MEASURING_MODE_NATURAL, | |
202 0.0f, // baselineOriginX, | |
203 0.0f, // baselineOriginY, | |
204 &glyphRunAnalysis), | |
205 "Could not create glyph run analysis."); | |
206 | |
207 //NOTE: this assumes that the glyph has already been measured | |
208 //with an exact same glyph run analysis. | |
209 RECT bbox; | |
210 bbox.left = glyph.fLeft; | |
211 bbox.top = glyph.fTop; | |
212 bbox.right = glyph.fLeft + glyph.fWidth; | |
213 bbox.bottom = glyph.fTop + glyph.fHeight; | |
214 HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType, | |
215 &bbox, | |
216 fBits.begin(), | |
217 fBits.count()), | |
218 "Could not draw mask."); | |
219 return fBits.begin(); | |
220 } | |
221 | |
222 /////////////////////////////////////////////////////////////////////////////// | |
223 | |
224 class StreamFontFileLoader : public IDWriteFontFileLoader { | 126 class StreamFontFileLoader : public IDWriteFontFileLoader { |
225 public: | 127 public: |
226 // IUnknown methods | 128 // IUnknown methods |
227 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); | 129 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); |
228 virtual ULONG STDMETHODCALLTYPE AddRef(); | 130 virtual ULONG STDMETHODCALLTYPE AddRef(); |
229 virtual ULONG STDMETHODCALLTYPE Release(); | 131 virtual ULONG STDMETHODCALLTYPE Release(); |
230 | 132 |
231 // IDWriteFontFileLoader methods | 133 // IDWriteFontFileLoader methods |
232 virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey( | 134 virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey( |
233 void const* fontFileReferenceKey, | 135 void const* fontFileReferenceKey, |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 virtual unsigned generateGlyphCount() SK_OVERRIDE; | 439 virtual unsigned generateGlyphCount() SK_OVERRIDE; |
538 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; | 440 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; |
539 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; | 441 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE; |
540 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; | 442 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; |
541 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; | 443 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; |
542 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; | 444 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; |
543 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, | 445 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, |
544 SkPaint::FontMetrics* mY) SK_OVERRIDE; | 446 SkPaint::FontMetrics* mY) SK_OVERRIDE; |
545 | 447 |
546 private: | 448 private: |
547 DWriteOffscreen fOffscreen; | 449 const void* drawDWMask(const SkGlyph& glyph); |
| 450 |
| 451 SkTDArray<uint8_t> fBits; |
548 DWRITE_MATRIX fXform; | 452 DWRITE_MATRIX fXform; |
549 SkAutoTUnref<DWriteFontTypeface> fTypeface; | 453 SkAutoTUnref<DWriteFontTypeface> fTypeface; |
550 int fGlyphCount; | 454 int fGlyphCount; |
| 455 DWRITE_RENDERING_MODE fRenderingMode; |
| 456 DWRITE_TEXTURE_TYPE fTextureType; |
| 457 DWRITE_MEASURING_MODE fMeasuringMode; |
551 }; | 458 }; |
552 | 459 |
553 static bool are_same(IUnknown* a, IUnknown* b) { | 460 static bool are_same(IUnknown* a, IUnknown* b) { |
554 SkTScopedComPtr<IUnknown> iunkA; | 461 SkTScopedComPtr<IUnknown> iunkA; |
555 if (FAILED(a->QueryInterface(&iunkA))) { | 462 if (FAILED(a->QueryInterface(&iunkA))) { |
556 return false; | 463 return false; |
557 } | 464 } |
558 | 465 |
559 SkTScopedComPtr<IUnknown> iunkB; | 466 SkTScopedComPtr<IUnknown> iunkB; |
560 if (FAILED(b->QueryInterface(&iunkB))) { | 467 if (FAILED(b->QueryInterface(&iunkB))) { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 , fTypeface(SkRef(typeface)) | 576 , fTypeface(SkRef(typeface)) |
670 , fGlyphCount(-1) { | 577 , fGlyphCount(-1) { |
671 | 578 |
672 fXform.m11 = SkScalarToFloat(fRec.fPost2x2[0][0]); | 579 fXform.m11 = SkScalarToFloat(fRec.fPost2x2[0][0]); |
673 fXform.m12 = SkScalarToFloat(fRec.fPost2x2[1][0]); | 580 fXform.m12 = SkScalarToFloat(fRec.fPost2x2[1][0]); |
674 fXform.m21 = SkScalarToFloat(fRec.fPost2x2[0][1]); | 581 fXform.m21 = SkScalarToFloat(fRec.fPost2x2[0][1]); |
675 fXform.m22 = SkScalarToFloat(fRec.fPost2x2[1][1]); | 582 fXform.m22 = SkScalarToFloat(fRec.fPost2x2[1][1]); |
676 fXform.dx = 0; | 583 fXform.dx = 0; |
677 fXform.dy = 0; | 584 fXform.dy = 0; |
678 | 585 |
679 fOffscreen.init(fTypeface->fFactory.get(), fTypeface->fDWriteFontFace.get(), | 586 if (SkMask::kBW_Format == fRec.fMaskFormat) { |
680 fXform, SkScalarToFloat(fRec.fTextSize)); | 587 fRenderingMode = DWRITE_RENDERING_MODE_ALIASED; |
| 588 fTextureType = DWRITE_TEXTURE_ALIASED_1x1; |
| 589 fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC; |
| 590 } else { |
| 591 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; |
| 592 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; |
| 593 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| 594 } |
| 595 |
| 596 if (this->isSubpixel()) { |
| 597 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; |
| 598 } |
681 } | 599 } |
682 | 600 |
683 SkScalerContext_DW::~SkScalerContext_DW() { | 601 SkScalerContext_DW::~SkScalerContext_DW() { |
684 } | 602 } |
685 | 603 |
686 unsigned SkScalerContext_DW::generateGlyphCount() { | 604 unsigned SkScalerContext_DW::generateGlyphCount() { |
687 if (fGlyphCount < 0) { | 605 if (fGlyphCount < 0) { |
688 fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount(); | 606 fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount(); |
689 } | 607 } |
690 return fGlyphCount; | 608 return fGlyphCount; |
(...skipping 10 matching lines...) Expand all Loading... |
701 //and where the right/left side bearing ends up after hinting. | 619 //and where the right/left side bearing ends up after hinting. |
702 //DirectWrite does not provide this information. | 620 //DirectWrite does not provide this information. |
703 glyph->fRsbDelta = 0; | 621 glyph->fRsbDelta = 0; |
704 glyph->fLsbDelta = 0; | 622 glyph->fLsbDelta = 0; |
705 | 623 |
706 glyph->fAdvanceX = 0; | 624 glyph->fAdvanceX = 0; |
707 glyph->fAdvanceY = 0; | 625 glyph->fAdvanceY = 0; |
708 | 626 |
709 uint16_t glyphId = glyph->getGlyphID(); | 627 uint16_t glyphId = glyph->getGlyphID(); |
710 DWRITE_GLYPH_METRICS gm; | 628 DWRITE_GLYPH_METRICS gm; |
711 HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm), | 629 |
712 "Could not get design metrics."); | 630 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || |
| 631 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) |
| 632 { |
| 633 HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics( |
| 634 fRec.fTextSize, |
| 635 1.0f, // pixelsPerDip |
| 636 &fXform, |
| 637 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode, |
| 638 &glyphId, 1, |
| 639 &gm), |
| 640 "Could not get gdi compatible glyph metrics."); |
| 641 } else { |
| 642 HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm)
, |
| 643 "Could not get design metrics."); |
| 644 } |
713 | 645 |
714 DWRITE_FONT_METRICS dwfm; | 646 DWRITE_FONT_METRICS dwfm; |
715 fTypeface->fDWriteFontFace->GetMetrics(&dwfm); | 647 fTypeface->fDWriteFontFace->GetMetrics(&dwfm); |
716 | |
717 SkScalar advanceX = SkScalarMulDiv(fRec.fTextSize, | 648 SkScalar advanceX = SkScalarMulDiv(fRec.fTextSize, |
718 SkIntToScalar(gm.advanceWidth), | 649 SkIntToScalar(gm.advanceWidth), |
719 SkIntToScalar(dwfm.designUnitsPerEm)); | 650 SkIntToScalar(dwfm.designUnitsPerEm)); |
720 | 651 |
721 if (!(fRec.fFlags & kSubpixelPositioning_Flag)) { | 652 if (!this->isSubpixel()) { |
722 advanceX = SkScalarRoundToScalar(advanceX); | 653 advanceX = SkScalarRoundToScalar(advanceX); |
723 } | 654 } |
724 | 655 |
725 SkVector vecs[1] = { { advanceX, 0 } }; | 656 SkVector vecs[1] = { { advanceX, 0 } }; |
726 SkMatrix mat; | 657 SkMatrix mat; |
727 fRec.getMatrixFrom2x2(&mat); | 658 fRec.getMatrixFrom2x2(&mat); |
728 mat.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); | 659 mat.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); |
729 | 660 |
730 glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX); | 661 glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX); |
731 glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); | 662 glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); |
(...skipping 19 matching lines...) Expand all Loading... |
751 DWRITE_GLYPH_RUN run; | 682 DWRITE_GLYPH_RUN run; |
752 run.glyphCount = 1; | 683 run.glyphCount = 1; |
753 run.glyphAdvances = &advance; | 684 run.glyphAdvances = &advance; |
754 run.fontFace = fTypeface->fDWriteFontFace.get(); | 685 run.fontFace = fTypeface->fDWriteFontFace.get(); |
755 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); | 686 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); |
756 run.bidiLevel = 0; | 687 run.bidiLevel = 0; |
757 run.glyphIndices = &glyphId; | 688 run.glyphIndices = &glyphId; |
758 run.isSideways = FALSE; | 689 run.isSideways = FALSE; |
759 run.glyphOffsets = &offset; | 690 run.glyphOffsets = &offset; |
760 | 691 |
761 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | |
762 DWRITE_RENDERING_MODE renderingMode; | |
763 DWRITE_TEXTURE_TYPE textureType; | |
764 if (isBW) { | |
765 renderingMode = DWRITE_RENDERING_MODE_ALIASED; | |
766 textureType = DWRITE_TEXTURE_ALIASED_1x1; | |
767 } else { | |
768 renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | |
769 textureType = DWRITE_TEXTURE_CLEARTYPE_3x1; | |
770 } | |
771 | |
772 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; | 692 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
773 HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( | 693 HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( |
774 &run, | 694 &run, |
775 1.0f, // pixelsPerDip, | 695 1.0f, // pixelsPerDip, |
776 &fXform, | 696 &fXform, |
777 renderingMode, | 697 fRenderingMode, |
778 DWRITE_MEASURING_MODE_NATURAL, | 698 fMeasuringMode, |
779 0.0f, // baselineOriginX, | 699 0.0f, // baselineOriginX, |
780 0.0f, // baselineOriginY, | 700 0.0f, // baselineOriginY, |
781 &glyphRunAnalysis), | 701 &glyphRunAnalysis), |
782 "Could not create glyph run analysis."); | 702 "Could not create glyph run analysis."); |
783 | 703 |
784 RECT bbox; | 704 RECT bbox; |
785 HRVM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, &bbox), | 705 HRVM(glyphRunAnalysis->GetAlphaTextureBounds(fTextureType, &bbox), |
786 "Could not get texture bounds."); | 706 "Could not get texture bounds."); |
787 | 707 |
788 glyph->fWidth = SkToU16(bbox.right - bbox.left); | 708 glyph->fWidth = SkToU16(bbox.right - bbox.left); |
789 glyph->fHeight = SkToU16(bbox.bottom - bbox.top); | 709 glyph->fHeight = SkToU16(bbox.bottom - bbox.top); |
790 glyph->fLeft = SkToS16(bbox.left); | 710 glyph->fLeft = SkToS16(bbox.left); |
791 glyph->fTop = SkToS16(bbox.top); | 711 glyph->fTop = SkToS16(bbox.top); |
792 } | 712 } |
793 | 713 |
794 void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx, | 714 void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx, |
795 SkPaint::FontMetrics* my) { | 715 SkPaint::FontMetrics* my) { |
796 if (!(mx || my)) | 716 if (!(mx || my)) |
797 return; | 717 return; |
798 | 718 |
799 if (mx) { | 719 if (mx) { |
800 sk_bzero(mx, sizeof(*mx)); | 720 sk_bzero(mx, sizeof(*mx)); |
801 } | 721 } |
802 if (my) { | 722 if (my) { |
803 sk_bzero(my, sizeof(*my)); | 723 sk_bzero(my, sizeof(*my)); |
804 } | 724 } |
805 | 725 |
806 DWRITE_FONT_METRICS dwfm; | 726 DWRITE_FONT_METRICS dwfm; |
807 fTypeface->fDWriteFontFace->GetMetrics(&dwfm); | 727 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || |
| 728 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) |
| 729 { |
| 730 fTypeface->fDWriteFontFace->GetGdiCompatibleMetrics( |
| 731 fRec.fTextSize, |
| 732 1.0f, // pixelsPerDip |
| 733 &fXform, |
| 734 &dwfm); |
| 735 } else { |
| 736 fTypeface->fDWriteFontFace->GetMetrics(&dwfm); |
| 737 } |
808 | 738 |
809 SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm); | 739 SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm); |
810 if (mx) { | 740 if (mx) { |
811 mx->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem; | 741 mx->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem; |
812 mx->fAscent = mx->fTop; | 742 mx->fAscent = mx->fTop; |
813 mx->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem; | 743 mx->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem; |
814 mx->fBottom = mx->fDescent; | 744 mx->fBottom = mx->fDescent; |
815 mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem; | 745 mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem; |
816 mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem; | 746 mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem; |
817 mx->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlineP
osition) / upem; | 747 mx->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlineP
osition) / upem; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
924 for (U16CPU i = 0; i < width; i++) { | 854 for (U16CPU i = 0; i < width; i++) { |
925 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); | 855 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR); |
926 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); | 856 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG); |
927 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); | 857 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB); |
928 dst[i] = SkPackARGB32(0xFF, r, g, b); | 858 dst[i] = SkPackARGB32(0xFF, r, g, b); |
929 } | 859 } |
930 dst = (SkPMColor*)((char*)dst + dstRB); | 860 dst = (SkPMColor*)((char*)dst + dstRB); |
931 } | 861 } |
932 } | 862 } |
933 | 863 |
| 864 const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) { |
| 865 int sizeNeeded = glyph.fWidth * glyph.fHeight; |
| 866 if (DWRITE_RENDERING_MODE_ALIASED != fRenderingMode) { |
| 867 sizeNeeded *= 3; |
| 868 } |
| 869 if (sizeNeeded > fBits.count()) { |
| 870 fBits.setCount(sizeNeeded); |
| 871 } |
| 872 |
| 873 // erase |
| 874 memset(fBits.begin(), 0, sizeNeeded); |
| 875 |
| 876 fXform.dx = SkFixedToFloat(glyph.getSubXFixed()); |
| 877 fXform.dy = SkFixedToFloat(glyph.getSubYFixed()); |
| 878 |
| 879 FLOAT advance = 0.0f; |
| 880 |
| 881 UINT16 index = glyph.getGlyphID(); |
| 882 |
| 883 DWRITE_GLYPH_OFFSET offset; |
| 884 offset.advanceOffset = 0.0f; |
| 885 offset.ascenderOffset = 0.0f; |
| 886 |
| 887 DWRITE_GLYPH_RUN run; |
| 888 run.glyphCount = 1; |
| 889 run.glyphAdvances = &advance; |
| 890 run.fontFace = fTypeface->fDWriteFontFace.get(); |
| 891 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); |
| 892 run.bidiLevel = 0; |
| 893 run.glyphIndices = &index; |
| 894 run.isSideways = FALSE; |
| 895 run.glyphOffsets = &offset; |
| 896 |
| 897 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; |
| 898 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, |
| 899 1.0f, // pixelsPerDip, |
| 900 &fXform, |
| 901 fRenderingMode, |
| 902 fMeasuringMode, |
| 903 0.0f, // baselineOriginX, |
| 904 0.0f, // baselineOriginY, |
| 905 &glyphRunAnalysis), |
| 906 "Could not create glyph run analysis."); |
| 907 |
| 908 //NOTE: this assumes that the glyph has already been measured |
| 909 //with an exact same glyph run analysis. |
| 910 RECT bbox; |
| 911 bbox.left = glyph.fLeft; |
| 912 bbox.top = glyph.fTop; |
| 913 bbox.right = glyph.fLeft + glyph.fWidth; |
| 914 bbox.bottom = glyph.fTop + glyph.fHeight; |
| 915 HRNM(glyphRunAnalysis->CreateAlphaTexture(fTextureType, |
| 916 &bbox, |
| 917 fBits.begin(), |
| 918 sizeNeeded), |
| 919 "Could not draw mask."); |
| 920 return fBits.begin(); |
| 921 } |
| 922 |
934 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { | 923 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) { |
935 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | |
936 const bool isAA = !isLCD(fRec); | |
937 | |
938 //Create the mask. | 924 //Create the mask. |
939 const void* bits = fOffscreen.draw(glyph, isBW); | 925 const void* bits = this->drawDWMask(glyph); |
940 if (!bits) { | 926 if (!bits) { |
941 sk_bzero(glyph.fImage, glyph.computeImageSize()); | 927 sk_bzero(glyph.fImage, glyph.computeImageSize()); |
942 return; | 928 return; |
943 } | 929 } |
944 | 930 |
945 //Copy the mask into the glyph. | 931 //Copy the mask into the glyph. |
946 const uint8_t* src = (const uint8_t*)bits; | 932 const uint8_t* src = (const uint8_t*)bits; |
947 if (isBW) { | 933 if (DWRITE_RENDERING_MODE_ALIASED == fRenderingMode) { |
948 bilevel_to_bw(src, glyph); | 934 bilevel_to_bw(src, glyph); |
949 } else if (isAA) { | 935 ((SkGlyph*)&glyph)->fMaskFormat = SkMask::kBW_Format; |
| 936 } else if (!isLCD(fRec)) { |
950 if (fPreBlend.isApplicable()) { | 937 if (fPreBlend.isApplicable()) { |
951 rgb_to_a8<true>(src, glyph, fPreBlend.fG); | 938 rgb_to_a8<true>(src, glyph, fPreBlend.fG); |
952 } else { | 939 } else { |
953 rgb_to_a8<false>(src, glyph, fPreBlend.fG); | 940 rgb_to_a8<false>(src, glyph, fPreBlend.fG); |
954 } | 941 } |
955 } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) { | 942 } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) { |
956 if (fPreBlend.isApplicable()) { | 943 if (fPreBlend.isApplicable()) { |
957 rgb_to_lcd16<true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend
.fB); | 944 rgb_to_lcd16<true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend
.fB); |
958 } else { | 945 } else { |
959 rgb_to_lcd16<false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlen
d.fB); | 946 rgb_to_lcd16<false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlen
d.fB); |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 } | 1821 } |
1835 | 1822 |
1836 #include "SkFontMgr_indirect.h" | 1823 #include "SkFontMgr_indirect.h" |
1837 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { | 1824 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { |
1838 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); | 1825 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); |
1839 if (impl.get() == NULL) { | 1826 if (impl.get() == NULL) { |
1840 return NULL; | 1827 return NULL; |
1841 } | 1828 } |
1842 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); | 1829 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); |
1843 } | 1830 } |
OLD | NEW |