のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

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     }