(root)/
fontconfig-2.14.2/
src/
ftglue.c
       1  /* ftglue.c: Glue code for compiling the OpenType code from
       2   *           FreeType 1 using only the public API of FreeType 2
       3   *
       4   * By David Turner, The FreeType Project (www.freetype.org)
       5   *
       6   * This code is explicitely put in the public domain
       7   *
       8   * See ftglue.h for more information.
       9   */
      10  
      11  #include "ftglue.h"
      12  
      13  #if 0
      14  #include <stdio.h>
      15  #define  LOG(x)  ftglue_log x
      16  
      17  static void
      18  ftglue_log( const char*   format, ... )
      19  {
      20    va_list  ap;
      21  
      22    va_start( ap, format );
      23    vfprintf( stderr, format, ap );
      24    va_end( ap );
      25  }
      26  
      27  #else
      28  #define  LOG(x)  do {} while (0)
      29  #endif
      30  
      31  /* only used internally */
      32  static FT_Pointer
      33  ftglue_qalloc( FT_Memory  memory,
      34                 FT_ULong   size,
      35                 FT_Error  *perror )
      36  {
      37    FT_Error    error = 0;
      38    FT_Pointer  block = NULL;
      39  
      40    if ( size > 0 )
      41    {
      42      block = memory->alloc( memory, size );
      43      if ( !block )
      44        error = FT_Err_Out_Of_Memory;
      45    }
      46  
      47    *perror = error;
      48    return block;
      49  }
      50  
      51  #undef   QALLOC  /* just in case */
      52  #define  QALLOC(ptr,size)    ( (ptr) = ftglue_qalloc( memory, (size), &error ), error != 0 )
      53  #define  FREE(_ptr)                    \
      54    do {                                 \
      55      if ( (_ptr) )                      \
      56      {                                  \
      57        ftglue_free( memory, _ptr );     \
      58        _ptr = NULL;                     \
      59      }                                  \
      60    } while (0)
      61  
      62  
      63  static void
      64  ftglue_free( FT_Memory   memory,
      65               FT_Pointer  block )
      66  {
      67    if ( block )
      68      memory->free( memory, block );
      69  }
      70  
      71  FTGLUE_APIDEF( FT_Long )
      72  ftglue_stream_pos( FT_Stream   stream )
      73  {
      74    LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos ));
      75    return stream->pos;
      76  }
      77  
      78  
      79  FTGLUE_APIDEF( FT_Error )
      80  ftglue_stream_seek( FT_Stream   stream,
      81                      FT_Long     pos )
      82  {
      83    FT_Error  error = 0;
      84  
      85    if ( stream->read )
      86    {
      87      if ( stream->read( stream, pos, 0, 0 ) )
      88        error = FT_Err_Invalid_Stream_Operation;
      89    }
      90    else if ( pos < 0 || (FT_ULong) pos > stream->size )
      91      error = FT_Err_Invalid_Stream_Operation;
      92  
      93    if ( !error )
      94      stream->pos = pos;
      95    LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error ));
      96    return error;
      97  }
      98  
      99  
     100  FTGLUE_APIDEF( FT_Error )
     101  ftglue_stream_frame_enter( FT_Stream   stream,
     102                             FT_ULong    count )
     103  {
     104    FT_Error  error = FT_Err_Ok;
     105    FT_ULong  read_bytes;
     106  
     107    if ( stream->read )
     108    {
     109      /* allocate the frame in memory */
     110      FT_Memory  memory = stream->memory;
     111  
     112  
     113      if ( QALLOC( stream->base, count ) )
     114        goto Exit;
     115  
     116      /* read it */
     117      read_bytes = stream->read( stream, stream->pos,
     118                                 stream->base, count );
     119      if ( read_bytes < count )
     120      {
     121        FREE( stream->base );
     122        error = FT_Err_Invalid_Stream_Operation;
     123      }
     124      stream->cursor = stream->base;
     125      stream->limit  = stream->cursor + count;
     126      stream->pos   += read_bytes;
     127    }
     128    else
     129    {
     130      /* check current and new position */
     131      if ( stream->pos >= stream->size        ||
     132           stream->pos + count > stream->size )
     133      {
     134        error = FT_Err_Invalid_Stream_Operation;
     135        goto Exit;
     136      }
     137  
     138      /* set cursor */
     139      stream->cursor = stream->base + stream->pos;
     140      stream->limit  = stream->cursor + count;
     141      stream->pos   += count;
     142    }
     143  
     144  Exit:
     145    LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error ));
     146    return error;
     147  }
     148  
     149  
     150  FTGLUE_APIDEF( void )
     151  ftglue_stream_frame_exit( FT_Stream  stream )
     152  {
     153    if ( stream->read )
     154    {
     155      FT_Memory  memory = stream->memory;
     156  
     157      FREE( stream->base );
     158    }
     159    stream->cursor = 0;
     160    stream->limit  = 0;
     161  
     162    LOG(( "ftglue:stream:frame_exit()\n" ));
     163  }
     164  
     165  
     166  FTGLUE_APIDEF( FT_Error )
     167  ftglue_face_goto_table( FT_Face    face,
     168                          FT_ULong   the_tag,
     169                          FT_Stream  stream )
     170  {
     171    FT_Error  error;
     172  
     173    LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
     174                  face,
     175                  (int)((the_tag >> 24) & 0xFF),
     176                  (int)((the_tag >> 16) & 0xFF),
     177                  (int)((the_tag >> 8) & 0xFF),
     178                  (int)(the_tag & 0xFF),
     179                  stream ));
     180  
     181    if ( !FT_IS_SFNT(face) )
     182    {
     183      LOG(( "not a SFNT face !!\n" ));
     184      error = FT_Err_Invalid_Face_Handle;
     185    }
     186    else
     187    {
     188     /* parse the directory table directly, without using
     189      * FreeType's built-in data structures
     190      */
     191      FT_ULong  offset = 0, sig;
     192      FT_UInt   count, nn;
     193  
     194      if ( FILE_Seek( 0 ) || ACCESS_Frame( 4 ) )
     195        goto Exit;
     196  
     197      sig = GET_Tag4();
     198  
     199      FORGET_Frame();
     200  
     201      if ( sig == FT_MAKE_TAG( 't', 't', 'c', 'f' ) )
     202      {
     203        /* deal with TrueType collections */
     204  
     205        LOG(( ">> This is a TrueType Collection\n" ));
     206  
     207        if ( FILE_Seek( 12 + face->face_index*4 ) ||
     208             ACCESS_Frame( 4 )                    )
     209          goto Exit;
     210  
     211        offset = GET_ULong();
     212  
     213        FORGET_Frame();
     214      }
     215  
     216      LOG(( "TrueType offset = %ld\n", offset ));
     217  
     218      if ( FILE_Seek( offset+4 ) ||
     219           ACCESS_Frame( 2 )     )
     220        goto Exit;
     221  
     222      count = GET_UShort();
     223  
     224      FORGET_Frame();
     225  
     226      if ( FILE_Seek( offset+12 )   ||
     227           ACCESS_Frame( count*16 ) )
     228        goto Exit;
     229  
     230      for ( nn = 0; nn < count; nn++ )
     231      {
     232        FT_ULong  tag                = GET_ULong();
     233        FT_ULong  checksum FC_UNUSED = GET_ULong();
     234        FT_ULong  start              = GET_ULong();
     235        FT_ULong  size     FC_UNUSED = GET_ULong();
     236  
     237        if ( tag == the_tag )
     238        {
     239          LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
     240          error = ftglue_stream_seek( stream, start );
     241          goto FoundIt;
     242        }
     243      }
     244      error = FT_Err_Table_Missing;
     245  
     246    FoundIt:
     247      FORGET_Frame();
     248    }
     249  
     250  Exit:
     251    LOG(( "TrueType error=%d\n", error ));
     252  
     253    return error;
     254  }
     255  
     256  #undef QALLOC
     257  #include "fcaliastail.h"
     258  #undef __ftglue__