00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_STREAM_H
00022 #include FT_TRUETYPE_TAGS_H
00023 #include FT_INTERNAL_SFNT_H
00024
00025 #include "ttgload.h"
00026 #include "ttpload.h"
00027
00028 #include "tterrors.h"
00029
00030 #ifdef TT_USE_BYTECODE_INTERPRETER
00031 #include "ttinterp.h"
00032 #endif
00033
00034 #ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
00035 #include FT_TRUETYPE_UNPATENTED_H
00036 #endif
00037
00038 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
00039 #include "ttgxvar.h"
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048 #undef FT_COMPONENT
00049 #define FT_COMPONENT trace_ttobjs
00050
00051
00052 #ifdef TT_USE_BYTECODE_INTERPRETER
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 FT_LOCAL_DEF( void )
00073 tt_glyphzone_done( TT_GlyphZone zone )
00074 {
00075 FT_Memory memory = zone->memory;
00076
00077
00078 if ( memory )
00079 {
00080 FT_FREE( zone->contours );
00081 FT_FREE( zone->tags );
00082 FT_FREE( zone->cur );
00083 FT_FREE( zone->org );
00084 FT_FREE( zone->orus );
00085
00086 zone->max_points = zone->n_points = 0;
00087 zone->max_contours = zone->n_contours = 0;
00088 zone->memory = NULL;
00089 }
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 FT_LOCAL_DEF( FT_Error )
00115 tt_glyphzone_new( FT_Memory memory,
00116 FT_UShort maxPoints,
00117 FT_Short maxContours,
00118 TT_GlyphZone zone )
00119 {
00120 FT_Error error;
00121
00122
00123 FT_MEM_ZERO( zone, sizeof ( *zone ) );
00124 zone->memory = memory;
00125
00126 if ( FT_NEW_ARRAY( zone->org, maxPoints ) ||
00127 FT_NEW_ARRAY( zone->cur, maxPoints ) ||
00128 FT_NEW_ARRAY( zone->orus, maxPoints ) ||
00129 FT_NEW_ARRAY( zone->tags, maxPoints ) ||
00130 FT_NEW_ARRAY( zone->contours, maxContours ) )
00131 {
00132 tt_glyphzone_done( zone );
00133 }
00134 else
00135 {
00136 zone->max_points = maxPoints;
00137 zone->max_contours = maxContours;
00138 }
00139
00140 return error;
00141 }
00142 #endif
00143
00144
00145
00146
00147
00148 static FT_Bool
00149 tt_check_trickyness( FT_String* name )
00150 {
00151 #define TRICK_NAMES_MAX_CHARACTERS 16
00152 #define TRICK_NAMES_COUNT 7
00153 static const char trick_names[TRICK_NAMES_COUNT][TRICK_NAMES_MAX_CHARACTERS+1] =
00154 {
00155 "DFKaiSho-SB",
00156 "DFKaiShu",
00157 "DFKai-SB",
00158 "HuaTianSongTi?",
00159 "MingLiU",
00160 "PMingLiU",
00161 "MingLi43",
00162 };
00163 int nn;
00164
00165
00166 if ( !name )
00167 return FALSE;
00168
00169
00170
00171 for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
00172 if ( ft_strstr( name, trick_names[nn] ) )
00173 return TRUE;
00174
00175 return FALSE;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 FT_LOCAL_DEF( FT_Error )
00203 tt_face_init( FT_Stream stream,
00204 FT_Face ttface,
00205 FT_Int face_index,
00206 FT_Int num_params,
00207 FT_Parameter* params )
00208 {
00209 FT_Error error;
00210 FT_Library library;
00211 SFNT_Service sfnt;
00212 TT_Face face = (TT_Face)ttface;
00213
00214
00215 library = ttface->driver->root.library;
00216 sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
00217 if ( !sfnt )
00218 goto Bad_Format;
00219
00220
00221 if ( FT_STREAM_SEEK( 0 ) )
00222 goto Exit;
00223
00224
00225 error = sfnt->init_face( stream, face, face_index, num_params, params );
00226 if ( error )
00227 goto Exit;
00228
00229
00230
00231
00232 if ( face->format_tag != 0x00010000L &&
00233 face->format_tag != 0x00020000L &&
00234 face->format_tag != TTAG_true )
00235 {
00236 FT_TRACE2(( "[not a valid TTF font]\n" ));
00237 goto Bad_Format;
00238 }
00239
00240 #ifdef TT_USE_BYTECODE_INTERPRETER
00241 ttface->face_flags |= FT_FACE_FLAG_HINTER;
00242 #endif
00243
00244
00245 if ( face_index < 0 )
00246 return TT_Err_Ok;
00247
00248
00249 error = sfnt->load_face( stream, face, face_index, num_params, params );
00250 if ( error )
00251 goto Exit;
00252
00253 if ( tt_check_trickyness( ttface->family_name ) )
00254 ttface->face_flags |= FT_FACE_FLAG_TRICKY;
00255
00256 error = tt_face_load_hdmx( face, stream );
00257 if ( error )
00258 goto Exit;
00259
00260 if ( FT_IS_SCALABLE( ttface ) )
00261 {
00262
00263 #ifdef FT_CONFIG_OPTION_INCREMENTAL
00264
00265 if ( !ttface->internal->incremental_interface )
00266 error = tt_face_load_loca( face, stream );
00267 if ( !error )
00268 error = tt_face_load_cvt( face, stream );
00269 if ( !error )
00270 error = tt_face_load_fpgm( face, stream );
00271 if ( !error )
00272 error = tt_face_load_prep( face, stream );
00273
00274 #else
00275
00276 if ( !error )
00277 error = tt_face_load_loca( face, stream );
00278 if ( !error )
00279 error = tt_face_load_cvt( face, stream );
00280 if ( !error )
00281 error = tt_face_load_fpgm( face, stream );
00282 if ( !error )
00283 error = tt_face_load_prep( face, stream );
00284
00285 #endif
00286
00287 }
00288
00289 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
00290 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
00291
00292 {
00293 FT_Bool unpatented_hinting;
00294 int i;
00295
00296
00297
00298 unpatented_hinting = FT_BOOL
00299 ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
00300
00301 for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
00302 if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
00303 unpatented_hinting = TRUE;
00304
00305 if ( !unpatented_hinting )
00306 ttface->internal->ignore_unpatented_hinter = TRUE;
00307 }
00308
00309 #endif
00310
00311
00312
00313 TT_Init_Glyph_Loading( face );
00314
00315 Exit:
00316 return error;
00317
00318 Bad_Format:
00319 error = TT_Err_Unknown_File_Format;
00320 goto Exit;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 FT_LOCAL_DEF( void )
00336 tt_face_done( FT_Face ttface )
00337 {
00338 TT_Face face = (TT_Face)ttface;
00339 FT_Memory memory;
00340 FT_Stream stream;
00341 SFNT_Service sfnt;
00342
00343
00344 if ( !face )
00345 return;
00346
00347 memory = ttface->memory;
00348 stream = ttface->stream;
00349 sfnt = (SFNT_Service)face->sfnt;
00350
00351
00352 if ( face->extra.finalizer )
00353 face->extra.finalizer( face->extra.data );
00354
00355 if ( sfnt )
00356 sfnt->done_face( face );
00357
00358
00359 tt_face_done_loca( face );
00360
00361 tt_face_free_hdmx( face );
00362
00363
00364 FT_FREE( face->cvt );
00365 face->cvt_size = 0;
00366
00367
00368 FT_FRAME_RELEASE( face->font_program );
00369 FT_FRAME_RELEASE( face->cvt_program );
00370 face->font_program_size = 0;
00371 face->cvt_program_size = 0;
00372
00373 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
00374 tt_done_blend( memory, face->blend );
00375 face->blend = NULL;
00376 #endif
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386 #ifdef TT_USE_BYTECODE_INTERPRETER
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 FT_LOCAL_DEF( FT_Error )
00403 tt_size_run_fpgm( TT_Size size )
00404 {
00405 TT_Face face = (TT_Face)size->root.face;
00406 TT_ExecContext exec;
00407 FT_Error error;
00408
00409
00410
00411 if ( size->debug )
00412 exec = size->context;
00413 else
00414 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
00415
00416 if ( !exec )
00417 return TT_Err_Could_Not_Find_Context;
00418
00419 TT_Load_Context( exec, face, size );
00420
00421 exec->callTop = 0;
00422 exec->top = 0;
00423
00424 exec->period = 64;
00425 exec->phase = 0;
00426 exec->threshold = 0;
00427
00428 exec->instruction_trap = FALSE;
00429 exec->F_dot_P = 0x10000L;
00430
00431 {
00432 FT_Size_Metrics* metrics = &exec->metrics;
00433 TT_Size_Metrics* tt_metrics = &exec->tt_metrics;
00434
00435
00436 metrics->x_ppem = 0;
00437 metrics->y_ppem = 0;
00438 metrics->x_scale = 0;
00439 metrics->y_scale = 0;
00440
00441 tt_metrics->ppem = 0;
00442 tt_metrics->scale = 0;
00443 tt_metrics->ratio = 0x10000L;
00444 }
00445
00446
00447 TT_Set_CodeRange( exec,
00448 tt_coderange_font,
00449 face->font_program,
00450 face->font_program_size );
00451
00452
00453 TT_Clear_CodeRange( exec, tt_coderange_cvt );
00454 TT_Clear_CodeRange( exec, tt_coderange_glyph );
00455
00456 if ( face->font_program_size > 0 )
00457 {
00458 error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
00459
00460 if ( !error )
00461 error = face->interpreter( exec );
00462 }
00463 else
00464 error = TT_Err_Ok;
00465
00466 if ( !error )
00467 TT_Save_Context( exec, size );
00468
00469 return error;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 FT_LOCAL_DEF( FT_Error )
00488 tt_size_run_prep( TT_Size size )
00489 {
00490 TT_Face face = (TT_Face)size->root.face;
00491 TT_ExecContext exec;
00492 FT_Error error;
00493
00494
00495
00496 if ( size->debug )
00497 exec = size->context;
00498 else
00499 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
00500
00501 if ( !exec )
00502 return TT_Err_Could_Not_Find_Context;
00503
00504 TT_Load_Context( exec, face, size );
00505
00506 exec->callTop = 0;
00507 exec->top = 0;
00508
00509 exec->instruction_trap = FALSE;
00510
00511 TT_Set_CodeRange( exec,
00512 tt_coderange_cvt,
00513 face->cvt_program,
00514 face->cvt_program_size );
00515
00516 TT_Clear_CodeRange( exec, tt_coderange_glyph );
00517
00518 if ( face->cvt_program_size > 0 )
00519 {
00520 error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
00521
00522 if ( !error && !size->debug )
00523 error = face->interpreter( exec );
00524 }
00525 else
00526 error = TT_Err_Ok;
00527
00528
00529 size->GS = exec->GS;
00530
00531 TT_Save_Context( exec, size );
00532
00533 return error;
00534 }
00535
00536 #endif
00537
00538
00539 #ifdef TT_USE_BYTECODE_INTERPRETER
00540
00541 static void
00542 tt_size_done_bytecode( FT_Size ftsize )
00543 {
00544 TT_Size size = (TT_Size)ftsize;
00545 TT_Face face = (TT_Face)ftsize->face;
00546 FT_Memory memory = face->root.memory;
00547
00548
00549 if ( size->debug )
00550 {
00551
00552 size->context = NULL;
00553 size->debug = FALSE;
00554 }
00555
00556 FT_FREE( size->cvt );
00557 size->cvt_size = 0;
00558
00559
00560 FT_FREE( size->storage );
00561 size->storage_size = 0;
00562
00563
00564 tt_glyphzone_done( &size->twilight );
00565
00566 FT_FREE( size->function_defs );
00567 FT_FREE( size->instruction_defs );
00568
00569 size->num_function_defs = 0;
00570 size->max_function_defs = 0;
00571 size->num_instruction_defs = 0;
00572 size->max_instruction_defs = 0;
00573
00574 size->max_func = 0;
00575 size->max_ins = 0;
00576
00577 size->bytecode_ready = 0;
00578 size->cvt_ready = 0;
00579 }
00580
00581
00582
00583
00584 static FT_Error
00585 tt_size_init_bytecode( FT_Size ftsize )
00586 {
00587 FT_Error error;
00588 TT_Size size = (TT_Size)ftsize;
00589 TT_Face face = (TT_Face)ftsize->face;
00590 FT_Memory memory = face->root.memory;
00591 FT_Int i;
00592
00593 FT_UShort n_twilight;
00594 TT_MaxProfile* maxp = &face->max_profile;
00595
00596
00597 size->bytecode_ready = 1;
00598 size->cvt_ready = 0;
00599
00600 size->max_function_defs = maxp->maxFunctionDefs;
00601 size->max_instruction_defs = maxp->maxInstructionDefs;
00602
00603 size->num_function_defs = 0;
00604 size->num_instruction_defs = 0;
00605
00606 size->max_func = 0;
00607 size->max_ins = 0;
00608
00609 size->cvt_size = face->cvt_size;
00610 size->storage_size = maxp->maxStorage;
00611
00612
00613 {
00614 TT_Size_Metrics* metrics = &size->ttmetrics;
00615
00616
00617 metrics->rotated = FALSE;
00618 metrics->stretched = FALSE;
00619
00620
00621 for ( i = 0; i < 4; i++ )
00622 metrics->compensations[i] = 0;
00623 }
00624
00625
00626 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) ||
00627 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
00628 FT_NEW_ARRAY( size->cvt, size->cvt_size ) ||
00629 FT_NEW_ARRAY( size->storage, size->storage_size ) )
00630 goto Exit;
00631
00632
00633 n_twilight = maxp->maxTwilightPoints;
00634
00635
00636 n_twilight += 4;
00637
00638 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
00639 if ( error )
00640 goto Exit;
00641
00642 size->twilight.n_points = n_twilight;
00643
00644 size->GS = tt_default_graphics_state;
00645
00646
00647 {
00648 FT_Library library = face->root.driver->root.library;
00649
00650
00651 face->interpreter = (TT_Interpreter)
00652 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
00653 if ( !face->interpreter )
00654 face->interpreter = (TT_Interpreter)TT_RunIns;
00655 }
00656
00657
00658 error = tt_size_run_fpgm( size );
00659
00660 Exit:
00661 if ( error )
00662 tt_size_done_bytecode( ftsize );
00663
00664 return error;
00665 }
00666
00667
00668 FT_LOCAL_DEF( FT_Error )
00669 tt_size_ready_bytecode( TT_Size size )
00670 {
00671 FT_Error error = TT_Err_Ok;
00672
00673
00674 if ( !size->bytecode_ready )
00675 {
00676 error = tt_size_init_bytecode( (FT_Size)size );
00677 if ( error )
00678 goto Exit;
00679 }
00680
00681
00682 if ( !size->cvt_ready )
00683 {
00684 FT_UInt i;
00685 TT_Face face = (TT_Face)size->root.face;
00686
00687
00688
00689
00690 for ( i = 0; i < size->cvt_size; i++ )
00691 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
00692
00693
00694 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
00695 {
00696 size->twilight.org[i].x = 0;
00697 size->twilight.org[i].y = 0;
00698 size->twilight.cur[i].x = 0;
00699 size->twilight.cur[i].y = 0;
00700 }
00701
00702
00703 for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
00704 size->storage[i] = 0;
00705
00706 size->GS = tt_default_graphics_state;
00707
00708 error = tt_size_run_prep( size );
00709 if ( !error )
00710 size->cvt_ready = 1;
00711 }
00712
00713 Exit:
00714 return error;
00715 }
00716
00717 #endif
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 FT_LOCAL_DEF( FT_Error )
00735 tt_size_init( FT_Size ttsize )
00736 {
00737 TT_Size size = (TT_Size)ttsize;
00738 FT_Error error = TT_Err_Ok;
00739
00740 #ifdef TT_USE_BYTECODE_INTERPRETER
00741 size->bytecode_ready = 0;
00742 size->cvt_ready = 0;
00743 #endif
00744
00745 size->ttmetrics.valid = FALSE;
00746 size->strike_index = 0xFFFFFFFFUL;
00747
00748 return error;
00749 }
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 FT_LOCAL_DEF( void )
00764 tt_size_done( FT_Size ttsize )
00765 {
00766 TT_Size size = (TT_Size)ttsize;
00767
00768
00769 #ifdef TT_USE_BYTECODE_INTERPRETER
00770 if ( size->bytecode_ready )
00771 tt_size_done_bytecode( ttsize );
00772 #endif
00773
00774 size->ttmetrics.valid = FALSE;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 FT_LOCAL_DEF( FT_Error )
00791 tt_size_reset( TT_Size size )
00792 {
00793 TT_Face face;
00794 FT_Error error = TT_Err_Ok;
00795 FT_Size_Metrics* metrics;
00796
00797
00798 size->ttmetrics.valid = FALSE;
00799
00800 face = (TT_Face)size->root.face;
00801
00802 metrics = &size->metrics;
00803
00804
00805 *metrics = size->root.metrics;
00806
00807 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
00808 return TT_Err_Invalid_PPem;
00809
00810
00811
00812
00813
00814 if ( face->header.Flags & 8 )
00815 {
00816 metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
00817 face->root.units_per_EM );
00818 metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
00819 face->root.units_per_EM );
00820
00821 metrics->ascender =
00822 FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
00823 metrics->descender =
00824 FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
00825 metrics->height =
00826 FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
00827 metrics->max_advance =
00828 FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
00829 metrics->x_scale ) );
00830 }
00831
00832
00833 if ( metrics->x_ppem >= metrics->y_ppem )
00834 {
00835 size->ttmetrics.scale = metrics->x_scale;
00836 size->ttmetrics.ppem = metrics->x_ppem;
00837 size->ttmetrics.x_ratio = 0x10000L;
00838 size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
00839 0x10000L,
00840 metrics->x_ppem );
00841 }
00842 else
00843 {
00844 size->ttmetrics.scale = metrics->y_scale;
00845 size->ttmetrics.ppem = metrics->y_ppem;
00846 size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
00847 0x10000L,
00848 metrics->y_ppem );
00849 size->ttmetrics.y_ratio = 0x10000L;
00850 }
00851
00852 #ifdef TT_USE_BYTECODE_INTERPRETER
00853 size->cvt_ready = 0;
00854 #endif
00855
00856 if ( !error )
00857 size->ttmetrics.valid = TRUE;
00858
00859 return error;
00860 }
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 FT_LOCAL_DEF( FT_Error )
00878 tt_driver_init( FT_Module ttdriver )
00879 {
00880
00881 #ifdef TT_USE_BYTECODE_INTERPRETER
00882
00883 TT_Driver driver = (TT_Driver)ttdriver;
00884
00885
00886 if ( !TT_New_Context( driver ) )
00887 return TT_Err_Could_Not_Find_Context;
00888
00889 #else
00890
00891 FT_UNUSED( ttdriver );
00892
00893 #endif
00894
00895 return TT_Err_Ok;
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 FT_LOCAL_DEF( void )
00911 tt_driver_done( FT_Module ttdriver )
00912 {
00913 #ifdef TT_USE_BYTECODE_INTERPRETER
00914 TT_Driver driver = (TT_Driver)ttdriver;
00915
00916
00917
00918 if ( driver->context )
00919 {
00920 TT_Done_Context( driver->context );
00921 driver->context = NULL;
00922 }
00923 #else
00924 FT_UNUSED( ttdriver );
00925 #endif
00926
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 FT_LOCAL_DEF( FT_Error )
00945 tt_slot_init( FT_GlyphSlot slot )
00946 {
00947 return FT_GlyphLoader_CreateExtra( slot->internal->loader );
00948 }
00949
00950
00951