pfrgload.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  pfrgload.c                                                             */
00004 /*                                                                         */
00005 /*    FreeType PFR glyph loader (body).                                    */
00006 /*                                                                         */
00007 /*  Copyright 2002, 2003, 2005, 2007 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 "pfrgload.h"
00020 #include "pfrsbit.h"
00021 #include "pfrload.h"            /* for macro definitions */
00022 #include FT_INTERNAL_DEBUG_H
00023 
00024 #include "pfrerror.h"
00025 
00026 #undef  FT_COMPONENT
00027 #define FT_COMPONENT  trace_pfr
00028 
00029 
00030   /*************************************************************************/
00031   /*************************************************************************/
00032   /*****                                                               *****/
00033   /*****                      PFR GLYPH BUILDER                        *****/
00034   /*****                                                               *****/
00035   /*************************************************************************/
00036   /*************************************************************************/
00037 
00038 
00039   FT_LOCAL_DEF( void )
00040   pfr_glyph_init( PFR_Glyph       glyph,
00041                   FT_GlyphLoader  loader )
00042   {
00043     FT_ZERO( glyph );
00044 
00045     glyph->loader     = loader;
00046     glyph->path_begun = 0;
00047 
00048     FT_GlyphLoader_Rewind( loader );
00049   }
00050 
00051 
00052   FT_LOCAL_DEF( void )
00053   pfr_glyph_done( PFR_Glyph  glyph )
00054   {
00055     FT_Memory  memory = glyph->loader->memory;
00056 
00057 
00058     FT_FREE( glyph->x_control );
00059     glyph->y_control = NULL;
00060 
00061     glyph->max_xy_control = 0;
00062 #if 0
00063     glyph->num_x_control  = 0;
00064     glyph->num_y_control  = 0;
00065 #endif
00066 
00067     FT_FREE( glyph->subs );
00068 
00069     glyph->max_subs = 0;
00070     glyph->num_subs = 0;
00071 
00072     glyph->loader     = NULL;
00073     glyph->path_begun = 0;
00074   }
00075 
00076 
00077   /* close current contour, if any */
00078   static void
00079   pfr_glyph_close_contour( PFR_Glyph  glyph )
00080   {
00081     FT_GlyphLoader  loader  = glyph->loader;
00082     FT_Outline*     outline = &loader->current.outline;
00083     FT_Int          last, first;
00084 
00085 
00086     if ( !glyph->path_begun )
00087       return;
00088 
00089     /* compute first and last point indices in current glyph outline */
00090     last  = outline->n_points - 1;
00091     first = 0;
00092     if ( outline->n_contours > 0 )
00093       first = outline->contours[outline->n_contours - 1];
00094 
00095     /* if the last point falls on the same location than the first one */
00096     /* we need to delete it                                            */
00097     if ( last > first )
00098     {
00099       FT_Vector*  p1 = outline->points + first;
00100       FT_Vector*  p2 = outline->points + last;
00101 
00102 
00103       if ( p1->x == p2->x && p1->y == p2->y )
00104       {
00105         outline->n_points--;
00106         last--;
00107       }
00108     }
00109 
00110     /* don't add empty contours */
00111     if ( last >= first )
00112       outline->contours[outline->n_contours++] = (short)last;
00113 
00114     glyph->path_begun = 0;
00115   }
00116 
00117 
00118   /* reset glyph to start the loading of a new glyph */
00119   static void
00120   pfr_glyph_start( PFR_Glyph  glyph )
00121   {
00122     glyph->path_begun = 0;
00123   }
00124 
00125 
00126   static FT_Error
00127   pfr_glyph_line_to( PFR_Glyph   glyph,
00128                      FT_Vector*  to )
00129   {
00130     FT_GlyphLoader  loader  = glyph->loader;
00131     FT_Outline*     outline = &loader->current.outline;
00132     FT_Error        error;
00133 
00134 
00135     /* check that we have begun a new path */
00136     if ( !glyph->path_begun )
00137     {
00138       error = PFR_Err_Invalid_Table;
00139       FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));
00140       goto Exit;
00141     }
00142 
00143     error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 );
00144     if ( !error )
00145     {
00146       FT_UInt  n = outline->n_points;
00147 
00148 
00149       outline->points[n] = *to;
00150       outline->tags  [n] = FT_CURVE_TAG_ON;
00151 
00152       outline->n_points++;
00153     }
00154 
00155   Exit:
00156     return error;
00157   }
00158 
00159 
00160   static FT_Error
00161   pfr_glyph_curve_to( PFR_Glyph   glyph,
00162                       FT_Vector*  control1,
00163                       FT_Vector*  control2,
00164                       FT_Vector*  to )
00165   {
00166     FT_GlyphLoader  loader  = glyph->loader;
00167     FT_Outline*     outline = &loader->current.outline;
00168     FT_Error        error;
00169 
00170 
00171     /* check that we have begun a new path */
00172     if ( !glyph->path_begun )
00173     {
00174       error = PFR_Err_Invalid_Table;
00175       FT_ERROR(( "pfr_glyph_line_to: invalid glyph data\n" ));
00176       goto Exit;
00177     }
00178 
00179     error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 );
00180     if ( !error )
00181     {
00182       FT_Vector*  vec = outline->points         + outline->n_points;
00183       FT_Byte*    tag = (FT_Byte*)outline->tags + outline->n_points;
00184 
00185 
00186       vec[0] = *control1;
00187       vec[1] = *control2;
00188       vec[2] = *to;
00189       tag[0] = FT_CURVE_TAG_CUBIC;
00190       tag[1] = FT_CURVE_TAG_CUBIC;
00191       tag[2] = FT_CURVE_TAG_ON;
00192 
00193       outline->n_points = (FT_Short)( outline->n_points + 3 );
00194     }
00195 
00196   Exit:
00197     return error;
00198   }
00199 
00200 
00201   static FT_Error
00202   pfr_glyph_move_to( PFR_Glyph   glyph,
00203                      FT_Vector*  to )
00204   {
00205     FT_GlyphLoader  loader  = glyph->loader;
00206     FT_Error        error;
00207 
00208 
00209     /* close current contour if any */
00210     pfr_glyph_close_contour( glyph );
00211 
00212     /* indicate that a new contour has started */
00213     glyph->path_begun = 1;
00214 
00215     /* check that there is space for a new contour and a new point */
00216     error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 );
00217     if ( !error )
00218       /* add new start point */
00219       error = pfr_glyph_line_to( glyph, to );
00220 
00221     return error;
00222   }
00223 
00224 
00225   static void
00226   pfr_glyph_end( PFR_Glyph  glyph )
00227   {
00228     /* close current contour if any */
00229     pfr_glyph_close_contour( glyph );
00230 
00231     /* merge the current glyph into the stack */
00232     FT_GlyphLoader_Add( glyph->loader );
00233   }
00234 
00235 
00236   /*************************************************************************/
00237   /*************************************************************************/
00238   /*****                                                               *****/
00239   /*****                      PFR GLYPH LOADER                         *****/
00240   /*****                                                               *****/
00241   /*************************************************************************/
00242   /*************************************************************************/
00243 
00244 
00245   /* load a simple glyph */
00246   static FT_Error
00247   pfr_glyph_load_simple( PFR_Glyph  glyph,
00248                          FT_Byte*   p,
00249                          FT_Byte*   limit )
00250   {
00251     FT_Error   error  = 0;
00252     FT_Memory  memory = glyph->loader->memory;
00253     FT_UInt    flags, x_count, y_count, i, count, mask;
00254     FT_Int     x;
00255 
00256 
00257     PFR_CHECK( 1 );
00258     flags = PFR_NEXT_BYTE( p );
00259 
00260     /* test for composite glyphs */
00261     if ( flags & PFR_GLYPH_IS_COMPOUND )
00262       goto Failure;
00263 
00264     x_count = 0;
00265     y_count = 0;
00266 
00267     if ( flags & PFR_GLYPH_1BYTE_XYCOUNT )
00268     {
00269       PFR_CHECK( 1 );
00270       count   = PFR_NEXT_BYTE( p );
00271       x_count = ( count & 15 );
00272       y_count = ( count >> 4 );
00273     }
00274     else
00275     {
00276       if ( flags & PFR_GLYPH_XCOUNT )
00277       {
00278         PFR_CHECK( 1 );
00279         x_count = PFR_NEXT_BYTE( p );
00280       }
00281 
00282       if ( flags & PFR_GLYPH_YCOUNT )
00283       {
00284         PFR_CHECK( 1 );
00285         y_count = PFR_NEXT_BYTE( p );
00286       }
00287     }
00288 
00289     count = x_count + y_count;
00290 
00291     /* re-allocate array when necessary */
00292     if ( count > glyph->max_xy_control )
00293     {
00294       FT_UInt  new_max = FT_PAD_CEIL( count, 8 );
00295 
00296 
00297       if ( FT_RENEW_ARRAY( glyph->x_control,
00298                            glyph->max_xy_control,
00299                            new_max ) )
00300         goto Exit;
00301 
00302       glyph->max_xy_control = new_max;
00303     }
00304 
00305     glyph->y_control = glyph->x_control + x_count;
00306 
00307     mask  = 0;
00308     x     = 0;
00309 
00310     for ( i = 0; i < count; i++ )
00311     {
00312       if ( ( i & 7 ) == 0 )
00313       {
00314         PFR_CHECK( 1 );
00315         mask = PFR_NEXT_BYTE( p );
00316       }
00317 
00318       if ( mask & 1 )
00319       {
00320         PFR_CHECK( 2 );
00321         x = PFR_NEXT_SHORT( p );
00322       }
00323       else
00324       {
00325         PFR_CHECK( 1 );
00326         x += PFR_NEXT_BYTE( p );
00327       }
00328 
00329       glyph->x_control[i] = x;
00330 
00331       mask >>= 1;
00332     }
00333 
00334     /* XXX: for now we ignore the secondary stroke and edge definitions */
00335     /*      since we don't want to support native PFR hinting           */
00336     /*                                                                  */
00337     if ( flags & PFR_GLYPH_EXTRA_ITEMS )
00338     {
00339       error = pfr_extra_items_skip( &p, limit );
00340       if ( error )
00341         goto Exit;
00342     }
00343 
00344     pfr_glyph_start( glyph );
00345 
00346     /* now load a simple glyph */
00347     {
00348       FT_Vector   pos[4];
00349       FT_Vector*  cur;
00350 
00351 
00352       pos[0].x = pos[0].y = 0;
00353       pos[3]   = pos[0];
00354 
00355       for (;;)
00356       {
00357         FT_UInt  format, format_low, args_format = 0, args_count, n;
00358 
00359 
00360         /***************************************************************/
00361         /*  read instruction                                           */
00362         /*                                                             */
00363         PFR_CHECK( 1 );
00364         format     = PFR_NEXT_BYTE( p );
00365         format_low = format & 15;
00366 
00367         switch ( format >> 4 )
00368         {
00369         case 0:                             /* end glyph */
00370           FT_TRACE6(( "- end glyph" ));
00371           args_count = 0;
00372           break;
00373 
00374         case 1:                             /* general line operation */
00375           FT_TRACE6(( "- general line" ));
00376           goto Line1;
00377 
00378         case 4:                             /* move to inside contour  */
00379           FT_TRACE6(( "- move to inside" ));
00380           goto Line1;
00381 
00382         case 5:                             /* move to outside contour */
00383           FT_TRACE6(( "- move to outside" ));
00384         Line1:
00385           args_format = format_low;
00386           args_count  = 1;
00387           break;
00388 
00389         case 2:                             /* horizontal line to */
00390           FT_TRACE6(( "- horizontal line to cx.%d", format_low ));
00391           if ( format_low > x_count )
00392             goto Failure;
00393           pos[0].x   = glyph->x_control[format_low];
00394           pos[0].y   = pos[3].y;
00395           pos[3]     = pos[0];
00396           args_count = 0;
00397           break;
00398 
00399         case 3:                             /* vertical line to */
00400           FT_TRACE6(( "- vertical line to cy.%d", format_low ));
00401           if ( format_low > y_count )
00402             goto Failure;
00403           pos[0].x   = pos[3].x;
00404           pos[0].y   = glyph->y_control[format_low];
00405           pos[3]     = pos[0];
00406           args_count = 0;
00407           break;
00408 
00409         case 6:                             /* horizontal to vertical curve */
00410           FT_TRACE6(( "- hv curve " ));
00411           args_format = 0xB8E;
00412           args_count  = 3;
00413           break;
00414 
00415         case 7:                             /* vertical to horizontal curve */
00416           FT_TRACE6(( "- vh curve" ));
00417           args_format = 0xE2B;
00418           args_count  = 3;
00419           break;
00420 
00421         default:                            /* general curve to */
00422           FT_TRACE6(( "- general curve" ));
00423           args_count  = 4;
00424           args_format = format_low;
00425         }
00426 
00427         /***********************************************************/
00428         /*  now read arguments                                     */
00429         /*                                                         */
00430         cur = pos;
00431         for ( n = 0; n < args_count; n++ )
00432         {
00433           FT_UInt  idx;
00434           FT_Int   delta;
00435 
00436 
00437           /* read the X argument */
00438           switch ( args_format & 3 )
00439           {
00440           case 0:                           /* 8-bit index */
00441             PFR_CHECK( 1 );
00442             idx  = PFR_NEXT_BYTE( p );
00443             if ( idx > x_count )
00444               goto Failure;
00445             cur->x = glyph->x_control[idx];
00446             FT_TRACE7(( " cx#%d", idx ));
00447             break;
00448 
00449           case 1:                           /* 16-bit value */
00450             PFR_CHECK( 2 );
00451             cur->x = PFR_NEXT_SHORT( p );
00452             FT_TRACE7(( " x.%d", cur->x ));
00453             break;
00454 
00455           case 2:                           /* 8-bit delta */
00456             PFR_CHECK( 1 );
00457             delta  = PFR_NEXT_INT8( p );
00458             cur->x = pos[3].x + delta;
00459             FT_TRACE7(( " dx.%d", delta ));
00460             break;
00461 
00462           default:
00463             FT_TRACE7(( " |" ));
00464             cur->x = pos[3].x;
00465           }
00466 
00467           /* read the Y argument */
00468           switch ( ( args_format >> 2 ) & 3 )
00469           {
00470           case 0:                           /* 8-bit index */
00471             PFR_CHECK( 1 );
00472             idx  = PFR_NEXT_BYTE( p );
00473             if ( idx > y_count )
00474               goto Failure;
00475             cur->y = glyph->y_control[idx];
00476             FT_TRACE7(( " cy#%d", idx ));
00477             break;
00478 
00479           case 1:                           /* 16-bit absolute value */
00480             PFR_CHECK( 2 );
00481             cur->y = PFR_NEXT_SHORT( p );
00482             FT_TRACE7(( " y.%d", cur->y ));
00483             break;
00484 
00485           case 2:                           /* 8-bit delta */
00486             PFR_CHECK( 1 );
00487             delta  = PFR_NEXT_INT8( p );
00488             cur->y = pos[3].y + delta;
00489             FT_TRACE7(( " dy.%d", delta ));
00490             break;
00491 
00492           default:
00493             FT_TRACE7(( " -" ));
00494             cur->y = pos[3].y;
00495           }
00496 
00497           /* read the additional format flag for the general curve */
00498           if ( n == 0 && args_count == 4 )
00499           {
00500             PFR_CHECK( 1 );
00501             args_format = PFR_NEXT_BYTE( p );
00502             args_count--;
00503           }
00504           else
00505             args_format >>= 4;
00506 
00507           /* save the previous point */
00508           pos[3] = cur[0];
00509           cur++;
00510         }
00511 
00512         FT_TRACE7(( "\n" ));
00513 
00514         /***********************************************************/
00515         /*  finally, execute instruction                           */
00516         /*                                                         */
00517         switch ( format >> 4 )
00518         {
00519         case 0:                             /* end glyph => EXIT */
00520           pfr_glyph_end( glyph );
00521           goto Exit;
00522 
00523         case 1:                             /* line operations */
00524         case 2:
00525         case 3:
00526           error = pfr_glyph_line_to( glyph, pos );
00527           goto Test_Error;
00528 
00529         case 4:                             /* move to inside contour  */
00530         case 5:                             /* move to outside contour */
00531           error = pfr_glyph_move_to( glyph, pos );
00532           goto Test_Error;
00533 
00534         default:                            /* curve operations */
00535           error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 );
00536 
00537         Test_Error:  /* test error condition */
00538           if ( error )
00539             goto Exit;
00540         }
00541       } /* for (;;) */
00542     }
00543 
00544   Exit:
00545     return error;
00546 
00547   Failure:
00548   Too_Short:
00549     error = PFR_Err_Invalid_Table;
00550     FT_ERROR(( "pfr_glyph_load_simple: invalid glyph data\n" ));
00551     goto Exit;
00552   }
00553 
00554 
00555   /* load a composite/compound glyph */
00556   static FT_Error
00557   pfr_glyph_load_compound( PFR_Glyph  glyph,
00558                            FT_Byte*   p,
00559                            FT_Byte*   limit )
00560   {
00561     FT_Error        error  = 0;
00562     FT_GlyphLoader  loader = glyph->loader;
00563     FT_Memory       memory = loader->memory;
00564     PFR_SubGlyph    subglyph;
00565     FT_UInt         flags, i, count, org_count;
00566     FT_Int          x_pos, y_pos;
00567 
00568 
00569     PFR_CHECK( 1 );
00570     flags = PFR_NEXT_BYTE( p );
00571 
00572     /* test for composite glyphs */
00573     if ( !( flags & PFR_GLYPH_IS_COMPOUND ) )
00574       goto Failure;
00575 
00576     count = flags & 0x3F;
00577 
00578     /* ignore extra items when present */
00579     /*                                 */
00580     if ( flags & PFR_GLYPH_EXTRA_ITEMS )
00581     {
00582       error = pfr_extra_items_skip( &p, limit );
00583       if (error) goto Exit;
00584     }
00585 
00586     /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because   */
00587     /* the PFR format is dumb, using direct file offsets to point to the */
00588     /* sub-glyphs (instead of glyph indices).  Sigh.                     */
00589     /*                                                                   */
00590     /* For now, we load the list of sub-glyphs into a different array    */
00591     /* but this will prevent us from using the auto-hinter at its best   */
00592     /* quality.                                                          */
00593     /*                                                                   */
00594     org_count = glyph->num_subs;
00595 
00596     if ( org_count + count > glyph->max_subs )
00597     {
00598       FT_UInt  new_max = ( org_count + count + 3 ) & (FT_UInt)-4;
00599 
00600 
00601       if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) )
00602         goto Exit;
00603 
00604       glyph->max_subs = new_max;
00605     }
00606 
00607     subglyph = glyph->subs + org_count;
00608 
00609     for ( i = 0; i < count; i++, subglyph++ )
00610     {
00611       FT_UInt  format;
00612 
00613 
00614       x_pos = 0;
00615       y_pos = 0;
00616 
00617       PFR_CHECK( 1 );
00618       format = PFR_NEXT_BYTE( p );
00619 
00620       /* read scale when available */
00621       subglyph->x_scale = 0x10000L;
00622       if ( format & PFR_SUBGLYPH_XSCALE )
00623       {
00624         PFR_CHECK( 2 );
00625         subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4;
00626       }
00627 
00628       subglyph->y_scale = 0x10000L;
00629       if ( format & PFR_SUBGLYPH_YSCALE )
00630       {
00631         PFR_CHECK( 2 );
00632         subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4;
00633       }
00634 
00635       /* read offset */
00636       switch ( format & 3 )
00637       {
00638       case 1:
00639         PFR_CHECK( 2 );
00640         x_pos = PFR_NEXT_SHORT( p );
00641         break;
00642 
00643       case 2:
00644         PFR_CHECK( 1 );
00645         x_pos += PFR_NEXT_INT8( p );
00646         break;
00647 
00648       default:
00649         ;
00650       }
00651 
00652       switch ( ( format >> 2 ) & 3 )
00653       {
00654       case 1:
00655         PFR_CHECK( 2 );
00656         y_pos = PFR_NEXT_SHORT( p );
00657         break;
00658 
00659       case 2:
00660         PFR_CHECK( 1 );
00661         y_pos += PFR_NEXT_INT8( p );
00662         break;
00663 
00664       default:
00665         ;
00666       }
00667 
00668       subglyph->x_delta = x_pos;
00669       subglyph->y_delta = y_pos;
00670 
00671       /* read glyph position and size now */
00672       if ( format & PFR_SUBGLYPH_2BYTE_SIZE )
00673       {
00674         PFR_CHECK( 2 );
00675         subglyph->gps_size = PFR_NEXT_USHORT( p );
00676       }
00677       else
00678       {
00679         PFR_CHECK( 1 );
00680         subglyph->gps_size = PFR_NEXT_BYTE( p );
00681       }
00682 
00683       if ( format & PFR_SUBGLYPH_3BYTE_OFFSET )
00684       {
00685         PFR_CHECK( 3 );
00686         subglyph->gps_offset = PFR_NEXT_LONG( p );
00687       }
00688       else
00689       {
00690         PFR_CHECK( 2 );
00691         subglyph->gps_offset = PFR_NEXT_USHORT( p );
00692       }
00693 
00694       glyph->num_subs++;
00695     }
00696 
00697   Exit:
00698     return error;
00699 
00700   Failure:
00701   Too_Short:
00702     error = PFR_Err_Invalid_Table;
00703     FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" ));
00704     goto Exit;
00705   }
00706 
00707 
00708   static FT_Error
00709   pfr_glyph_load_rec( PFR_Glyph  glyph,
00710                       FT_Stream  stream,
00711                       FT_ULong   gps_offset,
00712                       FT_ULong   offset,
00713                       FT_ULong   size )
00714   {
00715     FT_Error  error;
00716     FT_Byte*  p;
00717     FT_Byte*  limit;
00718 
00719 
00720     if ( FT_STREAM_SEEK( gps_offset + offset ) ||
00721          FT_FRAME_ENTER( size )                )
00722       goto Exit;
00723 
00724     p     = (FT_Byte*)stream->cursor;
00725     limit = p + size;
00726 
00727     if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND )
00728     {
00729       FT_Int          n, old_count, count;
00730       FT_GlyphLoader  loader = glyph->loader;
00731       FT_Outline*     base   = &loader->base.outline;
00732 
00733 
00734       old_count = glyph->num_subs;
00735 
00736       /* this is a compound glyph - load it */
00737       error = pfr_glyph_load_compound( glyph, p, limit );
00738 
00739       FT_FRAME_EXIT();
00740 
00741       if ( error )
00742         goto Exit;
00743 
00744       count = glyph->num_subs - old_count;
00745 
00746       /* now, load each individual glyph */
00747       for ( n = 0; n < count; n++ )
00748       {
00749         FT_Int        i, old_points, num_points;
00750         PFR_SubGlyph  subglyph;
00751 
00752 
00753         subglyph   = glyph->subs + old_count + n;
00754         old_points = base->n_points;
00755 
00756         error = pfr_glyph_load_rec( glyph, stream, gps_offset,
00757                                     subglyph->gps_offset,
00758                                     subglyph->gps_size );
00759         if ( error )
00760           goto Exit;
00761 
00762         /* note that `glyph->subs' might have been re-allocated */
00763         subglyph   = glyph->subs + old_count + n;
00764         num_points = base->n_points - old_points;
00765 
00766         /* translate and eventually scale the new glyph points */
00767         if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L )
00768         {
00769           FT_Vector*  vec = base->points + old_points;
00770 
00771 
00772           for ( i = 0; i < num_points; i++, vec++ )
00773           {
00774             vec->x = FT_MulFix( vec->x, subglyph->x_scale ) +
00775                        subglyph->x_delta;
00776             vec->y = FT_MulFix( vec->y, subglyph->y_scale ) +
00777                        subglyph->y_delta;
00778           }
00779         }
00780         else
00781         {
00782           FT_Vector*  vec = loader->base.outline.points + old_points;
00783 
00784 
00785           for ( i = 0; i < num_points; i++, vec++ )
00786           {
00787             vec->x += subglyph->x_delta;
00788             vec->y += subglyph->y_delta;
00789           }
00790         }
00791 
00792         /* proceed to next sub-glyph */
00793       }
00794     }
00795     else
00796     {
00797       /* load a simple glyph */
00798       error = pfr_glyph_load_simple( glyph, p, limit );
00799 
00800       FT_FRAME_EXIT();
00801     }
00802 
00803   Exit:
00804     return error;
00805   }
00806 
00807 
00808 
00809 
00810 
00811   FT_LOCAL_DEF( FT_Error )
00812   pfr_glyph_load( PFR_Glyph  glyph,
00813                   FT_Stream  stream,
00814                   FT_ULong   gps_offset,
00815                   FT_ULong   offset,
00816                   FT_ULong   size )
00817   {
00818     /* initialize glyph loader */
00819     FT_GlyphLoader_Rewind( glyph->loader );
00820 
00821     glyph->num_subs = 0;
00822 
00823     /* load the glyph, recursively when needed */
00824     return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size );
00825   }
00826 
00827 
00828 /* END */

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