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

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, 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 "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  = PFR_Err_Ok;
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  = PFR_Err_Ok;
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       /* we arbitrarily limit the number of subglyphs */
00602       /* to avoid endless recursion                   */
00603       if ( new_max > 64 )
00604       {
00605         error = PFR_Err_Invalid_Table;
00606         FT_ERROR(( "pfr_glyph_load_compound:"
00607                    " too many compound glyphs components\n" ));
00608         goto Exit;
00609       }
00610 
00611       if ( FT_RENEW_ARRAY( glyph->subs, glyph->max_subs, new_max ) )
00612         goto Exit;
00613 
00614       glyph->max_subs = new_max;
00615     }
00616 
00617     subglyph = glyph->subs + org_count;
00618 
00619     for ( i = 0; i < count; i++, subglyph++ )
00620     {
00621       FT_UInt  format;
00622 
00623 
00624       x_pos = 0;
00625       y_pos = 0;
00626 
00627       PFR_CHECK( 1 );
00628       format = PFR_NEXT_BYTE( p );
00629 
00630       /* read scale when available */
00631       subglyph->x_scale = 0x10000L;
00632       if ( format & PFR_SUBGLYPH_XSCALE )
00633       {
00634         PFR_CHECK( 2 );
00635         subglyph->x_scale = PFR_NEXT_SHORT( p ) << 4;
00636       }
00637 
00638       subglyph->y_scale = 0x10000L;
00639       if ( format & PFR_SUBGLYPH_YSCALE )
00640       {
00641         PFR_CHECK( 2 );
00642         subglyph->y_scale = PFR_NEXT_SHORT( p ) << 4;
00643       }
00644 
00645       /* read offset */
00646       switch ( format & 3 )
00647       {
00648       case 1:
00649         PFR_CHECK( 2 );
00650         x_pos = PFR_NEXT_SHORT( p );
00651         break;
00652 
00653       case 2:
00654         PFR_CHECK( 1 );
00655         x_pos += PFR_NEXT_INT8( p );
00656         break;
00657 
00658       default:
00659         ;
00660       }
00661 
00662       switch ( ( format >> 2 ) & 3 )
00663       {
00664       case 1:
00665         PFR_CHECK( 2 );
00666         y_pos = PFR_NEXT_SHORT( p );
00667         break;
00668 
00669       case 2:
00670         PFR_CHECK( 1 );
00671         y_pos += PFR_NEXT_INT8( p );
00672         break;
00673 
00674       default:
00675         ;
00676       }
00677 
00678       subglyph->x_delta = x_pos;
00679       subglyph->y_delta = y_pos;
00680 
00681       /* read glyph position and size now */
00682       if ( format & PFR_SUBGLYPH_2BYTE_SIZE )
00683       {
00684         PFR_CHECK( 2 );
00685         subglyph->gps_size = PFR_NEXT_USHORT( p );
00686       }
00687       else
00688       {
00689         PFR_CHECK( 1 );
00690         subglyph->gps_size = PFR_NEXT_BYTE( p );
00691       }
00692 
00693       if ( format & PFR_SUBGLYPH_3BYTE_OFFSET )
00694       {
00695         PFR_CHECK( 3 );
00696         subglyph->gps_offset = PFR_NEXT_LONG( p );
00697       }
00698       else
00699       {
00700         PFR_CHECK( 2 );
00701         subglyph->gps_offset = PFR_NEXT_USHORT( p );
00702       }
00703 
00704       glyph->num_subs++;
00705     }
00706 
00707   Exit:
00708     return error;
00709 
00710   Failure:
00711   Too_Short:
00712     error = PFR_Err_Invalid_Table;
00713     FT_ERROR(( "pfr_glyph_load_compound: invalid glyph data\n" ));
00714     goto Exit;
00715   }
00716 
00717 
00718   static FT_Error
00719   pfr_glyph_load_rec( PFR_Glyph  glyph,
00720                       FT_Stream  stream,
00721                       FT_ULong   gps_offset,
00722                       FT_ULong   offset,
00723                       FT_ULong   size )
00724   {
00725     FT_Error  error;
00726     FT_Byte*  p;
00727     FT_Byte*  limit;
00728 
00729 
00730     if ( FT_STREAM_SEEK( gps_offset + offset ) ||
00731          FT_FRAME_ENTER( size )                )
00732       goto Exit;
00733 
00734     p     = (FT_Byte*)stream->cursor;
00735     limit = p + size;
00736 
00737     if ( size > 0 && *p & PFR_GLYPH_IS_COMPOUND )
00738     {
00739       FT_Int          n, old_count, count;
00740       FT_GlyphLoader  loader = glyph->loader;
00741       FT_Outline*     base   = &loader->base.outline;
00742 
00743 
00744       old_count = glyph->num_subs;
00745 
00746       /* this is a compound glyph - load it */
00747       error = pfr_glyph_load_compound( glyph, p, limit );
00748 
00749       FT_FRAME_EXIT();
00750 
00751       if ( error )
00752         goto Exit;
00753 
00754       count = glyph->num_subs - old_count;
00755 
00756       FT_TRACE4(( "compound glyph with %d elements (offset %lu):\n",
00757                   count, offset ));
00758 
00759       /* now, load each individual glyph */
00760       for ( n = 0; n < count; n++ )
00761       {
00762         FT_Int        i, old_points, num_points;
00763         PFR_SubGlyph  subglyph;
00764 
00765 
00766         FT_TRACE4(( "subglyph %d:\n", n ));
00767 
00768         subglyph   = glyph->subs + old_count + n;
00769         old_points = base->n_points;
00770 
00771         error = pfr_glyph_load_rec( glyph, stream, gps_offset,
00772                                     subglyph->gps_offset,
00773                                     subglyph->gps_size );
00774         if ( error )
00775           break;
00776 
00777         /* note that `glyph->subs' might have been re-allocated */
00778         subglyph   = glyph->subs + old_count + n;
00779         num_points = base->n_points - old_points;
00780 
00781         /* translate and eventually scale the new glyph points */
00782         if ( subglyph->x_scale != 0x10000L || subglyph->y_scale != 0x10000L )
00783         {
00784           FT_Vector*  vec = base->points + old_points;
00785 
00786 
00787           for ( i = 0; i < num_points; i++, vec++ )
00788           {
00789             vec->x = FT_MulFix( vec->x, subglyph->x_scale ) +
00790                        subglyph->x_delta;
00791             vec->y = FT_MulFix( vec->y, subglyph->y_scale ) +
00792                        subglyph->y_delta;
00793           }
00794         }
00795         else
00796         {
00797           FT_Vector*  vec = loader->base.outline.points + old_points;
00798 
00799 
00800           for ( i = 0; i < num_points; i++, vec++ )
00801           {
00802             vec->x += subglyph->x_delta;
00803             vec->y += subglyph->y_delta;
00804           }
00805         }
00806 
00807         /* proceed to next sub-glyph */
00808       }
00809 
00810       FT_TRACE4(( "end compound glyph with %d elements\n", count ));
00811     }
00812     else
00813     {
00814       FT_TRACE4(( "simple glyph (offset %lu)\n", offset ));
00815 
00816       /* load a simple glyph */
00817       error = pfr_glyph_load_simple( glyph, p, limit );
00818 
00819       FT_FRAME_EXIT();
00820     }
00821 
00822   Exit:
00823     return error;
00824   }
00825 
00826 
00827   FT_LOCAL_DEF( FT_Error )
00828   pfr_glyph_load( PFR_Glyph  glyph,
00829                   FT_Stream  stream,
00830                   FT_ULong   gps_offset,
00831                   FT_ULong   offset,
00832                   FT_ULong   size )
00833   {
00834     /* initialize glyph loader */
00835     FT_GlyphLoader_Rewind( glyph->loader );
00836 
00837     glyph->num_subs = 0;
00838 
00839     /* load the glyph, recursively when needed */
00840     return pfr_glyph_load_rec( glyph, stream, gps_offset, offset, size );
00841   }
00842 
00843 
00844 /* END */

Generated on Sun May 27 2012 04:33:53 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.