ReactOS 0.4.16-dev-2358-g0df3463
afshaper.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * afshaper.c
4 *
5 * HarfBuzz interface for accessing OpenType features (body).
6 *
7 * Copyright (C) 2013-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 <freetype/freetype.h>
20#include <freetype/ftadvanc.h>
21#include "afglobal.h"
22#include "aftypes.h"
23#include "afshaper.h"
24
25#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
26
27
28 /**************************************************************************
29 *
30 * The macro FT_COMPONENT is used in trace mode. It is an implicit
31 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
32 * messages during execution.
33 */
34#undef FT_COMPONENT
35#define FT_COMPONENT afshaper
36
37
38 /*
39 * We use `sets' (in the HarfBuzz sense, which comes quite near to the
40 * usual mathematical meaning) to manage both lookups and glyph indices.
41 *
42 * 1. For each coverage, collect lookup IDs in a set. Note that an
43 * auto-hinter `coverage' is represented by one `feature', and a
44 * feature consists of an arbitrary number of (font specific) `lookup's
45 * that actually do the mapping job. Please check the OpenType
46 * specification for more details on features and lookups.
47 *
48 * 2. Create glyph ID sets from the corresponding lookup sets.
49 *
50 * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed
51 * with all lookups specific to the OpenType script activated. It
52 * relies on the order of AF_DEFINE_STYLE_CLASS entries so that
53 * special coverages (like `oldstyle figures') don't get overwritten.
54 *
55 */
56
57
58 /* load coverage tags */
59#undef COVERAGE
60#define COVERAGE( name, NAME, description, \
61 tag1, tag2, tag3, tag4 ) \
62 static const hb_tag_t name ## _coverage[] = \
63 { \
64 HB_TAG( tag1, tag2, tag3, tag4 ), \
65 HB_TAG_NONE \
66 };
67
68
69#include "afcover.h"
70
71
72 /* define mapping between coverage tags and AF_Coverage */
73#undef COVERAGE
74#define COVERAGE( name, NAME, description, \
75 tag1, tag2, tag3, tag4 ) \
76 name ## _coverage,
77
78
79 static const hb_tag_t* coverages[] =
80 {
81#include "afcover.h"
82
83 NULL /* AF_COVERAGE_DEFAULT */
84 };
85
86
87 /* load HarfBuzz script tags */
88#undef SCRIPT
89#define SCRIPT( s, S, d, h, H, ss ) h,
90
91
92 static const hb_script_t scripts[] =
93 {
94#include "afscript.h"
95 };
96
97
100 AF_StyleClass style_class,
101 FT_UShort* gstyles,
102 FT_Bool default_script )
103 {
104 hb_face_t* face;
105
106 hb_set_t* gsub_lookups = NULL; /* GSUB lookups for a given script */
107 hb_set_t* gsub_glyphs = NULL; /* glyphs covered by GSUB lookups */
108 hb_set_t* gpos_lookups = NULL; /* GPOS lookups for a given script */
109 hb_set_t* gpos_glyphs = NULL; /* glyphs covered by GPOS lookups */
110
111 hb_script_t script;
112 const hb_tag_t* coverage_tags;
113 hb_tag_t script_tags[] = { HB_TAG_NONE,
114 HB_TAG_NONE,
115 HB_TAG_NONE,
116 HB_TAG_NONE };
117
118 hb_codepoint_t idx;
119#ifdef FT_DEBUG_LEVEL_TRACE
120 int count;
121#endif
122
123
124 if ( !globals || !style_class || !gstyles )
125 return FT_THROW( Invalid_Argument );
126
127 face = hb_font_get_face( globals->hb_font );
128
129 coverage_tags = coverages[style_class->coverage];
130 script = scripts[style_class->script];
131
132 /* Convert a HarfBuzz script tag into the corresponding OpenType */
133 /* tag or tags -- some Indic scripts like Devanagari have an old */
134 /* and a new set of features. */
135 hb_ot_tags_from_script( script,
136 &script_tags[0],
137 &script_tags[1] );
138
139 /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */
140 /* as the second tag. We change that to HB_TAG_NONE except for the */
141 /* default script. */
142 if ( default_script )
143 {
144 if ( script_tags[0] == HB_TAG_NONE )
145 script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT;
146 else
147 {
148 if ( script_tags[1] == HB_TAG_NONE )
149 script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT;
150 else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT )
151 script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT;
152 }
153 }
154 else
155 {
156 /* we use non-standard tags like `khms' for special purposes; */
157 /* HarfBuzz maps them to `DFLT', which we don't want to handle here */
158 if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT )
159 goto Exit;
160
161 if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT )
162 script_tags[1] = HB_TAG_NONE;
163 }
164
165 gsub_lookups = hb_set_create();
166 hb_ot_layout_collect_lookups( face,
167 HB_OT_TAG_GSUB,
168 script_tags,
169 NULL,
170 coverage_tags,
171 gsub_lookups );
172
173 if ( hb_set_is_empty( gsub_lookups ) )
174 goto Exit; /* nothing to do */
175
176 FT_TRACE4(( "GSUB lookups (style `%s'):\n"
177 " ",
178 af_style_names[style_class->style] ));
179
180#ifdef FT_DEBUG_LEVEL_TRACE
181 count = 0;
182#endif
183
184 gsub_glyphs = hb_set_create();
185 for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); )
186 {
187#ifdef FT_DEBUG_LEVEL_TRACE
188 FT_TRACE4(( " %d", idx ));
189 count++;
190#endif
191
192 /* get output coverage of GSUB feature */
193 hb_ot_layout_lookup_collect_glyphs( face,
194 HB_OT_TAG_GSUB,
195 idx,
196 NULL,
197 NULL,
198 NULL,
199 gsub_glyphs );
200 }
201
202#ifdef FT_DEBUG_LEVEL_TRACE
203 if ( !count )
204 FT_TRACE4(( " (none)" ));
205 FT_TRACE4(( "\n\n" ));
206#endif
207
208 FT_TRACE4(( "GPOS lookups (style `%s'):\n"
209 " ",
210 af_style_names[style_class->style] ));
211
212 gpos_lookups = hb_set_create();
213 hb_ot_layout_collect_lookups( face,
214 HB_OT_TAG_GPOS,
215 script_tags,
216 NULL,
217 coverage_tags,
218 gpos_lookups );
219
220#ifdef FT_DEBUG_LEVEL_TRACE
221 count = 0;
222#endif
223
224 gpos_glyphs = hb_set_create();
225 for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); )
226 {
227#ifdef FT_DEBUG_LEVEL_TRACE
228 FT_TRACE4(( " %d", idx ));
229 count++;
230#endif
231
232 /* get input coverage of GPOS feature */
233 hb_ot_layout_lookup_collect_glyphs( face,
234 HB_OT_TAG_GPOS,
235 idx,
236 NULL,
237 gpos_glyphs,
238 NULL,
239 NULL );
240 }
241
242#ifdef FT_DEBUG_LEVEL_TRACE
243 if ( !count )
244 FT_TRACE4(( " (none)" ));
245 FT_TRACE4(( "\n\n" ));
246#endif
247
248 /*
249 * We now check whether we can construct blue zones, using glyphs
250 * covered by the feature only. In case there is not a single zone
251 * (this is, not a single character is covered), we skip this coverage.
252 *
253 */
254 if ( style_class->coverage != AF_COVERAGE_DEFAULT )
255 {
256 AF_Blue_Stringset bss = style_class->blue_stringset;
258
259 FT_Bool found = 0;
260
261
262 for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ )
263 {
264 const char* p = &af_blue_strings[bs->string];
265
266
267 while ( *p )
268 {
269 hb_codepoint_t ch;
270
271
272 GET_UTF8_CHAR( ch, p );
273
274 for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups,
275 &idx ); )
276 {
277 hb_codepoint_t gidx = FT_Get_Char_Index( globals->face, ch );
278
279
280 if ( hb_ot_layout_lookup_would_substitute( face, idx,
281 &gidx, 1, 1 ) )
282 {
283 found = 1;
284 break;
285 }
286 }
287 }
288 }
289
290 if ( !found )
291 {
292 FT_TRACE4(( " no blue characters found; style skipped\n" ));
293 goto Exit;
294 }
295 }
296
297 /*
298 * Various OpenType features might use the same glyphs at different
299 * vertical positions; for example, superscript and subscript glyphs
300 * could be the same. However, the auto-hinter is completely
301 * agnostic of OpenType features after the feature analysis has been
302 * completed: The engine then simply receives a glyph index and returns a
303 * hinted and usually rendered glyph.
304 *
305 * Consider the superscript feature of font `pala.ttf': Some of the
306 * glyphs are `real', this is, they have a zero vertical offset, but
307 * most of them are small caps glyphs shifted up to the superscript
308 * position (this is, the `sups' feature is present in both the GSUB and
309 * GPOS tables). The code for blue zones computation actually uses a
310 * feature's y offset so that the `real' glyphs get correct hints. But
311 * later on it is impossible to decide whether a glyph index belongs to,
312 * say, the small caps or superscript feature.
313 *
314 * For this reason, we don't assign a style to a glyph if the current
315 * feature covers the glyph in both the GSUB and the GPOS tables. This
316 * is quite a broad condition, assuming that
317 *
318 * (a) glyphs that get used in multiple features are present in a
319 * feature without vertical shift,
320 *
321 * and
322 *
323 * (b) a feature's GPOS data really moves the glyph vertically.
324 *
325 * Not fulfilling condition (a) makes a font larger; it would also
326 * reduce the number of glyphs that could be addressed directly without
327 * using OpenType features, so this assumption is rather strong.
328 *
329 * Condition (b) is much weaker, and there might be glyphs which get
330 * missed. However, the OpenType features we are going to handle are
331 * primarily located in GSUB, and HarfBuzz doesn't provide an API to
332 * directly get the necessary information from the GPOS table. A
333 * possible solution might be to directly parse the GPOS table to find
334 * out whether a glyph gets shifted vertically, but this is something I
335 * would like to avoid if not really necessary.
336 *
337 * Note that we don't follow this logic for the default coverage.
338 * Complex scripts like Devanagari have mandatory GPOS features to
339 * position many glyph elements, using mark-to-base or mark-to-ligature
340 * tables; the number of glyphs missed due to condition (b) would be far
341 * too large.
342 *
343 */
344 if ( style_class->coverage != AF_COVERAGE_DEFAULT )
345 hb_set_subtract( gsub_glyphs, gpos_glyphs );
346
347#ifdef FT_DEBUG_LEVEL_TRACE
348 FT_TRACE4(( " glyphs without GPOS data (`*' means already assigned)" ));
349 count = 0;
350#endif
351
352 for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_glyphs, &idx ); )
353 {
354#ifdef FT_DEBUG_LEVEL_TRACE
355 if ( !( count % 10 ) )
356 FT_TRACE4(( "\n"
357 " " ));
358
359 FT_TRACE4(( " %d", idx ));
360 count++;
361#endif
362
363 /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */
364 /* can be arbitrary: some fonts use fake indices for processing */
365 /* internal to GSUB or GPOS, which is fully valid */
366 if ( idx >= (hb_codepoint_t)globals->glyph_count )
367 continue;
368
369 if ( gstyles[idx] == AF_STYLE_UNASSIGNED )
370 gstyles[idx] = (FT_UShort)style_class->style;
371#ifdef FT_DEBUG_LEVEL_TRACE
372 else
373 FT_TRACE4(( "*" ));
374#endif
375 }
376
377#ifdef FT_DEBUG_LEVEL_TRACE
378 if ( !count )
379 FT_TRACE4(( "\n"
380 " (none)" ));
381 FT_TRACE4(( "\n\n" ));
382#endif
383
384 Exit:
385 hb_set_destroy( gsub_lookups );
386 hb_set_destroy( gsub_glyphs );
387 hb_set_destroy( gpos_lookups );
388 hb_set_destroy( gpos_glyphs );
389
390 return FT_Err_Ok;
391 }
392
393
394 /* construct HarfBuzz features */
395#undef COVERAGE
396#define COVERAGE( name, NAME, description, \
397 tag1, tag2, tag3, tag4 ) \
398 static const hb_feature_t name ## _feature[] = \
399 { \
400 { \
401 HB_TAG( tag1, tag2, tag3, tag4 ), \
402 1, 0, (unsigned int)-1 \
403 } \
404 };
405
406
407#include "afcover.h"
408
409
410 /* define mapping between HarfBuzz features and AF_Coverage */
411#undef COVERAGE
412#define COVERAGE( name, NAME, description, \
413 tag1, tag2, tag3, tag4 ) \
414 name ## _feature,
415
416
417 static const hb_feature_t* features[] =
418 {
419#include "afcover.h"
420
421 NULL /* AF_COVERAGE_DEFAULT */
422 };
423
424
425 void*
427 {
428 FT_UNUSED( face );
429
430 return (void*)hb_buffer_create();
431 }
432
433
434 void
436 void* buf )
437 {
438 FT_UNUSED( face );
439
440 hb_buffer_destroy( (hb_buffer_t*)buf );
441 }
442
443
444 const char*
445 af_shaper_get_cluster( const char* p,
447 void* buf_,
448 unsigned int* count )
449 {
450 AF_StyleClass style_class;
451 const hb_feature_t* feature;
452 FT_Int upem;
453 const char* q;
454 int len;
455
456 hb_buffer_t* buf = (hb_buffer_t*)buf_;
457 hb_font_t* font;
458 hb_codepoint_t dummy;
459
460
461 upem = (FT_Int)metrics->globals->face->units_per_EM;
462 style_class = metrics->style_class;
463 feature = features[style_class->coverage];
464
465 font = metrics->globals->hb_font;
466
467 /* we shape at a size of units per EM; this means font units */
468 hb_font_set_scale( font, upem, upem );
469
470 while ( *p == ' ' )
471 p++;
472
473 /* count bytes up to next space (or end of buffer) */
474 q = p;
475 while ( !( *q == ' ' || *q == '\0' ) )
477 len = (int)( q - p );
478
479 /* feed character(s) to the HarfBuzz buffer */
480 hb_buffer_clear_contents( buf );
481 hb_buffer_add_utf8( buf, p, len, 0, len );
482
483 /* we let HarfBuzz guess the script and writing direction */
484 hb_buffer_guess_segment_properties( buf );
485
486 /* shape buffer, which means conversion from character codes to */
487 /* glyph indices, possibly applying a feature */
488 hb_shape( font, buf, feature, feature ? 1 : 0 );
489
490 if ( feature )
491 {
492 hb_buffer_t* hb_buf = metrics->globals->hb_buf;
493
494 unsigned int gcount;
495 hb_glyph_info_t* ginfo;
496
497 unsigned int hb_gcount;
498 hb_glyph_info_t* hb_ginfo;
499
500
501 /* we have to check whether applying a feature does actually change */
502 /* glyph indices; otherwise the affected glyph or glyphs aren't */
503 /* available at all in the feature */
504
505 hb_buffer_clear_contents( hb_buf );
506 hb_buffer_add_utf8( hb_buf, p, len, 0, len );
507 hb_buffer_guess_segment_properties( hb_buf );
508 hb_shape( font, hb_buf, NULL, 0 );
509
510 ginfo = hb_buffer_get_glyph_infos( buf, &gcount );
511 hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount );
512
513 if ( gcount == hb_gcount )
514 {
515 unsigned int i;
516
517
518 for (i = 0; i < gcount; i++ )
519 if ( ginfo[i].codepoint != hb_ginfo[i].codepoint )
520 break;
521
522 if ( i == gcount )
523 {
524 /* both buffers have identical glyph indices */
525 hb_buffer_clear_contents( buf );
526 }
527 }
528 }
529
530 *count = hb_buffer_get_length( buf );
531
532#ifdef FT_DEBUG_LEVEL_TRACE
533 if ( feature && *count > 1 )
534 FT_TRACE1(( "af_shaper_get_cluster:"
535 " input character mapped to multiple glyphs\n" ));
536#endif
537
538 return q;
539 }
540
541
544 void* buf_,
545 unsigned int idx,
547 FT_Long* y_offset )
548 {
549 hb_buffer_t* buf = (hb_buffer_t*)buf_;
550 hb_glyph_info_t* ginfo;
551 hb_glyph_position_t* gpos;
552 unsigned int gcount;
553
555
556
557 ginfo = hb_buffer_get_glyph_infos( buf, &gcount );
558 gpos = hb_buffer_get_glyph_positions( buf, &gcount );
559
560 if ( idx >= gcount )
561 return 0;
562
563 if ( advance )
564 *advance = gpos[idx].x_advance;
565 if ( y_offset )
566 *y_offset = gpos[idx].y_offset;
567
568 return ginfo[idx].codepoint;
569 }
570
571
572#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
573
574
577 AF_StyleClass style_class,
578 FT_UShort* gstyles,
579 FT_Bool default_script )
580 {
581 FT_UNUSED( globals );
582 FT_UNUSED( style_class );
583 FT_UNUSED( gstyles );
584 FT_UNUSED( default_script );
585
586 return FT_Err_Ok;
587 }
588
589
590 void*
592 {
593 FT_UNUSED( face );
594
595 return NULL;
596 }
597
598
599 void
601 void* buf )
602 {
603 FT_UNUSED( face );
604 FT_UNUSED( buf );
605 }
606
607
608 const char*
611 void* buf_,
612 unsigned int* count )
613 {
614 FT_Face face = metrics->globals->face;
615 FT_ULong ch, dummy = 0;
616 FT_ULong* buf = (FT_ULong*)buf_;
617
618
619 while ( *p == ' ' )
620 p++;
621
622 GET_UTF8_CHAR( ch, p );
623
624 /* since we don't have an engine to handle clusters, */
625 /* we scan the characters but return zero */
626 while ( !( *p == ' ' || *p == '\0' ) )
628
629 if ( dummy )
630 {
631 *buf = 0;
632 *count = 0;
633 }
634 else
635 {
637 *count = 1;
638 }
639
640 return p;
641 }
642
643
646 void* buf_,
647 unsigned int idx,
649 FT_Long* y_offset )
650 {
651 FT_Face face = metrics->globals->face;
652 FT_ULong glyph_index = *(FT_ULong*)buf_;
653
654 FT_UNUSED( idx );
655
656
657 if ( advance )
659 glyph_index,
663 advance );
664
665 if ( y_offset )
666 *y_offset = 0;
667
668 return glyph_index;
669 }
670
671
672#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */
673
674
675/* END */
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
af_blue_stringsets[]
Definition: afblue.c:467
af_blue_strings[]
Definition: afblue.c:26
@ AF_BLUE_STRING_MAX
Definition: afblue.h:294
#define GET_UTF8_CHAR(ch, p)
Definition: afblue.h:31
enum AF_Blue_Stringset_ AF_Blue_Stringset
#define AF_STYLE_UNASSIGNED
Definition: afglobal.h:79
void * af_shaper_buf_create(FT_Face face)
Definition: afshaper.c:591
const char * af_shaper_get_cluster(const char *p, AF_StyleMetrics metrics, void *buf_, unsigned int *count)
Definition: afshaper.c:609
FT_ULong af_shaper_get_elem(AF_StyleMetrics metrics, void *buf_, unsigned int idx, FT_Long *advance, FT_Long *y_offset)
Definition: afshaper.c:645
FT_Error af_shaper_get_coverage(AF_FaceGlobals globals, AF_StyleClass style_class, FT_UShort *gstyles, FT_Bool default_script)
Definition: afshaper.c:576
void af_shaper_buf_destroy(FT_Face face, void *buf)
Definition: afshaper.c:600
@ AF_COVERAGE_DEFAULT
Definition: aftypes.h:413
#define NULL
Definition: types.h:112
WORD face[3]
Definition: mesh.c:4747
unsigned int idx
Definition: utils.c:41
unsigned char ch[4][2]
Definition: console.c:118
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define FT_LOAD_IGNORE_TRANSFORM
Definition: freetype.h:3032
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3022
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3023
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3731
FT_Get_Advance(FT_Face face, FT_UInt gindex, FT_Int32 load_flags, FT_Fixed *padvance)
Definition: ftadvanc.c:74
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE1(varformat)
Definition: ftdebug.h:188
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
int FT_Error
Definition: fttypes.h:299
signed long FT_Long
Definition: fttypes.h:242
unsigned short FT_UShort
Definition: fttypes.h:209
signed int FT_Int
Definition: fttypes.h:220
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539
INTERNETFEATURELIST feature
Definition: misc.c:1719
script
Definition: msipriv.h:383
Definition: mk_font.cpp:20
#define FT_UNUSED(arg)
static void Exit(void)
Definition: sock.c:1330
FT_Long glyph_count
Definition: afglobal.h:108
AF_Style style
Definition: aftypes.h:448
AF_Script script
Definition: aftypes.h:451
AF_Blue_Stringset blue_stringset
Definition: aftypes.h:452
AF_Coverage coverage
Definition: aftypes.h:453