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

cidgload.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  cidgload.c                                                             */
00004 /*                                                                         */
00005 /*    CID-keyed Type1 Glyph Loader (body).                                 */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 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 "cidload.h"
00021 #include "cidgload.h"
00022 #include FT_INTERNAL_DEBUG_H
00023 #include FT_INTERNAL_STREAM_H
00024 #include FT_OUTLINE_H
00025 #include FT_INTERNAL_CALC_H
00026 
00027 #include "ciderrs.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_cidgload
00038 
00039 
00040   FT_CALLBACK_DEF( FT_Error )
00041   cid_load_glyph( T1_Decoder  decoder,
00042                   FT_UInt     glyph_index )
00043   {
00044     CID_Face       face = (CID_Face)decoder->builder.face;
00045     CID_FaceInfo   cid  = &face->cid;
00046     FT_Byte*       p;
00047     FT_UInt        fd_select;
00048     FT_Stream      stream       = face->cid_stream;
00049     FT_Error       error        = CID_Err_Ok;
00050     FT_Byte*       charstring   = 0;
00051     FT_Memory      memory       = face->root.memory;
00052     FT_ULong       glyph_length = 0;
00053     PSAux_Service  psaux        = (PSAux_Service)face->psaux;
00054 
00055 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00056     FT_Incremental_InterfaceRec *inc =
00057                                   face->root.internal->incremental_interface;
00058 #endif
00059 
00060 
00061     FT_TRACE4(( "cid_load_glyph: glyph index %d\n", glyph_index ));
00062 
00063 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00064 
00065     /* For incremental fonts get the character data using */
00066     /* the callback function.                             */
00067     if ( inc )
00068     {
00069       FT_Data  glyph_data;
00070 
00071 
00072       error = inc->funcs->get_glyph_data( inc->object,
00073                                           glyph_index, &glyph_data );
00074       if ( error )
00075         goto Exit;
00076 
00077       p         = (FT_Byte*)glyph_data.pointer;
00078       fd_select = (FT_UInt)cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
00079 
00080       if ( glyph_data.length != 0 )
00081       {
00082         glyph_length = glyph_data.length - cid->fd_bytes;
00083         (void)FT_ALLOC( charstring, glyph_length );
00084         if ( !error )
00085           ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes,
00086                      glyph_length );
00087       }
00088 
00089       inc->funcs->free_glyph_data( inc->object, &glyph_data );
00090 
00091       if ( error )
00092         goto Exit;
00093     }
00094 
00095     else
00096 
00097 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
00098 
00099     /* For ordinary fonts read the CID font dictionary index */
00100     /* and charstring offset from the CIDMap.                */
00101     {
00102       FT_UInt   entry_len = cid->fd_bytes + cid->gd_bytes;
00103       FT_ULong  off1;
00104 
00105 
00106       if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
00107                            glyph_index * entry_len )               ||
00108            FT_FRAME_ENTER( 2 * entry_len )                         )
00109         goto Exit;
00110 
00111       p            = (FT_Byte*)stream->cursor;
00112       fd_select    = (FT_UInt) cid_get_offset( &p, (FT_Byte)cid->fd_bytes );
00113       off1         = (FT_ULong)cid_get_offset( &p, (FT_Byte)cid->gd_bytes );
00114       p           += cid->fd_bytes;
00115       glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1;
00116       FT_FRAME_EXIT();
00117 
00118       if ( fd_select >= (FT_UInt)cid->num_dicts )
00119       {
00120         error = CID_Err_Invalid_Offset;
00121         goto Exit;
00122       }
00123       if ( glyph_length == 0 )
00124         goto Exit;
00125       if ( FT_ALLOC( charstring, glyph_length ) )
00126         goto Exit;
00127       if ( FT_STREAM_READ_AT( cid->data_offset + off1,
00128                               charstring, glyph_length ) )
00129         goto Exit;
00130     }
00131 
00132     /* Now set up the subrs array and parse the charstrings. */
00133     {
00134       CID_FaceDict  dict;
00135       CID_Subrs     cid_subrs = face->subrs + fd_select;
00136       FT_Int        cs_offset;
00137 
00138 
00139       /* Set up subrs */
00140       decoder->num_subrs = cid_subrs->num_subrs;
00141       decoder->subrs     = cid_subrs->code;
00142       decoder->subrs_len = 0;
00143 
00144       /* Set up font matrix */
00145       dict                 = cid->font_dicts + fd_select;
00146 
00147       decoder->font_matrix = dict->font_matrix;
00148       decoder->font_offset = dict->font_offset;
00149       decoder->lenIV       = dict->private_dict.lenIV;
00150 
00151       /* Decode the charstring. */
00152 
00153       /* Adjustment for seed bytes. */
00154       cs_offset = ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
00155 
00156       /* Decrypt only if lenIV >= 0. */
00157       if ( decoder->lenIV >= 0 )
00158         psaux->t1_decrypt( charstring, glyph_length, 4330 );
00159 
00160       error = decoder->funcs.parse_charstrings(
00161                 decoder, charstring + cs_offset,
00162                 (FT_Int)glyph_length - cs_offset );
00163     }
00164 
00165     FT_FREE( charstring );
00166 
00167 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00168 
00169     /* Incremental fonts can optionally override the metrics. */
00170     if ( !error && inc && inc->funcs->get_glyph_metrics )
00171     {
00172       FT_Incremental_MetricsRec  metrics;
00173 
00174 
00175       metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
00176       metrics.bearing_y = 0;
00177       metrics.advance   = FIXED_TO_INT( decoder->builder.advance.x );
00178       metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y );
00179 
00180       error = inc->funcs->get_glyph_metrics( inc->object,
00181                                              glyph_index, FALSE, &metrics );
00182 
00183       decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
00184       decoder->builder.advance.x      = INT_TO_FIXED( metrics.advance );
00185       decoder->builder.advance.y      = INT_TO_FIXED( metrics.advance_v );
00186     }
00187 
00188 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
00189 
00190   Exit:
00191     return error;
00192   }
00193 
00194 
00195 #if 0
00196 
00197 
00198   /*************************************************************************/
00199   /*************************************************************************/
00200   /*************************************************************************/
00201   /**********                                                      *********/
00202   /**********                                                      *********/
00203   /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
00204   /**********                                                      *********/
00205   /**********    The following code is in charge of computing      *********/
00206   /**********    the maximum advance width of the font.  It        *********/
00207   /**********    quickly processes each glyph charstring to        *********/
00208   /**********    extract the value from either a `sbw' or `seac'   *********/
00209   /**********    operator.                                         *********/
00210   /**********                                                      *********/
00211   /*************************************************************************/
00212   /*************************************************************************/
00213   /*************************************************************************/
00214 
00215 
00216   FT_LOCAL_DEF( FT_Error )
00217   cid_face_compute_max_advance( CID_Face  face,
00218                                 FT_Int*   max_advance )
00219   {
00220     FT_Error       error;
00221     T1_DecoderRec  decoder;
00222     FT_Int         glyph_index;
00223 
00224     PSAux_Service  psaux = (PSAux_Service)face->psaux;
00225 
00226 
00227     *max_advance = 0;
00228 
00229     /* Initialize load decoder */
00230     error = psaux->t1_decoder_funcs->init( &decoder,
00231                                            (FT_Face)face,
00232                                            0, /* size       */
00233                                            0, /* glyph slot */
00234                                            0, /* glyph names! XXX */
00235                                            0, /* blend == 0 */
00236                                            0, /* hinting == 0 */
00237                                            cid_load_glyph );
00238     if ( error )
00239       return error;
00240 
00241     /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
00242     /*       if we ever support CID-keyed multiple master fonts     */
00243 
00244     decoder.builder.metrics_only = 1;
00245     decoder.builder.load_points  = 0;
00246 
00247     /* for each glyph, parse the glyph charstring and extract */
00248     /* the advance width                                      */
00249     for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
00250           glyph_index++ )
00251     {
00252       /* now get load the unscaled outline */
00253       error = cid_load_glyph( &decoder, glyph_index );
00254       /* ignore the error if one occurred - skip to next glyph */
00255     }
00256 
00257     *max_advance = FIXED_TO_INT( decoder.builder.advance.x );
00258 
00259     psaux->t1_decoder_funcs->done( &decoder );
00260 
00261     return CID_Err_Ok;
00262   }
00263 
00264 
00265 #endif /* 0 */
00266 
00267 
00268   FT_LOCAL_DEF( FT_Error )
00269   cid_slot_load_glyph( FT_GlyphSlot  cidglyph,      /* CID_GlyphSlot */
00270                        FT_Size       cidsize,       /* CID_Size      */
00271                        FT_UInt       glyph_index,
00272                        FT_Int32      load_flags )
00273   {
00274     CID_GlyphSlot  glyph = (CID_GlyphSlot)cidglyph;
00275     FT_Error       error;
00276     T1_DecoderRec  decoder;
00277     CID_Face       face = (CID_Face)cidglyph->face;
00278     FT_Bool        hinting;
00279 
00280     PSAux_Service  psaux = (PSAux_Service)face->psaux;
00281     FT_Matrix      font_matrix;
00282     FT_Vector      font_offset;
00283 
00284 
00285     if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
00286     {
00287       error = CID_Err_Invalid_Argument;
00288       goto Exit;
00289     }
00290 
00291     if ( load_flags & FT_LOAD_NO_RECURSE )
00292       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
00293 
00294     glyph->x_scale = cidsize->metrics.x_scale;
00295     glyph->y_scale = cidsize->metrics.y_scale;
00296 
00297     cidglyph->outline.n_points   = 0;
00298     cidglyph->outline.n_contours = 0;
00299 
00300     hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
00301                        ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
00302 
00303     cidglyph->format = FT_GLYPH_FORMAT_OUTLINE;
00304 
00305     error = psaux->t1_decoder_funcs->init( &decoder,
00306                                            cidglyph->face,
00307                                            cidsize,
00308                                            cidglyph,
00309                                            0, /* glyph names -- XXX */
00310                                            0, /* blend == 0 */
00311                                            hinting,
00312                                            FT_LOAD_TARGET_MODE( load_flags ),
00313                                            cid_load_glyph );
00314     if ( error )
00315       goto Exit;
00316 
00317     /* TODO: initialize decoder.len_buildchar and decoder.buildchar */
00318     /*       if we ever support CID-keyed multiple master fonts     */
00319 
00320     /* set up the decoder */
00321     decoder.builder.no_recurse = FT_BOOL(
00322       ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) );
00323 
00324     error = cid_load_glyph( &decoder, glyph_index );
00325     if ( error )
00326       goto Exit;
00327 
00328     font_matrix = decoder.font_matrix;
00329     font_offset = decoder.font_offset;
00330 
00331     /* save new glyph tables */
00332     psaux->t1_decoder_funcs->done( &decoder );
00333 
00334     /* now set the metrics -- this is rather simple, as    */
00335     /* the left side bearing is the xMin, and the top side */
00336     /* bearing the yMax                                    */
00337     cidglyph->outline.flags &= FT_OUTLINE_OWNER;
00338     cidglyph->outline.flags |= FT_OUTLINE_REVERSE_FILL;
00339 
00340     /* for composite glyphs, return only left side bearing and */
00341     /* advance width                                           */
00342     if ( load_flags & FT_LOAD_NO_RECURSE )
00343     {
00344       FT_Slot_Internal  internal = cidglyph->internal;
00345 
00346 
00347       cidglyph->metrics.horiBearingX =
00348         FIXED_TO_INT( decoder.builder.left_bearing.x );
00349       cidglyph->metrics.horiAdvance =
00350         FIXED_TO_INT( decoder.builder.advance.x );
00351 
00352       internal->glyph_matrix      = font_matrix;
00353       internal->glyph_delta       = font_offset;
00354       internal->glyph_transformed = 1;
00355     }
00356     else
00357     {
00358       FT_BBox            cbox;
00359       FT_Glyph_Metrics*  metrics = &cidglyph->metrics;
00360       FT_Vector          advance;
00361 
00362 
00363       /* copy the _unscaled_ advance width */
00364       metrics->horiAdvance =
00365         FIXED_TO_INT( decoder.builder.advance.x );
00366       cidglyph->linearHoriAdvance =
00367         FIXED_TO_INT( decoder.builder.advance.x );
00368       cidglyph->internal->glyph_transformed = 0;
00369 
00370       /* make up vertical ones */
00371       metrics->vertAdvance        = ( face->cid.font_bbox.yMax -
00372                                       face->cid.font_bbox.yMin ) >> 16;
00373       cidglyph->linearVertAdvance = metrics->vertAdvance;
00374 
00375       cidglyph->format            = FT_GLYPH_FORMAT_OUTLINE;
00376 
00377       if ( cidsize->metrics.y_ppem < 24 )
00378         cidglyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
00379 
00380       /* apply the font matrix */
00381       FT_Outline_Transform( &cidglyph->outline, &font_matrix );
00382 
00383       FT_Outline_Translate( &cidglyph->outline,
00384                             font_offset.x,
00385                             font_offset.y );
00386 
00387       advance.x = metrics->horiAdvance;
00388       advance.y = 0;
00389       FT_Vector_Transform( &advance, &font_matrix );
00390       metrics->horiAdvance = advance.x + font_offset.x;
00391 
00392       advance.x = 0;
00393       advance.y = metrics->vertAdvance;
00394       FT_Vector_Transform( &advance, &font_matrix );
00395       metrics->vertAdvance = advance.y + font_offset.y;
00396 
00397       if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
00398       {
00399         /* scale the outline and the metrics */
00400         FT_Int       n;
00401         FT_Outline*  cur = decoder.builder.base;
00402         FT_Vector*   vec = cur->points;
00403         FT_Fixed     x_scale = glyph->x_scale;
00404         FT_Fixed     y_scale = glyph->y_scale;
00405 
00406 
00407         /* First of all, scale the points */
00408         if ( !hinting || !decoder.builder.hints_funcs )
00409           for ( n = cur->n_points; n > 0; n--, vec++ )
00410           {
00411             vec->x = FT_MulFix( vec->x, x_scale );
00412             vec->y = FT_MulFix( vec->y, y_scale );
00413           }
00414 
00415         /* Then scale the metrics */
00416         metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
00417         metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
00418       }
00419 
00420       /* compute the other metrics */
00421       FT_Outline_Get_CBox( &cidglyph->outline, &cbox );
00422 
00423       metrics->width  = cbox.xMax - cbox.xMin;
00424       metrics->height = cbox.yMax - cbox.yMin;
00425 
00426       metrics->horiBearingX = cbox.xMin;
00427       metrics->horiBearingY = cbox.yMax;
00428 
00429       if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) 
00430       {
00431         /* make up vertical ones */
00432         ft_synthesize_vertical_metrics( metrics,
00433                                         metrics->vertAdvance );
00434       }
00435     }
00436 
00437   Exit:
00438     return error;
00439   }
00440 
00441 
00442 /* END */

Generated on Thu May 24 2012 04:34:17 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.