misc/libfreetype/src/type1/t1gload.c
changeset 5172 88f2e05288ba
equal deleted inserted replaced
5171:f9283dc4860d 5172:88f2e05288ba
       
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  t1gload.c                                                              */
       
     4 /*                                                                         */
       
     5 /*    Type 1 Glyph Loader (body).                                          */
       
     6 /*                                                                         */
       
     7 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 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 "t1gload.h"
       
    21 #include FT_INTERNAL_CALC_H
       
    22 #include FT_INTERNAL_DEBUG_H
       
    23 #include FT_INTERNAL_STREAM_H
       
    24 #include FT_OUTLINE_H
       
    25 #include FT_INTERNAL_POSTSCRIPT_AUX_H
       
    26 
       
    27 #include "t1errors.h"
       
    28 
       
    29 
       
    30   /*************************************************************************/
       
    31   /*                                                                       */
       
    32   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
       
    33   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
       
    34   /* messages during execution.                                            */
       
    35   /*                                                                       */
       
    36 #undef  FT_COMPONENT
       
    37 #define FT_COMPONENT  trace_t1gload
       
    38 
       
    39 
       
    40   /*************************************************************************/
       
    41   /*************************************************************************/
       
    42   /*************************************************************************/
       
    43   /**********                                                      *********/
       
    44   /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
       
    45   /**********                                                      *********/
       
    46   /**********    The following code is in charge of computing      *********/
       
    47   /**********    the maximum advance width of the font.  It        *********/
       
    48   /**********    quickly processes each glyph charstring to        *********/
       
    49   /**********    extract the value from either a `sbw' or `seac'   *********/
       
    50   /**********    operator.                                         *********/
       
    51   /**********                                                      *********/
       
    52   /*************************************************************************/
       
    53   /*************************************************************************/
       
    54   /*************************************************************************/
       
    55 
       
    56 
       
    57   FT_LOCAL_DEF( FT_Error )
       
    58   T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder,
       
    59                                       FT_UInt     glyph_index,
       
    60                                       FT_Data*    char_string )
       
    61   {
       
    62     T1_Face   face  = (T1_Face)decoder->builder.face;
       
    63     T1_Font   type1 = &face->type1;
       
    64     FT_Error  error = T1_Err_Ok;
       
    65 
       
    66 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
    67     FT_Incremental_InterfaceRec *inc =
       
    68                       face->root.internal->incremental_interface;
       
    69 #endif
       
    70 
       
    71 
       
    72     decoder->font_matrix = type1->font_matrix;
       
    73     decoder->font_offset = type1->font_offset;
       
    74 
       
    75 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
    76 
       
    77     /* For incremental fonts get the character data using the */
       
    78     /* callback function.                                     */
       
    79     if ( inc )
       
    80       error = inc->funcs->get_glyph_data( inc->object,
       
    81                                           glyph_index, char_string );
       
    82     else
       
    83 
       
    84 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
       
    85 
       
    86     /* For ordinary fonts get the character data stored in the face record. */
       
    87     {
       
    88       char_string->pointer = type1->charstrings[glyph_index];
       
    89       char_string->length  = (FT_Int)type1->charstrings_len[glyph_index];
       
    90     }
       
    91 
       
    92     if ( !error )
       
    93       error = decoder->funcs.parse_charstrings(
       
    94                 decoder, (FT_Byte*)char_string->pointer,
       
    95                 char_string->length );
       
    96 
       
    97 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
    98 
       
    99     /* Incremental fonts can optionally override the metrics. */
       
   100     if ( !error && inc && inc->funcs->get_glyph_metrics )
       
   101     {
       
   102       FT_Incremental_MetricsRec  metrics;
       
   103 
       
   104 
       
   105       metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
       
   106       metrics.bearing_y = 0;
       
   107       metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
       
   108       metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
       
   109 
       
   110       error = inc->funcs->get_glyph_metrics( inc->object,
       
   111                                              glyph_index, FALSE, &metrics );
       
   112 
       
   113       decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
       
   114       decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
       
   115       decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
       
   116     }
       
   117 
       
   118 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
       
   119 
       
   120     return error;
       
   121   }
       
   122 
       
   123 
       
   124   FT_CALLBACK_DEF( FT_Error )
       
   125   T1_Parse_Glyph( T1_Decoder  decoder,
       
   126                   FT_UInt     glyph_index )
       
   127   {
       
   128     FT_Data   glyph_data;
       
   129     FT_Error  error = T1_Parse_Glyph_And_Get_Char_String(
       
   130                         decoder, glyph_index, &glyph_data );
       
   131 
       
   132 
       
   133 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
   134 
       
   135     if ( !error )
       
   136     {
       
   137       T1_Face  face = (T1_Face)decoder->builder.face;
       
   138 
       
   139 
       
   140       if ( face->root.internal->incremental_interface )
       
   141         face->root.internal->incremental_interface->funcs->free_glyph_data(
       
   142           face->root.internal->incremental_interface->object,
       
   143           &glyph_data );
       
   144     }
       
   145 
       
   146 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
       
   147 
       
   148     return error;
       
   149   }
       
   150 
       
   151 
       
   152   FT_LOCAL_DEF( FT_Error )
       
   153   T1_Compute_Max_Advance( T1_Face  face,
       
   154                           FT_Pos*  max_advance )
       
   155   {
       
   156     FT_Error       error;
       
   157     T1_DecoderRec  decoder;
       
   158     FT_Int         glyph_index;
       
   159     T1_Font        type1 = &face->type1;
       
   160     PSAux_Service  psaux = (PSAux_Service)face->psaux;
       
   161 
       
   162 
       
   163     FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
       
   164 
       
   165     *max_advance = 0;
       
   166 
       
   167     /* initialize load decoder */
       
   168     error = psaux->t1_decoder_funcs->init( &decoder,
       
   169                                            (FT_Face)face,
       
   170                                            0, /* size       */
       
   171                                            0, /* glyph slot */
       
   172                                            (FT_Byte**)type1->glyph_names,
       
   173                                            face->blend,
       
   174                                            0,
       
   175                                            FT_RENDER_MODE_NORMAL,
       
   176                                            T1_Parse_Glyph );
       
   177     if ( error )
       
   178       return error;
       
   179 
       
   180     decoder.builder.metrics_only = 1;
       
   181     decoder.builder.load_points  = 0;
       
   182 
       
   183     decoder.num_subrs     = type1->num_subrs;
       
   184     decoder.subrs         = type1->subrs;
       
   185     decoder.subrs_len     = type1->subrs_len;
       
   186 
       
   187     decoder.buildchar     = face->buildchar;
       
   188     decoder.len_buildchar = face->len_buildchar;
       
   189 
       
   190     *max_advance = 0;
       
   191 
       
   192     /* for each glyph, parse the glyph charstring and extract */
       
   193     /* the advance width                                      */
       
   194     for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
       
   195     {
       
   196       /* now get load the unscaled outline */
       
   197       error = T1_Parse_Glyph( &decoder, glyph_index );
       
   198       if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
       
   199         *max_advance = decoder.builder.advance.x;
       
   200 
       
   201       /* ignore the error if one occurred - skip to next glyph */
       
   202     }
       
   203 
       
   204     psaux->t1_decoder_funcs->done( &decoder );
       
   205 
       
   206     return T1_Err_Ok;
       
   207   }
       
   208 
       
   209 
       
   210   FT_LOCAL_DEF( FT_Error )
       
   211   T1_Get_Advances( T1_Face    face,
       
   212                    FT_UInt    first,
       
   213                    FT_UInt    count,
       
   214                    FT_ULong   load_flags,
       
   215                    FT_Fixed*  advances )
       
   216   {
       
   217     T1_DecoderRec  decoder;
       
   218     T1_Font        type1 = &face->type1;
       
   219     PSAux_Service  psaux = (PSAux_Service)face->psaux;
       
   220     FT_UInt        nn;
       
   221     FT_Error       error;
       
   222 
       
   223 
       
   224     if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
       
   225     {
       
   226       for ( nn = 0; nn < count; nn++ )
       
   227         advances[nn] = 0;
       
   228 
       
   229       return T1_Err_Ok;
       
   230     }
       
   231 
       
   232     error = psaux->t1_decoder_funcs->init( &decoder,
       
   233                                            (FT_Face)face,
       
   234                                            0, /* size       */
       
   235                                            0, /* glyph slot */
       
   236                                            (FT_Byte**)type1->glyph_names,
       
   237                                            face->blend,
       
   238                                            0,
       
   239                                            FT_RENDER_MODE_NORMAL,
       
   240                                            T1_Parse_Glyph );
       
   241     if ( error )
       
   242       return error;
       
   243 
       
   244     decoder.builder.metrics_only = 1;
       
   245     decoder.builder.load_points  = 0;
       
   246 
       
   247     decoder.num_subrs = type1->num_subrs;
       
   248     decoder.subrs     = type1->subrs;
       
   249     decoder.subrs_len = type1->subrs_len;
       
   250 
       
   251     decoder.buildchar     = face->buildchar;
       
   252     decoder.len_buildchar = face->len_buildchar;
       
   253 
       
   254     for ( nn = 0; nn < count; nn++ )
       
   255     {
       
   256       error = T1_Parse_Glyph( &decoder, first + nn );
       
   257       if ( !error )
       
   258         advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
       
   259       else
       
   260         advances[nn] = 0;
       
   261     }
       
   262 
       
   263     return T1_Err_Ok;
       
   264   }
       
   265 
       
   266 
       
   267   FT_LOCAL_DEF( FT_Error )
       
   268   T1_Load_Glyph( T1_GlyphSlot  glyph,
       
   269                  T1_Size       size,
       
   270                  FT_UInt       glyph_index,
       
   271                  FT_Int32      load_flags )
       
   272   {
       
   273     FT_Error                error;
       
   274     T1_DecoderRec           decoder;
       
   275     T1_Face                 face = (T1_Face)glyph->root.face;
       
   276     FT_Bool                 hinting;
       
   277     T1_Font                 type1         = &face->type1;
       
   278     PSAux_Service           psaux         = (PSAux_Service)face->psaux;
       
   279     const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
       
   280 
       
   281     FT_Matrix               font_matrix;
       
   282     FT_Vector               font_offset;
       
   283     FT_Data                 glyph_data;
       
   284     FT_Bool                 must_finish_decoder = FALSE;
       
   285 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
   286     FT_Bool                 glyph_data_loaded = 0;
       
   287 #endif
       
   288 
       
   289 
       
   290 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
   291     if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
       
   292          !face->root.internal->incremental_interface   )
       
   293 #else
       
   294     if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
       
   295 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
       
   296     {
       
   297       error = T1_Err_Invalid_Argument;
       
   298       goto Exit;
       
   299     }
       
   300 
       
   301     FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
       
   302 
       
   303     if ( load_flags & FT_LOAD_NO_RECURSE )
       
   304       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
       
   305 
       
   306     if ( size )
       
   307     {
       
   308       glyph->x_scale = size->root.metrics.x_scale;
       
   309       glyph->y_scale = size->root.metrics.y_scale;
       
   310     }
       
   311     else
       
   312     {
       
   313       glyph->x_scale = 0x10000L;
       
   314       glyph->y_scale = 0x10000L;
       
   315     }
       
   316 
       
   317     glyph->root.outline.n_points   = 0;
       
   318     glyph->root.outline.n_contours = 0;
       
   319 
       
   320     hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
       
   321                        ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
       
   322 
       
   323     glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
       
   324 
       
   325     error = decoder_funcs->init( &decoder,
       
   326                                  (FT_Face)face,
       
   327                                  (FT_Size)size,
       
   328                                  (FT_GlyphSlot)glyph,
       
   329                                  (FT_Byte**)type1->glyph_names,
       
   330                                  face->blend,
       
   331                                  FT_BOOL( hinting ),
       
   332                                  FT_LOAD_TARGET_MODE( load_flags ),
       
   333                                  T1_Parse_Glyph );
       
   334     if ( error )
       
   335       goto Exit;
       
   336 
       
   337     must_finish_decoder = TRUE;
       
   338 
       
   339     decoder.builder.no_recurse = FT_BOOL(
       
   340                                    ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
       
   341 
       
   342     decoder.num_subrs     = type1->num_subrs;
       
   343     decoder.subrs         = type1->subrs;
       
   344     decoder.subrs_len     = type1->subrs_len;
       
   345 
       
   346     decoder.buildchar     = face->buildchar;
       
   347     decoder.len_buildchar = face->len_buildchar;
       
   348 
       
   349     /* now load the unscaled outline */
       
   350     error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
       
   351                                                 &glyph_data );
       
   352     if ( error )
       
   353       goto Exit;
       
   354 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
   355     glyph_data_loaded = 1;
       
   356 #endif
       
   357 
       
   358     font_matrix = decoder.font_matrix;
       
   359     font_offset = decoder.font_offset;
       
   360 
       
   361     /* save new glyph tables */
       
   362     decoder_funcs->done( &decoder );
       
   363 
       
   364     must_finish_decoder = FALSE;
       
   365 
       
   366     /* now, set the metrics -- this is rather simple, as   */
       
   367     /* the left side bearing is the xMin, and the top side */
       
   368     /* bearing the yMax                                    */
       
   369     if ( !error )
       
   370     {
       
   371       glyph->root.outline.flags &= FT_OUTLINE_OWNER;
       
   372       glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
       
   373 
       
   374       /* for composite glyphs, return only left side bearing and */
       
   375       /* advance width                                           */
       
   376       if ( load_flags & FT_LOAD_NO_RECURSE )
       
   377       {
       
   378         FT_Slot_Internal  internal = glyph->root.internal;
       
   379 
       
   380 
       
   381         glyph->root.metrics.horiBearingX =
       
   382           FIXED_TO_INT( decoder.builder.left_bearing.x );
       
   383         glyph->root.metrics.horiAdvance  =
       
   384           FIXED_TO_INT( decoder.builder.advance.x );
       
   385 
       
   386         internal->glyph_matrix      = font_matrix;
       
   387         internal->glyph_delta       = font_offset;
       
   388         internal->glyph_transformed = 1;
       
   389       }
       
   390       else
       
   391       {
       
   392         FT_BBox            cbox;
       
   393         FT_Glyph_Metrics*  metrics = &glyph->root.metrics;
       
   394         FT_Vector          advance;
       
   395 
       
   396 
       
   397         /* copy the _unscaled_ advance width */
       
   398         metrics->horiAdvance =
       
   399           FIXED_TO_INT( decoder.builder.advance.x );
       
   400         glyph->root.linearHoriAdvance =
       
   401           FIXED_TO_INT( decoder.builder.advance.x );
       
   402         glyph->root.internal->glyph_transformed = 0;
       
   403 
       
   404         if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 
       
   405         {
       
   406           /* make up vertical ones */
       
   407           metrics->vertAdvance = ( face->type1.font_bbox.yMax -
       
   408                                    face->type1.font_bbox.yMin ) >> 16;
       
   409           glyph->root.linearVertAdvance = metrics->vertAdvance;
       
   410         }
       
   411         else
       
   412         {
       
   413           metrics->vertAdvance =
       
   414             FIXED_TO_INT( decoder.builder.advance.y );
       
   415           glyph->root.linearVertAdvance =
       
   416             FIXED_TO_INT( decoder.builder.advance.y );
       
   417         }
       
   418 
       
   419         glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
       
   420 
       
   421         if ( size && size->root.metrics.y_ppem < 24 )
       
   422           glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
       
   423 
       
   424 #if 1
       
   425         /* apply the font matrix, if any */
       
   426         if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx ||
       
   427              font_matrix.xy != 0        || font_matrix.yx != 0              )
       
   428           FT_Outline_Transform( &glyph->root.outline, &font_matrix );
       
   429 
       
   430         if ( font_offset.x || font_offset.y )
       
   431           FT_Outline_Translate( &glyph->root.outline,
       
   432                                 font_offset.x,
       
   433                                 font_offset.y );
       
   434 
       
   435         advance.x = metrics->horiAdvance;
       
   436         advance.y = 0;
       
   437         FT_Vector_Transform( &advance, &font_matrix );
       
   438         metrics->horiAdvance = advance.x + font_offset.x;
       
   439         advance.x = 0;
       
   440         advance.y = metrics->vertAdvance;
       
   441         FT_Vector_Transform( &advance, &font_matrix );
       
   442         metrics->vertAdvance = advance.y + font_offset.y;
       
   443 #endif
       
   444 
       
   445         if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
       
   446         {
       
   447           /* scale the outline and the metrics */
       
   448           FT_Int       n;
       
   449           FT_Outline*  cur = decoder.builder.base;
       
   450           FT_Vector*   vec = cur->points;
       
   451           FT_Fixed     x_scale = glyph->x_scale;
       
   452           FT_Fixed     y_scale = glyph->y_scale;
       
   453 
       
   454 
       
   455           /* First of all, scale the points, if we are not hinting */
       
   456           if ( !hinting || ! decoder.builder.hints_funcs )
       
   457             for ( n = cur->n_points; n > 0; n--, vec++ )
       
   458             {
       
   459               vec->x = FT_MulFix( vec->x, x_scale );
       
   460               vec->y = FT_MulFix( vec->y, y_scale );
       
   461             }
       
   462 
       
   463           /* Then scale the metrics */
       
   464           metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
       
   465           metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
       
   466         }
       
   467 
       
   468         /* compute the other metrics */
       
   469         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
       
   470 
       
   471         metrics->width  = cbox.xMax - cbox.xMin;
       
   472         metrics->height = cbox.yMax - cbox.yMin;
       
   473 
       
   474         metrics->horiBearingX = cbox.xMin;
       
   475         metrics->horiBearingY = cbox.yMax;
       
   476 
       
   477         if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 
       
   478         {
       
   479           /* make up vertical ones */
       
   480           ft_synthesize_vertical_metrics( metrics,
       
   481                                           metrics->vertAdvance );
       
   482         }
       
   483       }
       
   484 
       
   485       /* Set control data to the glyph charstrings.  Note that this is */
       
   486       /* _not_ zero-terminated.                                        */
       
   487       glyph->root.control_data = (FT_Byte*)glyph_data.pointer;
       
   488       glyph->root.control_len  = glyph_data.length;
       
   489     }
       
   490 
       
   491 
       
   492   Exit:
       
   493 
       
   494 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       
   495     if ( glyph_data_loaded && face->root.internal->incremental_interface )
       
   496     {
       
   497       face->root.internal->incremental_interface->funcs->free_glyph_data(
       
   498         face->root.internal->incremental_interface->object,
       
   499         &glyph_data );
       
   500 
       
   501       /* Set the control data to null - it is no longer available if   */
       
   502       /* loaded incrementally.                                         */
       
   503       glyph->root.control_data = 0;
       
   504       glyph->root.control_len  = 0;
       
   505     }
       
   506 #endif
       
   507 
       
   508     if ( must_finish_decoder )
       
   509       decoder_funcs->done( &decoder );
       
   510 
       
   511     return error;
       
   512   }
       
   513 
       
   514 
       
   515 /* END */