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