ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ttkern.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttkern.c                                                               */
00004 /*                                                                         */
00005 /*    Load the basic TrueType kerning table.  This doesn't handle          */
00006 /*    kerning data within the GPOS table at the moment.                    */
00007 /*                                                                         */
00008 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */
00009 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00010 /*                                                                         */
00011 /*  This file is part of the FreeType project, and may only be used,       */
00012 /*  modified, and distributed under the terms of the FreeType project      */
00013 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00014 /*  this file you indicate that you have read the license and              */
00015 /*  understand and accept it fully.                                        */
00016 /*                                                                         */
00017 /***************************************************************************/
00018 
00019 
00020 #include <ft2build.h>
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_TRUETYPE_TAGS_H
00024 #include "ttkern.h"
00025 
00026 #include "sferrors.h"
00027 
00028 
00029   /*************************************************************************/
00030   /*                                                                       */
00031   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00032   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00033   /* messages during execution.                                            */
00034   /*                                                                       */
00035 #undef  FT_COMPONENT
00036 #define FT_COMPONENT  trace_ttkern
00037 
00038 
00039 #undef  TT_KERN_INDEX
00040 #define TT_KERN_INDEX( g1, g2 )  ( ( (FT_ULong)(g1) << 16 ) | (g2) )
00041 
00042 
00043   FT_LOCAL_DEF( FT_Error )
00044   tt_face_load_kern( TT_Face    face,
00045                      FT_Stream  stream )
00046   {
00047     FT_Error   error;
00048     FT_ULong   table_size;
00049     FT_Byte*   p;
00050     FT_Byte*   p_limit;
00051     FT_UInt    nn, num_tables;
00052     FT_UInt32  avail = 0, ordered = 0;
00053 
00054 
00055     /* the kern table is optional; exit silently if it is missing */
00056     error = face->goto_table( face, TTAG_kern, stream, &table_size );
00057     if ( error )
00058       goto Exit;
00059 
00060     if ( table_size < 4 )  /* the case of a malformed table */
00061     {
00062       FT_ERROR(( "tt_face_load_kern:"
00063                  " kerning table is too small - ignored\n" ));
00064       error = SFNT_Err_Table_Missing;
00065       goto Exit;
00066     }
00067 
00068     if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) )
00069     {
00070       FT_ERROR(( "tt_face_load_kern:"
00071                  " could not extract kerning table\n" ));
00072       goto Exit;
00073     }
00074 
00075     face->kern_table_size = table_size;
00076 
00077     p       = face->kern_table;
00078     p_limit = p + table_size;
00079 
00080     p         += 2; /* skip version */
00081     num_tables = FT_NEXT_USHORT( p );
00082 
00083     if ( num_tables > 32 ) /* we only support up to 32 sub-tables */
00084       num_tables = 32;
00085 
00086     for ( nn = 0; nn < num_tables; nn++ )
00087     {
00088       FT_UInt    num_pairs, length, coverage;
00089       FT_Byte*   p_next;
00090       FT_UInt32  mask = (FT_UInt32)1UL << nn;
00091 
00092 
00093       if ( p + 6 > p_limit )
00094         break;
00095 
00096       p_next = p;
00097 
00098       p += 2; /* skip version */
00099       length   = FT_NEXT_USHORT( p );
00100       coverage = FT_NEXT_USHORT( p );
00101 
00102       if ( length <= 6 )
00103         break;
00104 
00105       p_next += length;
00106 
00107       if ( p_next > p_limit )  /* handle broken table */
00108         p_next = p_limit;
00109 
00110       /* only use horizontal kerning tables */
00111       if ( ( coverage & ~8 ) != 0x0001 ||
00112            p + 8 > p_limit             )
00113         goto NextTable;
00114 
00115       num_pairs = FT_NEXT_USHORT( p );
00116       p        += 6;
00117 
00118       if ( ( p_next - p ) < 6 * (int)num_pairs ) /* handle broken count */
00119         num_pairs = (FT_UInt)( ( p_next - p ) / 6 );
00120 
00121       avail |= mask;
00122 
00123       /*
00124        *  Now check whether the pairs in this table are ordered.
00125        *  We then can use binary search.
00126        */
00127       if ( num_pairs > 0 )
00128       {
00129         FT_ULong  count;
00130         FT_ULong  old_pair;
00131 
00132 
00133         old_pair = FT_NEXT_ULONG( p );
00134         p       += 2;
00135 
00136         for ( count = num_pairs - 1; count > 0; count-- )
00137         {
00138           FT_UInt32  cur_pair;
00139 
00140 
00141           cur_pair = FT_NEXT_ULONG( p );
00142           if ( cur_pair <= old_pair )
00143             break;
00144 
00145           p += 2;
00146           old_pair = cur_pair;
00147         }
00148 
00149         if ( count == 0 )
00150           ordered |= mask;
00151       }
00152 
00153     NextTable:
00154       p = p_next;
00155     }
00156 
00157     face->num_kern_tables = nn;
00158     face->kern_avail_bits = avail;
00159     face->kern_order_bits = ordered;
00160 
00161   Exit:
00162     return error;
00163   }
00164 
00165 
00166   FT_LOCAL_DEF( void )
00167   tt_face_done_kern( TT_Face  face )
00168   {
00169     FT_Stream  stream = face->root.stream;
00170 
00171 
00172     FT_FRAME_RELEASE( face->kern_table );
00173     face->kern_table_size = 0;
00174     face->num_kern_tables = 0;
00175     face->kern_avail_bits = 0;
00176     face->kern_order_bits = 0;
00177   }
00178 
00179 
00180   FT_LOCAL_DEF( FT_Int )
00181   tt_face_get_kerning( TT_Face  face,
00182                        FT_UInt  left_glyph,
00183                        FT_UInt  right_glyph )
00184   {
00185     FT_Int    result = 0;
00186     FT_UInt   count, mask = 1;
00187     FT_Byte*  p       = face->kern_table;
00188     FT_Byte*  p_limit = p + face->kern_table_size;
00189 
00190 
00191     p   += 4;
00192     mask = 0x0001;
00193 
00194     for ( count = face->num_kern_tables;
00195           count > 0 && p + 6 <= p_limit;
00196           count--, mask <<= 1 )
00197     {
00198       FT_Byte* base     = p;
00199       FT_Byte* next     = base;
00200       FT_UInt  version  = FT_NEXT_USHORT( p );
00201       FT_UInt  length   = FT_NEXT_USHORT( p );
00202       FT_UInt  coverage = FT_NEXT_USHORT( p );
00203       FT_UInt  num_pairs;
00204       FT_Int   value    = 0;
00205 
00206       FT_UNUSED( version );
00207 
00208 
00209       next = base + length;
00210 
00211       if ( next > p_limit )  /* handle broken table */
00212         next = p_limit;
00213 
00214       if ( ( face->kern_avail_bits & mask ) == 0 )
00215         goto NextTable;
00216 
00217       if ( p + 8 > next )
00218         goto NextTable;
00219 
00220       num_pairs = FT_NEXT_USHORT( p );
00221       p        += 6;
00222 
00223       if ( ( next - p ) < 6 * (int)num_pairs )  /* handle broken count  */
00224         num_pairs = (FT_UInt)( ( next - p ) / 6 );
00225 
00226       switch ( coverage >> 8 )
00227       {
00228       case 0:
00229         {
00230           FT_ULong  key0 = TT_KERN_INDEX( left_glyph, right_glyph );
00231 
00232 
00233           if ( face->kern_order_bits & mask )   /* binary search */
00234           {
00235             FT_UInt   min = 0;
00236             FT_UInt   max = num_pairs;
00237 
00238 
00239             while ( min < max )
00240             {
00241               FT_UInt   mid = ( min + max ) >> 1;
00242               FT_Byte*  q   = p + 6 * mid;
00243               FT_ULong  key;
00244 
00245 
00246               key = FT_NEXT_ULONG( q );
00247 
00248               if ( key == key0 )
00249               {
00250                 value = FT_PEEK_SHORT( q );
00251                 goto Found;
00252               }
00253               if ( key < key0 )
00254                 min = mid + 1;
00255               else
00256                 max = mid;
00257             }
00258           }
00259           else /* linear search */
00260           {
00261             FT_UInt  count2;
00262 
00263 
00264             for ( count2 = num_pairs; count2 > 0; count2-- )
00265             {
00266               FT_ULong  key = FT_NEXT_ULONG( p );
00267 
00268 
00269               if ( key == key0 )
00270               {
00271                 value = FT_PEEK_SHORT( p );
00272                 goto Found;
00273               }
00274               p += 2;
00275             }
00276           }
00277         }
00278         break;
00279 
00280        /*
00281         *  We don't support format 2 because we haven't seen a single font
00282         *  using it in real life...
00283         */
00284 
00285       default:
00286         ;
00287       }
00288 
00289       goto NextTable;
00290 
00291     Found:
00292       if ( coverage & 8 ) /* override or add */
00293         result = value;
00294       else
00295         result += value;
00296 
00297     NextTable:
00298       p = next;
00299     }
00300 
00301     return result;
00302   }
00303 
00304 #undef TT_KERN_INDEX
00305 
00306 /* END */

Generated on Sat May 26 2012 04:32:56 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.