ReactOS 0.4.15-dev-7674-gc0b4db1
ttgload.c
Go to the documentation of this file.
1/***************************************************************************/
2/* */
3/* ttgload.c */
4/* */
5/* TrueType Glyph Loader (body). */
6/* */
7/* Copyright 1996-2018 by */
8/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
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 */
12/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13/* this file you indicate that you have read the license and */
14/* understand and accept it fully. */
15/* */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_CONFIG_CONFIG_H
22#include FT_INTERNAL_CALC_H
23#include FT_INTERNAL_STREAM_H
24#include FT_INTERNAL_SFNT_H
25#include FT_TRUETYPE_TAGS_H
26#include FT_OUTLINE_H
27#include FT_DRIVER_H
28#include FT_LIST_H
29
30#include "ttgload.h"
31#include "ttpload.h"
32
33#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
34#include "ttgxvar.h"
35#endif
36
37#include "tterrors.h"
38#include "ttsubpix.h"
39
40
41 /*************************************************************************/
42 /* */
43 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
44 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
45 /* messages during execution. */
46 /* */
47#undef FT_COMPONENT
48#define FT_COMPONENT trace_ttgload
49
50
51 /*************************************************************************/
52 /* */
53 /* Composite glyph flags. */
54 /* */
55#define ARGS_ARE_WORDS 0x0001
56#define ARGS_ARE_XY_VALUES 0x0002
57#define ROUND_XY_TO_GRID 0x0004
58#define WE_HAVE_A_SCALE 0x0008
59/* reserved 0x0010 */
60#define MORE_COMPONENTS 0x0020
61#define WE_HAVE_AN_XY_SCALE 0x0040
62#define WE_HAVE_A_2X2 0x0080
63#define WE_HAVE_INSTR 0x0100
64#define USE_MY_METRICS 0x0200
65#define OVERLAP_COMPOUND 0x0400
66#define SCALED_COMPONENT_OFFSET 0x0800
67#define UNSCALED_COMPONENT_OFFSET 0x1000
68
69
70 /*************************************************************************/
71 /* */
72 /* Return the horizontal metrics in font units for a given glyph. */
73 /* */
74 FT_LOCAL_DEF( void )
77 FT_Short* lsb,
78 FT_UShort* aw )
79 {
80 ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
81
82 FT_TRACE5(( " advance width (font units): %d\n", *aw ));
83 FT_TRACE5(( " left side bearing (font units): %d\n", *lsb ));
84 }
85
86
87 /*************************************************************************/
88 /* */
89 /* Return the vertical metrics in font units for a given glyph. */
90 /* See function `tt_loader_set_pp' below for explanations. */
91 /* */
92 FT_LOCAL_DEF( void )
95 FT_Pos yMax,
96 FT_Short* tsb,
97 FT_UShort* ah )
98 {
99 if ( face->vertical_info )
100 ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
101
102 else if ( face->os2.version != 0xFFFFU )
103 {
104 *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
105 *ah = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
106 face->os2.sTypoDescender );
107 }
108
109 else
110 {
111 *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
112 *ah = (FT_UShort)FT_ABS( face->horizontal.Ascender -
113 face->horizontal.Descender );
114 }
115
116 FT_TRACE5(( " advance height (font units): %d\n", *ah ));
117 FT_TRACE5(( " top side bearing (font units): %d\n", *tsb ));
118 }
119
120
121 static FT_Error
123 FT_UInt glyph_index )
124 {
125 TT_Face face = loader->face;
126#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
128#endif
129
131 FT_Stream stream = loader->stream;
132
133 FT_Short left_bearing = 0, top_bearing = 0;
134 FT_UShort advance_width = 0, advance_height = 0;
135
136 /* we must preserve the stream position */
137 /* (which gets altered by the metrics functions) */
139
140
141 TT_Get_HMetrics( face, glyph_index,
142 &left_bearing,
143 &advance_width );
144 TT_Get_VMetrics( face, glyph_index,
145 loader->bbox.yMax,
146 &top_bearing,
147 &advance_height );
148
149 if ( FT_STREAM_SEEK( pos ) )
150 return error;
151
152 loader->left_bearing = left_bearing;
153 loader->advance = advance_width;
154 loader->top_bearing = top_bearing;
155 loader->vadvance = advance_height;
156
157#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
158 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
159 loader->exec )
160 {
161 loader->exec->sph_tweak_flags = 0;
162
163 /* This may not be the right place for this, but it works... */
164 /* Note that we have to unconditionally load the tweaks since */
165 /* it is possible that glyphs individually switch ClearType's */
166 /* backward compatibility mode on and off. */
167 sph_set_tweaks( loader, glyph_index );
168 }
169#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
170
171 if ( !loader->linear_def )
172 {
173 loader->linear_def = 1;
174 loader->linear = advance_width;
175 }
176
177 return FT_Err_Ok;
178 }
179
180
181#ifdef FT_CONFIG_OPTION_INCREMENTAL
182
183 static void
184 tt_get_metrics_incr_overrides( TT_Loader loader,
185 FT_UInt glyph_index )
186 {
187 TT_Face face = loader->face;
188
189 FT_Short left_bearing = 0, top_bearing = 0;
190 FT_UShort advance_width = 0, advance_height = 0;
191
192
193 /* If this is an incrementally loaded font check whether there are */
194 /* overriding metrics for this glyph. */
195 if ( face->root.internal->incremental_interface &&
196 face->root.internal->incremental_interface->funcs->get_glyph_metrics )
197 {
198 FT_Incremental_MetricsRec incr_metrics;
200
201
202 incr_metrics.bearing_x = loader->left_bearing;
203 incr_metrics.bearing_y = 0;
204 incr_metrics.advance = loader->advance;
205 incr_metrics.advance_v = 0;
206
207 error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
208 face->root.internal->incremental_interface->object,
209 glyph_index, FALSE, &incr_metrics );
210 if ( error )
211 goto Exit;
212
213 left_bearing = (FT_Short)incr_metrics.bearing_x;
214 advance_width = (FT_UShort)incr_metrics.advance;
215
216#if 0
217
218 /* GWW: Do I do the same for vertical metrics? */
219 incr_metrics.bearing_x = 0;
220 incr_metrics.bearing_y = loader->top_bearing;
221 incr_metrics.advance = loader->vadvance;
222
223 error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
224 face->root.internal->incremental_interface->object,
225 glyph_index, TRUE, &incr_metrics );
226 if ( error )
227 goto Exit;
228
229 top_bearing = (FT_Short)incr_metrics.bearing_y;
230 advance_height = (FT_UShort)incr_metrics.advance;
231
232#endif /* 0 */
233
234 loader->left_bearing = left_bearing;
235 loader->advance = advance_width;
236 loader->top_bearing = top_bearing;
237 loader->vadvance = advance_height;
238
239 if ( !loader->linear_def )
240 {
241 loader->linear_def = 1;
242 loader->linear = advance_width;
243 }
244 }
245
246 Exit:
247 return;
248 }
249
250#endif /* FT_CONFIG_OPTION_INCREMENTAL */
251
252
253 /*************************************************************************/
254 /* */
255 /* The following functions are used by default with TrueType fonts. */
256 /* However, they can be replaced by alternatives if we need to support */
257 /* TrueType-compressed formats (like MicroType) in the future. */
258 /* */
259 /*************************************************************************/
260
263 FT_UInt glyph_index,
265 FT_UInt byte_count )
266 {
268 FT_Stream stream = loader->stream;
269
270 /* for non-debug mode */
271 FT_UNUSED( glyph_index );
272
273
274 FT_TRACE4(( "Glyph %ld\n", glyph_index ));
275
276 /* the following line sets the `error' variable through macros! */
277 if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
278 return error;
279
280 loader->cursor = stream->cursor;
281 loader->limit = stream->limit;
282
283 return FT_Err_Ok;
284 }
285
286
287 FT_CALLBACK_DEF( void )
289 {
290 FT_Stream stream = loader->stream;
291
292
294 }
295
296
299 {
300 FT_Byte* p = loader->cursor;
301 FT_Byte* limit = loader->limit;
302
303
304 if ( p + 10 > limit )
305 return FT_THROW( Invalid_Outline );
306
307 loader->n_contours = FT_NEXT_SHORT( p );
308
309 loader->bbox.xMin = FT_NEXT_SHORT( p );
310 loader->bbox.yMin = FT_NEXT_SHORT( p );
311 loader->bbox.xMax = FT_NEXT_SHORT( p );
312 loader->bbox.yMax = FT_NEXT_SHORT( p );
313
314 FT_TRACE5(( " # of contours: %d\n", loader->n_contours ));
315 FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
316 loader->bbox.xMax ));
317 FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
318 loader->bbox.yMax ));
319 loader->cursor = p;
320
321 return FT_Err_Ok;
322 }
323
324
327 {
329 FT_Byte* p = load->cursor;
330 FT_Byte* limit = load->limit;
331 FT_GlyphLoader gloader = load->gloader;
332 FT_Int n_contours = load->n_contours;
334 FT_UShort n_ins;
335 FT_Int n_points;
336
337 FT_Byte *flag, *flag_limit;
338 FT_Byte c, count;
339 FT_Vector *vec, *vec_limit;
340 FT_Pos x;
341 FT_Short *cont, *cont_limit, prev_cont;
342 FT_Int xy_size = 0;
343
344
345 /* check that we can add the contours to the glyph */
346 error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
347 if ( error )
348 goto Fail;
349
350 /* reading the contours' endpoints & number of points */
351 cont = gloader->current.outline.contours;
352 cont_limit = cont + n_contours;
353
354 /* check space for contours array + instructions count */
355 if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
356 goto Invalid_Outline;
357
358 prev_cont = FT_NEXT_SHORT( p );
359
360 if ( n_contours > 0 )
361 cont[0] = prev_cont;
362
363 if ( prev_cont < 0 )
364 goto Invalid_Outline;
365
366 for ( cont++; cont < cont_limit; cont++ )
367 {
368 cont[0] = FT_NEXT_SHORT( p );
369 if ( cont[0] <= prev_cont )
370 {
371 /* unordered contours: this is invalid */
372 goto Invalid_Outline;
373 }
374 prev_cont = cont[0];
375 }
376
377 n_points = 0;
378 if ( n_contours > 0 )
379 {
380 n_points = cont[-1] + 1;
381 if ( n_points < 0 )
382 goto Invalid_Outline;
383 }
384
385 /* note that we will add four phantom points later */
386 error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
387 if ( error )
388 goto Fail;
389
390 /* reading the bytecode instructions */
391 load->glyph->control_len = 0;
392 load->glyph->control_data = NULL;
393
394 if ( p + 2 > limit )
395 goto Invalid_Outline;
396
397 n_ins = FT_NEXT_USHORT( p );
398
399 FT_TRACE5(( " Instructions size: %u\n", n_ins ));
400
401#ifdef TT_USE_BYTECODE_INTERPRETER
402
403 if ( IS_HINTED( load->load_flags ) )
404 {
405 FT_ULong tmp;
406
407
408 /* check instructions size */
409 if ( ( limit - p ) < n_ins )
410 {
411 FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
412 error = FT_THROW( Too_Many_Hints );
413 goto Fail;
414 }
415
416 /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
417 /* and thus update the bytecode array size by ourselves */
418
419 tmp = load->exec->glyphSize;
420 error = Update_Max( load->exec->memory,
421 &tmp,
422 sizeof ( FT_Byte ),
423 (void*)&load->exec->glyphIns,
424 n_ins );
425
426 load->exec->glyphSize = (FT_UShort)tmp;
427 if ( error )
428 return error;
429
430 load->glyph->control_len = n_ins;
431 load->glyph->control_data = load->exec->glyphIns;
432
433 if ( n_ins )
434 FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
435 }
436
437#endif /* TT_USE_BYTECODE_INTERPRETER */
438
439 p += n_ins;
440
441 outline = &gloader->current.outline;
442
443 /* reading the point tags */
444 flag = (FT_Byte*)outline->tags;
445 flag_limit = flag + n_points;
446
447 FT_ASSERT( flag );
448
449 while ( flag < flag_limit )
450 {
451 if ( p + 1 > limit )
452 goto Invalid_Outline;
453
454 *flag++ = c = FT_NEXT_BYTE( p );
455 if ( c & 8 )
456 {
457 if ( p + 1 > limit )
458 goto Invalid_Outline;
459
460 count = FT_NEXT_BYTE( p );
461 if ( flag + (FT_Int)count > flag_limit )
462 goto Invalid_Outline;
463
464 for ( ; count > 0; count-- )
465 *flag++ = c;
466 }
467 }
468
469 /* reading the X coordinates */
470
471 vec = outline->points;
472 vec_limit = vec + n_points;
473 flag = (FT_Byte*)outline->tags;
474 x = 0;
475
476 if ( p + xy_size > limit )
477 goto Invalid_Outline;
478
479 for ( ; vec < vec_limit; vec++, flag++ )
480 {
481 FT_Pos y = 0;
482 FT_Byte f = *flag;
483
484
485 if ( f & 2 )
486 {
487 if ( p + 1 > limit )
488 goto Invalid_Outline;
489
490 y = (FT_Pos)FT_NEXT_BYTE( p );
491 if ( ( f & 16 ) == 0 )
492 y = -y;
493 }
494 else if ( ( f & 16 ) == 0 )
495 {
496 if ( p + 2 > limit )
497 goto Invalid_Outline;
498
499 y = (FT_Pos)FT_NEXT_SHORT( p );
500 }
501
502 x += y;
503 vec->x = x;
504 /* the cast is for stupid compilers */
505 *flag = (FT_Byte)( f & ~( 2 | 16 ) );
506 }
507
508 /* reading the Y coordinates */
509
510 vec = gloader->current.outline.points;
511 vec_limit = vec + n_points;
512 flag = (FT_Byte*)outline->tags;
513 x = 0;
514
515 for ( ; vec < vec_limit; vec++, flag++ )
516 {
517 FT_Pos y = 0;
518 FT_Byte f = *flag;
519
520
521 if ( f & 4 )
522 {
523 if ( p + 1 > limit )
524 goto Invalid_Outline;
525
526 y = (FT_Pos)FT_NEXT_BYTE( p );
527 if ( ( f & 32 ) == 0 )
528 y = -y;
529 }
530 else if ( ( f & 32 ) == 0 )
531 {
532 if ( p + 2 > limit )
533 goto Invalid_Outline;
534
535 y = (FT_Pos)FT_NEXT_SHORT( p );
536 }
537
538 x += y;
539 vec->y = x;
540 /* the cast is for stupid compilers */
541 *flag = (FT_Byte)( f & FT_CURVE_TAG_ON );
542 }
543
544 outline->n_points = (FT_Short)n_points;
545 outline->n_contours = (FT_Short)n_contours;
546
547 load->cursor = p;
548
549 Fail:
550 return error;
551
552 Invalid_Outline:
553 error = FT_THROW( Invalid_Outline );
554 goto Fail;
555 }
556
557
560 {
562 FT_Byte* p = loader->cursor;
563 FT_Byte* limit = loader->limit;
564 FT_GlyphLoader gloader = loader->gloader;
565 FT_SubGlyph subglyph;
566 FT_UInt num_subglyphs;
567
568
569 num_subglyphs = 0;
570
571 do
572 {
573 FT_Fixed xx, xy, yy, yx;
575
576
577 /* check that we can load a new subglyph */
578 error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
579 if ( error )
580 goto Fail;
581
582 /* check space */
583 if ( p + 4 > limit )
584 goto Invalid_Composite;
585
586 subglyph = gloader->current.subglyphs + num_subglyphs;
587
588 subglyph->arg1 = subglyph->arg2 = 0;
589
590 subglyph->flags = FT_NEXT_USHORT( p );
591 subglyph->index = FT_NEXT_USHORT( p );
592
593 /* check space */
594 count = 2;
595 if ( subglyph->flags & ARGS_ARE_WORDS )
596 count += 2;
597 if ( subglyph->flags & WE_HAVE_A_SCALE )
598 count += 2;
599 else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
600 count += 4;
601 else if ( subglyph->flags & WE_HAVE_A_2X2 )
602 count += 8;
603
604 if ( p + count > limit )
605 goto Invalid_Composite;
606
607 /* read arguments */
608 if ( subglyph->flags & ARGS_ARE_XY_VALUES )
609 {
610 if ( subglyph->flags & ARGS_ARE_WORDS )
611 {
612 subglyph->arg1 = FT_NEXT_SHORT( p );
613 subglyph->arg2 = FT_NEXT_SHORT( p );
614 }
615 else
616 {
617 subglyph->arg1 = FT_NEXT_CHAR( p );
618 subglyph->arg2 = FT_NEXT_CHAR( p );
619 }
620 }
621 else
622 {
623 if ( subglyph->flags & ARGS_ARE_WORDS )
624 {
625 subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
626 subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
627 }
628 else
629 {
630 subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
631 subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
632 }
633 }
634
635 /* read transform */
636 xx = yy = 0x10000L;
637 xy = yx = 0;
638
639 if ( subglyph->flags & WE_HAVE_A_SCALE )
640 {
641 xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
642 yy = xx;
643 }
644 else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
645 {
646 xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
647 yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
648 }
649 else if ( subglyph->flags & WE_HAVE_A_2X2 )
650 {
651 xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
652 yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
653 xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
654 yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
655 }
656
657 subglyph->transform.xx = xx;
658 subglyph->transform.xy = xy;
659 subglyph->transform.yx = yx;
660 subglyph->transform.yy = yy;
661
662 num_subglyphs++;
663
664 } while ( subglyph->flags & MORE_COMPONENTS );
665
666 gloader->current.num_subglyphs = num_subglyphs;
667 FT_TRACE5(( " %d component%s\n",
668 num_subglyphs,
669 num_subglyphs > 1 ? "s" : "" ));
670
671#ifdef FT_DEBUG_LEVEL_TRACE
672 {
673 FT_UInt i;
674
675
676 subglyph = gloader->current.subglyphs;
677
678 for ( i = 0; i < num_subglyphs; i++ )
679 {
680 if ( num_subglyphs > 1 )
681 FT_TRACE7(( " subglyph %d:\n", i ));
682
683 FT_TRACE7(( " glyph index: %d\n", subglyph->index ));
684
685 if ( subglyph->flags & ARGS_ARE_XY_VALUES )
686 FT_TRACE7(( " offset: x=%d, y=%d\n",
687 subglyph->arg1,
688 subglyph->arg2 ));
689 else
690 FT_TRACE7(( " matching points: base=%d, component=%d\n",
691 subglyph->arg1,
692 subglyph->arg2 ));
693
694 if ( subglyph->flags & WE_HAVE_A_SCALE )
695 FT_TRACE7(( " scaling: %f\n",
696 subglyph->transform.xx / 65536.0 ));
697 else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
698 FT_TRACE7(( " scaling: x=%f, y=%f\n",
699 subglyph->transform.xx / 65536.0,
700 subglyph->transform.yy / 65536.0 ));
701 else if ( subglyph->flags & WE_HAVE_A_2X2 )
702 FT_TRACE7(( " scaling: xx=%f, yx=%f\n"
703 " xy=%f, yy=%f\n",
704 subglyph->transform.xx / 65536.0,
705 subglyph->transform.yx / 65536.0,
706 subglyph->transform.xy / 65536.0,
707 subglyph->transform.yy / 65536.0 ));
708
709 subglyph++;
710 }
711 }
712#endif /* FT_DEBUG_LEVEL_TRACE */
713
714#ifdef TT_USE_BYTECODE_INTERPRETER
715
716 {
717 FT_Stream stream = loader->stream;
718
719
720 /* we must undo the FT_FRAME_ENTER in order to point */
721 /* to the composite instructions, if we find some. */
722 /* We will process them later. */
723 /* */
724 loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
725 p - limit );
726 }
727
728#endif
729
730 loader->cursor = p;
731
732 Fail:
733 return error;
734
735 Invalid_Composite:
736 error = FT_THROW( Invalid_Composite );
737 goto Fail;
738 }
739
740
741 FT_LOCAL_DEF( void )
743 {
744 face->access_glyph_frame = TT_Access_Glyph_Frame;
745 face->read_glyph_header = TT_Load_Glyph_Header;
746 face->read_simple_glyph = TT_Load_Simple_Glyph;
747 face->read_composite_glyph = TT_Load_Composite_Glyph;
748 face->forget_glyph_frame = TT_Forget_Glyph_Frame;
749 }
750
751
752 static void
755 FT_UInt start_point,
756 FT_UInt start_contour )
757 {
758 zone->n_points = (FT_UShort)load->outline.n_points -
759 (FT_UShort)start_point;
760 zone->n_contours = load->outline.n_contours -
761 (FT_Short)start_contour;
762 zone->org = load->extra_points + start_point;
763 zone->cur = load->outline.points + start_point;
764 zone->orus = load->extra_points2 + start_point;
765 zone->tags = (FT_Byte*)load->outline.tags + start_point;
766 zone->contours = (FT_UShort*)load->outline.contours + start_contour;
767 zone->first_point = (FT_UShort)start_point;
768 }
769
770
771 /*************************************************************************/
772 /* */
773 /* <Function> */
774 /* TT_Hint_Glyph */
775 /* */
776 /* <Description> */
777 /* Hint the glyph using the zone prepared by the caller. Note that */
778 /* the zone is supposed to include four phantom points. */
779 /* */
780 static FT_Error
782 FT_Bool is_composite )
783 {
784#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
785 defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
786 TT_Face face = loader->face;
788#endif
789
790 TT_GlyphZone zone = &loader->zone;
791
792#ifdef TT_USE_BYTECODE_INTERPRETER
793 FT_Long n_ins;
794#else
795 FT_UNUSED( is_composite );
796#endif
797
798
799#ifdef TT_USE_BYTECODE_INTERPRETER
800 if ( loader->glyph->control_len > 0xFFFFL )
801 {
802 FT_TRACE1(( "TT_Hint_Glyph: too long instructions" ));
803 FT_TRACE1(( " (0x%lx byte) is truncated\n",
804 loader->glyph->control_len ));
805 }
806 n_ins = loader->glyph->control_len;
807
808 /* save original point position in org */
809 if ( n_ins > 0 )
810 FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
811
812 /* Reset graphics state. */
813 loader->exec->GS = loader->size->GS;
814
815 /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
816 /* completely refer to the (already) hinted subglyphs. */
817 if ( is_composite )
818 {
819 loader->exec->metrics.x_scale = 1 << 16;
820 loader->exec->metrics.y_scale = 1 << 16;
821
822 FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
823 }
824 else
825 {
826 loader->exec->metrics.x_scale = loader->size->metrics->x_scale;
827 loader->exec->metrics.y_scale = loader->size->metrics->y_scale;
828 }
829#endif
830
831 /* round phantom points */
832 zone->cur[zone->n_points - 4].x =
833 FT_PIX_ROUND( zone->cur[zone->n_points - 4].x );
834 zone->cur[zone->n_points - 3].x =
835 FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
836 zone->cur[zone->n_points - 2].y =
837 FT_PIX_ROUND( zone->cur[zone->n_points - 2].y );
838 zone->cur[zone->n_points - 1].y =
839 FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
840
841#ifdef TT_USE_BYTECODE_INTERPRETER
842
843 if ( n_ins > 0 )
844 {
846
847 FT_GlyphLoader gloader = loader->gloader;
848 FT_Outline current_outline = gloader->current.outline;
849
850
851 TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
852 loader->exec->glyphIns, n_ins );
853
854 loader->exec->is_composite = is_composite;
855 loader->exec->pts = *zone;
856
857 error = TT_Run_Context( loader->exec );
858 if ( error && loader->exec->pedantic_hinting )
859 return error;
860
861 /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
862 current_outline.tags[0] |=
863 ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
864 }
865
866#endif
867
868#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
869 /* Save possibly modified glyph phantom points unless in v40 backward */
870 /* compatibility mode, where no movement on the x axis means no reason */
871 /* to change bearings or advance widths. */
872 if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
873 loader->exec->backward_compatibility ) )
874 {
875#endif
876 loader->pp1 = zone->cur[zone->n_points - 4];
877 loader->pp2 = zone->cur[zone->n_points - 3];
878 loader->pp3 = zone->cur[zone->n_points - 2];
879 loader->pp4 = zone->cur[zone->n_points - 1];
880#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
881 }
882#endif
883
884#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
885 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
886 {
887 if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
888 FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
889
890 else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
891 FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
892 }
893#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
894
895 return FT_Err_Ok;
896 }
897
898
899 /*************************************************************************/
900 /* */
901 /* <Function> */
902 /* TT_Process_Simple_Glyph */
903 /* */
904 /* <Description> */
905 /* Once a simple glyph has been loaded, it needs to be processed. */
906 /* Usually, this means scaling and hinting through bytecode */
907 /* interpretation. */
908 /* */
909 static FT_Error
911 {
912 FT_GlyphLoader gloader = loader->gloader;
915 FT_Int n_points;
916
917
918 outline = &gloader->current.outline;
919 n_points = outline->n_points;
920
921 /* set phantom points */
922
923 outline->points[n_points ] = loader->pp1;
924 outline->points[n_points + 1] = loader->pp2;
925 outline->points[n_points + 2] = loader->pp3;
926 outline->points[n_points + 3] = loader->pp4;
927
928 outline->tags[n_points ] = 0;
929 outline->tags[n_points + 1] = 0;
930 outline->tags[n_points + 2] = 0;
931 outline->tags[n_points + 3] = 0;
932
933 n_points += 4;
934
935#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
936
937 if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
938 FT_IS_VARIATION( FT_FACE( loader->face ) ) )
939 {
940 /* Deltas apply to the unscaled data. */
941 error = TT_Vary_Apply_Glyph_Deltas( loader->face,
942 loader->glyph_index,
943 outline,
944 (FT_UInt)n_points );
945
946 /* recalculate linear horizontal and vertical advances */
947 /* if we don't have HVAR and VVAR, respectively */
948 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
949 loader->linear = outline->points[n_points - 3].x -
950 outline->points[n_points - 4].x;
951 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
952 loader->vadvance = outline->points[n_points - 1].x -
953 outline->points[n_points - 2].x;
954
955 if ( error )
956 return error;
957 }
958
959#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
960
961 if ( IS_HINTED( loader->load_flags ) )
962 {
963 tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
964
965 FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
966 loader->zone.n_points + 4 );
967 }
968
969 {
970#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
971 TT_Face face = loader->face;
973
974 FT_String* family = face->root.family_name;
975 FT_UInt ppem = loader->size->metrics->x_ppem;
976 FT_String* style = face->root.style_name;
977 FT_UInt x_scale_factor = 1000;
978#endif
979
980 FT_Vector* vec = outline->points;
981 FT_Vector* limit = outline->points + n_points;
982
983 FT_Fixed x_scale = 0; /* pacify compiler */
984 FT_Fixed y_scale = 0;
985
986 FT_Bool do_scale = FALSE;
987
988
989#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
990
991 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
992 {
993 /* scale, but only if enabled and only if TT hinting is being used */
994 if ( IS_HINTED( loader->load_flags ) )
995 x_scale_factor = sph_test_tweak_x_scaling( face,
996 family,
997 ppem,
998 style,
999 loader->glyph_index );
1000 /* scale the glyph */
1001 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
1002 x_scale_factor != 1000 )
1003 {
1004 x_scale = FT_MulDiv( loader->size->metrics->x_scale,
1005 (FT_Long)x_scale_factor, 1000 );
1006 y_scale = loader->size->metrics->y_scale;
1007
1008 /* compensate for any scaling by de/emboldening; */
1009 /* the amount was determined via experimentation */
1010 if ( x_scale_factor != 1000 && ppem > 11 )
1012 FT_MulFix( 1280 * ppem,
1013 1000 - x_scale_factor ),
1014 0 );
1015 do_scale = TRUE;
1016 }
1017 }
1018 else
1019
1020#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
1021
1022 {
1023 /* scale the glyph */
1024 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1025 {
1026 x_scale = loader->size->metrics->x_scale;
1027 y_scale = loader->size->metrics->y_scale;
1028
1029 do_scale = TRUE;
1030 }
1031 }
1032
1033 if ( do_scale )
1034 {
1035 for ( ; vec < limit; vec++ )
1036 {
1037 vec->x = FT_MulFix( vec->x, x_scale );
1038 vec->y = FT_MulFix( vec->y, y_scale );
1039 }
1040 }
1041
1042#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1043 /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
1044 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
1045 !IS_HINTED( loader->load_flags ) )
1046#endif
1047 {
1048 loader->pp1 = outline->points[n_points - 4];
1049 loader->pp2 = outline->points[n_points - 3];
1050 }
1051
1052#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1053 /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
1054 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
1055 !IS_HINTED( loader->load_flags ) )
1056#endif
1057 {
1058 loader->pp3 = outline->points[n_points - 2];
1059 loader->pp4 = outline->points[n_points - 1];
1060 }
1061 }
1062
1063 if ( IS_HINTED( loader->load_flags ) )
1064 {
1065 loader->zone.n_points += 4;
1066
1067 error = TT_Hint_Glyph( loader, 0 );
1068 }
1069
1070 return error;
1071 }
1072
1073
1074 /*************************************************************************/
1075 /* */
1076 /* <Function> */
1077 /* TT_Process_Composite_Component */
1078 /* */
1079 /* <Description> */
1080 /* Once a composite component has been loaded, it needs to be */
1081 /* processed. Usually, this means transforming and translating. */
1082 /* */
1083 static FT_Error
1085 FT_SubGlyph subglyph,
1086 FT_UInt start_point,
1087 FT_UInt num_base_points )
1088 {
1089 FT_GlyphLoader gloader = loader->gloader;
1091 FT_Bool have_scale;
1092 FT_Pos x, y;
1093
1094
1095 current.points = gloader->base.outline.points +
1096 num_base_points;
1097 current.n_points = gloader->base.outline.n_points -
1098 (short)num_base_points;
1099
1100 have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE |
1102 WE_HAVE_A_2X2 ) );
1103
1104 /* perform the transform required for this subglyph */
1105 if ( have_scale )
1106 FT_Outline_Transform( &current, &subglyph->transform );
1107
1108 /* get offset */
1109 if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
1110 {
1111 FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points;
1112 FT_UInt k = (FT_UInt)subglyph->arg1;
1113 FT_UInt l = (FT_UInt)subglyph->arg2;
1114 FT_Vector* p1;
1115 FT_Vector* p2;
1116
1117
1118 /* match l-th point of the newly loaded component to the k-th point */
1119 /* of the previously loaded components. */
1120
1121 /* change to the point numbers used by our outline */
1122 k += start_point;
1123 l += num_base_points;
1124 if ( k >= num_base_points ||
1125 l >= num_points )
1126 return FT_THROW( Invalid_Composite );
1127
1128 p1 = gloader->base.outline.points + k;
1129 p2 = gloader->base.outline.points + l;
1130
1131 x = p1->x - p2->x;
1132 y = p1->y - p2->y;
1133 }
1134 else
1135 {
1136 x = subglyph->arg1;
1137 y = subglyph->arg2;
1138
1139 if ( !x && !y )
1140 return FT_Err_Ok;
1141
1142 /* Use a default value dependent on */
1143 /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old */
1144 /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit. */
1145
1146 if ( have_scale &&
1147#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
1148 !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
1149#else
1150 ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
1151#endif
1152 {
1153
1154#if 0
1155
1156 /*******************************************************************/
1157 /* */
1158 /* This algorithm is what Apple documents. But it doesn't work. */
1159 /* */
1160 int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
1161 : -subglyph->transform.xx;
1162 int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
1163 : -subglyph->transform.yx;
1164 int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
1165 : -subglyph->transform.xy;
1166 int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
1167 : -subglyph->transform.yy;
1168 int m = a > b ? a : b;
1169 int n = c > d ? c : d;
1170
1171
1172 if ( a - b <= 33 && a - b >= -33 )
1173 m *= 2;
1174 if ( c - d <= 33 && c - d >= -33 )
1175 n *= 2;
1176 x = FT_MulFix( x, m );
1177 y = FT_MulFix( y, n );
1178
1179#else /* 1 */
1180
1181 /*******************************************************************/
1182 /* */
1183 /* This algorithm is a guess and works much better than the above. */
1184 /* */
1185 FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx,
1186 subglyph->transform.xy );
1187 FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy,
1188 subglyph->transform.yx );
1189
1190
1191 x = FT_MulFix( x, mac_xscale );
1192 y = FT_MulFix( y, mac_yscale );
1193
1194#endif /* 1 */
1195
1196 }
1197
1198 if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
1199 {
1200 FT_Fixed x_scale = loader->size->metrics->x_scale;
1201 FT_Fixed y_scale = loader->size->metrics->y_scale;
1202
1203
1204 x = FT_MulFix( x, x_scale );
1205 y = FT_MulFix( y, y_scale );
1206
1207 if ( subglyph->flags & ROUND_XY_TO_GRID )
1208 {
1209 TT_Face face = loader->face;
1211
1212
1213 if ( IS_HINTED( loader->load_flags ) )
1214 {
1215 /*
1216 * We round the horizontal offset only if there is hinting along
1217 * the x axis; this corresponds to integer advance width values.
1218 *
1219 * Theoretically, a glyph's bytecode can toggle ClearType's
1220 * `backward compatibility' mode, which would allow modification
1221 * of the advance width. In reality, however, applications
1222 * neither allow nor expect modified advance widths if sub-pixel
1223 * rendering is active.
1224 *
1225 */
1226 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_35 )
1227 x = FT_PIX_ROUND( x );
1228
1229 y = FT_PIX_ROUND( y );
1230 }
1231 }
1232 }
1233 }
1234
1235 if ( x || y )
1237
1238 return FT_Err_Ok;
1239 }
1240
1241
1242 /*************************************************************************/
1243 /* */
1244 /* <Function> */
1245 /* TT_Process_Composite_Glyph */
1246 /* */
1247 /* <Description> */
1248 /* This is slightly different from TT_Process_Simple_Glyph, in that */
1249 /* its sole purpose is to hint the glyph. Thus this function is */
1250 /* only available when bytecode interpreter is enabled. */
1251 /* */
1252 static FT_Error
1254 FT_UInt start_point,
1255 FT_UInt start_contour )
1256 {
1259 FT_UInt i;
1260
1261
1262 outline = &loader->gloader->base.outline;
1263
1264 /* make room for phantom points */
1266 outline->n_points + 4,
1267 0 );
1268 if ( error )
1269 return error;
1270
1271 outline->points[outline->n_points ] = loader->pp1;
1272 outline->points[outline->n_points + 1] = loader->pp2;
1273 outline->points[outline->n_points + 2] = loader->pp3;
1274 outline->points[outline->n_points + 3] = loader->pp4;
1275
1276 outline->tags[outline->n_points ] = 0;
1277 outline->tags[outline->n_points + 1] = 0;
1278 outline->tags[outline->n_points + 2] = 0;
1279 outline->tags[outline->n_points + 3] = 0;
1280
1281#ifdef TT_USE_BYTECODE_INTERPRETER
1282
1283 {
1284 FT_Stream stream = loader->stream;
1285 FT_UShort n_ins, max_ins;
1286 FT_ULong tmp;
1287
1288
1289 /* TT_Load_Composite_Glyph only gives us the offset of instructions */
1290 /* so we read them here */
1291 if ( FT_STREAM_SEEK( loader->ins_pos ) ||
1292 FT_READ_USHORT( n_ins ) )
1293 return error;
1294
1295 FT_TRACE5(( " Instructions size = %d\n", n_ins ));
1296
1297 /* check it */
1298 max_ins = loader->face->max_profile.maxSizeOfInstructions;
1299 if ( n_ins > max_ins )
1300 {
1301 /* don't trust `maxSizeOfInstructions'; */
1302 /* only do a rough safety check */
1303 if ( (FT_Int)n_ins > loader->byte_len )
1304 {
1305 FT_TRACE1(( "TT_Process_Composite_Glyph:"
1306 " too many instructions (%d) for glyph with length %d\n",
1307 n_ins, loader->byte_len ));
1308 return FT_THROW( Too_Many_Hints );
1309 }
1310
1311 tmp = loader->exec->glyphSize;
1312 error = Update_Max( loader->exec->memory,
1313 &tmp,
1314 sizeof ( FT_Byte ),
1315 (void*)&loader->exec->glyphIns,
1316 n_ins );
1317
1318 loader->exec->glyphSize = (FT_UShort)tmp;
1319 if ( error )
1320 return error;
1321 }
1322 else if ( n_ins == 0 )
1323 return FT_Err_Ok;
1324
1325 if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
1326 return error;
1327
1328 loader->glyph->control_data = loader->exec->glyphIns;
1329 loader->glyph->control_len = n_ins;
1330 }
1331
1332#endif
1333
1334 tt_prepare_zone( &loader->zone, &loader->gloader->base,
1335 start_point, start_contour );
1336
1337 /* Some points are likely touched during execution of */
1338 /* instructions on components. So let's untouch them. */
1339 for ( i = 0; i < loader->zone.n_points; i++ )
1340 loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
1341
1342 loader->zone.n_points += 4;
1343
1344 return TT_Hint_Glyph( loader, 1 );
1345 }
1346
1347
1348 /*
1349 * Calculate the phantom points
1350 *
1351 * Defining the right side bearing (rsb) as
1352 *
1353 * rsb = aw - (lsb + xmax - xmin)
1354 *
1355 * (with `aw' the advance width, `lsb' the left side bearing, and `xmin'
1356 * and `xmax' the glyph's minimum and maximum x value), the OpenType
1357 * specification defines the initial position of horizontal phantom points
1358 * as
1359 *
1360 * pp1 = (round(xmin - lsb), 0) ,
1361 * pp2 = (round(pp1 + aw), 0) .
1362 *
1363 * Note that the rounding to the grid (in the device space) is not
1364 * documented currently in the specification.
1365 *
1366 * However, the specification lacks the precise definition of vertical
1367 * phantom points. Greg Hitchcock provided the following explanation.
1368 *
1369 * - a `vmtx' table is present
1370 *
1371 * For any glyph, the minimum and maximum y values (`ymin' and `ymax')
1372 * are given in the `glyf' table, the top side bearing (tsb) and advance
1373 * height (ah) are given in the `vmtx' table. The bottom side bearing
1374 * (bsb) is then calculated as
1375 *
1376 * bsb = ah - (tsb + ymax - ymin) ,
1377 *
1378 * and the initial position of vertical phantom points is
1379 *
1380 * pp3 = (x, round(ymax + tsb)) ,
1381 * pp4 = (x, round(pp3 - ah)) .
1382 *
1383 * See below for value `x'.
1384 *
1385 * - no `vmtx' table in the font
1386 *
1387 * If there is an `OS/2' table, we set
1388 *
1389 * DefaultAscender = sTypoAscender ,
1390 * DefaultDescender = sTypoDescender ,
1391 *
1392 * otherwise we use data from the `hhea' table:
1393 *
1394 * DefaultAscender = Ascender ,
1395 * DefaultDescender = Descender .
1396 *
1397 * With these two variables we can now set
1398 *
1399 * ah = DefaultAscender - sDefaultDescender ,
1400 * tsb = DefaultAscender - yMax ,
1401 *
1402 * and proceed as if a `vmtx' table was present.
1403 *
1404 * Usually we have
1405 *
1406 * x = aw / 2 , (1)
1407 *
1408 * but there is one compatibility case where it can be set to
1409 *
1410 * x = -DefaultDescender -
1411 * ((DefaultAscender - DefaultDescender - aw) / 2) . (2)
1412 *
1413 * and another one with
1414 *
1415 * x = 0 . (3)
1416 *
1417 * In Windows, the history of those values is quite complicated,
1418 * depending on the hinting engine (that is, the graphics framework).
1419 *
1420 * framework from to formula
1421 * ----------------------------------------------------------
1422 * GDI Windows 98 current (1)
1423 * (Windows 2000 for NT)
1424 * GDI+ Windows XP Windows 7 (2)
1425 * GDI+ Windows 8 current (3)
1426 * DWrite Windows 7 current (3)
1427 *
1428 * For simplicity, FreeType uses (1) for grayscale subpixel hinting and
1429 * (3) for everything else.
1430 *
1431 */
1432 static void
1434 {
1435 FT_Bool subpixel_hinting = 0;
1436 FT_Bool grayscale = 0;
1437 FT_Bool use_aw_2 = 0;
1438
1439#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1441#endif
1442
1443
1444#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
1445 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
1446 {
1447 subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
1448 : 0;
1449 grayscale = loader->exec ? loader->exec->grayscale
1450 : 0;
1451 }
1452#endif
1453#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
1454 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
1455 {
1456 subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
1457 : 0;
1458 grayscale = loader->exec ? loader->exec->grayscale_cleartype
1459 : 0;
1460 }
1461#endif
1462
1463 use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
1464
1465 loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
1466 loader->pp1.y = 0;
1467 loader->pp2.x = loader->pp1.x + loader->advance;
1468 loader->pp2.y = 0;
1469
1470 loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
1471 loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
1472 loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
1473 loader->pp4.y = loader->pp3.y - loader->vadvance;
1474 }
1475
1476
1477 /* a utility function to retrieve i-th node from given FT_List */
1478 static FT_ListNode
1480 FT_UInt idx )
1481 {
1483
1484
1485 if ( !list )
1486 return NULL;
1487
1488 for ( cur = list->head; cur; cur = cur->next )
1489 {
1490 if ( !idx )
1491 return cur;
1492
1493 idx--;
1494 }
1495
1496 return NULL;
1497 }
1498
1499
1500 /*************************************************************************/
1501 /* */
1502 /* <Function> */
1503 /* load_truetype_glyph */
1504 /* */
1505 /* <Description> */
1506 /* Loads a given truetype glyph. Handles composites and uses a */
1507 /* TT_Loader object. */
1508 /* */
1509 static FT_Error
1511 FT_UInt glyph_index,
1512 FT_UInt recurse_count,
1513 FT_Bool header_only )
1514 {
1516 FT_Fixed x_scale, y_scale;
1518 TT_Face face = loader->face;
1519 FT_GlyphLoader gloader = loader->gloader;
1520 FT_Bool opened_frame = 0;
1521
1522#ifdef FT_CONFIG_OPTION_INCREMENTAL
1523 FT_StreamRec inc_stream;
1524 FT_Data glyph_data;
1525 FT_Bool glyph_data_loaded = 0;
1526#endif
1527
1528
1529#ifdef FT_DEBUG_LEVEL_TRACE
1530 if ( recurse_count )
1531 FT_TRACE5(( " nesting level: %d\n", recurse_count ));
1532#endif
1533
1534 /* some fonts have an incorrect value of `maxComponentDepth' */
1535 if ( recurse_count > face->max_profile.maxComponentDepth )
1536 {
1537 FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n",
1538 recurse_count ));
1539 face->max_profile.maxComponentDepth = (FT_UShort)recurse_count;
1540 }
1541
1542#ifndef FT_CONFIG_OPTION_INCREMENTAL
1543 /* check glyph index */
1544 if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
1545 {
1546 error = FT_THROW( Invalid_Glyph_Index );
1547 goto Exit;
1548 }
1549#endif
1550
1551 loader->glyph_index = glyph_index;
1552
1553 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1554 {
1555 x_scale = loader->size->metrics->x_scale;
1556 y_scale = loader->size->metrics->y_scale;
1557 }
1558 else
1559 {
1560 x_scale = 0x10000L;
1561 y_scale = 0x10000L;
1562 }
1563
1564 /* Set `offset' to the start of the glyph relative to the start of */
1565 /* the `glyf' table, and `byte_len' to the length of the glyph in */
1566 /* bytes. */
1567
1568#ifdef FT_CONFIG_OPTION_INCREMENTAL
1569
1570 /* If we are loading glyph data via the incremental interface, set */
1571 /* the loader stream to a memory stream reading the data returned */
1572 /* by the interface. */
1573 if ( face->root.internal->incremental_interface )
1574 {
1575 error = face->root.internal->incremental_interface->funcs->get_glyph_data(
1576 face->root.internal->incremental_interface->object,
1577 glyph_index, &glyph_data );
1578 if ( error )
1579 goto Exit;
1580
1581 glyph_data_loaded = 1;
1582 offset = 0;
1583 loader->byte_len = glyph_data.length;
1584
1585 FT_ZERO( &inc_stream );
1586 FT_Stream_OpenMemory( &inc_stream,
1587 glyph_data.pointer,
1588 (FT_ULong)glyph_data.length );
1589
1590 loader->stream = &inc_stream;
1591 }
1592 else
1593
1594#endif /* FT_CONFIG_OPTION_INCREMENTAL */
1595
1596 offset = tt_face_get_location( face, glyph_index,
1597 (FT_UInt*)&loader->byte_len );
1598
1599 if ( loader->byte_len > 0 )
1600 {
1601#ifdef FT_CONFIG_OPTION_INCREMENTAL
1602 /* for the incremental interface, `glyf_offset' is always zero */
1603 if ( !face->glyf_offset &&
1604 !face->root.internal->incremental_interface )
1605#else
1606 if ( !face->glyf_offset )
1607#endif /* FT_CONFIG_OPTION_INCREMENTAL */
1608 {
1609 FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
1610 error = FT_THROW( Invalid_Table );
1611 goto Exit;
1612 }
1613
1614 error = face->access_glyph_frame( loader, glyph_index,
1615 face->glyf_offset + offset,
1616 (FT_UInt)loader->byte_len );
1617 if ( error )
1618 goto Exit;
1619
1620 opened_frame = 1;
1621
1622 /* read glyph header first */
1623 error = face->read_glyph_header( loader );
1624 if ( error )
1625 goto Exit;
1626
1627 /* the metrics must be computed after loading the glyph header */
1628 /* since we need the glyph's `yMax' value in case the vertical */
1629 /* metrics must be emulated */
1630 error = tt_get_metrics( loader, glyph_index );
1631 if ( error )
1632 goto Exit;
1633
1634 if ( header_only )
1635 goto Exit;
1636 }
1637
1638 if ( loader->byte_len == 0 || loader->n_contours == 0 )
1639 {
1640 loader->bbox.xMin = 0;
1641 loader->bbox.xMax = 0;
1642 loader->bbox.yMin = 0;
1643 loader->bbox.yMax = 0;
1644
1645 error = tt_get_metrics( loader, glyph_index );
1646 if ( error )
1647 goto Exit;
1648
1649 if ( header_only )
1650 goto Exit;
1651
1652 /* must initialize points before (possibly) overriding */
1653 /* glyph metrics from the incremental interface */
1654 tt_loader_set_pp( loader );
1655
1656#ifdef FT_CONFIG_OPTION_INCREMENTAL
1657 tt_get_metrics_incr_overrides( loader, glyph_index );
1658#endif
1659
1660#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1661
1662 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1664 {
1665 /* a small outline structure with four elements for */
1666 /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1667 FT_Vector points[4];
1668 char tags[4] = { 1, 1, 1, 1 };
1669 short contours[4] = { 0, 1, 2, 3 };
1671
1672
1673 points[0].x = loader->pp1.x;
1674 points[0].y = loader->pp1.y;
1675 points[1].x = loader->pp2.x;
1676 points[1].y = loader->pp2.y;
1677
1678 points[2].x = loader->pp3.x;
1679 points[2].y = loader->pp3.y;
1680 points[3].x = loader->pp4.x;
1681 points[3].y = loader->pp4.y;
1682
1683 outline.n_points = 4;
1684 outline.n_contours = 4;
1685 outline.points = points;
1686 outline.tags = tags;
1687 outline.contours = contours;
1688
1689 /* this must be done before scaling */
1690 error = TT_Vary_Apply_Glyph_Deltas( loader->face,
1691 glyph_index,
1692 &outline,
1693 (FT_UInt)outline.n_points );
1694 if ( error )
1695 goto Exit;
1696
1697 loader->pp1.x = points[0].x;
1698 loader->pp1.y = points[0].y;
1699 loader->pp2.x = points[1].x;
1700 loader->pp2.y = points[1].y;
1701
1702 loader->pp3.x = points[2].x;
1703 loader->pp3.y = points[2].y;
1704 loader->pp4.x = points[3].x;
1705 loader->pp4.y = points[3].y;
1706
1707
1708 /* recalculate linear horizontal and vertical advances */
1709 /* if we don't have HVAR and VVAR, respectively */
1710 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1711 loader->linear = loader->pp2.x - loader->pp1.x;
1712 if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1713 loader->vadvance = loader->pp4.x - loader->pp3.x;
1714 }
1715
1716#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1717
1718 /* scale phantom points, if necessary; */
1719 /* they get rounded in `TT_Hint_Glyph' */
1720 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1721 {
1722 loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1723 loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1724 /* pp1.y and pp2.y are always zero */
1725
1726 loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1727 loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1728 loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1729 loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1730 }
1731
1732 error = FT_Err_Ok;
1733 goto Exit;
1734 }
1735
1736 /* must initialize phantom points before (possibly) overriding */
1737 /* glyph metrics from the incremental interface */
1738 tt_loader_set_pp( loader );
1739
1740#ifdef FT_CONFIG_OPTION_INCREMENTAL
1741 tt_get_metrics_incr_overrides( loader, glyph_index );
1742#endif
1743
1744 /***********************************************************************/
1745 /***********************************************************************/
1746 /***********************************************************************/
1747
1748 /* if it is a simple glyph, load it */
1749
1750 if ( loader->n_contours > 0 )
1751 {
1752 error = face->read_simple_glyph( loader );
1753 if ( error )
1754 goto Exit;
1755
1756 /* all data have been read */
1757 face->forget_glyph_frame( loader );
1758 opened_frame = 0;
1759
1760 error = TT_Process_Simple_Glyph( loader );
1761 if ( error )
1762 goto Exit;
1763
1764 FT_GlyphLoader_Add( gloader );
1765 }
1766
1767 /***********************************************************************/
1768 /***********************************************************************/
1769 /***********************************************************************/
1770
1771 /* otherwise, load a composite! */
1772 else if ( loader->n_contours < 0 )
1773 {
1774 FT_Memory memory = face->root.memory;
1775
1776 FT_UInt start_point;
1777 FT_UInt start_contour;
1778 FT_ULong ins_pos; /* position of composite instructions, if any */
1779
1780 FT_ListNode node, node2;
1781
1782
1783 /* normalize the `n_contours' value */
1784 loader->n_contours = -1;
1785
1786 /*
1787 * We store the glyph index directly in the `node->data' pointer,
1788 * following the glib solution (cf. macro `GUINT_TO_POINTER') with a
1789 * double cast to make this portable. Note, however, that this needs
1790 * pointers with a width of at least 32 bits.
1791 */
1792
1793
1794 /* clear the nodes filled by sibling chains */
1795 node = ft_list_get_node_at( &loader->composites, recurse_count );
1796 for ( node2 = node; node2; node2 = node2->next )
1797 node2->data = (void*)FT_ULONG_MAX;
1798
1799 /* check whether we already have a composite glyph with this index */
1800 if ( FT_List_Find( &loader->composites,
1801 FT_UINT_TO_POINTER( glyph_index ) ) )
1802 {
1803 FT_TRACE1(( "TT_Load_Composite_Glyph:"
1804 " infinite recursion detected\n" ));
1805 error = FT_THROW( Invalid_Composite );
1806 goto Exit;
1807 }
1808
1809 else if ( node )
1810 node->data = FT_UINT_TO_POINTER( glyph_index );
1811
1812 else
1813 {
1814 if ( FT_NEW( node ) )
1815 goto Exit;
1816 node->data = FT_UINT_TO_POINTER( glyph_index );
1817 FT_List_Add( &loader->composites, node );
1818 }
1819
1820 start_point = (FT_UInt)gloader->base.outline.n_points;
1821 start_contour = (FT_UInt)gloader->base.outline.n_contours;
1822
1823 /* for each subglyph, read composite header */
1824 error = face->read_composite_glyph( loader );
1825 if ( error )
1826 goto Exit;
1827
1828 /* store the offset of instructions */
1829 ins_pos = loader->ins_pos;
1830
1831 /* all data we need are read */
1832 face->forget_glyph_frame( loader );
1833 opened_frame = 0;
1834
1835#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1836
1837 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1839 {
1840 short i, limit;
1841 FT_SubGlyph subglyph;
1842
1845 char* tags = NULL;
1846 short* contours = NULL;
1847
1848
1849 limit = (short)gloader->current.num_subglyphs;
1850
1851 /* construct an outline structure for */
1852 /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1853 outline.n_points = (short)( gloader->current.num_subglyphs + 4 );
1854 outline.n_contours = outline.n_points;
1855
1856 outline.points = NULL;
1857 outline.tags = NULL;
1858 outline.contours = NULL;
1859
1860 if ( FT_NEW_ARRAY( points, outline.n_points ) ||
1861 FT_NEW_ARRAY( tags, outline.n_points ) ||
1862 FT_NEW_ARRAY( contours, outline.n_points ) )
1863 goto Exit1;
1864
1865 subglyph = gloader->current.subglyphs;
1866
1867 for ( i = 0; i < limit; i++, subglyph++ )
1868 {
1869 /* applying deltas for anchor points doesn't make sense, */
1870 /* but we don't have to specially check this since */
1871 /* unused delta values are zero anyways */
1872 points[i].x = subglyph->arg1;
1873 points[i].y = subglyph->arg2;
1874 tags[i] = 1;
1875 contours[i] = i;
1876 }
1877
1878 points[i].x = loader->pp1.x;
1879 points[i].y = loader->pp1.y;
1880 tags[i] = 1;
1881 contours[i] = i;
1882
1883 i++;
1884 points[i].x = loader->pp2.x;
1885 points[i].y = loader->pp2.y;
1886 tags[i] = 1;
1887 contours[i] = i;
1888
1889 i++;
1890 points[i].x = loader->pp3.x;
1891 points[i].y = loader->pp3.y;
1892 tags[i] = 1;
1893 contours[i] = i;
1894
1895 i++;
1896 points[i].x = loader->pp4.x;
1897 points[i].y = loader->pp4.y;
1898 tags[i] = 1;
1899 contours[i] = i;
1900
1901 outline.points = points;
1902 outline.tags = tags;
1903 outline.contours = contours;
1904
1905 /* this call provides additional offsets */
1906 /* for each component's translation */
1907 if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
1908 face,
1909 glyph_index,
1910 &outline,
1911 (FT_UInt)outline.n_points ) ) )
1912 goto Exit1;
1913
1914 subglyph = gloader->current.subglyphs;
1915
1916 for ( i = 0; i < limit; i++, subglyph++ )
1917 {
1918 if ( subglyph->flags & ARGS_ARE_XY_VALUES )
1919 {
1920 subglyph->arg1 = (FT_Int16)points[i].x;
1921 subglyph->arg2 = (FT_Int16)points[i].y;
1922 }
1923 }
1924
1925 loader->pp1.x = points[i + 0].x;
1926 loader->pp1.y = points[i + 0].y;
1927 loader->pp2.x = points[i + 1].x;
1928 loader->pp2.y = points[i + 1].y;
1929
1930 loader->pp3.x = points[i + 2].x;
1931 loader->pp3.y = points[i + 2].y;
1932 loader->pp4.x = points[i + 3].x;
1933 loader->pp4.y = points[i + 3].y;
1934
1935 /* recalculate linear horizontal and vertical advances */
1936 /* if we don't have HVAR and VVAR, respectively */
1937 if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1938 loader->linear = loader->pp2.x - loader->pp1.x;
1939 if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1940 loader->vadvance = loader->pp4.x - loader->pp3.x;
1941
1942 Exit1:
1943 FT_FREE( outline.points );
1944 FT_FREE( outline.tags );
1945 FT_FREE( outline.contours );
1946
1947 if ( error )
1948 goto Exit;
1949 }
1950
1951#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1952
1953 /* scale phantom points, if necessary; */
1954 /* they get rounded in `TT_Hint_Glyph' */
1955 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1956 {
1957 loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1958 loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1959 /* pp1.y and pp2.y are always zero */
1960
1961 loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1962 loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1963 loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1964 loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1965 }
1966
1967 /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
1968 /* `as is' in the glyph slot (the client application will be */
1969 /* responsible for interpreting these data)... */
1970 if ( loader->load_flags & FT_LOAD_NO_RECURSE )
1971 {
1972 FT_GlyphLoader_Add( gloader );
1973 loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1974
1975 goto Exit;
1976 }
1977
1978 /*********************************************************************/
1979 /*********************************************************************/
1980 /*********************************************************************/
1981
1982 {
1983 FT_UInt n, num_base_points;
1984 FT_SubGlyph subglyph = NULL;
1985
1986 FT_UInt num_points = start_point;
1987 FT_UInt num_subglyphs = gloader->current.num_subglyphs;
1988 FT_UInt num_base_subgs = gloader->base.num_subglyphs;
1989
1990 FT_Stream old_stream = loader->stream;
1991 FT_Int old_byte_len = loader->byte_len;
1992
1993
1994 FT_GlyphLoader_Add( gloader );
1995
1996 /* read each subglyph independently */
1997 for ( n = 0; n < num_subglyphs; n++ )
1998 {
1999 FT_Vector pp[4];
2000
2001 FT_Int linear_hadvance;
2002 FT_Int linear_vadvance;
2003
2004
2005 /* Each time we call load_truetype_glyph in this loop, the */
2006 /* value of `gloader.base.subglyphs' can change due to table */
2007 /* reallocations. We thus need to recompute the subglyph */
2008 /* pointer on each iteration. */
2009 subglyph = gloader->base.subglyphs + num_base_subgs + n;
2010
2011 pp[0] = loader->pp1;
2012 pp[1] = loader->pp2;
2013 pp[2] = loader->pp3;
2014 pp[3] = loader->pp4;
2015
2016 linear_hadvance = loader->linear;
2017 linear_vadvance = loader->vadvance;
2018
2019 num_base_points = (FT_UInt)gloader->base.outline.n_points;
2020
2021 error = load_truetype_glyph( loader,
2022 (FT_UInt)subglyph->index,
2023 recurse_count + 1,
2024 FALSE );
2025 if ( error )
2026 goto Exit;
2027
2028 /* restore subglyph pointer */
2029 subglyph = gloader->base.subglyphs + num_base_subgs + n;
2030
2031 /* restore phantom points if necessary */
2032 if ( !( subglyph->flags & USE_MY_METRICS ) )
2033 {
2034 loader->pp1 = pp[0];
2035 loader->pp2 = pp[1];
2036 loader->pp3 = pp[2];
2037 loader->pp4 = pp[3];
2038
2039 loader->linear = linear_hadvance;
2040 loader->vadvance = linear_vadvance;
2041 }
2042
2043 num_points = (FT_UInt)gloader->base.outline.n_points;
2044
2045 if ( num_points == num_base_points )
2046 continue;
2047
2048 /* gloader->base.outline consists of three parts: */
2049 /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
2050 /* */
2051 /* (1): exists from the beginning */
2052 /* (2): components that have been loaded so far */
2053 /* (3): the newly loaded component */
2055 subglyph,
2056 start_point,
2057 num_base_points );
2058 if ( error )
2059 goto Exit;
2060 }
2061
2062 loader->stream = old_stream;
2063 loader->byte_len = old_byte_len;
2064
2065 /* process the glyph */
2066 loader->ins_pos = ins_pos;
2067 if ( IS_HINTED( loader->load_flags ) &&
2069 subglyph->flags & WE_HAVE_INSTR &&
2070#endif
2071 num_points > start_point )
2072 {
2074 start_point,
2075 start_contour );
2076 if ( error )
2077 goto Exit;
2078 }
2079 }
2080 }
2081
2082 /***********************************************************************/
2083 /***********************************************************************/
2084 /***********************************************************************/
2085
2086 Exit:
2087
2088 if ( opened_frame )
2089 face->forget_glyph_frame( loader );
2090
2091#ifdef FT_CONFIG_OPTION_INCREMENTAL
2092
2093 if ( glyph_data_loaded )
2094 face->root.internal->incremental_interface->funcs->free_glyph_data(
2095 face->root.internal->incremental_interface->object,
2096 &glyph_data );
2097
2098#endif
2099
2100 return error;
2101 }
2102
2103
2104 static FT_Error
2106 FT_UInt glyph_index )
2107 {
2108 TT_Face face = loader->face;
2109#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
2110 defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2112#endif
2113
2114 FT_BBox bbox;
2115 FT_Fixed y_scale;
2116 TT_GlyphSlot glyph = loader->glyph;
2117 TT_Size size = loader->size;
2118
2119
2120 y_scale = 0x10000L;
2121 if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
2122 y_scale = size->metrics->y_scale;
2123
2124 if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
2125 FT_Outline_Get_CBox( &glyph->outline, &bbox );
2126 else
2127 bbox = loader->bbox;
2128
2129 /* get the device-independent horizontal advance; it is scaled later */
2130 /* by the base layer. */
2131 glyph->linearHoriAdvance = loader->linear;
2132
2133 glyph->metrics.horiBearingX = bbox.xMin;
2134 glyph->metrics.horiBearingY = bbox.yMax;
2135 glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
2136
2137 /* Adjust advance width to the value contained in the hdmx table */
2138 /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
2139 /* mode of the v40 interpreter is active. See `ttinterp.h' for */
2140 /* details on backward compatibility mode. */
2141 if (
2143 !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
2144 ( loader->exec && loader->exec->backward_compatibility ) ) &&
2145#endif
2146 !face->postscript.isFixedPitch &&
2147 IS_HINTED( loader->load_flags ) &&
2148 !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
2149 {
2150 FT_Byte* widthp;
2151
2152
2154 size->metrics->x_ppem,
2155 glyph_index );
2156
2157#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2158
2159 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2160 {
2161 FT_Bool ignore_x_mode;
2162
2163
2164 ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
2166
2167 if ( widthp &&
2168 ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
2169 !ignore_x_mode ||
2170 SPH_OPTION_BITMAP_WIDTHS ) )
2171 glyph->metrics.horiAdvance = *widthp * 64;
2172 }
2173 else
2174
2175#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2176
2177 {
2178 if ( widthp )
2179 glyph->metrics.horiAdvance = *widthp * 64;
2180 }
2181 }
2182
2183 /* set glyph dimensions */
2184 glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin );
2185 glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin );
2186
2187 /* Now take care of vertical metrics. In the case where there is */
2188 /* no vertical information within the font (relatively common), */
2189 /* create some metrics manually */
2190 {
2191 FT_Pos top; /* scaled vertical top side bearing */
2192 FT_Pos advance; /* scaled vertical advance height */
2193
2194
2195 /* Get the unscaled top bearing and advance height. */
2196 if ( face->vertical_info &&
2197 face->vertical.number_Of_VMetrics > 0 )
2198 {
2199 top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
2200 y_scale );
2201
2202 if ( loader->pp3.y <= loader->pp4.y )
2203 advance = 0;
2204 else
2205 advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
2206 y_scale );
2207 }
2208 else
2209 {
2210 FT_Pos height;
2211
2212
2213 /* XXX Compute top side bearing and advance height in */
2214 /* Get_VMetrics instead of here. */
2215
2216 /* NOTE: The OS/2 values are the only `portable' ones, */
2217 /* which is why we use them, if there is an OS/2 */
2218 /* table in the font. Otherwise, we use the */
2219 /* values defined in the horizontal header. */
2220
2222 bbox.yMin ),
2223 y_scale );
2224 if ( face->os2.version != 0xFFFFU )
2225 advance = (FT_Pos)( face->os2.sTypoAscender -
2226 face->os2.sTypoDescender );
2227 else
2228 advance = (FT_Pos)( face->horizontal.Ascender -
2229 face->horizontal.Descender );
2230
2231 top = ( advance - height ) / 2;
2232 }
2233
2234#ifdef FT_CONFIG_OPTION_INCREMENTAL
2235 {
2237 FT_Incremental_MetricsRec incr_metrics;
2239
2240
2241 incr = face->root.internal->incremental_interface;
2242
2243 /* If this is an incrementally loaded font see if there are */
2244 /* overriding metrics for this glyph. */
2245 if ( incr && incr->funcs->get_glyph_metrics )
2246 {
2247 incr_metrics.bearing_x = 0;
2248 incr_metrics.bearing_y = top;
2249 incr_metrics.advance = advance;
2250
2251 error = incr->funcs->get_glyph_metrics( incr->object,
2252 glyph_index,
2253 TRUE,
2254 &incr_metrics );
2255 if ( error )
2256 return error;
2257
2258 top = incr_metrics.bearing_y;
2259 advance = incr_metrics.advance;
2260 }
2261 }
2262
2263 /* GWW: Do vertical metrics get loaded incrementally too? */
2264
2265#endif /* FT_CONFIG_OPTION_INCREMENTAL */
2266
2267 glyph->linearVertAdvance = advance;
2268
2269 /* scale the metrics */
2270 if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
2271 {
2272 top = FT_MulFix( top, y_scale );
2273 advance = FT_MulFix( advance, y_scale );
2274 }
2275
2276 /* XXX: for now, we have no better algorithm for the lsb, but it */
2277 /* should work fine. */
2278 /* */
2279 glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
2280 glyph->metrics.horiAdvance / 2;
2281 glyph->metrics.vertBearingY = top;
2282 glyph->metrics.vertAdvance = advance;
2283 }
2284
2285 return 0;
2286 }
2287
2288
2289#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2290
2291 static FT_Error
2292 load_sbit_image( TT_Size size,
2293 TT_GlyphSlot glyph,
2294 FT_UInt glyph_index,
2295 FT_Int32 load_flags )
2296 {
2297 TT_Face face;
2301 TT_SBit_MetricsRec sbit_metrics;
2302
2303
2304 face = (TT_Face)glyph->face;
2305 sfnt = (SFNT_Service)face->sfnt;
2306 stream = face->root.stream;
2307
2309 size->strike_index,
2310 glyph_index,
2311 (FT_UInt)load_flags,
2312 stream,
2313 &glyph->bitmap,
2314 &sbit_metrics );
2315 if ( !error )
2316 {
2317 glyph->outline.n_points = 0;
2318 glyph->outline.n_contours = 0;
2319
2320 glyph->metrics.width = (FT_Pos)sbit_metrics.width * 64;
2321 glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64;
2322
2323 glyph->metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64;
2324 glyph->metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64;
2325 glyph->metrics.horiAdvance = (FT_Pos)sbit_metrics.horiAdvance * 64;
2326
2327 glyph->metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64;
2328 glyph->metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64;
2329 glyph->metrics.vertAdvance = (FT_Pos)sbit_metrics.vertAdvance * 64;
2330
2331 glyph->format = FT_GLYPH_FORMAT_BITMAP;
2332
2333 if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2334 {
2335 glyph->bitmap_left = sbit_metrics.vertBearingX;
2336 glyph->bitmap_top = sbit_metrics.vertBearingY;
2337 }
2338 else
2339 {
2340 glyph->bitmap_left = sbit_metrics.horiBearingX;
2341 glyph->bitmap_top = sbit_metrics.horiBearingY;
2342 }
2343 }
2344
2345 return error;
2346 }
2347
2348#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2349
2350
2351 static FT_Error
2353 TT_Size size,
2354 TT_GlyphSlot glyph,
2355 FT_Int32 load_flags,
2356 FT_Bool glyf_table_only )
2357 {
2358 TT_Face face;
2360
2361#ifdef TT_USE_BYTECODE_INTERPRETER
2363 FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2364#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
2365 defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2367#endif
2368#endif
2369
2370
2371 face = (TT_Face)glyph->face;
2372 stream = face->root.stream;
2373
2374 FT_ZERO( loader );
2375
2376#ifdef TT_USE_BYTECODE_INTERPRETER
2377
2378 /* load execution context */
2379 if ( IS_HINTED( load_flags ) && !glyf_table_only )
2380 {
2381 TT_ExecContext exec;
2382 FT_Bool grayscale = TRUE;
2383#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2384 FT_Bool subpixel_hinting_lean;
2385 FT_Bool grayscale_cleartype;
2386#endif
2387
2388#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2389 FT_Bool subpixel_hinting = FALSE;
2390
2391#if 0
2392 /* not used yet */
2393 FT_Bool compatible_widths;
2394 FT_Bool symmetrical_smoothing;
2395 FT_Bool bgr;
2396 FT_Bool vertical_lcd;
2397 FT_Bool subpixel_positioned;
2398 FT_Bool gray_cleartype;
2399#endif
2400#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2401
2402 FT_Bool reexecute = FALSE;
2403
2404
2405 if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
2406 {
2407 error = tt_size_ready_bytecode( size, pedantic );
2408 if ( error )
2409 return error;
2410 }
2411 else if ( size->bytecode_ready )
2412 return size->bytecode_ready;
2413 else if ( size->cvt_ready )
2414 return size->cvt_ready;
2415
2416 /* query new execution context */
2417 exec = size->context;
2418 if ( !exec )
2419 return FT_THROW( Could_Not_Find_Context );
2420
2421#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2422 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2423 {
2424 subpixel_hinting_lean =
2425 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2427 grayscale_cleartype =
2428 FT_BOOL( subpixel_hinting_lean &&
2429 !( ( load_flags &
2431 ( load_flags &
2433 exec->vertical_lcd_lean =
2434 FT_BOOL( subpixel_hinting_lean &&
2435 ( load_flags &
2437 }
2438 else
2439 {
2440 subpixel_hinting_lean = FALSE;
2441 grayscale_cleartype = FALSE;
2442 exec->vertical_lcd_lean = FALSE;
2443 }
2444#endif
2445
2446#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2447
2448 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2449 {
2450 subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
2452 SPH_OPTION_SET_SUBPIXEL );
2453
2454 if ( subpixel_hinting )
2455 grayscale = FALSE;
2456 else if ( SPH_OPTION_SET_GRAYSCALE )
2457 {
2458 grayscale = TRUE;
2459 subpixel_hinting = FALSE;
2460 }
2461 else
2462 grayscale = FALSE;
2463
2464 if ( FT_IS_TRICKY( glyph->face ) )
2465 subpixel_hinting = FALSE;
2466
2467 exec->ignore_x_mode = subpixel_hinting || grayscale;
2468 exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
2469 if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
2470 exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
2471
2472#if 1
2473 exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
2474 exec->symmetrical_smoothing = TRUE;
2475 exec->bgr = FALSE;
2476 exec->vertical_lcd = FALSE;
2477 exec->subpixel_positioned = TRUE;
2478 exec->gray_cleartype = FALSE;
2479#else /* 0 */
2480 exec->compatible_widths =
2481 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2482 TT_LOAD_COMPATIBLE_WIDTHS );
2483 exec->symmetrical_smoothing =
2484 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2485 TT_LOAD_SYMMETRICAL_SMOOTHING );
2486 exec->bgr =
2487 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2488 TT_LOAD_BGR );
2489 exec->vertical_lcd =
2490 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2491 TT_LOAD_VERTICAL_LCD );
2492 exec->subpixel_positioned =
2493 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2494 TT_LOAD_SUBPIXEL_POSITIONED );
2495 exec->gray_cleartype =
2496 FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2497 TT_LOAD_GRAY_CLEARTYPE );
2498#endif /* 0 */
2499
2500 }
2501 else
2502
2503#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2504
2505#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2506 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2507 grayscale = FT_BOOL( !subpixel_hinting_lean &&
2508 FT_LOAD_TARGET_MODE( load_flags ) !=
2510 else
2511#endif
2512 grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2514
2515 error = TT_Load_Context( exec, face, size );
2516 if ( error )
2517 return error;
2518
2519#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2520
2521 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2522 {
2523 /* a change from mono to subpixel rendering (and vice versa) */
2524 /* requires a re-execution of the CVT program */
2525 if ( subpixel_hinting != exec->subpixel_hinting )
2526 {
2527 FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2528 " re-executing `prep' table\n" ));
2529
2530 exec->subpixel_hinting = subpixel_hinting;
2531 reexecute = TRUE;
2532 }
2533
2534 /* a change from mono to grayscale rendering (and vice versa) */
2535 /* requires a re-execution of the CVT program */
2536 if ( grayscale != exec->grayscale )
2537 {
2538 FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2539 " re-executing `prep' table\n" ));
2540
2541 exec->grayscale = grayscale;
2542 reexecute = TRUE;
2543 }
2544 }
2545 else
2546
2547#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2548
2549 {
2550
2551#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2552 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2553 {
2554 /* a change from mono to subpixel rendering (and vice versa) */
2555 /* requires a re-execution of the CVT program */
2556 if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
2557 {
2558 FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2559 " re-executing `prep' table\n" ));
2560
2561 exec->subpixel_hinting_lean = subpixel_hinting_lean;
2562 reexecute = TRUE;
2563 }
2564
2565 /* a change from colored to grayscale subpixel rendering (and */
2566 /* vice versa) requires a re-execution of the CVT program */
2567 if ( grayscale_cleartype != exec->grayscale_cleartype )
2568 {
2569 FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
2570 " re-executing `prep' table\n" ));
2571
2572 exec->grayscale_cleartype = grayscale_cleartype;
2573 reexecute = TRUE;
2574 }
2575 }
2576#endif
2577
2578 /* a change from mono to grayscale rendering (and vice versa) */
2579 /* requires a re-execution of the CVT program */
2580 if ( grayscale != exec->grayscale )
2581 {
2582 FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2583 " re-executing `prep' table\n" ));
2584
2585 exec->grayscale = grayscale;
2586 reexecute = TRUE;
2587 }
2588 }
2589
2590 if ( reexecute )
2591 {
2592 FT_UInt i;
2593
2594
2595 for ( i = 0; i < size->cvt_size; i++ )
2596 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
2597 error = tt_size_run_prep( size, pedantic );
2598 if ( error )
2599 return error;
2600 }
2601
2602 /* check whether the cvt program has disabled hinting */
2603 if ( exec->GS.instruct_control & 1 )
2604 load_flags |= FT_LOAD_NO_HINTING;
2605
2606 /* load default graphics state -- if needed */
2607 if ( exec->GS.instruct_control & 2 )
2609
2610#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2611 /* check whether we have a font hinted for ClearType -- */
2612 /* note that this flag can also be modified in a glyph's bytecode */
2613 if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
2614 exec->GS.instruct_control & 4 )
2615 exec->ignore_x_mode = 0;
2616#endif
2617
2618 exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2619 loader->exec = exec;
2620 loader->instructions = exec->glyphIns;
2621 }
2622
2623#endif /* TT_USE_BYTECODE_INTERPRETER */
2624
2625 /* get face's glyph loader */
2626 if ( !glyf_table_only )
2627 {
2628 FT_GlyphLoader gloader = glyph->internal->loader;
2629
2630
2631 FT_GlyphLoader_Rewind( gloader );
2632 loader->gloader = gloader;
2633 }
2634
2635 loader->load_flags = (FT_ULong)load_flags;
2636
2637 loader->face = face;
2638 loader->size = size;
2639 loader->glyph = (FT_GlyphSlot)glyph;
2640 loader->stream = stream;
2641
2642 loader->composites.head = NULL;
2643 loader->composites.tail = NULL;
2644
2645 return FT_Err_Ok;
2646 }
2647
2648
2649 static void
2651 {
2652 FT_List_Finalize( &loader->composites,
2653 NULL,
2654 loader->face->root.memory,
2655 NULL );
2656 }
2657
2658
2659 /*************************************************************************/
2660 /* */
2661 /* <Function> */
2662 /* TT_Load_Glyph */
2663 /* */
2664 /* <Description> */
2665 /* A function used to load a single glyph within a given glyph slot, */
2666 /* for a given size. */
2667 /* */
2668 /* <Input> */
2669 /* glyph :: A handle to a target slot object where the glyph */
2670 /* will be loaded. */
2671 /* */
2672 /* size :: A handle to the source face size at which the glyph */
2673 /* must be scaled/loaded. */
2674 /* */
2675 /* glyph_index :: The index of the glyph in the font file. */
2676 /* */
2677 /* load_flags :: A flag indicating what to load for this glyph. The */
2678 /* FT_LOAD_XXX constants can be used to control the */
2679 /* glyph loading process (e.g., whether the outline */
2680 /* should be scaled, whether to load bitmaps or not, */
2681 /* whether to hint the outline, etc). */
2682 /* */
2683 /* <Return> */
2684 /* FreeType error code. 0 means success. */
2685 /* */
2688 TT_GlyphSlot glyph,
2689 FT_UInt glyph_index,
2690 FT_Int32 load_flags )
2691 {
2693 TT_LoaderRec loader;
2694
2695#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
2696#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \
2697 FT_IS_VARIATION( glyph->face ) ) )
2698#else
2699#define IS_DEFAULT_INSTANCE 1
2700#endif
2701
2702
2703 FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
2704
2705#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2706
2707 /* try to load embedded bitmap (if any) */
2708 if ( size->strike_index != 0xFFFFFFFFUL &&
2709 ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
2711 {
2712 error = load_sbit_image( size, glyph, glyph_index, load_flags );
2713 if ( FT_ERR_EQ( error, Missing_Bitmap ) )
2714 {
2715 /* the bitmap strike is incomplete and misses the requested glyph; */
2716 /* if we have a bitmap-only font, return an empty glyph */
2717 if ( !FT_IS_SCALABLE( glyph->face ) )
2718 {
2719 TT_Face face = (TT_Face)glyph->face;
2720 FT_Short left_bearing = 0, top_bearing = 0;
2721 FT_UShort advance_width = 0, advance_height = 0;
2722
2723
2724 /* to return an empty glyph, however, we need metrics data */
2725 /* from the `hmtx' (or `vmtx') table; the assumption is that */
2726 /* empty glyphs are missing intentionally, representing */
2727 /* whitespace - not having at least horizontal metrics is */
2728 /* thus considered an error */
2729 if ( !face->horz_metrics_size )
2730 return error;
2731
2732 /* we now construct an empty bitmap glyph */
2733 TT_Get_HMetrics( face, glyph_index,
2734 &left_bearing,
2735 &advance_width );
2736 TT_Get_VMetrics( face, glyph_index,
2737 0,
2738 &top_bearing,
2739 &advance_height );
2740
2741 glyph->outline.n_points = 0;
2742 glyph->outline.n_contours = 0;
2743
2744 glyph->metrics.width = 0;
2745 glyph->metrics.height = 0;
2746
2747 glyph->metrics.horiBearingX = left_bearing;
2748 glyph->metrics.horiBearingY = 0;
2749 glyph->metrics.horiAdvance = advance_width;
2750
2751 glyph->metrics.vertBearingX = 0;
2752 glyph->metrics.vertBearingY = top_bearing;
2753 glyph->metrics.vertAdvance = advance_height;
2754
2755 glyph->format = FT_GLYPH_FORMAT_BITMAP;
2756 glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
2757
2758 glyph->bitmap_left = 0;
2759 glyph->bitmap_top = 0;
2760
2761 return FT_Err_Ok;
2762 }
2763 }
2764 else if ( error )
2765 {
2766 /* return error if font is not scalable */
2767 if ( !FT_IS_SCALABLE( glyph->face ) )
2768 return error;
2769 }
2770 else
2771 {
2772 if ( FT_IS_SCALABLE( glyph->face ) )
2773 {
2774 /* for the bbox we need the header only */
2775 (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
2776 (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
2777 tt_loader_done( &loader );
2778 glyph->linearHoriAdvance = loader.linear;
2779 glyph->linearVertAdvance = loader.vadvance;
2780
2781 /* sanity checks: if `xxxAdvance' in the sbit metric */
2782 /* structure isn't set, use `linearXXXAdvance' */
2783 if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
2784 glyph->metrics.horiAdvance =
2785 FT_MulFix( glyph->linearHoriAdvance,
2786 size->metrics->x_scale );
2787 if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
2788 glyph->metrics.vertAdvance =
2789 FT_MulFix( glyph->linearVertAdvance,
2790 size->metrics->y_scale );
2791 }
2792
2793 return FT_Err_Ok;
2794 }
2795 }
2796
2797#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2798
2799 /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
2800 if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
2801 {
2802 error = FT_THROW( Invalid_Size_Handle );
2803 goto Exit;
2804 }
2805
2806 if ( load_flags & FT_LOAD_SBITS_ONLY )
2807 {
2808 error = FT_THROW( Invalid_Argument );
2809 goto Exit;
2810 }
2811
2812 error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
2813 if ( error )
2814 goto Exit;
2815
2816 glyph->format = FT_GLYPH_FORMAT_OUTLINE;
2817 glyph->num_subglyphs = 0;
2818 glyph->outline.flags = 0;
2819
2820 /* main loading loop */
2821 error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
2822 if ( !error )
2823 {
2824 if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
2825 {
2826 glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
2827 glyph->subglyphs = loader.gloader->base.subglyphs;
2828 }
2829 else
2830 {
2831 glyph->outline = loader.gloader->base.outline;
2832 glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
2833
2834 /* Translate array so that (0,0) is the glyph's origin. Note */
2835 /* that this behaviour is independent on the value of bit 1 of */
2836 /* the `flags' field in the `head' table -- at least major */
2837 /* applications like Acroread indicate that. */
2838 if ( loader.pp1.x )
2839 FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
2840 }
2841
2842#ifdef TT_USE_BYTECODE_INTERPRETER
2843
2844 if ( IS_HINTED( load_flags ) )
2845 {
2846 if ( loader.exec->GS.scan_control )
2847 {
2848 /* convert scan conversion mode to FT_OUTLINE_XXX flags */
2849 switch ( loader.exec->GS.scan_type )
2850 {
2851 case 0: /* simple drop-outs including stubs */
2852 glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
2853 break;
2854 case 1: /* simple drop-outs excluding stubs */
2855 /* nothing; it's the default rendering mode */
2856 break;
2857 case 4: /* smart drop-outs including stubs */
2858 glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
2860 break;
2861 case 5: /* smart drop-outs excluding stubs */
2862 glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
2863 break;
2864
2865 default: /* no drop-out control */
2866 glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
2867 break;
2868 }
2869 }
2870 else
2871 glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
2872 }
2873
2874#endif /* TT_USE_BYTECODE_INTERPRETER */
2875
2876 error = compute_glyph_metrics( &loader, glyph_index );
2877 }
2878
2879 tt_loader_done( &loader );
2880
2881 /* Set the `high precision' bit flag. */
2882 /* This is _critical_ to get correct output for monochrome */
2883 /* TrueType glyphs at all sizes using the bytecode interpreter. */
2884 /* */
2885 if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
2886 size->metrics->y_ppem < 24 )
2887 glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
2888
2889 Exit:
2890#ifdef FT_DEBUG_LEVEL_TRACE
2891 if ( error )
2892 FT_TRACE1(( " failed (error code 0x%x)\n",
2893 error ));
2894#endif
2895
2896 return error;
2897 }
2898
2899
2900/* END */
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
Arabic default style
Definition: afstyles.h:94
r l[0]
Definition: byte_order.h:168
Definition: list.h:37
#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
Definition: ftoption.h:887
#define TT_USE_BYTECODE_INTERPRETER
Definition: ftoption.h:879
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
WORD face[3]
Definition: mesh.c:4747
unsigned int idx
Definition: utils.c:41
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
int Fail
Definition: ehthrow.cxx:24
#define FT_LOAD_VERTICAL_LAYOUT
Definition: freetype.h:3013
#define FT_LOAD_TARGET_LCD_V
Definition: freetype.h:3124
#define FT_LOAD_TARGET_MODE(x)
Definition: freetype.h:3137
#define FT_LOAD_SBITS_ONLY
Definition: freetype.h:3032
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3012
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3009
#define FT_LOAD_NO_RECURSE
Definition: freetype.h:3018
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3010
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1312
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:554
#define FT_IS_VARIATION(face)
Definition: freetype.h:1442
#define FT_LOAD_COMPUTE_METRICS
Definition: freetype.h:3025
#define FT_IS_NAMED_INSTANCE(face)
Definition: freetype.h:1424
#define FT_LOAD_TARGET_LCD
Definition: freetype.h:3123
@ FT_RENDER_MODE_MONO
Definition: freetype.h:3236
#define FT_IS_TRICKY(face)
Definition: freetype.h:1474
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
#define FT_LOAD_PEDANTIC
Definition: freetype.h:3016
FT_Vector * vec
Definition: ftbbox.c:448
return FT_Err_Ok
Definition: ftbbox.c:511
FT_BBox bbox
Definition: ftbbox.c:446
#define SUB_LONG(a, b)
Definition: ftcalc.h:422
FT_Hypot(FT_Fixed x, FT_Fixed y)
Definition: ftcalc.c:155
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:533
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
signed short FT_Int16
Definition: ftconfig.h:170
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
#define FT_UINT_TO_POINTER(x)
Definition: ftconfig.h:341
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
#define FT_TRACE7(varformat)
Definition: ftdebug.h:164
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
#define TT_INTERPRETER_VERSION_38
Definition: ftdriver.h:748
#define TT_INTERPRETER_VERSION_40
Definition: ftdriver.h:749
#define TT_INTERPRETER_VERSION_35
Definition: ftdriver.h:747
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:328
FT_GlyphLoader_Rewind(FT_GlyphLoader loader)
Definition: ftgloadr.c:88
#define FT_GLYPHLOADER_CHECK_POINTS(_loader, _points, _contours)
Definition: ftgloadr.h:118
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:281
#define FT_CURVE_TAG_TOUCH_BOTH
Definition: ftimage.h:462
#define FT_OUTLINE_SMART_DROPOUTS
Definition: ftimage.h:432
#define FT_CURVE_TAG_HAS_SCANMODE
Definition: ftimage.h:457
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:183
#define FT_OUTLINE_IGNORE_DROPOUTS
Definition: ftimage.h:431
#define FT_OUTLINE_INCLUDE_STUBS
Definition: ftimage.h:433
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
#define FT_OUTLINE_HIGH_PRECISION
Definition: ftimage.h:435
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
FT_List_Finalize(FT_List list, FT_List_Destructor destroy, FT_Memory memory, void *user)
Definition: ftutil.c:413
FT_BEGIN_HEADER FT_List_Find(FT_List list, void *data)
Definition: ftutil.c:244
FT_List_Add(FT_List list, FT_ListNode node)
Definition: ftutil.c:269
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:244
#define FT_ZERO(p)
Definition: ftmemory.h:237
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
#define FT_FACE(x)
Definition: ftobjs.h:630
#define FT_ABS(a)
Definition: ftobjs.h:74
#define FT_FACE_DRIVER(x)
Definition: ftobjs.h:634
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:93
FT_Outline_EmboldenXY(FT_Outline *outline, FT_Pos xstrength, FT_Pos ystrength)
Definition: ftoutln.c:909
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:426
#define FT_ULONG_MAX
Definition: ftstdlib.h:68
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_STREAM_POS()
Definition: ftstream.h:486
#define FT_NEXT_CHAR(buffer)
Definition: ftstream.h:217
#define FT_FRAME_EXIT()
Definition: ftstream.h:517
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:591
signed long FT_Fixed
Definition: fttypes.h:288
int FT_Error
Definition: fttypes.h:300
signed long FT_Long
Definition: fttypes.h:242
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:578
signed int FT_Int
Definition: fttypes.h:220
FxCollectionEntry * cur
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint limit
Definition: glext.h:10326
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei const GLfloat * points
Definition: glext.h:8112
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define d
Definition: ke_i.h:81
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
struct task_struct * current
Definition: linux.c:32
#define for
Definition: utility.h:88
const char * tags[7 *8]
Definition: apphelp.c:216
static char memory[1024 *256]
Definition: process.c:116
DWORD zone
Definition: sec_mgr.c:1754
int k
Definition: mpi.c:3369
int load
Definition: msacm.c:1365
struct @1665::@1666 driver
int xx
Definition: npserver.c:29
SFNT_Interface * SFNT_Service
Definition: sfnt.h:628
static void Exit(void)
Definition: sock.c:1330
FT_Pos xMin
Definition: ftimage.h:117
FT_Pos yMax
Definition: ftimage.h:118
FT_Pos yMin
Definition: ftimage.h:117
FT_Pos xMax
Definition: ftimage.h:118
const FT_Byte * pointer
Definition: fttypes.h:408
FT_Int length
Definition: fttypes.h:409
FT_Memory memory
Definition: freetype.h:1112
FT_SubGlyph subglyphs
Definition: ftgloadr.h:56
FT_UInt num_subglyphs
Definition: ftgloadr.h:55
FT_Outline outline
Definition: ftgloadr.h:52
FT_GlyphLoadRec current
Definition: ftgloadr.h:70
FT_GlyphLoadRec base
Definition: ftgloadr.h:69
FT_Int bitmap_top
Definition: freetype.h:1925
void * control_data
Definition: freetype.h:1932
FT_Int bitmap_left
Definition: freetype.h:1924
FT_Bitmap bitmap
Definition: freetype.h:1923
FT_Outline outline
Definition: freetype.h:1927
FT_Slot_Internal internal
Definition: freetype.h:1940
FT_Fixed linearHoriAdvance
Definition: freetype.h:1917
FT_Fixed linearVertAdvance
Definition: freetype.h:1918
FT_Glyph_Metrics metrics
Definition: freetype.h:1916
FT_Glyph_Format format
Definition: freetype.h:1921
FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics
Definition: ftincrem.h:274
const FT_Incremental_FuncsRec * funcs
Definition: ftincrem.h:317
FT_ListNode next
Definition: fttypes.h:547
void * data
Definition: fttypes.h:548
FT_ListNode head
Definition: fttypes.h:569
FT_ListNode tail
Definition: fttypes.h:570
FT_Fixed xx
Definition: fttypes.h:387
FT_Fixed yx
Definition: fttypes.h:388
FT_Fixed yy
Definition: fttypes.h:388
FT_Fixed xy
Definition: fttypes.h:387
short n_contours
Definition: ftimage.h:336
int flags
Definition: ftimage.h:343
short * contours
Definition: ftimage.h:341
FT_Vector * points
Definition: ftimage.h:339
short n_points
Definition: ftimage.h:337
char * tags
Definition: ftimage.h:340
FT_Fixed y_scale
Definition: freetype.h:1644
FT_Fixed x_scale
Definition: freetype.h:1643
FT_UShort x_ppem
Definition: freetype.h:1640
FT_GlyphLoader loader
Definition: ftobjs.h:467
FT_Int arg2
Definition: ftgloadr.h:44
FT_UShort flags
Definition: ftgloadr.h:42
FT_Matrix transform
Definition: ftgloadr.h:45
FT_Int index
Definition: ftgloadr.h:41
FT_Int arg1
Definition: ftgloadr.h:43
FT_Pos x
Definition: ftimage.h:76
FT_Pos y
Definition: ftimage.h:77
TT_Load_SBit_Image_Func load_sbit_image
Definition: sfnt.h:595
FT_Memory memory
Definition: ttinterp.h:153
TT_GlyphZoneRec pts
Definition: ttinterp.h:170
FT_Bool is_composite
Definition: ttinterp.h:229
FT_Bool pedantic_hinting
Definition: ttinterp.h:230
TT_GraphicsState GS
Definition: ttinterp.h:177
FT_UInt glyphSize
Definition: ttinterp.h:192
FT_Bool grayscale
Definition: ttinterp.h:251
FT_Size_Metrics metrics
Definition: ttinterp.h:174
FT_Byte * glyphIns
Definition: ttinterp.h:193
TT_MaxProfile max_profile
Definition: tttypes.h:1404
FT_FaceRec root
Definition: tttypes.h:1393
FT_UShort n_points
Definition: tttypes.h:1604
FT_Vector * orus
Definition: tttypes.h:1609
FT_Vector * cur
Definition: tttypes.h:1608
FT_Byte * tags
Definition: tttypes.h:1611
FT_Byte instruct_control
Definition: ttobjs.h:86
FT_Bool scan_control
Definition: ttobjs.h:91
FT_Int scan_type
Definition: ttobjs.h:92
FT_Int top_bearing
Definition: tttypes.h:1669
FT_Vector pp4
Definition: tttypes.h:1672
FT_ULong load_flags
Definition: tttypes.h:1642
TT_ExecContext exec
Definition: tttypes.h:1661
TT_Size size
Definition: tttypes.h:1638
FT_Vector pp3
Definition: tttypes.h:1671
FT_Int byte_len
Definition: tttypes.h:1646
FT_UInt glyph_index
Definition: tttypes.h:1643
FT_ULong ins_pos
Definition: tttypes.h:1663
FT_GlyphLoader gloader
Definition: tttypes.h:1640
FT_Int advance
Definition: tttypes.h:1651
FT_ListRec composites
Definition: tttypes.h:1679
FT_GlyphSlot glyph
Definition: tttypes.h:1639
FT_Short n_contours
Definition: tttypes.h:1648
FT_Vector pp2
Definition: tttypes.h:1655
FT_Bool linear_def
Definition: tttypes.h:1653
FT_Vector pp1
Definition: tttypes.h:1654
TT_GlyphZoneRec zone
Definition: tttypes.h:1659
FT_Byte * instructions
Definition: tttypes.h:1662
FT_Stream stream
Definition: tttypes.h:1645
TT_Face face
Definition: tttypes.h:1637
FT_BBox bbox
Definition: tttypes.h:1649
FT_Int linear
Definition: tttypes.h:1652
FT_Int left_bearing
Definition: tttypes.h:1650
FT_Int vadvance
Definition: tttypes.h:1670
FT_UShort maxSizeOfInstructions
Definition: tttables.h:581
FT_Short vertBearingY
Definition: tttypes.h:469
FT_Short horiBearingX
Definition: tttypes.h:464
FT_UShort horiAdvance
Definition: tttypes.h:466
FT_Short horiBearingY
Definition: tttypes.h:465
FT_Short vertBearingX
Definition: tttypes.h:468
FT_UShort height
Definition: tttypes.h:461
FT_UShort width
Definition: tttypes.h:462
FT_UShort vertAdvance
Definition: tttypes.h:470
FT_Size_Metrics * metrics
Definition: ttobjs.h:281
Definition: mesh.c:5330
Definition: parse.h:23
SFNT_Service sfnt
Definition: ttdriver.c:206
#define WE_HAVE_INSTR
Definition: ttgload.c:63
static FT_Error TT_Process_Composite_Glyph(TT_Loader loader, FT_UInt start_point, FT_UInt start_contour)
Definition: ttgload.c:1253
TT_Access_Glyph_Frame(TT_Loader loader, FT_UInt glyph_index, FT_ULong offset, FT_UInt byte_count)
Definition: ttgload.c:262
static void tt_loader_done(TT_Loader loader)
Definition: ttgload.c:2650
TT_Load_Glyph(TT_Size size, TT_GlyphSlot glyph, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ttgload.c:2687
static void tt_prepare_zone(TT_GlyphZone zone, FT_GlyphLoad load, FT_UInt start_point, FT_UInt start_contour)
Definition: ttgload.c:753
static FT_Error load_truetype_glyph(TT_Loader loader, FT_UInt glyph_index, FT_UInt recurse_count, FT_Bool header_only)
Definition: ttgload.c:1510
static FT_Error tt_get_metrics(TT_Loader loader, FT_UInt glyph_index)
Definition: ttgload.c:122
TT_Load_Simple_Glyph(TT_Loader load)
Definition: ttgload.c:326
#define WE_HAVE_A_2X2
Definition: ttgload.c:62
#define WE_HAVE_A_SCALE
Definition: ttgload.c:58
TT_Init_Glyph_Loading(TT_Face face)
Definition: ttgload.c:742
static void tt_loader_set_pp(TT_Loader loader)
Definition: ttgload.c:1433
#define MORE_COMPONENTS
Definition: ttgload.c:60
#define USE_MY_METRICS
Definition: ttgload.c:64
static FT_Error TT_Process_Simple_Glyph(TT_Loader loader)
Definition: ttgload.c:910
TT_Load_Glyph_Header(TT_Loader loader)
Definition: ttgload.c:298
static FT_Error tt_loader_init(TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, FT_Int32 load_flags, FT_Bool glyf_table_only)
Definition: ttgload.c:2352
#define UNSCALED_COMPONENT_OFFSET
Definition: ttgload.c:67
static FT_Error TT_Process_Composite_Component(TT_Loader loader, FT_SubGlyph subglyph, FT_UInt start_point, FT_UInt num_base_points)
Definition: ttgload.c:1084
#define IS_DEFAULT_INSTANCE
static FT_ListNode ft_list_get_node_at(FT_List list, FT_UInt idx)
Definition: ttgload.c:1479
TT_Get_HMetrics(TT_Face face, FT_UInt idx, FT_Short *lsb, FT_UShort *aw)
Definition: ttgload.c:75
#define ARGS_ARE_XY_VALUES
Definition: ttgload.c:56
#define ARGS_ARE_WORDS
Definition: ttgload.c:55
static FT_Error compute_glyph_metrics(TT_Loader loader, FT_UInt glyph_index)
Definition: ttgload.c:2105
#define WE_HAVE_AN_XY_SCALE
Definition: ttgload.c:61
TT_Forget_Glyph_Frame(TT_Loader loader)
Definition: ttgload.c:288
#define ROUND_XY_TO_GRID
Definition: ttgload.c:57
TT_Get_VMetrics(TT_Face face, FT_UInt idx, FT_Pos yMax, FT_Short *tsb, FT_UShort *ah)
Definition: ttgload.c:93
static FT_Error TT_Hint_Glyph(TT_Loader loader, FT_Bool is_composite)
Definition: ttgload.c:781
#define SCALED_COMPONENT_OFFSET
Definition: ttgload.c:66
TT_Load_Composite_Glyph(TT_Loader loader)
Definition: ttgload.c:559
const TT_GraphicsState tt_default_graphics_state
#define IS_HINTED(flags)
Definition: ttobjs.h:417
typedefFT_BEGIN_HEADER struct TT_DriverRec_ * TT_Driver
Definition: ttobjs.h:39
@ tt_coderange_glyph
Definition: ttobjs.h:140
tt_face_get_device_metrics(TT_Face face, FT_UInt ppem, FT_UInt gindex)
Definition: ttpload.c:619
tt_face_get_location(TT_Face face, FT_UInt gindex, FT_UInt *asize)
Definition: ttpload.c:195
#define TT_FACE_FLAG_VAR_HADVANCE
Definition: tttypes.h:1113
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:973
#define TT_FACE_FLAG_VAR_VADVANCE
Definition: tttypes.h:1118
Definition: dlist.c:348
GLvoid * data
Definition: dlist.c:359
int pedantic
Definition: widl.c:113
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList