4 * Copyright (C) 2011-2012 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
16 /* originally file `afglobal.c' (2011-Mar-28) from FreeType */
18 /* heavily modified 2011 by Werner Lemberg <wl@gnu.org> */
31 #ifdef FT_OPTION_AUTOFIT2
36 /* populate this list when you add new scripts */
37 static TA_ScriptClass
const ta_script_classes
[] =
39 &ta_dummy_script_class
,
40 #ifdef FT_OPTION_AUTOFIT2
41 &ta_latin2_script_class
,
43 &ta_latin_script_class
,
46 &ta_indic_script_class
,
48 NULL
/* do not remove */
52 /* Compute the script index of each glyph within a given face. */
55 ta_face_globals_compute_script_coverage(TA_FaceGlobals globals
)
57 FT_Error error
= FT_Err_Ok
;
58 FT_Face face
= globals
->face
;
59 FT_CharMap old_charmap
= face
->charmap
;
60 FT_Byte
* gscripts
= globals
->glyph_scripts
;
65 /* the value TA_SCRIPT_NONE means `uncovered glyph' */
66 memset(globals
->glyph_scripts
, TA_SCRIPT_NONE
, globals
->glyph_count
);
68 error
= FT_Select_Charmap(face
, FT_ENCODING_UNICODE
);
71 /* ignore this error; we simply use the fallback script */
72 /* XXX: Shouldn't we rather disable hinting? */
77 /* scan each script in a Unicode charmap */
78 for (ss
= 0; ta_script_classes
[ss
]; ss
++)
80 TA_ScriptClass clazz
= ta_script_classes
[ss
];
81 TA_Script_UniRange range
;
84 if (clazz
->script_uni_ranges
== NULL
)
87 /* scan all Unicode points in the range and */
88 /* set the corresponding glyph script index */
89 for (range
= clazz
->script_uni_ranges
; range
->first
!= 0; range
++)
91 FT_ULong charcode
= range
->first
;
95 gindex
= FT_Get_Char_Index(face
, charcode
);
98 && gindex
< (FT_ULong
)globals
->glyph_count
99 && gscripts
[gindex
] == TA_SCRIPT_NONE
)
100 gscripts
[gindex
] = (FT_Byte
)ss
;
104 charcode
= FT_Get_Next_Char(face
, charcode
, &gindex
);
106 if (gindex
== 0 || charcode
> range
->last
)
109 if (gindex
< (FT_ULong
)globals
->glyph_count
110 && gscripts
[gindex
] == TA_SCRIPT_NONE
)
111 gscripts
[gindex
] = (FT_Byte
)ss
;
116 /* mark ASCII digits */
117 for (i
= 0x30; i
<= 0x39; i
++)
119 FT_UInt gindex
= FT_Get_Char_Index(face
, i
);
123 && gindex
< (FT_ULong
)globals
->glyph_count
)
124 gscripts
[gindex
] |= TA_DIGIT
;
128 /* by default, all uncovered glyphs are set to the fallback script */
129 /* XXX: Shouldn't we disable hinting or do something similar? */
130 if (globals
->font
->fallback_script
!= TA_SCRIPT_NONE
)
135 for (nn
= 0; nn
< globals
->glyph_count
; nn
++)
137 if ((gscripts
[nn
] & ~TA_DIGIT
) == TA_SCRIPT_NONE
)
139 gscripts
[nn
] &= ~TA_SCRIPT_NONE
;
140 gscripts
[nn
] |= globals
->font
->fallback_script
;
145 FT_Set_Charmap(face
, old_charmap
);
151 ta_face_globals_new(FT_Face face
,
152 TA_FaceGlobals
*aglobals
,
156 TA_FaceGlobals globals
;
159 globals
= (TA_FaceGlobals
)calloc(1, sizeof (TA_FaceGlobalsRec
) +
160 face
->num_glyphs
* sizeof (FT_Byte
));
163 error
= FT_Err_Out_Of_Memory
;
167 globals
->face
= face
;
168 globals
->glyph_count
= face
->num_glyphs
;
169 globals
->glyph_scripts
= (FT_Byte
*)(globals
+ 1);
170 globals
->font
= font
;
172 error
= ta_face_globals_compute_script_coverage(globals
);
175 ta_face_globals_free(globals
);
179 globals
->increase_x_height
= TA_PROP_INCREASE_X_HEIGHT_MAX
;
188 ta_face_globals_free(TA_FaceGlobals globals
)
195 for (nn
= 0; nn
< TA_SCRIPT_MAX
; nn
++)
197 if (globals
->metrics
[nn
])
199 TA_ScriptClass clazz
= ta_script_classes
[nn
];
203 FT_ASSERT(globals
->metrics
[nn
]->clazz
== clazz
);
206 if (clazz
->script_metrics_done
)
207 clazz
->script_metrics_done(globals
->metrics
[nn
]);
209 free(globals
->metrics
[nn
]);
210 globals
->metrics
[nn
] = NULL
;
214 globals
->glyph_count
= 0;
215 globals
->glyph_scripts
= NULL
; /* no need to free this one! */
216 globals
->face
= NULL
;
225 ta_face_globals_get_metrics(TA_FaceGlobals globals
,
228 TA_ScriptMetrics
*ametrics
)
230 TA_ScriptMetrics metrics
= NULL
;
232 TA_ScriptClass clazz
;
233 FT_UInt script
= options
& 15;
234 const FT_Offset script_max
= sizeof (ta_script_classes
)
235 / sizeof (ta_script_classes
[0]);
236 FT_Error error
= FT_Err_Ok
;
239 if (gindex
>= (FT_ULong
)globals
->glyph_count
)
241 error
= FT_Err_Invalid_Argument
;
247 || gidx
+ 1 >= script_max
)
248 gidx
= globals
->glyph_scripts
[gindex
] & TA_SCRIPT_NONE
;
250 clazz
= ta_script_classes
[gidx
];
252 script
= clazz
->script
;
254 metrics
= globals
->metrics
[clazz
->script
];
257 /* create the global metrics object if necessary */
258 metrics
= (TA_ScriptMetrics
)calloc(1, clazz
->script_metrics_size
);
261 error
= FT_Err_Out_Of_Memory
;
265 metrics
->clazz
= clazz
;
266 metrics
->globals
= globals
;
268 if (clazz
->script_metrics_init
)
270 error
= clazz
->script_metrics_init(metrics
, globals
->face
);
273 if (clazz
->script_metrics_done
)
274 clazz
->script_metrics_done(metrics
);
282 globals
->metrics
[clazz
->script
] = metrics
;
293 ta_face_globals_is_digit(TA_FaceGlobals globals
,
296 if (gindex
< (FT_ULong
)globals
->glyph_count
)
297 return (FT_Bool
)(globals
->glyph_scripts
[gindex
] & TA_DIGIT
);
302 /* end of taglobal.c */