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

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 Sun May 27 2012 04:34:04 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.