ReactOS Fundraising Campaign 2012
 
€ 4,060 / € 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

ftccmap.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftccmap.c                                                              */
00004 /*                                                                         */
00005 /*    FreeType CharMap cache (body)                                        */
00006 /*                                                                         */
00007 /*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
00008 /*            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_FREETYPE_H
00022 #include FT_CACHE_H
00023 #include "ftcmanag.h"
00024 #include FT_INTERNAL_MEMORY_H
00025 #include FT_INTERNAL_DEBUG_H
00026 
00027 #include "ftccback.h"
00028 #include "ftcerror.h"
00029 
00030 #undef  FT_COMPONENT
00031 #define FT_COMPONENT  trace_cache
00032 
00033 
00034 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00035 
00036   typedef enum  FTC_OldCMapType_
00037   {
00038     FTC_OLD_CMAP_BY_INDEX    = 0,
00039     FTC_OLD_CMAP_BY_ENCODING = 1,
00040     FTC_OLD_CMAP_BY_ID       = 2
00041 
00042   } FTC_OldCMapType;
00043 
00044 
00045   typedef struct  FTC_OldCMapIdRec_
00046   {
00047     FT_UInt  platform;
00048     FT_UInt  encoding;
00049 
00050   } FTC_OldCMapIdRec, *FTC_OldCMapId;
00051 
00052 
00053   typedef struct  FTC_OldCMapDescRec_
00054   {
00055     FTC_FaceID       face_id;
00056     FTC_OldCMapType  type;
00057 
00058     union
00059     {
00060       FT_UInt           index;
00061       FT_Encoding       encoding;
00062       FTC_OldCMapIdRec  id;
00063 
00064     } u;
00065 
00066   } FTC_OldCMapDescRec, *FTC_OldCMapDesc;
00067 
00068 #endif /* FT_CONFIG_OLD_INTERNALS */
00069 
00070 
00071   /*************************************************************************/
00072   /*                                                                       */
00073   /* Each FTC_CMapNode contains a simple array to map a range of character */
00074   /* codes to equivalent glyph indices.                                    */
00075   /*                                                                       */
00076   /* For now, the implementation is very basic: Each node maps a range of  */
00077   /* 128 consecutive character codes to their corresponding glyph indices. */
00078   /*                                                                       */
00079   /* We could do more complex things, but I don't think it is really very  */
00080   /* useful.                                                               */
00081   /*                                                                       */
00082   /*************************************************************************/
00083 
00084 
00085   /* number of glyph indices / character code per node */
00086 #define FTC_CMAP_INDICES_MAX  128
00087 
00088   /* compute a query/node hash */
00089 #define FTC_CMAP_HASH( faceid, index, charcode )         \
00090           ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \
00091             ( (charcode) / FTC_CMAP_INDICES_MAX )      )
00092 
00093   /* the charmap query */
00094   typedef struct  FTC_CMapQueryRec_
00095   {
00096     FTC_FaceID  face_id;
00097     FT_UInt     cmap_index;
00098     FT_UInt32   char_code;
00099 
00100   } FTC_CMapQueryRec, *FTC_CMapQuery;
00101 
00102 #define FTC_CMAP_QUERY( x )  ((FTC_CMapQuery)(x))
00103 #define FTC_CMAP_QUERY_HASH( x )                                         \
00104           FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->char_code )
00105 
00106   /* the cmap cache node */
00107   typedef struct  FTC_CMapNodeRec_
00108   {
00109     FTC_NodeRec  node;
00110     FTC_FaceID   face_id;
00111     FT_UInt      cmap_index;
00112     FT_UInt32    first;                         /* first character in node */
00113     FT_UInt16    indices[FTC_CMAP_INDICES_MAX]; /* array of glyph indices  */
00114 
00115   } FTC_CMapNodeRec, *FTC_CMapNode;
00116 
00117 #define FTC_CMAP_NODE( x ) ( (FTC_CMapNode)( x ) )
00118 #define FTC_CMAP_NODE_HASH( x )                                      \
00119           FTC_CMAP_HASH( (x)->face_id, (x)->cmap_index, (x)->first )
00120 
00121   /* if (indices[n] == FTC_CMAP_UNKNOWN), we assume that the corresponding */
00122   /* glyph indices haven't been queried through FT_Get_Glyph_Index() yet   */
00123 #define FTC_CMAP_UNKNOWN  ( (FT_UInt16)-1 )
00124 
00125 
00126   /*************************************************************************/
00127   /*************************************************************************/
00128   /*****                                                               *****/
00129   /*****                        CHARMAP NODES                          *****/
00130   /*****                                                               *****/
00131   /*************************************************************************/
00132   /*************************************************************************/
00133 
00134 
00135   FT_CALLBACK_DEF( void )
00136   ftc_cmap_node_free( FTC_Node   ftcnode,
00137                       FTC_Cache  cache )
00138   {
00139     FTC_CMapNode  node   = (FTC_CMapNode)ftcnode;
00140     FT_Memory     memory = cache->memory;
00141 
00142 
00143     FT_FREE( node );
00144   }
00145 
00146 
00147   /* initialize a new cmap node */
00148   FT_CALLBACK_DEF( FT_Error )
00149   ftc_cmap_node_new( FTC_Node   *ftcanode,
00150                      FT_Pointer  ftcquery,
00151                      FTC_Cache   cache )
00152   {
00153     FTC_CMapNode  *anode  = (FTC_CMapNode*)ftcanode;
00154     FTC_CMapQuery  query  = (FTC_CMapQuery)ftcquery;
00155     FT_Error       error;
00156     FT_Memory      memory = cache->memory;
00157     FTC_CMapNode   node   = NULL;
00158     FT_UInt        nn;
00159 
00160 
00161     if ( !FT_NEW( node ) )
00162     {
00163       node->face_id    = query->face_id;
00164       node->cmap_index = query->cmap_index;
00165       node->first      = (query->char_code / FTC_CMAP_INDICES_MAX) *
00166                          FTC_CMAP_INDICES_MAX;
00167 
00168       for ( nn = 0; nn < FTC_CMAP_INDICES_MAX; nn++ )
00169         node->indices[nn] = FTC_CMAP_UNKNOWN;
00170     }
00171 
00172     *anode = node;
00173     return error;
00174   }
00175 
00176 
00177   /* compute the weight of a given cmap node */
00178   FT_CALLBACK_DEF( FT_Offset )
00179   ftc_cmap_node_weight( FTC_Node   cnode,
00180                         FTC_Cache  cache )
00181   {
00182     FT_UNUSED( cnode );
00183     FT_UNUSED( cache );
00184 
00185     return sizeof ( *cnode );
00186   }
00187 
00188 
00189   /* compare a cmap node to a given query */
00190   FT_CALLBACK_DEF( FT_Bool )
00191   ftc_cmap_node_compare( FTC_Node    ftcnode,
00192                          FT_Pointer  ftcquery,
00193                          FTC_Cache   cache )
00194   {
00195     FTC_CMapNode   node  = (FTC_CMapNode)ftcnode;
00196     FTC_CMapQuery  query = (FTC_CMapQuery)ftcquery;
00197     FT_UNUSED( cache );
00198 
00199 
00200     if ( node->face_id    == query->face_id    &&
00201          node->cmap_index == query->cmap_index )
00202     {
00203       FT_UInt32  offset = (FT_UInt32)( query->char_code - node->first );
00204 
00205 
00206       return FT_BOOL( offset < FTC_CMAP_INDICES_MAX );
00207     }
00208 
00209     return 0;
00210   }
00211 
00212 
00213   FT_CALLBACK_DEF( FT_Bool )
00214   ftc_cmap_node_remove_faceid( FTC_Node    ftcnode,
00215                                FT_Pointer  ftcface_id,
00216                                FTC_Cache   cache )
00217   {
00218     FTC_CMapNode  node    = (FTC_CMapNode)ftcnode;
00219     FTC_FaceID    face_id = (FTC_FaceID)ftcface_id;
00220     FT_UNUSED( cache );
00221 
00222     return FT_BOOL( node->face_id == face_id );
00223   }
00224 
00225 
00226   /*************************************************************************/
00227   /*************************************************************************/
00228   /*****                                                               *****/
00229   /*****                    GLYPH IMAGE CACHE                          *****/
00230   /*****                                                               *****/
00231   /*************************************************************************/
00232   /*************************************************************************/
00233 
00234 
00235   FT_CALLBACK_TABLE_DEF
00236   const FTC_CacheClassRec  ftc_cmap_cache_class =
00237   {
00238     ftc_cmap_node_new,
00239     ftc_cmap_node_weight,
00240     ftc_cmap_node_compare,
00241     ftc_cmap_node_remove_faceid,
00242     ftc_cmap_node_free,
00243 
00244     sizeof ( FTC_CacheRec ),
00245     ftc_cache_init,
00246     ftc_cache_done,
00247   };
00248 
00249 
00250   /* documentation is in ftcache.h */
00251 
00252   FT_EXPORT_DEF( FT_Error )
00253   FTC_CMapCache_New( FTC_Manager     manager,
00254                      FTC_CMapCache  *acache )
00255   {
00256     return FTC_Manager_RegisterCache( manager,
00257                                       &ftc_cmap_cache_class,
00258                                       FTC_CACHE_P( acache ) );
00259   }
00260 
00261 
00262 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00263 
00264   /*
00265    *  Unfortunately, it is not possible to support binary backwards
00266    *  compatibility in the cmap cache.  The FTC_CMapCache_Lookup signature
00267    *  changes were too deep, and there is no clever hackish way to detect
00268    *  what kind of structure we are being passed.
00269    *
00270    *  On the other hand it seems that no production code is using this
00271    *  function on Unix distributions.
00272    */
00273 
00274 #endif
00275 
00276 
00277   /* documentation is in ftcache.h */
00278 
00279   FT_EXPORT_DEF( FT_UInt )
00280   FTC_CMapCache_Lookup( FTC_CMapCache  cmap_cache,
00281                         FTC_FaceID     face_id,
00282                         FT_Int         cmap_index,
00283                         FT_UInt32      char_code )
00284   {
00285     FTC_Cache         cache = FTC_CACHE( cmap_cache );
00286     FTC_CMapQueryRec  query;
00287     FTC_Node          node;
00288     FT_Error          error;
00289     FT_UInt           gindex = 0;
00290     FT_PtrDist        hash;
00291     FT_Int            no_cmap_change = 0;
00292 
00293 
00294     if ( cmap_index < 0 )
00295     {
00296       /* Treat a negative cmap index as a special value, meaning that you */
00297       /* don't want to change the FT_Face's character map through this    */
00298       /* call.  This can be useful if the face requester callback already */
00299       /* sets the face's charmap to the appropriate value.                */
00300 
00301       no_cmap_change = 1;
00302       cmap_index     = 0;
00303     }
00304 
00305     if ( !cache )
00306     {
00307       FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" ));
00308       return 0;
00309     }
00310 
00311 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
00312 
00313     /*
00314      * If cmap_index is greater than the maximum number of cachable
00315      * charmaps, we assume the request is from a legacy rogue client 
00316      * using old internal header. See include/config/ftoption.h.
00317      */
00318     if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change )
00319     {
00320       FTC_OldCMapDesc  desc = (FTC_OldCMapDesc) face_id;
00321 
00322 
00323       char_code     = (FT_UInt32)cmap_index;
00324       query.face_id = desc->face_id;
00325 
00326 
00327       switch ( desc->type )
00328       {
00329       case FTC_OLD_CMAP_BY_INDEX:
00330         query.cmap_index = desc->u.index;
00331         query.char_code  = (FT_UInt32)cmap_index;
00332         break;
00333 
00334       case FTC_OLD_CMAP_BY_ENCODING:
00335         {
00336           FT_Face  face;
00337 
00338 
00339           error = FTC_Manager_LookupFace( cache->manager, desc->face_id,
00340                                           &face );
00341           if ( error )
00342             return 0;
00343 
00344           FT_Select_Charmap( face, desc->u.encoding );
00345 
00346           return FT_Get_Char_Index( face, char_code );
00347         }
00348 
00349       default:
00350         return 0;
00351       }
00352     }
00353     else
00354 
00355 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
00356 
00357     {
00358       query.face_id    = face_id;
00359       query.cmap_index = (FT_UInt)cmap_index;
00360       query.char_code  = char_code;
00361     }
00362 
00363     hash = FTC_CMAP_HASH( face_id, cmap_index, char_code );
00364 
00365 #if 1
00366     FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query,
00367                           node, error );
00368 #else
00369     error = FTC_Cache_Lookup( cache, hash, &query, &node );
00370 #endif
00371     if ( error )
00372       goto Exit;
00373 
00374     FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) <
00375                 FTC_CMAP_INDICES_MAX );
00376 
00377     /* something rotten can happen with rogue clients */
00378     if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >=
00379                     FTC_CMAP_INDICES_MAX ) )
00380       return 0; /* XXX: should return appropriate error */
00381 
00382     gindex = FTC_CMAP_NODE( node )->indices[char_code -
00383                                             FTC_CMAP_NODE( node )->first];
00384     if ( gindex == FTC_CMAP_UNKNOWN )
00385     {
00386       FT_Face  face;
00387 
00388 
00389       gindex = 0;
00390 
00391       error = FTC_Manager_LookupFace( cache->manager,
00392                                       FTC_CMAP_NODE( node )->face_id,
00393                                       &face );
00394       if ( error )
00395         goto Exit;
00396 
00397 #ifdef FT_MAX_CHARMAP_CACHEABLE
00398       /* something rotten can happen with rogue clients */
00399       if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE )
00400         return 0; /* XXX: should return appropriate error */
00401 #endif
00402 
00403       if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps )
00404       {
00405         FT_CharMap  old, cmap  = NULL;
00406 
00407 
00408         old  = face->charmap;
00409         cmap = face->charmaps[cmap_index];
00410 
00411         if ( old != cmap && !no_cmap_change )
00412           FT_Set_Charmap( face, cmap );
00413 
00414         gindex = FT_Get_Char_Index( face, char_code );
00415 
00416         if ( old != cmap && !no_cmap_change )
00417           FT_Set_Charmap( face, old );
00418       }
00419 
00420       FTC_CMAP_NODE( node )->indices[char_code -
00421                                      FTC_CMAP_NODE( node )->first]
00422         = (FT_UShort)gindex;
00423     }
00424 
00425   Exit:
00426     return gindex;
00427   }
00428 
00429 
00430 /* END */

Generated on Tue May 22 2012 04:37:49 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.