ttkern.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:7k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttkern.c                                                               */
  4. /*                                                                         */
  5. /*    Load the basic TrueType kerning table.  This doesn't handle          */
  6. /*    kerning data within the GPOS table at the moment.                    */
  7. /*                                                                         */
  8. /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
  9. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  10. /*                                                                         */
  11. /*  This file is part of the FreeType project, and may only be used,       */
  12. /*  modified, and distributed under the terms of the FreeType project      */
  13. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  14. /*  this file you indicate that you have read the license and              */
  15. /*  understand and accept it fully.                                        */
  16. /*                                                                         */
  17. /***************************************************************************/
  18. #include <ft2build.h>
  19. #include FT_INTERNAL_DEBUG_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_TRUETYPE_TAGS_H
  22. #include "ttkern.h"
  23. #include "ttload.h"
  24. #include "sferrors.h"
  25.   /*************************************************************************/
  26.   /*                                                                       */
  27.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  28.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  29.   /* messages during execution.                                            */
  30.   /*                                                                       */
  31. #undef  FT_COMPONENT
  32. #define FT_COMPONENT  trace_ttkern
  33. #undef  TT_KERN_INDEX
  34. #define TT_KERN_INDEX( g1, g2 )  ( ( (FT_ULong)(g1) << 16 ) | (g2) )
  35.   FT_LOCAL_DEF( FT_Error )
  36.   tt_face_load_kern( TT_Face    face,
  37.                      FT_Stream  stream )
  38.   {
  39.     FT_Error   error;
  40.     FT_ULong   table_size;
  41.     FT_Byte*   p;
  42.     FT_Byte*   p_limit;
  43.     FT_UInt    nn, num_tables;
  44.     FT_UInt32  avail = 0, ordered = 0;
  45.     /* the kern table is optional; exit silently if it is missing */
  46.     error = face->goto_table( face, TTAG_kern, stream, &table_size );
  47.     if ( error )
  48.       goto Exit;
  49.     if ( table_size < 4 )  /* the case of a malformed table */
  50.     {
  51.       FT_ERROR(( "kerning table is too small - ignoredn" ));
  52.       error = SFNT_Err_Table_Missing;
  53.       goto Exit;
  54.     }
  55.     if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) )
  56.     {
  57.       FT_ERROR(( "could not extract kerning tablen" ));
  58.       goto Exit;
  59.     }
  60.     face->kern_table_size = table_size;
  61.     p       = face->kern_table;
  62.     p_limit = p + table_size;
  63.     p         += 2; /* skip version */
  64.     num_tables = FT_NEXT_USHORT( p );
  65.     if ( num_tables > 32 ) /* we only support up to 32 sub-tables */
  66.       num_tables = 32;
  67.     for ( nn = 0; nn < num_tables; nn++ )
  68.     {
  69.       FT_UInt    num_pairs, length, coverage;
  70.       FT_Byte*   p_next;
  71.       FT_UInt32  mask = 1UL << nn;
  72.       if ( p + 6 > p_limit )
  73.         break;
  74.       p_next = p;
  75.       p += 2; /* skip version */
  76.       length   = FT_NEXT_USHORT( p );
  77.       coverage = FT_NEXT_USHORT( p );
  78.       if ( length <= 6 )
  79.         break;
  80.       p_next += length;
  81.       /* only use horizontal kerning tables */
  82.       if ( ( coverage & ~8 ) != 0x0001 ||
  83.            p + 8 > p_limit             )
  84.         goto NextTable;
  85.       num_pairs = FT_NEXT_USHORT( p );
  86.       p        += 6;
  87.       if ( p + 6 * num_pairs > p_limit )
  88.         goto NextTable;
  89.       avail |= mask;
  90.       /*
  91.        *  Now check whether the pairs in this table are ordered.
  92.        *  We then can use binary search.
  93.        */
  94.       if ( num_pairs > 0 )
  95.       {
  96.         FT_UInt  count;
  97.         FT_UInt  old_pair;
  98.         old_pair = FT_NEXT_ULONG( p );
  99.         p       += 2;
  100.         for ( count = num_pairs - 1; count > 0; count-- )
  101.         {
  102.           FT_UInt32  cur_pair;
  103.           cur_pair = FT_NEXT_ULONG( p );
  104.           if ( cur_pair <= old_pair )
  105.             break;
  106.           p += 2;
  107.           old_pair = cur_pair;
  108.         }
  109.         if ( count == 0 )
  110.           ordered |= mask;
  111.       }
  112.     NextTable:
  113.       p = p_next;
  114.     }
  115.     face->num_kern_tables = nn;
  116.     face->kern_avail_bits = avail;
  117.     face->kern_order_bits = ordered;
  118.   Exit:
  119.     return error;
  120.   }
  121.   FT_LOCAL_DEF( void )
  122.   tt_face_done_kern( TT_Face  face )
  123.   {
  124.     FT_Stream  stream = face->root.stream;
  125.     FT_FRAME_RELEASE( face->kern_table );
  126.     face->kern_table_size = 0;
  127.     face->num_kern_tables = 0;
  128.     face->kern_avail_bits = 0;
  129.     face->kern_order_bits = 0;
  130.   }
  131.   FT_LOCAL_DEF( FT_Int )
  132.   tt_face_get_kerning( TT_Face  face,
  133.                        FT_UInt  left_glyph,
  134.                        FT_UInt  right_glyph )
  135.   {
  136.     FT_Int    result = 0;
  137.     FT_UInt   count, mask = 1;
  138.     FT_Byte*  p       = face->kern_table;
  139.     p   += 4;
  140.     mask = 0x0001;
  141.     for ( count = face->num_kern_tables; count > 0; count--, mask <<= 1 )
  142.     {
  143.       FT_Byte* base     = p;
  144.       FT_Byte* next     = base;
  145.       FT_UInt  version  = FT_NEXT_USHORT( p );
  146.       FT_UInt  length   = FT_NEXT_USHORT( p );
  147.       FT_UInt  coverage = FT_NEXT_USHORT( p );
  148.       FT_Int   value    = 0;
  149.       FT_UNUSED( version );
  150.       next = base + length;
  151.       if ( ( face->kern_avail_bits & mask ) == 0 )
  152.         goto NextTable;
  153.       if ( p + 8 > next )
  154.         goto NextTable;
  155.       switch ( coverage >> 8 )
  156.       {
  157.       case 0:
  158.         {
  159.           FT_UInt   num_pairs = FT_NEXT_USHORT( p );
  160.           FT_ULong  key0      = TT_KERN_INDEX( left_glyph, right_glyph );
  161.           p += 6;
  162.           if ( face->kern_order_bits & mask )   /* binary search */
  163.           {
  164.             FT_UInt   min = 0;
  165.             FT_UInt   max = num_pairs;
  166.             while ( min < max )
  167.             {
  168.               FT_UInt   mid = ( min + max ) >> 1;
  169.               FT_Byte*  q   = p + 6 * mid;
  170.               FT_ULong  key;
  171.               key = FT_NEXT_ULONG( q );
  172.               if ( key == key0 )
  173.               {
  174.                 value = FT_PEEK_SHORT( q );
  175.                 goto Found;
  176.               }
  177.               if ( key < key0 )
  178.                 min = mid + 1;
  179.               else
  180.                 max = mid;
  181.             }
  182.           }
  183.           else /* linear search */
  184.           {
  185.             FT_UInt  count2;
  186.             for ( count2 = num_pairs; count2 > 0; count2-- )
  187.             {
  188.               FT_ULong  key = FT_NEXT_ULONG( p );
  189.               if ( key == key0 )
  190.               {
  191.                 value = FT_PEEK_SHORT( p );
  192.                 goto Found;
  193.               }
  194.               p += 2;
  195.             }
  196.           }
  197.         }
  198.         break;
  199.        /*
  200.         *  We don't support format 2 because we haven't seen a single font
  201.         *  using it in real life...
  202.         */
  203.       default:
  204.         ;
  205.       }
  206.       goto NextTable;
  207.     Found:
  208.       if ( coverage & 8 ) /* override or add */
  209.         result = value;
  210.       else
  211.         result += value;
  212.     NextTable:
  213.       p = next;
  214.     }
  215.     return result;
  216.   }
  217. #undef TT_KERN_INDEX
  218. /* END */