OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* ttgxvar.c */ | 3 /* ttgxvar.c */ |
4 /* */ | 4 /* */ |
5 /* TrueType GX Font Variation loader */ | 5 /* TrueType GX Font Variation loader */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2004-2011 by */ | 7 /* Copyright 2004-2013 by */ |
8 /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ | 8 /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ |
9 /* */ | 9 /* */ |
10 /* This file is part of the FreeType project, and may only be used, */ | 10 /* This file is part of the FreeType project, and may only be used, */ |
11 /* modified, and distributed under the terms of the FreeType project */ | 11 /* modified, and distributed under the terms of the FreeType project */ |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
13 /* this file you indicate that you have read the license and */ | 13 /* this file you indicate that you have read the license and */ |
14 /* understand and accept it fully. */ | 14 /* understand and accept it fully. */ |
15 /* */ | 15 /* */ |
16 /***************************************************************************/ | 16 /***************************************************************************/ |
17 | 17 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 #include "ttpload.h" | 54 #include "ttpload.h" |
55 #include "ttgxvar.h" | 55 #include "ttgxvar.h" |
56 | 56 |
57 #include "tterrors.h" | 57 #include "tterrors.h" |
58 | 58 |
59 | 59 |
60 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT | 60 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT |
61 | 61 |
62 | 62 |
63 #define FT_Stream_FTell( stream ) \ | 63 #define FT_Stream_FTell( stream ) \ |
64 ( (stream)->cursor - (stream)->base ) | 64 (FT_ULong)( (stream)->cursor - (stream)->base ) |
65 #define FT_Stream_SeekSet( stream, off ) \ | 65 #define FT_Stream_SeekSet( stream, off ) \ |
66 ( (stream)->cursor = (stream)->base+(off) ) | 66 ( (stream)->cursor = (stream)->base + (off) ) |
67 | 67 |
68 | 68 |
69 /*************************************************************************/ | 69 /*************************************************************************/ |
70 /* */ | 70 /* */ |
71 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ | 71 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
72 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ | 72 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
73 /* messages during execution. */ | 73 /* messages during execution. */ |
74 /* */ | 74 /* */ |
75 #undef FT_COMPONENT | 75 #undef FT_COMPONENT |
76 #define FT_COMPONENT trace_ttgxvar | 76 #define FT_COMPONENT trace_ttgxvar |
77 | 77 |
78 | 78 |
79 /*************************************************************************/ | 79 /*************************************************************************/ |
80 /*************************************************************************/ | 80 /*************************************************************************/ |
81 /***** *****/ | 81 /***** *****/ |
82 /***** Internal Routines *****/ | 82 /***** Internal Routines *****/ |
83 /***** *****/ | 83 /***** *****/ |
84 /*************************************************************************/ | 84 /*************************************************************************/ |
85 /*************************************************************************/ | 85 /*************************************************************************/ |
86 | 86 |
87 | 87 |
88 /*************************************************************************/ | 88 /*************************************************************************/ |
89 /* */ | 89 /* */ |
90 /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ | 90 /* The macro ALL_POINTS is used in `ft_var_readpackedpoints'. It */ |
91 /* indicates that there is a delta for every point without needing to */ | 91 /* indicates that there is a delta for every point without needing to */ |
92 /* enumerate all of them. */ | 92 /* enumerate all of them. */ |
93 /* */ | 93 /* */ |
94 #define ALL_POINTS (FT_UShort*)( -1 ) | 94 |
| 95 /* ensure that value `0' has the same width as a pointer */ |
| 96 #define ALL_POINTS (FT_UShort*)~(FT_PtrDist)0 |
95 | 97 |
96 | 98 |
97 #define GX_PT_POINTS_ARE_WORDS 0x80 | 99 #define GX_PT_POINTS_ARE_WORDS 0x80 |
98 #define GX_PT_POINT_RUN_COUNT_MASK 0x7F | 100 #define GX_PT_POINT_RUN_COUNT_MASK 0x7F |
99 | 101 |
100 | 102 |
101 /*************************************************************************/ | 103 /*************************************************************************/ |
102 /* */ | 104 /* */ |
103 /* <Function> */ | 105 /* <Function> */ |
104 /* ft_var_readpackedpoints */ | 106 /* ft_var_readpackedpoints */ |
(...skipping 18 matching lines...) Expand all Loading... |
123 ft_var_readpackedpoints( FT_Stream stream, | 125 ft_var_readpackedpoints( FT_Stream stream, |
124 FT_UInt *point_cnt ) | 126 FT_UInt *point_cnt ) |
125 { | 127 { |
126 FT_UShort *points = NULL; | 128 FT_UShort *points = NULL; |
127 FT_Int n; | 129 FT_Int n; |
128 FT_Int runcnt; | 130 FT_Int runcnt; |
129 FT_Int i; | 131 FT_Int i; |
130 FT_Int j; | 132 FT_Int j; |
131 FT_Int first; | 133 FT_Int first; |
132 FT_Memory memory = stream->memory; | 134 FT_Memory memory = stream->memory; |
133 FT_Error error = TT_Err_Ok; | 135 FT_Error error = FT_Err_Ok; |
134 | 136 |
135 FT_UNUSED( error ); | 137 FT_UNUSED( error ); |
136 | 138 |
137 | 139 |
138 *point_cnt = n = FT_GET_BYTE(); | 140 *point_cnt = n = FT_GET_BYTE(); |
139 if ( n == 0 ) | 141 if ( n == 0 ) |
140 return ALL_POINTS; | 142 return ALL_POINTS; |
141 | 143 |
142 if ( n & GX_PT_POINTS_ARE_WORDS ) | 144 if ( n & GX_PT_POINTS_ARE_WORDS ) |
143 n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); | 145 n = FT_GET_BYTE() | ( ( n & GX_PT_POINT_RUN_COUNT_MASK ) << 8 ); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 /* */ | 210 /* */ |
209 static FT_Short* | 211 static FT_Short* |
210 ft_var_readpackeddeltas( FT_Stream stream, | 212 ft_var_readpackeddeltas( FT_Stream stream, |
211 FT_Offset delta_cnt ) | 213 FT_Offset delta_cnt ) |
212 { | 214 { |
213 FT_Short *deltas = NULL; | 215 FT_Short *deltas = NULL; |
214 FT_UInt runcnt; | 216 FT_UInt runcnt; |
215 FT_Offset i; | 217 FT_Offset i; |
216 FT_UInt j; | 218 FT_UInt j; |
217 FT_Memory memory = stream->memory; | 219 FT_Memory memory = stream->memory; |
218 FT_Error error = TT_Err_Ok; | 220 FT_Error error = FT_Err_Ok; |
219 | 221 |
220 FT_UNUSED( error ); | 222 FT_UNUSED( error ); |
221 | 223 |
222 | 224 |
223 if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) | 225 if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) |
224 return NULL; | 226 return NULL; |
225 | 227 |
226 i = 0; | 228 i = 0; |
227 while ( i < delta_cnt ) | 229 while ( i < delta_cnt ) |
228 { | 230 { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 /* <InOut> */ | 278 /* <InOut> */ |
277 /* face :: The font face. */ | 279 /* face :: The font face. */ |
278 /* */ | 280 /* */ |
279 static void | 281 static void |
280 ft_var_load_avar( TT_Face face ) | 282 ft_var_load_avar( TT_Face face ) |
281 { | 283 { |
282 FT_Stream stream = FT_FACE_STREAM(face); | 284 FT_Stream stream = FT_FACE_STREAM(face); |
283 FT_Memory memory = stream->memory; | 285 FT_Memory memory = stream->memory; |
284 GX_Blend blend = face->blend; | 286 GX_Blend blend = face->blend; |
285 GX_AVarSegment segment; | 287 GX_AVarSegment segment; |
286 FT_Error error = TT_Err_Ok; | 288 FT_Error error = FT_Err_Ok; |
287 FT_ULong version; | 289 FT_ULong version; |
288 FT_Long axisCount; | 290 FT_Long axisCount; |
289 FT_Int i, j; | 291 FT_Int i, j; |
290 FT_ULong table_len; | 292 FT_ULong table_len; |
291 | 293 |
292 FT_UNUSED( error ); | 294 FT_UNUSED( error ); |
293 | 295 |
294 | 296 |
295 blend->avar_checked = TRUE; | 297 blend->avar_checked = TRUE; |
296 if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0
) | 298 if ( (error = face->goto_table( face, TTAG_avar, stream, &table_len )) != 0
) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) | 407 if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) |
406 goto Exit; | 408 goto Exit; |
407 | 409 |
408 blend->tuplecount = gvar_head.globalCoordCount; | 410 blend->tuplecount = gvar_head.globalCoordCount; |
409 blend->gv_glyphcnt = gvar_head.glyphCount; | 411 blend->gv_glyphcnt = gvar_head.glyphCount; |
410 offsetToData = gvar_start + gvar_head.offsetToData; | 412 offsetToData = gvar_start + gvar_head.offsetToData; |
411 | 413 |
412 if ( gvar_head.version != (FT_Long)0x00010000L || | 414 if ( gvar_head.version != (FT_Long)0x00010000L || |
413 gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) | 415 gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) |
414 { | 416 { |
415 error = TT_Err_Invalid_Table; | 417 error = FT_THROW( Invalid_Table ); |
416 goto Exit; | 418 goto Exit; |
417 } | 419 } |
418 | 420 |
419 if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) | 421 if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) |
420 goto Exit; | 422 goto Exit; |
421 | 423 |
422 if ( gvar_head.flags & 1 ) | 424 if ( gvar_head.flags & 1 ) |
423 { | 425 { |
424 /* long offsets (one more offset than glyphs, to mark size of last) */ | 426 /* long offsets (one more offset than glyphs, to mark size of last) */ |
425 if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) | 427 if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 /* An FT_Fixed value containing the scaling factor. */ | 496 /* An FT_Fixed value containing the scaling factor. */ |
495 /* */ | 497 /* */ |
496 static FT_Fixed | 498 static FT_Fixed |
497 ft_var_apply_tuple( GX_Blend blend, | 499 ft_var_apply_tuple( GX_Blend blend, |
498 FT_UShort tupleIndex, | 500 FT_UShort tupleIndex, |
499 FT_Fixed* tuple_coords, | 501 FT_Fixed* tuple_coords, |
500 FT_Fixed* im_start_coords, | 502 FT_Fixed* im_start_coords, |
501 FT_Fixed* im_end_coords ) | 503 FT_Fixed* im_end_coords ) |
502 { | 504 { |
503 FT_UInt i; | 505 FT_UInt i; |
504 FT_Fixed apply; | 506 FT_Fixed apply = 0x10000L; |
505 FT_Fixed temp; | |
506 | 507 |
507 | 508 |
508 apply = 0x10000L; | |
509 for ( i = 0; i < blend->num_axis; ++i ) | 509 for ( i = 0; i < blend->num_axis; ++i ) |
510 { | 510 { |
511 if ( tuple_coords[i] == 0 ) | 511 if ( tuple_coords[i] == 0 ) |
512 /* It's not clear why (for intermediate tuples) we don't need */ | 512 /* It's not clear why (for intermediate tuples) we don't need */ |
513 /* to check against start/end -- the documentation says we don't. */ | 513 /* to check against start/end -- the documentation says we don't. */ |
514 /* Similarly, it's unclear why we don't need to scale along the */ | 514 /* Similarly, it's unclear why we don't need to scale along the */ |
515 /* axis. */ | 515 /* axis. */ |
516 continue; | 516 continue; |
517 | 517 |
518 else if ( blend->normalizedcoords[i] == 0 || | 518 else if ( blend->normalizedcoords[i] == 0 || |
519 ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || | 519 ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || |
520 ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) | 520 ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) |
521 { | 521 { |
522 apply = 0; | 522 apply = 0; |
523 break; | 523 break; |
524 } | 524 } |
525 | 525 |
526 else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) | 526 else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) |
527 /* not an intermediate tuple */ | 527 /* not an intermediate tuple */ |
528 apply = FT_MulDiv( apply, | 528 apply = FT_MulFix( apply, |
529 blend->normalizedcoords[i] > 0 | 529 blend->normalizedcoords[i] > 0 |
530 ? blend->normalizedcoords[i] | 530 ? blend->normalizedcoords[i] |
531 : -blend->normalizedcoords[i], | 531 : -blend->normalizedcoords[i] ); |
532 0x10000L ); | |
533 | 532 |
534 else if ( blend->normalizedcoords[i] <= im_start_coords[i] || | 533 else if ( blend->normalizedcoords[i] <= im_start_coords[i] || |
535 blend->normalizedcoords[i] >= im_end_coords[i] ) | 534 blend->normalizedcoords[i] >= im_end_coords[i] ) |
536 { | 535 { |
537 apply = 0; | 536 apply = 0; |
538 break; | 537 break; |
539 } | 538 } |
540 | 539 |
541 else if ( blend->normalizedcoords[i] < tuple_coords[i] ) | 540 else if ( blend->normalizedcoords[i] < tuple_coords[i] ) |
542 { | 541 apply = FT_MulDiv( apply, |
543 temp = FT_MulDiv( blend->normalizedcoords[i] - im_start_coords[i], | 542 blend->normalizedcoords[i] - im_start_coords[i], |
544 0x10000L, | 543 tuple_coords[i] - im_start_coords[i] ); |
545 tuple_coords[i] - im_start_coords[i]); | |
546 apply = FT_MulDiv( apply, temp, 0x10000L ); | |
547 } | |
548 | 544 |
549 else | 545 else |
550 { | 546 apply = FT_MulDiv( apply, |
551 temp = FT_MulDiv( im_end_coords[i] - blend->normalizedcoords[i], | 547 im_end_coords[i] - blend->normalizedcoords[i], |
552 0x10000L, | 548 im_end_coords[i] - tuple_coords[i] ); |
553 im_end_coords[i] - tuple_coords[i] ); | |
554 apply = FT_MulDiv( apply, temp, 0x10000L ); | |
555 } | |
556 } | 549 } |
557 | 550 |
558 return apply; | 551 return apply; |
559 } | 552 } |
560 | 553 |
561 | 554 |
562 /*************************************************************************/ | 555 /*************************************************************************/ |
563 /*************************************************************************/ | 556 /*************************************************************************/ |
564 /***** *****/ | 557 /***** *****/ |
565 /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ | 558 /***** MULTIPLE MASTERS SERVICE FUNCTIONS *****/ |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 /* <Return> */ | 605 /* <Return> */ |
613 /* FreeType error code. 0 means success. */ | 606 /* FreeType error code. 0 means success. */ |
614 /* */ | 607 /* */ |
615 FT_LOCAL_DEF( FT_Error ) | 608 FT_LOCAL_DEF( FT_Error ) |
616 TT_Get_MM_Var( TT_Face face, | 609 TT_Get_MM_Var( TT_Face face, |
617 FT_MM_Var* *master ) | 610 FT_MM_Var* *master ) |
618 { | 611 { |
619 FT_Stream stream = face->root.stream; | 612 FT_Stream stream = face->root.stream; |
620 FT_Memory memory = face->root.memory; | 613 FT_Memory memory = face->root.memory; |
621 FT_ULong table_len; | 614 FT_ULong table_len; |
622 FT_Error error = TT_Err_Ok; | 615 FT_Error error = FT_Err_Ok; |
623 FT_ULong fvar_start; | 616 FT_ULong fvar_start; |
624 FT_Int i, j; | 617 FT_Int i, j; |
625 FT_MM_Var* mmvar = NULL; | 618 FT_MM_Var* mmvar = NULL; |
626 FT_Fixed* next_coords; | 619 FT_Fixed* next_coords; |
627 FT_String* next_name; | 620 FT_String* next_name; |
628 FT_Var_Axis* a; | 621 FT_Var_Axis* a; |
629 FT_Var_Named_Style* ns; | 622 FT_Var_Named_Style* ns; |
630 GX_FVar_Head fvar_head; | 623 GX_FVar_Head fvar_head; |
631 | 624 |
632 static const FT_Frame_Field fvar_fields[] = | 625 static const FT_Frame_Field fvar_fields[] = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 fvar_head.countSizePairs != 2 || | 676 fvar_head.countSizePairs != 2 || |
684 fvar_head.axisSize != 20 || | 677 fvar_head.axisSize != 20 || |
685 /* axisCount limit implied by 16-bit instanceSize */ | 678 /* axisCount limit implied by 16-bit instanceSize */ |
686 fvar_head.axisCount > 0x3FFE || | 679 fvar_head.axisCount > 0x3FFE || |
687 fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || | 680 fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || |
688 /* instanceCount limit implied by limited range of name IDs */ | 681 /* instanceCount limit implied by limited range of name IDs */ |
689 fvar_head.instanceCount > 0x7EFF || | 682 fvar_head.instanceCount > 0x7EFF || |
690 fvar_head.offsetToData + fvar_head.axisCount * 20U + | 683 fvar_head.offsetToData + fvar_head.axisCount * 20U + |
691 fvar_head.instanceCount * fvar_head.instanceSize > table_len ) | 684 fvar_head.instanceCount * fvar_head.instanceSize > table_len ) |
692 { | 685 { |
693 error = TT_Err_Invalid_Table; | 686 error = FT_THROW( Invalid_Table ); |
694 goto Exit; | 687 goto Exit; |
695 } | 688 } |
696 | 689 |
697 if ( FT_NEW( face->blend ) ) | 690 if ( FT_NEW( face->blend ) ) |
698 goto Exit; | 691 goto Exit; |
699 | 692 |
700 /* cannot overflow 32-bit arithmetic because of limits above */ | 693 /* cannot overflow 32-bit arithmetic because of limits above */ |
701 face->blend->mmvar_len = | 694 face->blend->mmvar_len = |
702 sizeof ( FT_MM_Var ) + | 695 sizeof ( FT_MM_Var ) + |
703 fvar_head.axisCount * sizeof ( FT_Var_Axis ) + | 696 fvar_head.axisCount * sizeof ( FT_Var_Axis ) + |
704 fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + | 697 fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + |
705 fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + | 698 fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + |
706 5 * fvar_head.axisCount; | 699 5 * fvar_head.axisCount; |
707 | 700 |
708 if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) | 701 if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) |
709 goto Exit; | 702 goto Exit; |
710 face->blend->mmvar = mmvar; | 703 face->blend->mmvar = mmvar; |
711 | 704 |
712 mmvar->num_axis = | 705 mmvar->num_axis = |
713 fvar_head.axisCount; | 706 fvar_head.axisCount; |
714 mmvar->num_designs = | 707 mmvar->num_designs = |
715 (FT_UInt)-1; /* meaningless in this context; each glyph */ | 708 ~0U; /* meaningless in this context; each glyph */ |
716 /* may have a different number of designs */ | 709 /* may have a different number of designs */ |
717 /* (or tuples, as called by Apple) */ | 710 /* (or tuples, as called by Apple) */ |
718 mmvar->num_namedstyles = | 711 mmvar->num_namedstyles = |
719 fvar_head.instanceCount; | 712 fvar_head.instanceCount; |
720 mmvar->axis = | 713 mmvar->axis = |
721 (FT_Var_Axis*)&(mmvar[1]); | 714 (FT_Var_Axis*)&(mmvar[1]); |
722 mmvar->namedstyle = | 715 mmvar->namedstyle = |
723 (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); | 716 (FT_Var_Named_Style*)&(mmvar->axis[fvar_head.axisCount]); |
724 | 717 |
725 next_coords = | 718 next_coords = |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 /* coords :: An array of num_coords, each between [-1,1]. */ | 842 /* coords :: An array of num_coords, each between [-1,1]. */ |
850 /* */ | 843 /* */ |
851 /* <Return> */ | 844 /* <Return> */ |
852 /* FreeType error code. 0 means success. */ | 845 /* FreeType error code. 0 means success. */ |
853 /* */ | 846 /* */ |
854 FT_LOCAL_DEF( FT_Error ) | 847 FT_LOCAL_DEF( FT_Error ) |
855 TT_Set_MM_Blend( TT_Face face, | 848 TT_Set_MM_Blend( TT_Face face, |
856 FT_UInt num_coords, | 849 FT_UInt num_coords, |
857 FT_Fixed* coords ) | 850 FT_Fixed* coords ) |
858 { | 851 { |
859 FT_Error error = TT_Err_Ok; | 852 FT_Error error = FT_Err_Ok; |
860 GX_Blend blend; | 853 GX_Blend blend; |
861 FT_MM_Var* mmvar; | 854 FT_MM_Var* mmvar; |
862 FT_UInt i; | 855 FT_UInt i; |
863 FT_Memory memory = face->root.memory; | 856 FT_Memory memory = face->root.memory; |
864 | 857 |
865 enum | 858 enum |
866 { | 859 { |
867 mcvt_retain, | 860 mcvt_retain, |
868 mcvt_modify, | 861 mcvt_modify, |
869 mcvt_load | 862 mcvt_load |
870 | 863 |
871 } manageCvt; | 864 } manageCvt; |
872 | 865 |
873 | 866 |
874 face->doblend = FALSE; | 867 face->doblend = FALSE; |
875 | 868 |
876 if ( face->blend == NULL ) | 869 if ( face->blend == NULL ) |
877 { | 870 { |
878 if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) | 871 if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) |
879 goto Exit; | 872 goto Exit; |
880 } | 873 } |
881 | 874 |
882 blend = face->blend; | 875 blend = face->blend; |
883 mmvar = blend->mmvar; | 876 mmvar = blend->mmvar; |
884 | 877 |
885 if ( num_coords != mmvar->num_axis ) | 878 if ( num_coords != mmvar->num_axis ) |
886 { | 879 { |
887 error = TT_Err_Invalid_Argument; | 880 error = FT_THROW( Invalid_Argument ); |
888 goto Exit; | 881 goto Exit; |
889 } | 882 } |
890 | 883 |
891 for ( i = 0; i < num_coords; ++i ) | 884 for ( i = 0; i < num_coords; ++i ) |
892 if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) | 885 if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) |
893 { | 886 { |
894 error = TT_Err_Invalid_Argument; | 887 error = FT_THROW( Invalid_Argument ); |
895 goto Exit; | 888 goto Exit; |
896 } | 889 } |
897 | 890 |
898 if ( blend->glyphoffsets == NULL ) | 891 if ( blend->glyphoffsets == NULL ) |
899 if ( (error = ft_var_load_gvar( face )) != 0 ) | 892 if ( (error = ft_var_load_gvar( face )) != 0 ) |
900 goto Exit; | 893 goto Exit; |
901 | 894 |
902 if ( blend->normalizedcoords == NULL ) | 895 if ( blend->normalizedcoords == NULL ) |
903 { | 896 { |
904 if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) | 897 if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 /* coords :: A coordinate array with `num_coords' elements. */ | 978 /* coords :: A coordinate array with `num_coords' elements. */ |
986 /* */ | 979 /* */ |
987 /* <Return> */ | 980 /* <Return> */ |
988 /* FreeType error code. 0 means success. */ | 981 /* FreeType error code. 0 means success. */ |
989 /* */ | 982 /* */ |
990 FT_LOCAL_DEF( FT_Error ) | 983 FT_LOCAL_DEF( FT_Error ) |
991 TT_Set_Var_Design( TT_Face face, | 984 TT_Set_Var_Design( TT_Face face, |
992 FT_UInt num_coords, | 985 FT_UInt num_coords, |
993 FT_Fixed* coords ) | 986 FT_Fixed* coords ) |
994 { | 987 { |
995 FT_Error error = TT_Err_Ok; | 988 FT_Error error = FT_Err_Ok; |
996 FT_Fixed* normalized = NULL; | 989 FT_Fixed* normalized = NULL; |
997 GX_Blend blend; | 990 GX_Blend blend; |
998 FT_MM_Var* mmvar; | 991 FT_MM_Var* mmvar; |
999 FT_UInt i, j; | 992 FT_UInt i, j; |
1000 FT_Var_Axis* a; | 993 FT_Var_Axis* a; |
1001 GX_AVarSegment av; | 994 GX_AVarSegment av; |
1002 FT_Memory memory = face->root.memory; | 995 FT_Memory memory = face->root.memory; |
1003 | 996 |
1004 | 997 |
1005 if ( face->blend == NULL ) | 998 if ( face->blend == NULL ) |
1006 { | 999 { |
1007 if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) | 1000 if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) |
1008 goto Exit; | 1001 goto Exit; |
1009 } | 1002 } |
1010 | 1003 |
1011 blend = face->blend; | 1004 blend = face->blend; |
1012 mmvar = blend->mmvar; | 1005 mmvar = blend->mmvar; |
1013 | 1006 |
1014 if ( num_coords != mmvar->num_axis ) | 1007 if ( num_coords != mmvar->num_axis ) |
1015 { | 1008 { |
1016 error = TT_Err_Invalid_Argument; | 1009 error = FT_THROW( Invalid_Argument ); |
1017 goto Exit; | 1010 goto Exit; |
1018 } | 1011 } |
1019 | 1012 |
1020 /* Axis normalization is a two stage process. First we normalize */ | 1013 /* Axis normalization is a two stage process. First we normalize */ |
1021 /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ | 1014 /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ |
1022 /* Then, if there's an `avar' table, we renormalize this range. */ | 1015 /* Then, if there's an `avar' table, we renormalize this range. */ |
1023 | 1016 |
1024 if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) | 1017 if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) |
1025 goto Exit; | 1018 goto Exit; |
1026 | 1019 |
1027 a = mmvar->axis; | 1020 a = mmvar->axis; |
1028 for ( i = 0; i < mmvar->num_axis; ++i, ++a ) | 1021 for ( i = 0; i < mmvar->num_axis; ++i, ++a ) |
1029 { | 1022 { |
1030 if ( coords[i] > a->maximum || coords[i] < a->minimum ) | 1023 if ( coords[i] > a->maximum || coords[i] < a->minimum ) |
1031 { | 1024 { |
1032 error = TT_Err_Invalid_Argument; | 1025 error = FT_THROW( Invalid_Argument ); |
1033 goto Exit; | 1026 goto Exit; |
1034 } | 1027 } |
1035 | 1028 |
1036 if ( coords[i] < a->def ) | 1029 if ( coords[i] < a->def ) |
1037 { | 1030 normalized[i] = -FT_DivFix( coords[i] - a->def, a->minimum - a->def ); |
1038 normalized[i] = -FT_MulDiv( coords[i] - a->def, | |
1039 0x10000L, | |
1040 a->minimum - a->def ); | |
1041 } | |
1042 else if ( a->maximum == a->def ) | 1031 else if ( a->maximum == a->def ) |
1043 normalized[i] = 0; | 1032 normalized[i] = 0; |
1044 else | 1033 else |
1045 { | 1034 normalized[i] = FT_DivFix( coords[i] - a->def, a->maximum - a->def ); |
1046 normalized[i] = FT_MulDiv( coords[i] - a->def, | |
1047 0x10000L, | |
1048 a->maximum - a->def ); | |
1049 } | |
1050 } | 1035 } |
1051 | 1036 |
1052 if ( !blend->avar_checked ) | 1037 if ( !blend->avar_checked ) |
1053 ft_var_load_avar( face ); | 1038 ft_var_load_avar( face ); |
1054 | 1039 |
1055 if ( blend->avar_segment != NULL ) | 1040 if ( blend->avar_segment != NULL ) |
1056 { | 1041 { |
1057 av = blend->avar_segment; | 1042 av = blend->avar_segment; |
1058 for ( i = 0; i < mmvar->num_axis; ++i, ++av ) | 1043 for ( i = 0; i < mmvar->num_axis; ++i, ++av ) |
1059 { | 1044 { |
1060 for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) | 1045 for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) |
1061 if ( normalized[i] < av->correspondence[j].fromCoord ) | 1046 if ( normalized[i] < av->correspondence[j].fromCoord ) |
1062 { | 1047 { |
1063 normalized[i] = | 1048 normalized[i] = |
1064 FT_MulDiv( | 1049 FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, |
1065 FT_MulDiv( | 1050 av->correspondence[j].toCoord - |
1066 normalized[i] - av->correspondence[j - 1].fromCoord, | 1051 av->correspondence[j - 1].toCoord, |
1067 0x10000L, | 1052 av->correspondence[j].fromCoord - |
1068 av->correspondence[j].fromCoord - | 1053 av->correspondence[j - 1].fromCoord ) + |
1069 av->correspondence[j - 1].fromCoord ), | |
1070 av->correspondence[j].toCoord - | |
1071 av->correspondence[j - 1].toCoord, | |
1072 0x10000L ) + | |
1073 av->correspondence[j - 1].toCoord; | 1054 av->correspondence[j - 1].toCoord; |
1074 break; | 1055 break; |
1075 } | 1056 } |
1076 } | 1057 } |
1077 } | 1058 } |
1078 | 1059 |
1079 error = TT_Set_MM_Blend( face, num_coords, normalized ); | 1060 error = TT_Set_MM_Blend( face, num_coords, normalized ); |
1080 | 1061 |
1081 Exit: | 1062 Exit: |
1082 FT_FREE( normalized ); | 1063 FT_FREE( normalized ); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 FT_UShort* localpoints; | 1115 FT_UShort* localpoints; |
1135 FT_Short* deltas; | 1116 FT_Short* deltas; |
1136 | 1117 |
1137 | 1118 |
1138 FT_TRACE2(( "CVAR " )); | 1119 FT_TRACE2(( "CVAR " )); |
1139 | 1120 |
1140 if ( blend == NULL ) | 1121 if ( blend == NULL ) |
1141 { | 1122 { |
1142 FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); | 1123 FT_TRACE2(( "tt_face_vary_cvt: no blend specified\n" )); |
1143 | 1124 |
1144 error = TT_Err_Ok; | 1125 error = FT_Err_Ok; |
1145 goto Exit; | 1126 goto Exit; |
1146 } | 1127 } |
1147 | 1128 |
1148 if ( face->cvt == NULL ) | 1129 if ( face->cvt == NULL ) |
1149 { | 1130 { |
1150 FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); | 1131 FT_TRACE2(( "tt_face_vary_cvt: no `cvt ' table\n" )); |
1151 | 1132 |
1152 error = TT_Err_Ok; | 1133 error = FT_Err_Ok; |
1153 goto Exit; | 1134 goto Exit; |
1154 } | 1135 } |
1155 | 1136 |
1156 error = face->goto_table( face, TTAG_cvar, stream, &table_len ); | 1137 error = face->goto_table( face, TTAG_cvar, stream, &table_len ); |
1157 if ( error ) | 1138 if ( error ) |
1158 { | 1139 { |
1159 FT_TRACE2(( "is missing\n" )); | 1140 FT_TRACE2(( "is missing\n" )); |
1160 | 1141 |
1161 error = TT_Err_Ok; | 1142 error = FT_Err_Ok; |
1162 goto Exit; | 1143 goto Exit; |
1163 } | 1144 } |
1164 | 1145 |
1165 if ( FT_FRAME_ENTER( table_len ) ) | 1146 if ( FT_FRAME_ENTER( table_len ) ) |
1166 { | 1147 { |
1167 error = TT_Err_Ok; | 1148 error = FT_Err_Ok; |
1168 goto Exit; | 1149 goto Exit; |
1169 } | 1150 } |
1170 | 1151 |
1171 table_start = FT_Stream_FTell( stream ); | 1152 table_start = FT_Stream_FTell( stream ); |
1172 if ( FT_GET_LONG() != 0x00010000L ) | 1153 if ( FT_GET_LONG() != 0x00010000L ) |
1173 { | 1154 { |
1174 FT_TRACE2(( "bad table version\n" )); | 1155 FT_TRACE2(( "bad table version\n" )); |
1175 | 1156 |
1176 error = TT_Err_Ok; | 1157 error = FT_Err_Ok; |
1177 goto FExit; | 1158 goto FExit; |
1178 } | 1159 } |
1179 | 1160 |
1180 if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || | 1161 if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || |
1181 FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || | 1162 FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || |
1182 FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) | 1163 FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) |
1183 goto FExit; | 1164 goto FExit; |
1184 | 1165 |
1185 tupleCount = FT_GET_USHORT(); | 1166 tupleCount = FT_GET_USHORT(); |
1186 offsetToData = table_start + FT_GET_USHORT(); | 1167 offsetToData = table_start + FT_GET_USHORT(); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 FT_Fixed* im_start_coords = NULL; | 1318 FT_Fixed* im_start_coords = NULL; |
1338 FT_Fixed* im_end_coords = NULL; | 1319 FT_Fixed* im_end_coords = NULL; |
1339 FT_UInt point_count, spoint_count = 0; | 1320 FT_UInt point_count, spoint_count = 0; |
1340 FT_UShort* sharedpoints = NULL; | 1321 FT_UShort* sharedpoints = NULL; |
1341 FT_UShort* localpoints = NULL; | 1322 FT_UShort* localpoints = NULL; |
1342 FT_UShort* points; | 1323 FT_UShort* points; |
1343 FT_Short *deltas_x, *deltas_y; | 1324 FT_Short *deltas_x, *deltas_y; |
1344 | 1325 |
1345 | 1326 |
1346 if ( !face->doblend || blend == NULL ) | 1327 if ( !face->doblend || blend == NULL ) |
1347 return TT_Err_Invalid_Argument; | 1328 return FT_THROW( Invalid_Argument ); |
1348 | 1329 |
1349 /* to be freed by the caller */ | 1330 /* to be freed by the caller */ |
1350 if ( FT_NEW_ARRAY( delta_xy, n_points ) ) | 1331 if ( FT_NEW_ARRAY( delta_xy, n_points ) ) |
1351 goto Exit; | 1332 goto Exit; |
1352 *deltas = delta_xy; | 1333 *deltas = delta_xy; |
1353 | 1334 |
1354 if ( glyph_index >= blend->gv_glyphcnt || | 1335 if ( glyph_index >= blend->gv_glyphcnt || |
1355 blend->glyphoffsets[glyph_index] == | 1336 blend->glyphoffsets[glyph_index] == |
1356 blend->glyphoffsets[glyph_index + 1] ) | 1337 blend->glyphoffsets[glyph_index + 1] ) |
1357 return TT_Err_Ok; /* no variation data for this glyph */ | 1338 return FT_Err_Ok; /* no variation data for this glyph */ |
1358 | 1339 |
1359 if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || | 1340 if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || |
1360 FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - | 1341 FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - |
1361 blend->glyphoffsets[glyph_index] ) ) | 1342 blend->glyphoffsets[glyph_index] ) ) |
1362 goto Fail1; | 1343 goto Fail1; |
1363 | 1344 |
1364 glyph_start = FT_Stream_FTell( stream ); | 1345 glyph_start = FT_Stream_FTell( stream ); |
1365 | 1346 |
1366 /* each set of glyph variation data is formatted similarly to `cvar' */ | 1347 /* each set of glyph variation data is formatted similarly to `cvar' */ |
1367 /* (except we get shared points and global tuples) */ | 1348 /* (except we get shared points and global tuples) */ |
(...skipping 29 matching lines...) Expand all Loading... |
1397 tupleIndex = FT_GET_USHORT(); | 1378 tupleIndex = FT_GET_USHORT(); |
1398 | 1379 |
1399 if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) | 1380 if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) |
1400 { | 1381 { |
1401 for ( j = 0; j < blend->num_axis; ++j ) | 1382 for ( j = 0; j < blend->num_axis; ++j ) |
1402 tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ | 1383 tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ |
1403 /* short frac to fixed */ | 1384 /* short frac to fixed */ |
1404 } | 1385 } |
1405 else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) | 1386 else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) |
1406 { | 1387 { |
1407 error = TT_Err_Invalid_Table; | 1388 error = FT_THROW( Invalid_Table ); |
1408 goto Fail3; | 1389 goto Fail3; |
1409 } | 1390 } |
1410 else | 1391 else |
1411 { | 1392 { |
1412 FT_MEM_COPY( | 1393 FT_MEM_COPY( |
1413 tuple_coords, | 1394 tuple_coords, |
1414 &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], | 1395 &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], |
1415 blend->num_axis * sizeof ( FT_Fixed ) ); | 1396 blend->num_axis * sizeof ( FT_Fixed ) ); |
1416 } | 1397 } |
1417 | 1398 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1542 FT_FREE( blend->tuplecoords ); | 1523 FT_FREE( blend->tuplecoords ); |
1543 FT_FREE( blend->glyphoffsets ); | 1524 FT_FREE( blend->glyphoffsets ); |
1544 FT_FREE( blend ); | 1525 FT_FREE( blend ); |
1545 } | 1526 } |
1546 } | 1527 } |
1547 | 1528 |
1548 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ | 1529 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ |
1549 | 1530 |
1550 | 1531 |
1551 /* END */ | 1532 /* END */ |
OLD | NEW |