unicharToGlyph>charToGlyphID>getContextFromChar
98 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { 99 VALIDATE(); 100 uint32_t id = SkGlyph::MakeID(charCode); 101 const CharGlyphRec& rec = fCharToGlyphHash[ID2HashIndex(id)]; <===== kHashCount = 0x1000の配列 102 103 if (rec.fID == id) { 104 return rec.fGlyph->getGlyphID(); 105 } else { 106 return fScalerContext->charToGlyphID(charCode); 107 } 108 }
231 uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) { 232 233 unsigned glyphID; 234 SkScalerContext* ctx = getContextFromChar(uni, glyphID); 235 if (!ctx) { 236 return 0; // no more contexts, return missing glyph 237 } 238 // add the ctx's base, making glyphID unique for chain of contexts 239 glyphID += ctx->fBaseGlyphCount; 240 // check for overflow of 16bits, since our glyphID cannot exceed that 241 if (glyphID > 0xFFFF) { 242 glyphID = 0; 243 } 244 return SkToU16(glyphID); 245 }
165 SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni, unsigned& glyphID) { 166 SkScalerContext* ctx = this; 167 for (;;) { 168 glyphID = ctx->generateCharToGlyph(uni); 169 if (glyphID) { 170 break; // found it 171 } 172 ctx = ctx->getNextContext(); 173 if (NULL == ctx) { 174 return NULL; 175 } 176 } 177 return ctx; 178 }
928 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { 929 return SkToU16(FT_Get_Char_Index( fFace, uni )); 930 }
=============================================================================================================
148 static uint32_t MakeID(unsigned code) { 149 return code; 150 } 151 152 static uint32_t MakeID(unsigned code, SkFixed x, SkFixed y) { 153 SkASSERT(code <= kCodeMask); 154 x = FixedToSub(x); 155 y = FixedToSub(y); 156 return (x << (kSubShift + kSubShiftX)) | 157 (y << (kSubShift + kSubShiftY)) | 158 code; 159 }
247 248 struct CharGlyphRec { <========型 249 uint32_t fID; // unichar + subpixel 250 SkGlyph* fGlyph; 251 }; 252 // no reason to use the same kHashCount as fGlyphHash, but we do for now 253 CharGlyphRec fCharToGlyphHash[kHashCount]; <==================配列
53 SkGlyphCache::SkGlyphCache(const SkDescriptor* desc) 54 : fGlyphAlloc(kMinGlphAlloc), fImageAlloc(kMinImageAlloc) { 55 fPrev = fNext = NULL; 56 57 fDesc = desc->copy(); 58 fScalerContext = SkScalerContext::Create(desc); 59 fScalerContext->getFontMetrics(NULL, &fFontMetricsY); 60 61 // init to 0 so that all of the pointers will be null 62 memset(fGlyphHash, 0, sizeof(fGlyphHash)); 63 // init with 0xFF so that the charCode field will be -1, which is invalid 64 memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash)); <===================0xFFで初期化 65 66 fMemoryUsed = sizeof(*this) + kMinGlphAlloc + kMinImageAlloc; 67 68 fGlyphArray.setReserve(METRICS_RESERVE_COUNT); 69 70 fMetricsCount = 0; 71 fAdvanceCount = 0; 72 fAuxProcList = NULL; 73 }
117 enum { 118 kSubBits = 2, <===== kSubBits = 0x00000002 119 kSubMask = ((1 << kSubBits) - 1), <===== kSubMask = 0x00000003 120 kSubShift = 24, // must be large enough for glyphs and unichars <===== kSubShift = 0x00000018 121 kCodeMask = ((1 << kSubShift) - 1), <===== kCodeMask = 0x00FFFFFF 122 // relative offsets for X and Y subpixel bits 123 kSubShiftX = kSubBits, <===== kSubShiftX = 0x00000002 124 kSubShiftY = 0 <===== kSubShiftY = 0x00000000 125 };
262 static inline unsigned ID2HashIndex(uint32_t id) { 263 return (id ^ (id >> kShiftForHashIndex)) & kHashMask; <===== kHashMask = 0x0FFF <===== kShiftForHashIndex = 0x0010 (id ^ (id >> 16)) & 0x0FFF = 0x3010 ^ (0x3010 >> 16) = 0x3010 ^ (0x0000) & 0x0FFF = 0x3010 & 0x0FFF = 0x0010 264 } 255 enum { 256 // shift so that the top bits fall into kHashBits region 257 kShiftForHashIndex = SkGlyph::kSubShift + <===== kShiftForHashIndex = 0x0010=16 258 SkGlyph::kSubBits*2 - 259 kHashBits 260 }; 236 enum { 237 kHashBits = 12, <===== kHashBits = 0x0000000C 238 kHashCount = 1 << kHashBits, <===== kHashCount = 0x00001000 239 kHashMask = kHashCount - 1 <===== kHashMask = 0x00000FFF 240 };
91 unsigned getGlyphID(unsigned baseGlyphCount) const { 92 unsigned code = ID2Code(fID); <====== 下位3byte取得 93 SkASSERT(code >= baseGlyphCount); 94 return code - baseGlyphCount; 95 } 127 static unsigned ID2Code(uint32_t id) { 128 return id & kCodeMask; <===== kCodeMask = 0x00FFFFFF 129 }