| 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 | 9 |
| 10 #include "SkScalerContext.h" | 10 #include "SkScalerContext.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |