OLD | NEW |
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* */ | 2 /* */ |
3 /* cf2ft.c */ | 3 /* cf2ft.c */ |
4 /* */ | 4 /* */ |
5 /* FreeType Glue Component to Adobe's Interpreter (body). */ | 5 /* FreeType Glue Component to Adobe's Interpreter (body). */ |
6 /* */ | 6 /* */ |
7 /* Copyright 2013 Adobe Systems Incorporated. */ | 7 /* Copyright 2013-2014 Adobe Systems Incorporated. */ |
8 /* */ | 8 /* */ |
9 /* This software, and all works of authorship, whether in source or */ | 9 /* This software, and all works of authorship, whether in source or */ |
10 /* object code form as indicated by the copyright notice(s) included */ | 10 /* object code form as indicated by the copyright notice(s) included */ |
11 /* herein (collectively, the "Work") is made available, and may only be */ | 11 /* herein (collectively, the "Work") is made available, and may only be */ |
12 /* used, modified, and distributed under the FreeType Project License, */ | 12 /* used, modified, and distributed under the FreeType Project License, */ |
13 /* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ | 13 /* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ |
14 /* FreeType Project License, each contributor to the Work hereby grants */ | 14 /* FreeType Project License, each contributor to the Work hereby grants */ |
15 /* to any individual or legal entity exercising permissions granted by */ | 15 /* to any individual or legal entity exercising permissions granted by */ |
16 /* the FreeType Project License and this section (hereafter, "You" or */ | 16 /* the FreeType Project License and this section (hereafter, "You" or */ |
17 /* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ | 17 /* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ |
(...skipping 12 matching lines...) Expand all Loading... |
30 /* */ | 30 /* */ |
31 /* By using, modifying, or distributing the Work you indicate that you */ | 31 /* By using, modifying, or distributing the Work you indicate that you */ |
32 /* have read and understood the terms and conditions of the */ | 32 /* have read and understood the terms and conditions of the */ |
33 /* FreeType Project License as well as those provided in this section, */ | 33 /* FreeType Project License as well as those provided in this section, */ |
34 /* and you accept them fully. */ | 34 /* and you accept them fully. */ |
35 /* */ | 35 /* */ |
36 /***************************************************************************/ | 36 /***************************************************************************/ |
37 | 37 |
38 | 38 |
39 #include "cf2ft.h" | 39 #include "cf2ft.h" |
40 #include "../../include/freetype/internal/ftdebug.h" | 40 #include FT_INTERNAL_DEBUG_H |
41 | 41 |
42 #include "cf2font.h" | 42 #include "cf2font.h" |
43 #include "cf2error.h" | 43 #include "cf2error.h" |
44 | 44 |
45 | 45 |
46 #define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ | 46 #define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ |
47 | 47 |
48 | 48 |
49 /* | 49 /* |
50 * This check should avoid most internal overflow cases. Clients should | 50 * This check should avoid most internal overflow cases. Clients should |
51 * generally respond to `Glyph_Too_Big' by getting a glyph outline | 51 * generally respond to `Glyph_Too_Big' by getting a glyph outline |
52 * at EM size, scaling it and filling it as a graphics operation. | 52 * at EM size, scaling it and filling it as a graphics operation. |
53 * | 53 * |
54 */ | 54 */ |
55 static FT_Error | 55 static FT_Error |
56 cf2_checkTransform( const CF2_Matrix* transform, | 56 cf2_checkTransform( const CF2_Matrix* transform, |
57 CF2_Int unitsPerEm ) | 57 CF2_Int unitsPerEm ) |
58 { | 58 { |
59 CF2_Fixed maxScale; | 59 CF2_Fixed maxScale; |
60 | 60 |
61 | 61 |
62 FT_ASSERT( unitsPerEm > 0 ); | 62 FT_ASSERT( unitsPerEm > 0 ); |
63 | 63 |
64 FT_ASSERT( transform->a > 0 && transform->d > 0 ); | 64 if ( transform->a <= 0 || transform->d <= 0 ) |
| 65 return FT_THROW( Invalid_Size_Handle ); |
| 66 |
65 FT_ASSERT( transform->b == 0 && transform->c == 0 ); | 67 FT_ASSERT( transform->b == 0 && transform->c == 0 ); |
66 FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); | 68 FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); |
67 | 69 |
68 if ( unitsPerEm > 0x7FFF ) | 70 if ( unitsPerEm > 0x7FFF ) |
69 return FT_THROW( Glyph_Too_Big ); | 71 return FT_THROW( Glyph_Too_Big ); |
70 | 72 |
71 maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); | 73 maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); |
72 | 74 |
73 if ( transform->a > maxScale || transform->d > maxScale ) | 75 if ( transform->a > maxScale || transform->d > maxScale ) |
74 return FT_THROW( Glyph_Too_Big ); | 76 return FT_THROW( Glyph_Too_Big ); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 /* note: two successive moves simply close the contour twice */ | 135 /* note: two successive moves simply close the contour twice */ |
134 cff_builder_close_contour( builder ); | 136 cff_builder_close_contour( builder ); |
135 builder->path_begun = 0; | 137 builder->path_begun = 0; |
136 } | 138 } |
137 | 139 |
138 | 140 |
139 static void | 141 static void |
140 cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, | 142 cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, |
141 const CF2_CallbackParams params ) | 143 const CF2_CallbackParams params ) |
142 { | 144 { |
| 145 FT_Error error; |
| 146 |
143 /* downcast the object pointer */ | 147 /* downcast the object pointer */ |
144 CF2_Outline outline = (CF2_Outline)callbacks; | 148 CF2_Outline outline = (CF2_Outline)callbacks; |
145 CFF_Builder* builder; | 149 CFF_Builder* builder; |
146 FT_Error error; | |
147 | 150 |
148 | 151 |
149 FT_ASSERT( outline && outline->decoder ); | 152 FT_ASSERT( outline && outline->decoder ); |
150 FT_ASSERT( params->op == CF2_PathOpLineTo ); | 153 FT_ASSERT( params->op == CF2_PathOpLineTo ); |
151 | 154 |
152 builder = &outline->decoder->builder; | 155 builder = &outline->decoder->builder; |
153 | 156 |
154 if ( !builder->path_begun ) | 157 if ( !builder->path_begun ) |
155 { | 158 { |
156 /* record the move before the line; also check points and set */ | 159 /* record the move before the line; also check points and set */ |
157 /* `path_begun' */ | 160 /* `path_begun' */ |
158 » » error = cff_builder_start_point(builder, | 161 error = cff_builder_start_point( builder, |
159 params->pt0.x, | 162 params->pt0.x, |
160 params->pt0.y ); | 163 params->pt0.y ); |
161 » » if (callbacks && callbacks->error) *callbacks->error = error; | 164 if ( error ) |
162 » » if (error) return; | 165 { |
| 166 if ( !*callbacks->error ) |
| 167 *callbacks->error = error; |
| 168 return; |
| 169 } |
163 } | 170 } |
164 | 171 |
165 /* `cff_builder_add_point1' includes a check_points call for one point */ | 172 /* `cff_builder_add_point1' includes a check_points call for one point */ |
166 » error = cff_builder_add_point1(builder, | 173 error = cff_builder_add_point1( builder, |
167 params->pt1.x, | 174 params->pt1.x, |
168 params->pt1.y ); | 175 params->pt1.y ); |
169 » if (callbacks && callbacks->error) *callbacks->error = error; | 176 if ( error ) |
| 177 { |
| 178 if ( !*callbacks->error ) |
| 179 *callbacks->error = error; |
| 180 return; |
| 181 } |
170 } | 182 } |
171 | 183 |
172 | 184 |
173 static void | 185 static void |
174 cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, | 186 cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, |
175 const CF2_CallbackParams params ) | 187 const CF2_CallbackParams params ) |
176 { | 188 { |
| 189 FT_Error error; |
| 190 |
177 /* downcast the object pointer */ | 191 /* downcast the object pointer */ |
178 CF2_Outline outline = (CF2_Outline)callbacks; | 192 CF2_Outline outline = (CF2_Outline)callbacks; |
179 CFF_Builder* builder; | 193 CFF_Builder* builder; |
180 FT_Error error; | |
181 | 194 |
182 | 195 |
183 FT_ASSERT( outline && outline->decoder ); | 196 FT_ASSERT( outline && outline->decoder ); |
184 FT_ASSERT( params->op == CF2_PathOpCubeTo ); | 197 FT_ASSERT( params->op == CF2_PathOpCubeTo ); |
185 | 198 |
186 builder = &outline->decoder->builder; | 199 builder = &outline->decoder->builder; |
187 | 200 |
188 if ( !builder->path_begun ) | 201 if ( !builder->path_begun ) |
189 { | 202 { |
190 /* record the move before the line; also check points and set */ | 203 /* record the move before the line; also check points and set */ |
191 /* `path_begun' */ | 204 /* `path_begun' */ |
192 error = cff_builder_start_point( builder, | 205 error = cff_builder_start_point( builder, |
193 params->pt0.x, | 206 params->pt0.x, |
194 params->pt0.y ); | 207 params->pt0.y ); |
195 » if (callbacks && callbacks->error) *callbacks->error = error; | 208 if ( error ) |
196 » if (error) return; | 209 { |
| 210 if ( !*callbacks->error ) |
| 211 *callbacks->error = error; |
| 212 return; |
| 213 } |
197 } | 214 } |
198 | 215 |
199 /* prepare room for 3 points: 2 off-curve, 1 on-curve */ | 216 /* prepare room for 3 points: 2 off-curve, 1 on-curve */ |
200 error = cff_check_points( builder, 3 ); | 217 error = cff_check_points( builder, 3 ); |
201 » if (callbacks && callbacks->error) *callbacks->error = error; | 218 if ( error ) |
202 » if (error) return; | 219 { |
| 220 if ( !*callbacks->error ) |
| 221 *callbacks->error = error; |
| 222 return; |
| 223 } |
203 | 224 |
204 cff_builder_add_point( builder, | 225 cff_builder_add_point( builder, |
205 params->pt1.x, | 226 params->pt1.x, |
206 params->pt1.y, 0 ); | 227 params->pt1.y, 0 ); |
207 cff_builder_add_point( builder, | 228 cff_builder_add_point( builder, |
208 params->pt2.x, | 229 params->pt2.x, |
209 params->pt2.y, 0 ); | 230 params->pt2.y, 0 ); |
210 cff_builder_add_point( builder, | 231 cff_builder_add_point( builder, |
211 params->pt3.x, | 232 params->pt3.x, |
212 params->pt3.y, 1 ); | 233 params->pt3.y, 1 ); |
(...skipping 25 matching lines...) Expand all Loading... |
238 FT_Bool* scaled ) | 259 FT_Bool* scaled ) |
239 { | 260 { |
240 FT_ASSERT( decoder && decoder->builder.glyph ); | 261 FT_ASSERT( decoder && decoder->builder.glyph ); |
241 | 262 |
242 /* note: FreeType scale includes a factor of 64 */ | 263 /* note: FreeType scale includes a factor of 64 */ |
243 *hinted = decoder->builder.glyph->hint; | 264 *hinted = decoder->builder.glyph->hint; |
244 *scaled = decoder->builder.glyph->scaled; | 265 *scaled = decoder->builder.glyph->scaled; |
245 | 266 |
246 if ( *hinted ) | 267 if ( *hinted ) |
247 { | 268 { |
248 *x_scale = FT_DivFix( decoder->builder.glyph->x_scale, | 269 *x_scale = ( decoder->builder.glyph->x_scale + 32 ) / 64; |
249 cf2_intToFixed( 64 ) ); | 270 *y_scale = ( decoder->builder.glyph->y_scale + 32 ) / 64; |
250 *y_scale = FT_DivFix( decoder->builder.glyph->y_scale, | |
251 cf2_intToFixed( 64 ) ); | |
252 } | 271 } |
253 else | 272 else |
254 { | 273 { |
255 /* for unhinted outlines, `cff_slot_load' does the scaling, */ | 274 /* for unhinted outlines, `cff_slot_load' does the scaling, */ |
256 /* thus render at `unity' scale */ | 275 /* thus render at `unity' scale */ |
257 | 276 |
258 *x_scale = 0x0400; /* 1/64 as 16.16 */ | 277 *x_scale = 0x0400; /* 1/64 as 16.16 */ |
259 *y_scale = 0x0400; | 278 *y_scale = 0x0400; |
260 } | 279 } |
261 } | 280 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 &transform.d, | 365 &transform.d, |
347 &hinted, | 366 &hinted, |
348 &scaled ); | 367 &scaled ); |
349 | 368 |
350 font->renderingFlags = 0; | 369 font->renderingFlags = 0; |
351 if ( hinted ) | 370 if ( hinted ) |
352 font->renderingFlags |= CF2_FlagsHinted; | 371 font->renderingFlags |= CF2_FlagsHinted; |
353 if ( scaled && !driver->no_stem_darkening ) | 372 if ( scaled && !driver->no_stem_darkening ) |
354 font->renderingFlags |= CF2_FlagsDarkened; | 373 font->renderingFlags |= CF2_FlagsDarkened; |
355 | 374 |
| 375 font->darkenParams[0] = driver->darken_params[0]; |
| 376 font->darkenParams[1] = driver->darken_params[1]; |
| 377 font->darkenParams[2] = driver->darken_params[2]; |
| 378 font->darkenParams[3] = driver->darken_params[3]; |
| 379 font->darkenParams[4] = driver->darken_params[4]; |
| 380 font->darkenParams[5] = driver->darken_params[5]; |
| 381 font->darkenParams[6] = driver->darken_params[6]; |
| 382 font->darkenParams[7] = driver->darken_params[7]; |
| 383 |
356 /* now get an outline for this glyph; */ | 384 /* now get an outline for this glyph; */ |
357 /* also get units per em to validate scale */ | 385 /* also get units per em to validate scale */ |
358 font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); | 386 font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); |
359 | 387 |
360 error2 = cf2_checkTransform( &transform, font->unitsPerEm ); | 388 if ( scaled ) |
361 if ( error2 ) | 389 { |
362 return error2; | 390 error2 = cf2_checkTransform( &transform, font->unitsPerEm ); |
| 391 if ( error2 ) |
| 392 return error2; |
| 393 } |
363 | 394 |
364 error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); | 395 error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); |
365 if ( error2 ) | 396 if ( error2 ) |
366 return FT_ERR( Invalid_File_Format ); | 397 return FT_ERR( Invalid_File_Format ); |
367 | 398 |
368 cf2_setGlyphWidth( &font->outline, glyphWidth ); | 399 cf2_setGlyphWidth( &font->outline, glyphWidth ); |
369 | 400 |
370 return FT_Err_Ok; | 401 return FT_Err_Ok; |
371 } | 402 } |
372 } | 403 } |
373 | 404 |
374 | 405 |
375 /* get pointer to current FreeType subfont (based on current glyphID) */ | 406 /* get pointer to current FreeType subfont (based on current glyphID) */ |
376 FT_LOCAL_DEF( CFF_SubFont ) | 407 FT_LOCAL_DEF( CFF_SubFont ) |
377 cf2_getSubfont( CFF_Decoder* decoder ) | 408 cf2_getSubfont( CFF_Decoder* decoder ) |
378 { | 409 { |
379 FT_ASSERT( decoder && decoder->current_subfont ); | 410 FT_ASSERT( decoder && decoder->current_subfont ); |
380 | 411 |
381 return decoder->current_subfont; | 412 return decoder->current_subfont; |
382 } | 413 } |
383 | 414 |
384 | 415 |
385 /* get `y_ppem' from `CFF_Size' */ | 416 /* get `y_ppem' from `CFF_Size' */ |
386 FT_LOCAL_DEF( CF2_Fixed ) | 417 FT_LOCAL_DEF( CF2_Fixed ) |
387 cf2_getPpemY( CFF_Decoder* decoder ) | 418 cf2_getPpemY( CFF_Decoder* decoder ) |
388 { | 419 { |
389 FT_ASSERT( decoder && | 420 FT_ASSERT( decoder && |
390 decoder->builder.face && | 421 decoder->builder.face && |
391 decoder->builder.face->root.size ); | 422 decoder->builder.face->root.size ); |
392 FT_ASSERT( decoder->builder.face->root.size->metrics.y_ppem ); | |
393 | 423 |
| 424 /* |
| 425 * Note that `y_ppem' can be zero if there wasn't a call to |
| 426 * `FT_Set_Char_Size' or something similar. However, this isn't a |
| 427 * problem since we come to this place in the code only if |
| 428 * FT_LOAD_NO_SCALE is set (the other case gets caught by |
| 429 * `cf2_checkTransform'). The ppem value is needed to compute the stem |
| 430 * darkening, which is disabled for getting the unscaled outline. |
| 431 * |
| 432 */ |
394 return cf2_intToFixed( | 433 return cf2_intToFixed( |
395 decoder->builder.face->root.size->metrics.y_ppem ); | 434 decoder->builder.face->root.size->metrics.y_ppem ); |
396 } | 435 } |
397 | 436 |
398 | 437 |
399 /* get standard stem widths for the current subfont; */ | 438 /* get standard stem widths for the current subfont; */ |
400 /* FreeType stores these as integer font units */ | 439 /* FreeType stores these as integer font units */ |
401 /* (note: variable names seem swapped) */ | 440 /* (note: variable names seem swapped) */ |
402 FT_LOCAL_DEF( CF2_Fixed ) | 441 FT_LOCAL_DEF( CF2_Fixed ) |
403 cf2_getStdVW( CFF_Decoder* decoder ) | 442 cf2_getStdVW( CFF_Decoder* decoder ) |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 } | 540 } |
502 | 541 |
503 | 542 |
504 /* convert unbiased subroutine index to `CF2_Buffer' and */ | 543 /* convert unbiased subroutine index to `CF2_Buffer' and */ |
505 /* return 0 on success */ | 544 /* return 0 on success */ |
506 FT_LOCAL_DEF( CF2_Int ) | 545 FT_LOCAL_DEF( CF2_Int ) |
507 cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, | 546 cf2_initGlobalRegionBuffer( CFF_Decoder* decoder, |
508 CF2_UInt idx, | 547 CF2_UInt idx, |
509 CF2_Buffer buf ) | 548 CF2_Buffer buf ) |
510 { | 549 { |
511 FT_ASSERT( decoder && decoder->globals ); | 550 FT_ASSERT( decoder ); |
512 | 551 |
513 FT_ZERO( buf ); | 552 FT_ZERO( buf ); |
514 | 553 |
515 idx += decoder->globals_bias; | 554 idx += decoder->globals_bias; |
516 if ( idx >= decoder->num_globals ) | 555 if ( idx >= decoder->num_globals ) |
517 return TRUE; /* error */ | 556 return TRUE; /* error */ |
518 | 557 |
| 558 FT_ASSERT( decoder->globals ); |
| 559 |
519 buf->start = | 560 buf->start = |
520 buf->ptr = decoder->globals[idx]; | 561 buf->ptr = decoder->globals[idx]; |
521 buf->end = decoder->globals[idx + 1]; | 562 buf->end = decoder->globals[idx + 1]; |
522 | 563 |
523 return FALSE; /* success */ | 564 return FALSE; /* success */ |
524 } | 565 } |
525 | 566 |
526 | 567 |
527 /* convert AdobeStandardEncoding code to CF2_Buffer; */ | 568 /* convert AdobeStandardEncoding code to CF2_Buffer; */ |
528 /* used for seac component */ | 569 /* used for seac component */ |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 (FT_Byte**)&buf->start, | 615 (FT_Byte**)&buf->start, |
575 (FT_ULong)( buf->end - buf->start ) ); | 616 (FT_ULong)( buf->end - buf->start ) ); |
576 } | 617 } |
577 | 618 |
578 | 619 |
579 FT_LOCAL_DEF( CF2_Int ) | 620 FT_LOCAL_DEF( CF2_Int ) |
580 cf2_initLocalRegionBuffer( CFF_Decoder* decoder, | 621 cf2_initLocalRegionBuffer( CFF_Decoder* decoder, |
581 CF2_UInt idx, | 622 CF2_UInt idx, |
582 CF2_Buffer buf ) | 623 CF2_Buffer buf ) |
583 { | 624 { |
584 FT_ASSERT( decoder && decoder->locals ); | 625 FT_ASSERT( decoder ); |
585 | 626 |
586 FT_ZERO( buf ); | 627 FT_ZERO( buf ); |
587 | 628 |
588 idx += decoder->locals_bias; | 629 idx += decoder->locals_bias; |
589 if ( idx >= decoder->num_locals ) | 630 if ( idx >= decoder->num_locals ) |
590 return TRUE; /* error */ | 631 return TRUE; /* error */ |
591 | 632 |
| 633 FT_ASSERT( decoder->locals ); |
| 634 |
592 buf->start = | 635 buf->start = |
593 buf->ptr = decoder->locals[idx]; | 636 buf->ptr = decoder->locals[idx]; |
594 buf->end = decoder->locals[idx + 1]; | 637 buf->end = decoder->locals[idx + 1]; |
595 | 638 |
596 return FALSE; /* success */ | 639 return FALSE; /* success */ |
597 } | 640 } |
598 | 641 |
599 | 642 |
600 FT_LOCAL_DEF( CF2_Fixed ) | 643 FT_LOCAL_DEF( CF2_Fixed ) |
601 cf2_getDefaultWidthX( CFF_Decoder* decoder ) | 644 cf2_getDefaultWidthX( CFF_Decoder* decoder ) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 | 682 |
640 FT_ASSERT( decoder ); | 683 FT_ASSERT( decoder ); |
641 | 684 |
642 cff_builder_close_contour( &decoder->builder ); | 685 cff_builder_close_contour( &decoder->builder ); |
643 | 686 |
644 FT_GlyphLoader_Add( decoder->builder.loader ); | 687 FT_GlyphLoader_Add( decoder->builder.loader ); |
645 } | 688 } |
646 | 689 |
647 | 690 |
648 /* END */ | 691 /* END */ |
OLD | NEW |