のねのBlog

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

truetype cmap format 2 その2

Freetype2の場合:
※TT_PEAK_USHORTの場合、ポインタの場所を読む。(ポインタは進めない。)
※TT_NEXT_USHORTの場合、ポインタの場所を読み、ポインタを進める。

    391   /* return sub header corresponding to a given character code */
    392   /* NULL on invalid charcode                                  */
    393   static FT_Byte*
    394   tt_cmap2_get_subheader( FT_Byte*   table,
    395                           FT_UInt32  char_code )
    396   {
    397     FT_Byte*  result = NULL;
    398 
    399 
    400     if ( char_code < 0x10000UL )
    401     {
    402       FT_UInt   char_lo = (FT_UInt)( char_code & 0xFF );
    403       FT_UInt   char_hi = (FT_UInt)( char_code >> 8 );
    404       FT_Byte*  p       = table + 6;    /* keys table */
    405       FT_Byte*  subs    = table + 518;  /* subheaders table */
    406       FT_Byte*  sub;
    407 
    408 
    409       if ( char_hi == 0 )
    410       {
    411         /* an 8-bit character code -- we use subHeader 0 in this case */
    412         /* to test whether the character code is in the charmap       */
    413         /*                                                            */
    414         sub = subs;  /* jump to first sub-header */
    415 
    416         /* check that the sub-header for this byte is 0, which */
    417         /* indicates that it is really a valid one-byte value  */
    418         /* Otherwise, return 0                                 */
    419         /*                                                     */
    420         p += char_lo * 2;
    421         if ( TT_PEEK_USHORT( p ) != 0 )
    422           goto Exit;
    423       }
    424       else
    425       {
    426         /* a 16-bit character code */
    427 
    428         /* jump to key entry  */
    429         p  += char_hi * 2;
    430         /* jump to sub-header */
    431         sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) );
    432 
    433         /* check that the high byte isn't a valid one-byte value */
    434         if ( sub == subs )
    435           goto Exit;
    436       }
    437       result = sub;
    438     }
    439   Exit:
    440     return result;
    441   }
    442 
    443 
    444   FT_CALLBACK_DEF( FT_UInt )
    445   tt_cmap2_char_index( TT_CMap    cmap,
    446                        FT_UInt32  char_code )
    447   {
    448     FT_Byte*  table   = cmap->data;
    449     FT_UInt   result  = 0;
    450     FT_Byte*  subheader;
    451 
    452 
    453     subheader = tt_cmap2_get_subheader( table, char_code );
    454     if ( subheader )
    455     {
    456       FT_Byte*  p   = subheader;
    457       FT_UInt   idx = (FT_UInt)(char_code & 0xFF);
    458       FT_UInt   start, count;
    459       FT_Int    delta;
    460       FT_UInt   offset;
    461 
    462 
    463       start  = TT_NEXT_USHORT( p ); /// start = 0x0040
    464       count  = TT_NEXT_USHORT( p ); /// count = 0x00BF 0d191
    465       delta  = TT_NEXT_SHORT ( p ); /// delta = 0d63
    466       offset = TT_PEEK_USHORT( p );
    467 
    468       idx -= start;                /// <= idx = (charcode & 0xFF) - start
                                           ///       ex) charcode = 0xA140 - start 0?
                                           ///           charcode = 0x0040 - start  
    469       if ( idx < count && offset != 0 )
    470       {
    471         p  += offset + 2 * idx;
    472         idx = TT_PEEK_USHORT( p );
    473 
    474         if ( idx != 0 )
    475           result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU;
    476       }
    477     }
    478     return result;
    479   }
    87 #define FT_PAD_FLOOR( x, n )  ( (x) & ~TYPEOF( x )( (n)-1 ) )

CHAR
FT_PAD_FLOOR(0x34,8) = 0x34 & ~ (8-1)
= 0x34 & ~ 0x0007
= 0x34 & 0xFFF8
= 0x30

SHORT
FT_PAD_FLOOR(0x1234,8) = 0x1234 & ~ (8-1)
= 0x1234 & ~ 0x0007
= 0x1234 & 0xFFF8
= 0x1230

    333 
    334   /* typeof condition taken from gnulib's `intprops.h' header file */
    335 #if ( __GNUC__ >= 2                         || \
    336       defined( __IBM__TYPEOF__ )            || \
    337       ( __SUNPRO_C >= 0x5110 && !__STDC__ ) )
    338 #define TYPEOF( type )  (__typeof__ (type))
    339 #else
    340 #define TYPEOF( type )  /* empty */
    341 #endif
    342 
    343
int e;
__typeof__(e + 1) j;   /* the same as declaring int j;     */
e = (__typeof__(e)) f; /* the same as casting e = (int) f; */