Index: src/core/SkScalerContext.cpp |
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp |
index b18dc1a79c3112d7d1a532771548af9b66f60150..11208fec599bad1ca0dfeef7f3bab9c23f00dc96 100644 |
--- a/src/core/SkScalerContext.cpp |
+++ b/src/core/SkScalerContext.cpp |
@@ -83,7 +83,6 @@ static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag, |
SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) |
: fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL))) |
- , fBaseGlyphCount(0) |
, fTypeface(SkRef(typeface)) |
, fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_SkDescriptorTag, |
SkFlattenable::kSkPathEffect_Type))) |
@@ -94,8 +93,6 @@ SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) |
// Initialize based on our settings. Subclasses can also force this. |
, fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRasterizer != NULL) |
- , fNextContext(NULL) |
- |
, fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMaskPreBlend(fRec)) |
, fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec) |
: SkMaskGamma::PreBlend()) |
@@ -126,180 +123,22 @@ SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) |
} |
SkScalerContext::~SkScalerContext() { |
- SkDELETE(fNextContext); |
- |
SkSafeUnref(fPathEffect); |
SkSafeUnref(fMaskFilter); |
SkSafeUnref(fRasterizer); |
} |
-// Return the context associated with the next logical typeface, or NULL if |
-// there are no more entries in the fallback chain. |
-SkScalerContext* SkScalerContext::allocNextContext() const { |
-#ifdef SK_BUILD_FOR_ANDROID |
- SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID, |
- fRec.fOrigFontID, |
- fPaintOptionsAndroid); |
- if (0 == newFace) { |
- return NULL; |
- } |
- |
- SkAutoTUnref<SkTypeface> aur(newFace); |
- uint32_t newFontID = newFace->uniqueID(); |
- |
- SkWriteBuffer androidBuffer; |
- fPaintOptionsAndroid.flatten(androidBuffer); |
- |
- SkAutoDescriptor ad(sizeof(fRec) + androidBuffer.bytesWritten() |
- + SkDescriptor::ComputeOverhead(2)); |
- SkDescriptor* desc = ad.getDesc(); |
- |
- desc->init(); |
- SkScalerContext::Rec* newRec = |
- (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, |
- sizeof(fRec), &fRec); |
- androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag, |
- androidBuffer.bytesWritten(), NULL)); |
- |
- newRec->fFontID = newFontID; |
- desc->computeChecksum(); |
- |
- return newFace->createScalerContext(desc); |
-#else |
- return NULL; |
-#endif |
-} |
- |
-/* Return the next context, creating it if its not already created, but return |
- NULL if the fonthost says there are no more fonts to fallback to. |
- */ |
-SkScalerContext* SkScalerContext::getNextContext() { |
- SkScalerContext* next = fNextContext; |
- // if next is null, then either it isn't cached yet, or we're at the |
- // end of our possible chain |
- if (NULL == next) { |
- next = this->allocNextContext(); |
- if (NULL == next) { |
- return NULL; |
- } |
- // next's base is our base + our local count |
- next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount()); |
- // cache the answer |
- fNextContext = next; |
- } |
- return next; |
-} |
- |
-SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) { |
- unsigned glyphID = glyph.getGlyphID(); |
- SkScalerContext* ctx = this; |
- for (;;) { |
- unsigned count = ctx->getGlyphCount(); |
- if (glyphID < count) { |
- break; |
- } |
- glyphID -= count; |
- ctx = ctx->getNextContext(); |
- if (NULL == ctx) { |
-// SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID()); |
- // just return the original context (this) |
- return this; |
- } |
- } |
- return ctx; |
-} |
- |
-SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni, |
- uint16_t* glyphID) { |
- SkScalerContext* ctx = this; |
- for (;;) { |
- const uint16_t glyph = ctx->generateCharToGlyph(uni); |
- if (glyph) { |
- if (NULL != glyphID) { |
- *glyphID = glyph; |
- } |
- break; // found it |
- } |
- ctx = ctx->getNextContext(); |
- if (NULL == ctx) { |
- return NULL; |
- } |
- } |
- return ctx; |
-} |
- |
-#ifdef SK_BUILD_FOR_ANDROID |
-SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) { |
- SkScalerContext* ctx = this->getContextFromChar(uni, NULL); |
- if (NULL != ctx) { |
- return ctx->fRec.fFontID; |
- } else { |
- return 0; |
- } |
-} |
- |
-/* This loops through all available fallback contexts (if needed) until it |
- finds some context that can handle the unichar and return it. |
- |
- As this is somewhat expensive operation, it should only be done on the first |
- char of a run. |
- */ |
-unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) { |
- SkScalerContext* ctx = this->getContextFromChar(uni, NULL); |
- if (NULL != ctx) { |
- return ctx->fBaseGlyphCount; |
- } else { |
- SkDEBUGF(("--- no context for char %x\n", uni)); |
- return this->fBaseGlyphCount; |
- } |
-} |
-#endif |
- |
-/* This loops through all available fallback contexts (if needed) until it |
- finds some context that can handle the unichar. If all fail, returns 0 |
- */ |
-uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) { |
- |
- uint16_t tempID; |
- SkScalerContext* ctx = this->getContextFromChar(uni, &tempID); |
- if (NULL == ctx) { |
- return 0; // no more contexts, return missing glyph |
- } |
- // add the ctx's base, making glyphID unique for chain of contexts |
- unsigned glyphID = tempID + ctx->fBaseGlyphCount; |
- // check for overflow of 16bits, since our glyphID cannot exceed that |
- if (glyphID > 0xFFFF) { |
- glyphID = 0; |
- } |
- return SkToU16(glyphID); |
-} |
- |
-SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) { |
- SkScalerContext* ctx = this; |
- unsigned rangeEnd = 0; |
- do { |
- unsigned rangeStart = rangeEnd; |
- |
- rangeEnd += ctx->getGlyphCount(); |
- if (rangeStart <= glyphID && glyphID < rangeEnd) { |
- return ctx->generateGlyphToChar(glyphID - rangeStart); |
- } |
- ctx = ctx->getNextContext(); |
- } while (NULL != ctx); |
- return 0; |
-} |
- |
void SkScalerContext::getAdvance(SkGlyph* glyph) { |
// mark us as just having a valid advance |
glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE; |
// we mark the format before making the call, in case the impl |
// internally ends up calling its generateMetrics, which is OK |
// albeit slower than strictly necessary |
- this->getGlyphContext(*glyph)->generateAdvance(glyph); |
+ generateAdvance(glyph); |
} |
void SkScalerContext::getMetrics(SkGlyph* glyph) { |
- this->getGlyphContext(*glyph)->generateMetrics(glyph); |
+ generateMetrics(glyph); |
// for now we have separate cache entries for devkerning on and off |
// in the future we might share caches, but make our measure/draw |
@@ -737,7 +576,7 @@ void SkScalerContext::getImage(const SkGlyph& origGlyph) { |
generateMask(mask, devPath, fPreBlend); |
} |
} else { |
- this->getGlyphContext(*glyph)->generateImage(*glyph); |
+ generateImage(*glyph); |
} |
if (fMaskFilter) { |
@@ -811,8 +650,7 @@ SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) { |
void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, |
SkPath* devPath, SkMatrix* fillToDevMatrix) { |
SkPath path; |
- |
- this->getGlyphContext(glyph)->generatePath(glyph, &path); |
+ generatePath(glyph, &path); |
if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) { |
SkFixed dx = glyph.getSubXFixed(); |