OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 | 8 |
9 #include "SkScalerContext.h" | 9 #include "SkScalerContext.h" |
10 #include "SkAutoPixmapStorage.h" | 10 #include "SkAutoPixmapStorage.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 fRsbDelta = 0; | 55 fRsbDelta = 0; |
56 fLsbDelta = 0; | 56 fLsbDelta = 0; |
57 } | 57 } |
58 | 58 |
59 /////////////////////////////////////////////////////////////////////////////// | 59 /////////////////////////////////////////////////////////////////////////////// |
60 | 60 |
61 #ifdef SK_DEBUG | 61 #ifdef SK_DEBUG |
62 #define DUMP_RECx | 62 #define DUMP_RECx |
63 #endif | 63 #endif |
64 | 64 |
65 static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag, | 65 static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag, |
msarett
2016/04/06 17:05:38
I think you can delete this function.
| |
66 SkFlattenable::Type ft) { | 66 SkFlattenable::Type ft) { |
67 SkFlattenable* obj = nullptr; | 67 SkFlattenable* obj = nullptr; |
68 uint32_t len; | 68 uint32_t len; |
69 const void* data = desc->findEntry(tag, &len); | 69 const void* data = desc->findEntry(tag, &len); |
70 | 70 |
71 if (data) { | 71 if (data) { |
72 SkReadBuffer buffer(data, len); | 72 SkReadBuffer buffer(data, len); |
73 obj = buffer.readFlattenable(ft); | 73 obj = buffer.readFlattenable(ft); |
74 SkASSERT(buffer.offset() == buffer.size()); | 74 SkASSERT(buffer.offset() == buffer.size()); |
75 } | 75 } |
76 return obj; | 76 return obj; |
77 } | 77 } |
78 | 78 |
79 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) | 79 SkScalerContext::SkScalerContext(const SkScalerContextEffects& effects, |
80 const SkDescriptor* desc) | |
80 : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, nullpt r))) | 81 : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, nullpt r))) |
81 | 82 |
82 , fTypeface(SkRef(typeface)) | 83 , fTypeface(effects.fTypeface) |
83 , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_ SkDescriptorTag, | 84 , fPathEffect(effects.fPathEffect) |
84 SkFlattenable::kSkPathEffect_Type)) ) | 85 , fMaskFilter(effects.fMaskFilter) |
85 , fMaskFilter(static_cast<SkMaskFilter*>(load_flattenable(desc, kMaskFilter_ SkDescriptorTag, | 86 , fRasterizer(effects.fRasterizer) |
f(malita)
2016/04/06 13:28:32
Is there a way to take advantage of move semantics
| |
86 SkFlattenable::kSkMaskFilter_Type)) ) | |
87 , fRasterizer(static_cast<SkRasterizer*>(load_flattenable(desc, kRasterizer_ SkDescriptorTag, | |
88 SkFlattenable::kSkRasterizer_Type)) ) | |
89 // Initialize based on our settings. Subclasses can also force this. | 87 // Initialize based on our settings. Subclasses can also force this. |
90 , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != nullptr || f Rasterizer != nullptr) | 88 , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != nullptr || f Rasterizer != nullptr) |
91 | 89 |
92 , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMask PreBlend(fRec)) | 90 , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMask PreBlend(fRec)) |
93 , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec) | 91 , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec) |
94 : SkMaskGamma::PreBlend()) | 92 : SkMaskGamma::PreBlend()) |
95 { | 93 { |
96 #ifdef DUMP_REC | 94 #ifdef DUMP_REC |
97 desc->assertChecksum(); | 95 desc->assertChecksum(); |
98 SkDebugf("SkScalerContext checksum %x count %d length %d\n", | 96 SkDebugf("SkScalerContext checksum %x count %d length %d\n", |
99 desc->getChecksum(), desc->getCount(), desc->getLength()); | 97 desc->getChecksum(), desc->getCount(), desc->getLength()); |
100 SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n", | 98 SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n", |
101 rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0], | 99 rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0], |
102 rec->fPost2x2[0][1], rec->fPost2x2[1][0], rec->fPost2x2[1][1]); | 100 rec->fPost2x2[0][1], rec->fPost2x2[1][0], rec->fPost2x2[1][1]); |
103 SkDebugf(" frame %g miter %g hints %d framefill %d format %d join %d cap %d \n", | 101 SkDebugf(" frame %g miter %g hints %d framefill %d format %d join %d cap %d \n", |
104 rec->fFrameWidth, rec->fMiterLimit, rec->fHints, rec->fFrameAndFill, | 102 rec->fFrameWidth, rec->fMiterLimit, rec->fHints, rec->fFrameAndFill, |
105 rec->fMaskFormat, rec->fStrokeJoin, rec->fStrokeCap); | 103 rec->fMaskFormat, rec->fStrokeJoin, rec->fStrokeCap); |
106 SkDebugf(" pathEffect %x maskFilter %x\n", | 104 SkDebugf(" pathEffect %x maskFilter %x\n", |
107 desc->findEntry(kPathEffect_SkDescriptorTag, nullptr), | 105 desc->findEntry(kPathEffect_SkDescriptorTag, nullptr), |
108 desc->findEntry(kMaskFilter_SkDescriptorTag, nullptr)); | 106 desc->findEntry(kMaskFilter_SkDescriptorTag, nullptr)); |
109 #endif | 107 #endif |
110 } | 108 } |
111 | 109 |
112 SkScalerContext::~SkScalerContext() { | 110 SkScalerContext::~SkScalerContext() {} |
113 SkSafeUnref(fPathEffect); | |
114 SkSafeUnref(fMaskFilter); | |
115 SkSafeUnref(fRasterizer); | |
116 } | |
117 | 111 |
118 void SkScalerContext::getAdvance(SkGlyph* glyph) { | 112 void SkScalerContext::getAdvance(SkGlyph* glyph) { |
119 // mark us as just having a valid advance | 113 // mark us as just having a valid advance |
120 glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE; | 114 glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE; |
121 // we mark the format before making the call, in case the impl | 115 // we mark the format before making the call, in case the impl |
122 // internally ends up calling its generateMetrics, which is OK | 116 // internally ends up calling its generateMetrics, which is OK |
123 // albeit slower than strictly necessary | 117 // albeit slower than strictly necessary |
124 generateAdvance(glyph); | 118 generateAdvance(glyph); |
125 } | 119 } |
126 | 120 |
(...skipping 22 matching lines...) Expand all Loading... | |
149 if (fGenerateImageFromPath) { | 143 if (fGenerateImageFromPath) { |
150 SkPath devPath, fillPath; | 144 SkPath devPath, fillPath; |
151 SkMatrix fillToDevMatrix; | 145 SkMatrix fillToDevMatrix; |
152 | 146 |
153 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); | 147 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); |
154 | 148 |
155 if (fRasterizer) { | 149 if (fRasterizer) { |
156 SkMask mask; | 150 SkMask mask; |
157 | 151 |
158 if (fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr, | 152 if (fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr, |
159 fMaskFilter, &mask, | 153 fMaskFilter.get(), &mask, |
160 SkMask::kJustComputeBounds_CreateMode)) { | 154 SkMask::kJustComputeBounds_CreateMode)) { |
161 glyph->fLeft = mask.fBounds.fLeft; | 155 glyph->fLeft = mask.fBounds.fLeft; |
162 glyph->fTop = mask.fBounds.fTop; | 156 glyph->fTop = mask.fBounds.fTop; |
163 glyph->fWidth = SkToU16(mask.fBounds.width()); | 157 glyph->fWidth = SkToU16(mask.fBounds.width()); |
164 glyph->fHeight = SkToU16(mask.fBounds.height()); | 158 glyph->fHeight = SkToU16(mask.fBounds.height()); |
165 } else { | 159 } else { |
166 goto SK_ERROR; | 160 goto SK_ERROR; |
167 } | 161 } |
168 } else { | 162 } else { |
169 // just use devPath | 163 // just use devPath |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
478 // If we are going to draw-from-path, then we cannot generate color, since | 472 // If we are going to draw-from-path, then we cannot generate color, since |
479 // the path only makes a mask. This case should have been caught up in | 473 // the path only makes a mask. This case should have been caught up in |
480 // generateMetrics(). | 474 // generateMetrics(). |
481 SkASSERT(!fGenerateImageFromPath || | 475 SkASSERT(!fGenerateImageFromPath || |
482 SkMask::kARGB32_Format != origGlyph.fMaskFormat); | 476 SkMask::kARGB32_Format != origGlyph.fMaskFormat); |
483 | 477 |
484 if (fMaskFilter) { // restore the prefilter bounds | 478 if (fMaskFilter) { // restore the prefilter bounds |
485 tmpGlyph.initGlyphIdFrom(origGlyph); | 479 tmpGlyph.initGlyphIdFrom(origGlyph); |
486 | 480 |
487 // need the original bounds, sans our maskfilter | 481 // need the original bounds, sans our maskfilter |
488 SkMaskFilter* mf = fMaskFilter; | 482 SkMaskFilter* mf = fMaskFilter.release(); // temp disable |
489 fMaskFilter = nullptr; // temp disable | |
490 this->getMetrics(&tmpGlyph); | 483 this->getMetrics(&tmpGlyph); |
491 fMaskFilter = mf; // restore | 484 fMaskFilter = sk_sp<SkMaskFilter>(mf); // restore |
492 | 485 |
493 // we need the prefilter bounds to be <= filter bounds | 486 // we need the prefilter bounds to be <= filter bounds |
494 SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); | 487 SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); |
495 SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); | 488 SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); |
496 | 489 |
497 if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) { | 490 if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) { |
498 tmpGlyph.fImage = origGlyph.fImage; | 491 tmpGlyph.fImage = origGlyph.fImage; |
499 } else { | 492 } else { |
500 tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize()); | 493 tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize()); |
501 tmpGlyph.fImage = tmpGlyphImageStorage.get(); | 494 tmpGlyph.fImage = tmpGlyphImageStorage.get(); |
502 } | 495 } |
503 glyph = &tmpGlyph; | 496 glyph = &tmpGlyph; |
504 } | 497 } |
505 | 498 |
506 if (fGenerateImageFromPath) { | 499 if (fGenerateImageFromPath) { |
507 SkPath devPath, fillPath; | 500 SkPath devPath, fillPath; |
508 SkMatrix fillToDevMatrix; | 501 SkMatrix fillToDevMatrix; |
509 SkMask mask; | 502 SkMask mask; |
510 | 503 |
511 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); | 504 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); |
512 glyph->toMask(&mask); | 505 glyph->toMask(&mask); |
513 | 506 |
514 if (fRasterizer) { | 507 if (fRasterizer) { |
515 mask.fFormat = SkMask::kA8_Format; | 508 mask.fFormat = SkMask::kA8_Format; |
516 sk_bzero(glyph->fImage, mask.computeImageSize()); | 509 sk_bzero(glyph->fImage, mask.computeImageSize()); |
517 | 510 |
518 if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr, | 511 if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr, |
519 fMaskFilter, &mask, | 512 fMaskFilter.get(), &mask, |
520 SkMask::kJustRenderImage_CreateMode)) { | 513 SkMask::kJustRenderImage_CreateMode)) { |
521 return; | 514 return; |
522 } | 515 } |
523 if (fPreBlend.isApplicable()) { | 516 if (fPreBlend.isApplicable()) { |
524 applyLUTToA8Mask(mask, fPreBlend.fG); | 517 applyLUTToA8Mask(mask, fPreBlend.fG); |
525 } | 518 } |
526 } else { | 519 } else { |
527 SkASSERT(SkMask::kARGB32_Format != mask.fFormat); | 520 SkASSERT(SkMask::kARGB32_Format != mask.fFormat); |
528 generateMask(mask, devPath, fPreBlend); | 521 generateMask(mask, devPath, fPreBlend); |
529 } | 522 } |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
844 // The x axis is mapped onto the y axis. | 837 // The x axis is mapped onto the y axis. |
845 return kY_SkAxisAlignment; | 838 return kY_SkAxisAlignment; |
846 } | 839 } |
847 return kNone_SkAxisAlignment; | 840 return kNone_SkAxisAlignment; |
848 } | 841 } |
849 | 842 |
850 /////////////////////////////////////////////////////////////////////////////// | 843 /////////////////////////////////////////////////////////////////////////////// |
851 | 844 |
852 class SkScalerContext_Empty : public SkScalerContext { | 845 class SkScalerContext_Empty : public SkScalerContext { |
853 public: | 846 public: |
854 SkScalerContext_Empty(SkTypeface* face, const SkDescriptor* desc) | 847 SkScalerContext_Empty(const SkScalerContextEffects& effects, const SkDescrip tor* desc) |
855 : SkScalerContext(face, desc) {} | 848 : SkScalerContext(effects, desc) {} |
856 | 849 |
857 protected: | 850 protected: |
858 unsigned generateGlyphCount() override { | 851 unsigned generateGlyphCount() override { |
859 return 0; | 852 return 0; |
860 } | 853 } |
861 uint16_t generateCharToGlyph(SkUnichar uni) override { | 854 uint16_t generateCharToGlyph(SkUnichar uni) override { |
862 return 0; | 855 return 0; |
863 } | 856 } |
864 void generateAdvance(SkGlyph* glyph) override { | 857 void generateAdvance(SkGlyph* glyph) override { |
865 glyph->zeroMetrics(); | 858 glyph->zeroMetrics(); |
866 } | 859 } |
867 void generateMetrics(SkGlyph* glyph) override { | 860 void generateMetrics(SkGlyph* glyph) override { |
868 glyph->zeroMetrics(); | 861 glyph->zeroMetrics(); |
869 } | 862 } |
870 void generateImage(const SkGlyph& glyph) override {} | 863 void generateImage(const SkGlyph& glyph) override {} |
871 void generatePath(const SkGlyph& glyph, SkPath* path) override {} | 864 void generatePath(const SkGlyph& glyph, SkPath* path) override {} |
872 void generateFontMetrics(SkPaint::FontMetrics* metrics) override { | 865 void generateFontMetrics(SkPaint::FontMetrics* metrics) override { |
873 if (metrics) { | 866 if (metrics) { |
874 sk_bzero(metrics, sizeof(*metrics)); | 867 sk_bzero(metrics, sizeof(*metrics)); |
875 } | 868 } |
876 } | 869 } |
877 }; | 870 }; |
878 | 871 |
879 extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc); | 872 extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc); |
880 | 873 |
881 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc, | 874 SkScalerContext* SkTypeface::createScalerContext(const SkScalerContextEffects& e ffects, |
875 const SkDescriptor* desc, | |
882 bool allowFailure) const { | 876 bool allowFailure) const { |
883 SkScalerContext* c = this->onCreateScalerContext(desc); | 877 SkScalerContext* c = this->onCreateScalerContext(effects, desc); |
884 | 878 |
885 if (!c && !allowFailure) { | 879 if (!c && !allowFailure) { |
886 c = new SkScalerContext_Empty(const_cast<SkTypeface*>(this), desc); | 880 SkScalerContextEffects effects; |
881 effects.fTypeface = sk_ref_sp(const_cast<SkTypeface*>(this)); | |
882 c = new SkScalerContext_Empty(effects, desc); | |
887 } | 883 } |
888 return c; | 884 return c; |
889 } | 885 } |
OLD | NEW |