uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) { unsigned glyphID = this->generateCharToGlyph(uni); if (0 == glyphID) { // try auxcontext SkScalerContext* ctx = this->loadAuxContext(); if (NULL != ctx) { glyphID = ctx->generateCharToGlyph(uni); if (0 != glyphID) { // only fiddle with it if its not missing glyphID += this->getGlyphCount(); if (glyphID > 0xFFFF) { glyphID = 0; } } } } #ifdef TRACK_MISSING_CHARS if (0 == glyphID) { bool announce = false; if (uni > 0xFFFF) { // we don't record these announce = true; } else { unsigned index = uni >> 3; unsigned mask = 1 << (uni & 7); SkASSERT(index < SK_ARRAY_COUNT(gMissingChars)); if ((gMissingChars[index] & mask) == 0) { gMissingChars[index] |= mask; announce = true; } } if (announce) { printf(">>> MISSING CHAR <<< 0x%04X\n", uni); } }
SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni, unsigned& glyphID) { SkScalerContext* ctx = this; for (;;) { glyphID = ctx->generateCharToGlyph(uni); if (glyphID) { break; // found it } ctx = ctx->getNextContext(); if (NULL == ctx) { return NULL; } } return ctx; }
/* 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; unsigned glyphID; for (;;) { glyphID = ctx->generateCharToGlyph(uni); if (glyphID) { break; // found it } ctx = ctx->getNextContext(); if (NULL == ctx) { SkDebugf("--- no context for char %x\n", uni); // just return the original context (this) return this->fBaseGlyphCount; } } return ctx->fBaseGlyphCount; }
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; }
/* 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) { SkScalerContext* ctx = this; unsigned glyphID; for (;;) { glyphID = ctx->generateCharToGlyph(uni); if (glyphID) { break; // found it } ctx = ctx->getNextContext(); if (NULL == ctx) { return 0; // no more contexts, return missing glyph } } // add the ctx's base, making glyphID unique for chain of contexts glyphID += ctx->fBaseGlyphCount; // check for overflow of 16bits, since our glyphID cannot exceed that if (glyphID > 0xFFFF) { glyphID = 0; } return SkToU16(glyphID); }