t1gload.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  t1gload.c                                                              */
00004 /*                                                                         */
00005 /*    Type 1 Glyph Loader (body).                                          */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include "t1gload.h"
00021 #include FT_INTERNAL_CALC_H
00022 #include FT_INTERNAL_DEBUG_H
00023 #include FT_INTERNAL_STREAM_H
00024 #include FT_OUTLINE_H
00025 #include FT_INTERNAL_POSTSCRIPT_AUX_H
00026 
00027 #include "t1errors.h"
00028 
00029 
00030   /*************************************************************************/
00031   /*                                                                       */
00032   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00033   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00034   /* messages during execution.                                            */
00035   /*                                                                       */
00036 #undef  FT_COMPONENT
00037 #define FT_COMPONENT  trace_t1gload
00038 
00039 
00040   /*************************************************************************/
00041   /*************************************************************************/
00042   /*************************************************************************/
00043   /**********                                                      *********/
00044   /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
00045   /**********                                                      *********/
00046   /**********    The following code is in charge of computing      *********/
00047   /**********    the maximum advance width of the font.  It        *********/
00048   /**********    quickly processes each glyph charstring to        *********/
00049   /**********    extract the value from either a `sbw' or `seac'   *********/
00050   /**********    operator.                                         *********/
00051   /**********                                                      *********/
00052   /*************************************************************************/
00053   /*************************************************************************/
00054   /*************************************************************************/
00055 
00056 
00057   FT_LOCAL_DEF( FT_Error )
00058   T1_Parse_Glyph_And_Get_Char_String( T1_Decoder  decoder,
00059                                       FT_UInt     glyph_index,
00060                                       FT_Data*    char_string )
00061   {
00062     T1_Face   face  = (T1_Face)decoder->builder.face;
00063     T1_Font   type1 = &face->type1;
00064     FT_Error  error = T1_Err_Ok;
00065 
00066 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00067     FT_Incremental_InterfaceRec *inc =
00068                       face->root.internal->incremental_interface;
00069 #endif
00070 
00071 
00072     decoder->font_matrix = type1->font_matrix;
00073     decoder->font_offset = type1->font_offset;
00074 
00075 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00076 
00077     /* For incremental fonts get the character data using the */
00078     /* callback function.                                     */
00079     if ( inc )
00080       error = inc->funcs->get_glyph_data( inc->object,
00081                                           glyph_index, char_string );
00082     else
00083 
00084 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
00085 
00086     /* For ordinary fonts get the character data stored in the face record. */
00087     {
00088       char_string->pointer = type1->charstrings[glyph_index];
00089       char_string->length  = (FT_Int)type1->charstrings_len[glyph_index];
00090     }
00091 
00092     if ( !error )
00093       error = decoder->funcs.parse_charstrings(
00094                 decoder, (FT_Byte*)char_string->pointer,
00095                 char_string->length );
00096 
00097 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00098 
00099     /* Incremental fonts can optionally override the metrics. */
00100     if ( !error && inc && inc->funcs->get_glyph_metrics )
00101     {
00102       FT_Incremental_MetricsRec  metrics;
00103 
00104 
00105       metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
00106       metrics.bearing_y = 0;
00107       metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
00108       metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
00109 
00110       error = inc->funcs->get_glyph_metrics( inc->object,
00111                                              glyph_index, FALSE, &metrics );
00112 
00113       decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
00114       decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
00115       decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
00116     }
00117 
00118 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
00119 
00120     return error;
00121   }
00122 
00123 
00124   FT_CALLBACK_DEF( FT_Error )
00125   T1_Parse_Glyph( T1_Decoder  decoder,
00126                   FT_UInt     glyph_index )
00127   {
00128     FT_Data   glyph_data;
00129     FT_Error  error = T1_Parse_Glyph_And_Get_Char_String(
00130                         decoder, glyph_index, &glyph_data );
00131 
00132 
00133 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00134 
00135     if ( !error )
00136     {
00137       T1_Face  face = (T1_Face)decoder->builder.face;
00138 
00139 
00140       if ( face->root.internal->incremental_interface )
00141         face->root.internal->incremental_interface->funcs->free_glyph_data(
00142           face->root.internal->incremental_interface->object,
00143           &glyph_data );
00144     }
00145 
00146 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
00147 
00148     return error;
00149   }
00150 
00151 
00152   FT_LOCAL_DEF( FT_Error )
00153   T1_Compute_Max_Advance( T1_Face  face,
00154                           FT_Pos*  max_advance )
00155   {
00156     FT_Error       error;
00157     T1_DecoderRec  decoder;
00158     FT_Int         glyph_index;
00159     T1_Font        type1 = &face->type1;
00160     PSAux_Service  psaux = (PSAux_Service)face->psaux;
00161 
00162 
00163     FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
00164 
00165     *max_advance = 0;
00166 
00167     /* initialize load decoder */
00168     error = psaux->t1_decoder_funcs->init( &decoder,
00169                                            (FT_Face)face,
00170                                            0, /* size       */
00171                                            0, /* glyph slot */
00172                                            (FT_Byte**)type1->glyph_names,
00173                                            face->blend,
00174                                            0,
00175                                            FT_RENDER_MODE_NORMAL,
00176                                            T1_Parse_Glyph );
00177     if ( error )
00178       return error;
00179 
00180     decoder.builder.metrics_only = 1;
00181     decoder.builder.load_points  = 0;
00182 
00183     decoder.num_subrs     = type1->num_subrs;
00184     decoder.subrs         = type1->subrs;
00185     decoder.subrs_len     = type1->subrs_len;
00186 
00187     decoder.buildchar     = face->buildchar;
00188     decoder.len_buildchar = face->len_buildchar;
00189 
00190     *max_advance = 0;
00191 
00192     /* for each glyph, parse the glyph charstring and extract */
00193     /* the advance width                                      */
00194     for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
00195     {
00196       /* now get load the unscaled outline */
00197       error = T1_Parse_Glyph( &decoder, glyph_index );
00198       if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
00199         *max_advance = decoder.builder.advance.x;
00200 
00201       /* ignore the error if one occurred - skip to next glyph */
00202     }
00203 
00204     psaux->t1_decoder_funcs->done( &decoder );
00205 
00206     return T1_Err_Ok;
00207   }
00208 
00209 
00210   FT_LOCAL_DEF( FT_Error )
00211   T1_Get_Advances( T1_Face    face,
00212                    FT_UInt    first,
00213                    FT_UInt    count,
00214                    FT_ULong   load_flags,
00215                    FT_Fixed*  advances )
00216   {
00217     T1_DecoderRec  decoder;
00218     T1_Font        type1 = &face->type1;
00219     PSAux_Service  psaux = (PSAux_Service)face->psaux;
00220     FT_UInt        nn;
00221     FT_Error       error;
00222 
00223 
00224     if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
00225     {
00226       for ( nn = 0; nn < count; nn++ )
00227         advances[nn] = 0;
00228 
00229       return T1_Err_Ok;
00230     }
00231 
00232     error = psaux->t1_decoder_funcs->init( &decoder,
00233                                            (FT_Face)face,
00234                                            0, /* size       */
00235                                            0, /* glyph slot */
00236                                            (FT_Byte**)type1->glyph_names,
00237                                            face->blend,
00238                                            0,
00239                                            FT_RENDER_MODE_NORMAL,
00240                                            T1_Parse_Glyph );
00241     if ( error )
00242       return error;
00243 
00244     decoder.builder.metrics_only = 1;
00245     decoder.builder.load_points  = 0;
00246 
00247     decoder.num_subrs = type1->num_subrs;
00248     decoder.subrs     = type1->subrs;
00249     decoder.subrs_len = type1->subrs_len;
00250 
00251     decoder.buildchar     = face->buildchar;
00252     decoder.len_buildchar = face->len_buildchar;
00253 
00254     for ( nn = 0; nn < count; nn++ )
00255     {
00256       error = T1_Parse_Glyph( &decoder, first + nn );
00257       if ( !error )
00258         advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
00259       else
00260         advances[nn] = 0;
00261     }
00262 
00263     return T1_Err_Ok;
00264   }
00265 
00266 
00267   FT_LOCAL_DEF( FT_Error )
00268   T1_Load_Glyph( T1_GlyphSlot  glyph,
00269                  T1_Size       size,
00270                  FT_UInt       glyph_index,
00271                  FT_Int32      load_flags )
00272   {
00273     FT_Error                error;
00274     T1_DecoderRec           decoder;
00275     T1_Face                 face = (T1_Face)glyph->root.face;
00276     FT_Bool                 hinting;
00277     T1_Font                 type1         = &face->type1;
00278     PSAux_Service           psaux         = (PSAux_Service)face->psaux;
00279     const T1_Decoder_Funcs  decoder_funcs = psaux->t1_decoder_funcs;
00280 
00281     FT_Matrix               font_matrix;
00282     FT_Vector               font_offset;
00283     FT_Data                 glyph_data;
00284     FT_Bool                 must_finish_decoder = FALSE;
00285 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00286     FT_Bool                 glyph_data_loaded = 0;
00287 #endif
00288 
00289 
00290 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00291     if ( glyph_index >= (FT_UInt)face->root.num_glyphs &&
00292          !face->root.internal->incremental_interface   )
00293 #else
00294     if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
00295 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
00296     {
00297       error = T1_Err_Invalid_Argument;
00298       goto Exit;
00299     }
00300 
00301     FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
00302 
00303     if ( load_flags & FT_LOAD_NO_RECURSE )
00304       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
00305 
00306     if ( size )
00307     {
00308       glyph->x_scale = size->root.metrics.x_scale;
00309       glyph->y_scale = size->root.metrics.y_scale;
00310     }
00311     else
00312     {
00313       glyph->x_scale = 0x10000L;
00314       glyph->y_scale = 0x10000L;
00315     }
00316 
00317     glyph->root.outline.n_points   = 0;
00318     glyph->root.outline.n_contours = 0;
00319 
00320     hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
00321                        ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
00322 
00323     glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
00324 
00325     error = decoder_funcs->init( &decoder,
00326                                  (FT_Face)face,
00327                                  (FT_Size)size,
00328                                  (FT_GlyphSlot)glyph,
00329                                  (FT_Byte**)type1->glyph_names,
00330                                  face->blend,
00331                                  FT_BOOL( hinting ),
00332                                  FT_LOAD_TARGET_MODE( load_flags ),
00333                                  T1_Parse_Glyph );
00334     if ( error )
00335       goto Exit;
00336 
00337     must_finish_decoder = TRUE;
00338 
00339     decoder.builder.no_recurse = FT_BOOL(
00340                                    ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
00341 
00342     decoder.num_subrs     = type1->num_subrs;
00343     decoder.subrs         = type1->subrs;
00344     decoder.subrs_len     = type1->subrs_len;
00345 
00346     decoder.buildchar     = face->buildchar;
00347     decoder.len_buildchar = face->len_buildchar;
00348 
00349     /* now load the unscaled outline */
00350     error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
00351                                                 &glyph_data );
00352     if ( error )
00353       goto Exit;
00354 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00355     glyph_data_loaded = 1;
00356 #endif
00357 
00358     font_matrix = decoder.font_matrix;
00359     font_offset = decoder.font_offset;
00360 
00361     /* save new glyph tables */
00362     decoder_funcs->done( &decoder );
00363 
00364     must_finish_decoder = FALSE;
00365 
00366     /* now, set the metrics -- this is rather simple, as   */
00367     /* the left side bearing is the xMin, and the top side */
00368     /* bearing the yMax                                    */
00369     if ( !error )
00370     {
00371       glyph->root.outline.flags &= FT_OUTLINE_OWNER;
00372       glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
00373 
00374       /* for composite glyphs, return only left side bearing and */
00375       /* advance width                                           */
00376       if ( load_flags & FT_LOAD_NO_RECURSE )
00377       {
00378         FT_Slot_Internal  internal = glyph->root.internal;
00379 
00380 
00381         glyph->root.metrics.horiBearingX =
00382           FIXED_TO_INT( decoder.builder.left_bearing.x );
00383         glyph->root.metrics.horiAdvance  =
00384           FIXED_TO_INT( decoder.builder.advance.x );
00385 
00386         internal->glyph_matrix      = font_matrix;
00387         internal->glyph_delta       = font_offset;
00388         internal->glyph_transformed = 1;
00389       }
00390       else
00391       {
00392         FT_BBox            cbox;
00393         FT_Glyph_Metrics*  metrics = &glyph->root.metrics;
00394         FT_Vector          advance;
00395 
00396 
00397         /* copy the _unscaled_ advance width */
00398         metrics->horiAdvance =
00399           FIXED_TO_INT( decoder.builder.advance.x );
00400         glyph->root.linearHoriAdvance =
00401           FIXED_TO_INT( decoder.builder.advance.x );
00402         glyph->root.internal->glyph_transformed = 0;
00403 
00404         if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 
00405         {
00406           /* make up vertical ones */
00407           metrics->vertAdvance = ( face->type1.font_bbox.yMax -
00408                                    face->type1.font_bbox.yMin ) >> 16;
00409           glyph->root.linearVertAdvance = metrics->vertAdvance;
00410         }
00411         else
00412         {
00413           metrics->vertAdvance =
00414             FIXED_TO_INT( decoder.builder.advance.y );
00415           glyph->root.linearVertAdvance =
00416             FIXED_TO_INT( decoder.builder.advance.y );
00417         }
00418 
00419         glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
00420 
00421         if ( size && size->root.metrics.y_ppem < 24 )
00422           glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
00423 
00424 #if 1
00425         /* apply the font matrix, if any */
00426         if ( font_matrix.xx != 0x10000L || font_matrix.yy != font_matrix.xx ||
00427              font_matrix.xy != 0        || font_matrix.yx != 0              )
00428           FT_Outline_Transform( &glyph->root.outline, &font_matrix );
00429 
00430         if ( font_offset.x || font_offset.y )
00431           FT_Outline_Translate( &glyph->root.outline,
00432                                 font_offset.x,
00433                                 font_offset.y );
00434 
00435         advance.x = metrics->horiAdvance;
00436         advance.y = 0;
00437         FT_Vector_Transform( &advance, &font_matrix );
00438         metrics->horiAdvance = advance.x + font_offset.x;
00439         advance.x = 0;
00440         advance.y = metrics->vertAdvance;
00441         FT_Vector_Transform( &advance, &font_matrix );
00442         metrics->vertAdvance = advance.y + font_offset.y;
00443 #endif
00444 
00445         if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
00446         {
00447           /* scale the outline and the metrics */
00448           FT_Int       n;
00449           FT_Outline*  cur = decoder.builder.base;
00450           FT_Vector*   vec = cur->points;
00451           FT_Fixed     x_scale = glyph->x_scale;
00452           FT_Fixed     y_scale = glyph->y_scale;
00453 
00454 
00455           /* First of all, scale the points, if we are not hinting */
00456           if ( !hinting || ! decoder.builder.hints_funcs )
00457             for ( n = cur->n_points; n > 0; n--, vec++ )
00458             {
00459               vec->x = FT_MulFix( vec->x, x_scale );
00460               vec->y = FT_MulFix( vec->y, y_scale );
00461             }
00462 
00463           /* Then scale the metrics */
00464           metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
00465           metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
00466         }
00467 
00468         /* compute the other metrics */
00469         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
00470 
00471         metrics->width  = cbox.xMax - cbox.xMin;
00472         metrics->height = cbox.yMax - cbox.yMin;
00473 
00474         metrics->horiBearingX = cbox.xMin;
00475         metrics->horiBearingY = cbox.yMax;
00476 
00477         if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 
00478         {
00479           /* make up vertical ones */
00480           ft_synthesize_vertical_metrics( metrics,
00481                                           metrics->vertAdvance );
00482         }
00483       }
00484 
00485       /* Set control data to the glyph charstrings.  Note that this is */
00486       /* _not_ zero-terminated.                                        */
00487       glyph->root.control_data = (FT_Byte*)glyph_data.pointer;
00488       glyph->root.control_len  = glyph_data.length;
00489     }
00490 
00491 
00492   Exit:
00493 
00494 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00495     if ( glyph_data_loaded && face->root.internal->incremental_interface )
00496     {
00497       face->root.internal->incremental_interface->funcs->free_glyph_data(
00498         face->root.internal->incremental_interface->object,
00499         &glyph_data );
00500 
00501       /* Set the control data to null - it is no longer available if   */
00502       /* loaded incrementally.                                         */
00503       glyph->root.control_data = 0;
00504       glyph->root.control_len  = 0;
00505     }
00506 #endif
00507 
00508     if ( must_finish_decoder )
00509       decoder_funcs->done( &decoder );
00510 
00511     return error;
00512   }
00513 
00514 
00515 /* END */

Generated on Tue Jul 5 14:13:54 2011 for ROOT_528-00b_version by  doxygen 1.5.1