SkGlyph* SkGlyphCache::lookupByPackedGlyphID(PackedGlyphID packedGlyphID, MetricsType type) { SkGlyph* glyph = fGlyphMap.find(packedGlyphID); if (nullptr == glyph) { glyph = this->allocateNewGlyph(packedGlyphID, type); } else { if (type == kFull_MetricsType && glyph->isJustAdvance()) { fScalerContext->getMetrics(glyph); } } return glyph; }
SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { SkGlyph* glyph; int hi = 0; int count = fGlyphArray.count(); if (count) { SkGlyph** gptr = fGlyphArray.begin(); int lo = 0; hi = count - 1; while (lo < hi) { int mid = (hi + lo) >> 1; if (gptr[mid]->fID < id) { lo = mid + 1; } else { hi = mid; } } glyph = gptr[hi]; if (glyph->fID == id) { if (kFull_MetricsType == mtype && glyph->isJustAdvance()) { fScalerContext->getMetrics(glyph); } return glyph; } // check if we need to bump hi before falling though to the allocator if (glyph->fID < id) { hi += 1; } } // not found, but hi tells us where to inser the new glyph fMemoryUsed += sizeof(SkGlyph); glyph = (SkGlyph*)fGlyphAlloc.alloc(sizeof(SkGlyph), SkChunkAlloc::kThrow_AllocFailType); glyph->init(id); *fGlyphArray.insert(hi) = glyph; if (kJustAdvance_MetricsType == mtype) { fScalerContext->getAdvance(glyph); } else { SkASSERT(kFull_MetricsType == mtype); fScalerContext->getMetrics(glyph); } return glyph; }
const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { VALIDATE(); uint32_t id = SkGlyph::MakeID(glyphID); unsigned index = ID2HashIndex(id); SkGlyph* glyph = fGlyphHash[index]; if (NULL == glyph || glyph->fID != id) { RecordHashCollisionIf(glyph != NULL); glyph = this->lookupMetrics(glyphID, kFull_MetricsType); fGlyphHash[index] = glyph; } else { RecordHashSuccess(); if (glyph->isJustAdvance()) { fScalerContext->getMetrics(glyph); } } SkASSERT(glyph->isFullMetrics()); return *glyph; }