Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  cidparse.c                                                             */
  4. /*                                                                         */
  5. /*    CID-keyed Type1 parser (body).                                       */
  6. /*                                                                         */
  7. /*  Copyright 1996-2007, 2009, 2013 by                                     */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.  
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_INTERNAL_OBJECTS_H
  22. #include FT_INTERNAL_STREAM_H
  23.  
  24. #include "cidparse.h"
  25.  
  26. #include "ciderrs.h"
  27.  
  28.  
  29.   /*************************************************************************/
  30.   /*                                                                       */
  31.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  32.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  33.   /* messages during execution.                                            */
  34.   /*                                                                       */
  35. #undef  FT_COMPONENT
  36. #define FT_COMPONENT  trace_cidparse
  37.  
  38.  
  39.   /*************************************************************************/
  40.   /*************************************************************************/
  41.   /*************************************************************************/
  42.   /*****                                                               *****/
  43.   /*****                    INPUT STREAM PARSER                        *****/
  44.   /*****                                                               *****/
  45.   /*************************************************************************/
  46.   /*************************************************************************/
  47.   /*************************************************************************/
  48.  
  49.  
  50.   FT_LOCAL_DEF( FT_Error )
  51.   cid_parser_new( CID_Parser*    parser,
  52.                   FT_Stream      stream,
  53.                   FT_Memory      memory,
  54.                   PSAux_Service  psaux )
  55.   {
  56.     FT_Error  error;
  57.     FT_ULong  base_offset, offset, ps_len;
  58.     FT_Byte   *cur, *limit;
  59.     FT_Byte   *arg1, *arg2;
  60.  
  61.  
  62.     FT_MEM_ZERO( parser, sizeof ( *parser ) );
  63.     psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
  64.  
  65.     parser->stream = stream;
  66.  
  67.     base_offset = FT_STREAM_POS();
  68.  
  69.     /* first of all, check the font format in the header */
  70.     if ( FT_FRAME_ENTER( 31 ) )
  71.       goto Exit;
  72.  
  73.     if ( ft_strncmp( (char *)stream->cursor,
  74.                      "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
  75.     {
  76.       FT_TRACE2(( "  not a CID-keyed font\n" ));
  77.       error = FT_THROW( Unknown_File_Format );
  78.     }
  79.  
  80.     FT_FRAME_EXIT();
  81.     if ( error )
  82.       goto Exit;
  83.  
  84.   Again:
  85.     /* now, read the rest of the file until we find */
  86.     /* `StartData' or `/sfnts'                      */
  87.     {
  88.       FT_Byte   buffer[256 + 10];
  89.       FT_Long   read_len = 256 + 10; /* same as signed FT_Stream->size */
  90.       FT_Byte*  p        = buffer;
  91.  
  92.  
  93.       for ( offset = FT_STREAM_POS(); ; offset += 256 )
  94.       {
  95.         FT_Long  stream_len; /* same as signed FT_Stream->size */
  96.  
  97.  
  98.         stream_len = stream->size - FT_STREAM_POS();
  99.         if ( stream_len == 0 )
  100.         {
  101.           FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
  102.           error = FT_THROW( Invalid_File_Format );
  103.           goto Exit;
  104.         }
  105.  
  106.         read_len = FT_MIN( read_len, stream_len );
  107.         if ( FT_STREAM_READ( p, read_len ) )
  108.           goto Exit;
  109.  
  110.         if ( read_len < 256 )
  111.           p[read_len]  = '\0';
  112.  
  113.         limit = p + read_len - 10;
  114.  
  115.         for ( p = buffer; p < limit; p++ )
  116.         {
  117.           if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
  118.           {
  119.             /* save offset of binary data after `StartData' */
  120.             offset += (FT_ULong)( p - buffer + 10 );
  121.             goto Found;
  122.           }
  123.           else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
  124.           {
  125.             offset += (FT_ULong)( p - buffer + 7 );
  126.             goto Found;
  127.           }
  128.         }
  129.  
  130.         FT_MEM_MOVE( buffer, p, 10 );
  131.         read_len = 256;
  132.         p = buffer + 10;
  133.       }
  134.     }
  135.  
  136.   Found:
  137.     /* We have found the start of the binary data or the `/sfnts' token. */
  138.     /* Now rewind and extract the frame corresponding to this PostScript */
  139.     /* section.                                                          */
  140.  
  141.     ps_len = offset - base_offset;
  142.     if ( FT_STREAM_SEEK( base_offset )                  ||
  143.          FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
  144.       goto Exit;
  145.  
  146.     parser->data_offset    = offset;
  147.     parser->postscript_len = ps_len;
  148.     parser->root.base      = parser->postscript;
  149.     parser->root.cursor    = parser->postscript;
  150.     parser->root.limit     = parser->root.cursor + ps_len;
  151.     parser->num_dict       = -1;
  152.  
  153.     /* Finally, we check whether `StartData' or `/sfnts' was real --  */
  154.     /* it could be in a comment or string.  We also get the arguments */
  155.     /* of `StartData' to find out whether the data is represented in  */
  156.     /* binary or hex format.                                          */
  157.  
  158.     arg1 = parser->root.cursor;
  159.     cid_parser_skip_PS_token( parser );
  160.     cid_parser_skip_spaces  ( parser );
  161.     arg2 = parser->root.cursor;
  162.     cid_parser_skip_PS_token( parser );
  163.     cid_parser_skip_spaces  ( parser );
  164.  
  165.     limit = parser->root.limit;
  166.     cur   = parser->root.cursor;
  167.  
  168.     while ( cur < limit )
  169.     {
  170.       if ( parser->root.error )
  171.       {
  172.         error = parser->root.error;
  173.         goto Exit;
  174.       }
  175.  
  176.       if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
  177.       {
  178.         if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
  179.           parser->binary_length = ft_atol( (const char *)arg2 );
  180.  
  181.         limit = parser->root.limit;
  182.         cur   = parser->root.cursor;
  183.         goto Exit;
  184.       }
  185.       else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
  186.       {
  187.         FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
  188.         error = FT_THROW( Unknown_File_Format );
  189.         goto Exit;
  190.       }
  191.  
  192.       cid_parser_skip_PS_token( parser );
  193.       cid_parser_skip_spaces  ( parser );
  194.       arg1 = arg2;
  195.       arg2 = cur;
  196.       cur  = parser->root.cursor;
  197.     }
  198.  
  199.     /* we haven't found the correct `StartData'; go back and continue */
  200.     /* searching                                                      */
  201.     FT_FRAME_RELEASE( parser->postscript );
  202.     if ( !FT_STREAM_SEEK( offset ) )
  203.       goto Again;
  204.  
  205.   Exit:
  206.     return error;
  207.   }
  208.  
  209.  
  210.   FT_LOCAL_DEF( void )
  211.   cid_parser_done( CID_Parser*  parser )
  212.   {
  213.     /* always free the private dictionary */
  214.     if ( parser->postscript )
  215.     {
  216.       FT_Stream  stream = parser->stream;
  217.  
  218.  
  219.       FT_FRAME_RELEASE( parser->postscript );
  220.     }
  221.     parser->root.funcs.done( &parser->root );
  222.   }
  223.  
  224.  
  225. /* END */
  226.