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