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