Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: src/core/SkScalerContext.cpp

Issue 434623002: Remove ALL font fallback logic from Skia. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix win font host Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkScalerContext.h ('k') | src/pdf/SkPDFDevice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 9
10 #include "SkScalerContext.h" 10 #include "SkScalerContext.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 SkReadBuffer buffer(data, len); 76 SkReadBuffer buffer(data, len);
77 obj = buffer.readFlattenable(ft); 77 obj = buffer.readFlattenable(ft);
78 SkASSERT(buffer.offset() == buffer.size()); 78 SkASSERT(buffer.offset() == buffer.size());
79 } 79 }
80 return obj; 80 return obj;
81 } 81 }
82 82
83 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) 83 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc)
84 : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL)) ) 84 : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL)) )
85 85
86 , fBaseGlyphCount(0)
87 , fTypeface(SkRef(typeface)) 86 , fTypeface(SkRef(typeface))
88 , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_ SkDescriptorTag, 87 , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_ SkDescriptorTag,
89 SkFlattenable::kSkPathEffect_Type)) ) 88 SkFlattenable::kSkPathEffect_Type)) )
90 , fMaskFilter(static_cast<SkMaskFilter*>(load_flattenable(desc, kMaskFilter_ SkDescriptorTag, 89 , fMaskFilter(static_cast<SkMaskFilter*>(load_flattenable(desc, kMaskFilter_ SkDescriptorTag,
91 SkFlattenable::kSkMaskFilter_Type)) ) 90 SkFlattenable::kSkMaskFilter_Type)) )
92 , fRasterizer(static_cast<SkRasterizer*>(load_flattenable(desc, kRasterizer_ SkDescriptorTag, 91 , fRasterizer(static_cast<SkRasterizer*>(load_flattenable(desc, kRasterizer_ SkDescriptorTag,
93 SkFlattenable::kSkRasterizer_Type)) ) 92 SkFlattenable::kSkRasterizer_Type)) )
94 // Initialize based on our settings. Subclasses can also force this. 93 // Initialize based on our settings. Subclasses can also force this.
95 , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRas terizer != NULL) 94 , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRas terizer != NULL)
96 95
97 , fNextContext(NULL)
98
99 , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMask PreBlend(fRec)) 96 , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMask PreBlend(fRec))
100 , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec) 97 , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec)
101 : SkMaskGamma::PreBlend()) 98 : SkMaskGamma::PreBlend())
102 { 99 {
103 #ifdef DUMP_REC 100 #ifdef DUMP_REC
104 desc->assertChecksum(); 101 desc->assertChecksum();
105 SkDebugf("SkScalerContext checksum %x count %d length %d\n", 102 SkDebugf("SkScalerContext checksum %x count %d length %d\n",
106 desc->getChecksum(), desc->getCount(), desc->getLength()); 103 desc->getChecksum(), desc->getCount(), desc->getLength());
107 SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n", 104 SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n",
108 rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0], 105 rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0],
(...skipping 10 matching lines...) Expand all
119 const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len); 116 const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len);
120 if (data) { 117 if (data) {
121 SkReadBuffer buffer(data, len); 118 SkReadBuffer buffer(data, len);
122 fPaintOptionsAndroid.unflatten(buffer); 119 fPaintOptionsAndroid.unflatten(buffer);
123 SkASSERT(buffer.offset() == buffer.size()); 120 SkASSERT(buffer.offset() == buffer.size());
124 } 121 }
125 #endif 122 #endif
126 } 123 }
127 124
128 SkScalerContext::~SkScalerContext() { 125 SkScalerContext::~SkScalerContext() {
129 SkDELETE(fNextContext);
130
131 SkSafeUnref(fPathEffect); 126 SkSafeUnref(fPathEffect);
132 SkSafeUnref(fMaskFilter); 127 SkSafeUnref(fMaskFilter);
133 SkSafeUnref(fRasterizer); 128 SkSafeUnref(fRasterizer);
134 } 129 }
135 130
136 // Return the context associated with the next logical typeface, or NULL if
137 // there are no more entries in the fallback chain.
138 SkScalerContext* SkScalerContext::allocNextContext() const {
139 #ifdef SK_BUILD_FOR_ANDROID
140 SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID,
141 fRec.fOrigFontID,
142 fPaintOptionsAndroid);
143 if (0 == newFace) {
144 return NULL;
145 }
146
147 SkAutoTUnref<SkTypeface> aur(newFace);
148 uint32_t newFontID = newFace->uniqueID();
149
150 SkWriteBuffer androidBuffer;
151 fPaintOptionsAndroid.flatten(androidBuffer);
152
153 SkAutoDescriptor ad(sizeof(fRec) + androidBuffer.bytesWritten()
154 + SkDescriptor::ComputeOverhead(2));
155 SkDescriptor* desc = ad.getDesc();
156
157 desc->init();
158 SkScalerContext::Rec* newRec =
159 (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag,
160 sizeof(fRec), &fRec);
161 androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag,
162 androidBuffer.bytesWritten(), NUL L));
163
164 newRec->fFontID = newFontID;
165 desc->computeChecksum();
166
167 return newFace->createScalerContext(desc);
168 #else
169 return NULL;
170 #endif
171 }
172
173 /* Return the next context, creating it if its not already created, but return
174 NULL if the fonthost says there are no more fonts to fallback to.
175 */
176 SkScalerContext* SkScalerContext::getNextContext() {
177 SkScalerContext* next = fNextContext;
178 // if next is null, then either it isn't cached yet, or we're at the
179 // end of our possible chain
180 if (NULL == next) {
181 next = this->allocNextContext();
182 if (NULL == next) {
183 return NULL;
184 }
185 // next's base is our base + our local count
186 next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount());
187 // cache the answer
188 fNextContext = next;
189 }
190 return next;
191 }
192
193 SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) {
194 unsigned glyphID = glyph.getGlyphID();
195 SkScalerContext* ctx = this;
196 for (;;) {
197 unsigned count = ctx->getGlyphCount();
198 if (glyphID < count) {
199 break;
200 }
201 glyphID -= count;
202 ctx = ctx->getNextContext();
203 if (NULL == ctx) {
204 // SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID());
205 // just return the original context (this)
206 return this;
207 }
208 }
209 return ctx;
210 }
211
212 SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni,
213 uint16_t* glyphID) {
214 SkScalerContext* ctx = this;
215 for (;;) {
216 const uint16_t glyph = ctx->generateCharToGlyph(uni);
217 if (glyph) {
218 if (NULL != glyphID) {
219 *glyphID = glyph;
220 }
221 break; // found it
222 }
223 ctx = ctx->getNextContext();
224 if (NULL == ctx) {
225 return NULL;
226 }
227 }
228 return ctx;
229 }
230
231 #ifdef SK_BUILD_FOR_ANDROID
232 SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) {
233 SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
234 if (NULL != ctx) {
235 return ctx->fRec.fFontID;
236 } else {
237 return 0;
238 }
239 }
240
241 /* This loops through all available fallback contexts (if needed) until it
242 finds some context that can handle the unichar and return it.
243
244 As this is somewhat expensive operation, it should only be done on the first
245 char of a run.
246 */
247 unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) {
248 SkScalerContext* ctx = this->getContextFromChar(uni, NULL);
249 if (NULL != ctx) {
250 return ctx->fBaseGlyphCount;
251 } else {
252 SkDEBUGF(("--- no context for char %x\n", uni));
253 return this->fBaseGlyphCount;
254 }
255 }
256 #endif
257
258 /* This loops through all available fallback contexts (if needed) until it
259 finds some context that can handle the unichar. If all fail, returns 0
260 */
261 uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) {
262
263 uint16_t tempID;
264 SkScalerContext* ctx = this->getContextFromChar(uni, &tempID);
265 if (NULL == ctx) {
266 return 0; // no more contexts, return missing glyph
267 }
268 // add the ctx's base, making glyphID unique for chain of contexts
269 unsigned glyphID = tempID + ctx->fBaseGlyphCount;
270 // check for overflow of 16bits, since our glyphID cannot exceed that
271 if (glyphID > 0xFFFF) {
272 glyphID = 0;
273 }
274 return SkToU16(glyphID);
275 }
276
277 SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) {
278 SkScalerContext* ctx = this;
279 unsigned rangeEnd = 0;
280 do {
281 unsigned rangeStart = rangeEnd;
282
283 rangeEnd += ctx->getGlyphCount();
284 if (rangeStart <= glyphID && glyphID < rangeEnd) {
285 return ctx->generateGlyphToChar(glyphID - rangeStart);
286 }
287 ctx = ctx->getNextContext();
288 } while (NULL != ctx);
289 return 0;
290 }
291
292 void SkScalerContext::getAdvance(SkGlyph* glyph) { 131 void SkScalerContext::getAdvance(SkGlyph* glyph) {
293 // mark us as just having a valid advance 132 // mark us as just having a valid advance
294 glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE; 133 glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE;
295 // we mark the format before making the call, in case the impl 134 // we mark the format before making the call, in case the impl
296 // internally ends up calling its generateMetrics, which is OK 135 // internally ends up calling its generateMetrics, which is OK
297 // albeit slower than strictly necessary 136 // albeit slower than strictly necessary
298 this->getGlyphContext(*glyph)->generateAdvance(glyph); 137 generateAdvance(glyph);
299 } 138 }
300 139
301 void SkScalerContext::getMetrics(SkGlyph* glyph) { 140 void SkScalerContext::getMetrics(SkGlyph* glyph) {
302 this->getGlyphContext(*glyph)->generateMetrics(glyph); 141 generateMetrics(glyph);
303 142
304 // for now we have separate cache entries for devkerning on and off 143 // for now we have separate cache entries for devkerning on and off
305 // in the future we might share caches, but make our measure/draw 144 // in the future we might share caches, but make our measure/draw
306 // code make the distinction. Thus we zap the values if the caller 145 // code make the distinction. Thus we zap the values if the caller
307 // has not asked for them. 146 // has not asked for them.
308 if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) { 147 if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) {
309 // no devkern, so zap the fields 148 // no devkern, so zap the fields
310 glyph->fLsbDelta = glyph->fRsbDelta = 0; 149 glyph->fLsbDelta = glyph->fRsbDelta = 0;
311 } 150 }
312 151
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 return; 569 return;
731 } 570 }
732 if (fPreBlend.isApplicable()) { 571 if (fPreBlend.isApplicable()) {
733 applyLUTToA8Mask(mask, fPreBlend.fG); 572 applyLUTToA8Mask(mask, fPreBlend.fG);
734 } 573 }
735 } else { 574 } else {
736 SkASSERT(SkMask::kARGB32_Format != mask.fFormat); 575 SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
737 generateMask(mask, devPath, fPreBlend); 576 generateMask(mask, devPath, fPreBlend);
738 } 577 }
739 } else { 578 } else {
740 this->getGlyphContext(*glyph)->generateImage(*glyph); 579 generateImage(*glyph);
741 } 580 }
742 581
743 if (fMaskFilter) { 582 if (fMaskFilter) {
744 SkMask srcM, dstM; 583 SkMask srcM, dstM;
745 SkMatrix matrix; 584 SkMatrix matrix;
746 585
747 // the src glyph image shouldn't be 3D 586 // the src glyph image shouldn't be 3D
748 SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat); 587 SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
749 588
750 SkAutoSMalloc<32*32> a8storage; 589 SkAutoSMalloc<32*32> a8storage;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 643
805 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) { 644 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) {
806 return 0; 645 return 0;
807 } 646 }
808 647
809 /////////////////////////////////////////////////////////////////////////////// 648 ///////////////////////////////////////////////////////////////////////////////
810 649
811 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, 650 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath,
812 SkPath* devPath, SkMatrix* fillToDevMatrix) { 651 SkPath* devPath, SkMatrix* fillToDevMatrix) {
813 SkPath path; 652 SkPath path;
814 653 generatePath(glyph, &path);
815 this->getGlyphContext(glyph)->generatePath(glyph, &path);
816 654
817 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) { 655 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
818 SkFixed dx = glyph.getSubXFixed(); 656 SkFixed dx = glyph.getSubXFixed();
819 SkFixed dy = glyph.getSubYFixed(); 657 SkFixed dy = glyph.getSubYFixed();
820 if (dx | dy) { 658 if (dx | dy) {
821 path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy)); 659 path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy));
822 } 660 }
823 } 661 }
824 662
825 if (fRec.fFrameWidth > 0 || fPathEffect != NULL) { 663 if (fRec.fFrameWidth > 0 || fPathEffect != NULL) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc, 805 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc,
968 bool allowFailure) const { 806 bool allowFailure) const {
969 SkScalerContext* c = this->onCreateScalerContext(desc); 807 SkScalerContext* c = this->onCreateScalerContext(desc);
970 808
971 if (!c && !allowFailure) { 809 if (!c && !allowFailure) {
972 c = SkNEW_ARGS(SkScalerContext_Empty, 810 c = SkNEW_ARGS(SkScalerContext_Empty,
973 (const_cast<SkTypeface*>(this), desc)); 811 (const_cast<SkTypeface*>(this), desc));
974 } 812 }
975 return c; 813 return c;
976 } 814 }
OLDNEW
« no previous file with comments | « src/core/SkScalerContext.h ('k') | src/pdf/SkPDFDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698