Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpfrgload.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
1.7.6.1
|