blob: bcbd3b56c0d06c224d8544094006b100ded5edbd [file] [log] [blame]
David Turnerd2b1f351999-12-16 23:11:37 +00001/***************************************************************************/
2/* */
3/* ttobjs.c */
4/* */
5/* Objects manager (body). */
6/* */
Werner Lemberg18931a52011-02-01 07:08:43 +01007/* Copyright 1996-2011 */
David Turnerd2b1f351999-12-16 23:11:37 +00008/* David Turner, Robert Wilhelm, and Werner Lemberg. */
9/* */
Werner Lemberg78575dc2000-06-12 19:36:41 +000010/* This file is part of the FreeType project, and may only be used, */
11/* modified, and distributed under the terms of the FreeType project */
David Turnerd2b1f351999-12-16 23:11:37 +000012/* 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. */
Werner Lemberg328abf32003-12-24 13:37:58 +000015/* */
David Turnerd2b1f351999-12-16 23:11:37 +000016/***************************************************************************/
17
Werner Lembergcc069be2000-12-08 16:17:16 +000018
David Turner19ed8af2000-12-08 02:42:29 +000019#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
David Turner19ed8af2000-12-08 02:42:29 +000021#include FT_INTERNAL_STREAM_H
David Turner19ed8af2000-12-08 02:42:29 +000022#include FT_TRUETYPE_TAGS_H
23#include FT_INTERNAL_SFNT_H
David Turnerd2b1f351999-12-16 23:11:37 +000024
David Turner8d3a4012001-03-20 11:14:24 +000025#include "ttgload.h"
26#include "ttpload.h"
Werner Lemberg7fa51b52000-07-08 19:51:42 +000027
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000028#include "tterrors.h"
29
David Turner6aa260c2006-08-25 22:45:13 +000030#ifdef TT_USE_BYTECODE_INTERPRETER
David Turner8d3a4012001-03-20 11:14:24 +000031#include "ttinterp.h"
David Turnera90663f2000-07-08 00:41:13 +000032#endif
33
David Turner8b6db862003-08-17 22:09:14 +000034#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING
Graham Asher3ea859f2003-04-25 11:40:46 +000035#include FT_TRUETYPE_UNPATENTED_H
36#endif
Werner Lemberg78575dc2000-06-12 19:36:41 +000037
Werner Lemberg44bb3032004-04-25 20:15:11 +000038#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
39#include "ttgxvar.h"
40#endif
41
Werner Lemberg78575dc2000-06-12 19:36:41 +000042 /*************************************************************************/
43 /* */
44 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
45 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
46 /* messages during execution. */
47 /* */
Werner Lemberg5811c7c2000-07-02 13:53:16 +000048#undef FT_COMPONENT
49#define FT_COMPONENT trace_ttobjs
David Turnerd2b1f351999-12-16 23:11:37 +000050
51
David Turner6aa260c2006-08-25 22:45:13 +000052#ifdef TT_USE_BYTECODE_INTERPRETER
Werner Lemberg321cd272000-07-27 11:20:20 +000053
David Turnerd2b1f351999-12-16 23:11:37 +000054 /*************************************************************************/
55 /* */
56 /* GLYPH ZONE FUNCTIONS */
57 /* */
58 /*************************************************************************/
59
Werner Lemberg321cd272000-07-27 11:20:20 +000060
David Turnerf9b8dec2000-06-16 19:34:52 +000061 /*************************************************************************/
62 /* */
63 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +000064 /* tt_glyphzone_done */
David Turnerf9b8dec2000-06-16 19:34:52 +000065 /* */
66 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +000067 /* Deallocate a glyph zone. */
David Turnerf9b8dec2000-06-16 19:34:52 +000068 /* */
69 /* <Input> */
70 /* zone :: A pointer to the target glyph zone. */
71 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +000072 FT_LOCAL_DEF( void )
David Turnerb08fe2d2002-08-27 20:20:29 +000073 tt_glyphzone_done( TT_GlyphZone zone )
David Turnerf9b8dec2000-06-16 19:34:52 +000074 {
75 FT_Memory memory = zone->memory;
76
Werner Lembergb442ca12003-04-23 15:50:27 +000077
David Turnerb2805372003-03-13 21:07:51 +000078 if ( memory )
79 {
80 FT_FREE( zone->contours );
81 FT_FREE( zone->tags );
82 FT_FREE( zone->cur );
83 FT_FREE( zone->org );
David Turner33f5f242006-08-16 16:50:55 +000084 FT_FREE( zone->orus );
Werner Lemberg5811c7c2000-07-02 13:53:16 +000085
David Turnerb2805372003-03-13 21:07:51 +000086 zone->max_points = zone->n_points = 0;
87 zone->max_contours = zone->n_contours = 0;
88 zone->memory = NULL;
89 }
David Turnerf9b8dec2000-06-16 19:34:52 +000090 }
91
92
93 /*************************************************************************/
94 /* */
95 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +000096 /* tt_glyphzone_new */
David Turnerf9b8dec2000-06-16 19:34:52 +000097 /* */
98 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +000099 /* Allocate a new glyph zone. */
David Turnerf9b8dec2000-06-16 19:34:52 +0000100 /* */
101 /* <Input> */
102 /* memory :: A handle to the current memory object. */
103 /* */
104 /* maxPoints :: The capacity of glyph zone in points. */
105 /* */
106 /* maxContours :: The capacity of glyph zone in contours. */
107 /* */
108 /* <Output> */
109 /* zone :: A pointer to the target glyph zone record. */
110 /* */
111 /* <Return> */
112 /* FreeType error code. 0 means success. */
113 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000114 FT_LOCAL_DEF( FT_Error )
David Turnerb08fe2d2002-08-27 20:20:29 +0000115 tt_glyphzone_new( FT_Memory memory,
Werner Lemberg91db04c2002-04-01 14:25:28 +0000116 FT_UShort maxPoints,
117 FT_Short maxContours,
118 TT_GlyphZone zone )
David Turnerf9b8dec2000-06-16 19:34:52 +0000119 {
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000120 FT_Error error;
121
David Turnerf9b8dec2000-06-16 19:34:52 +0000122
Werner Lembergb3d5e9c2002-07-28 05:05:24 +0000123 FT_MEM_ZERO( zone, sizeof ( *zone ) );
David Turnerf9b8dec2000-06-16 19:34:52 +0000124 zone->memory = memory;
125
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000126 if ( FT_NEW_ARRAY( zone->org, maxPoints ) ||
127 FT_NEW_ARRAY( zone->cur, maxPoints ) ||
David Turner33f5f242006-08-16 16:50:55 +0000128 FT_NEW_ARRAY( zone->orus, maxPoints ) ||
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000129 FT_NEW_ARRAY( zone->tags, maxPoints ) ||
130 FT_NEW_ARRAY( zone->contours, maxContours ) )
David Turnerf9b8dec2000-06-16 19:34:52 +0000131 {
David Turnerb08fe2d2002-08-27 20:20:29 +0000132 tt_glyphzone_done( zone );
David Turnerf9b8dec2000-06-16 19:34:52 +0000133 }
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000134 else
135 {
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +0000136 zone->max_points = maxPoints;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000137 zone->max_contours = maxContours;
138 }
David Turnerf9b8dec2000-06-16 19:34:52 +0000139
140 return error;
141 }
David Turner6aa260c2006-08-25 22:45:13 +0000142#endif /* TT_USE_BYTECODE_INTERPRETER */
Werner Lemberg321cd272000-07-27 11:20:20 +0000143
David Turnerf9b8dec2000-06-16 19:34:52 +0000144
Werner Lembergb972a2a2008-12-11 08:55:48 +0000145 /* Compare the face with a list of well-known `tricky' fonts. */
146 /* This list shall be expanded as we find more of them. */
147
148 static FT_Bool
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900149 tt_check_trickyness_family( FT_String* name )
Werner Lembergb972a2a2008-12-11 08:55:48 +0000150 {
Werner Lemberg9871b842010-11-22 19:30:41 +0100151
Oran Agra2e7a4e92009-04-05 18:03:02 +0300152#define TRICK_NAMES_MAX_CHARACTERS 16
Werner Lemberg9871b842010-11-22 19:30:41 +0100153#define TRICK_NAMES_COUNT 8
154
155 static const char trick_names[TRICK_NAMES_COUNT]
156 [TRICK_NAMES_MAX_CHARACTERS + 1] =
Werner Lembergb972a2a2008-12-11 08:55:48 +0000157 {
158 "DFKaiSho-SB", /* dfkaisb.ttf */
Werner Lemberg0552a492009-02-11 22:59:40 +0000159 "DFKaiShu",
Werner Lembergb972a2a2008-12-11 08:55:48 +0000160 "DFKai-SB", /* kaiu.ttf */
suzuki toshiya8b05b5d2010-08-28 21:16:26 +0900161 "HuaTianKaiTi?", /* htkt2.ttf */
Werner Lembergb972a2a2008-12-11 08:55:48 +0000162 "HuaTianSongTi?", /* htst3.ttf */
163 "MingLiU", /* mingliu.ttf & mingliu.ttc */
164 "PMingLiU", /* mingliu.ttc */
165 "MingLi43", /* mingli.ttf */
Werner Lembergb972a2a2008-12-11 08:55:48 +0000166 };
Werner Lemberg9871b842010-11-22 19:30:41 +0100167
Werner Lembergb972a2a2008-12-11 08:55:48 +0000168 int nn;
Werner Lemberg9871b842010-11-22 19:30:41 +0100169
170
Oran Agra2e7a4e92009-04-05 18:03:02 +0300171 for ( nn = 0; nn < TRICK_NAMES_COUNT; nn++ )
Werner Lembergb972a2a2008-12-11 08:55:48 +0000172 if ( ft_strstr( name, trick_names[nn] ) )
173 return TRUE;
174
175 return FALSE;
176 }
177
178
Werner Lemberg9871b842010-11-22 19:30:41 +0100179 /* XXX: This function should be in the `sfnt' module. */
180
181 /* Some PDF generators clear the checksums in the TrueType header table. */
182 /* For example, Quartz ContextPDF clears all entries, or Bullzip PDF */
183 /* Printer clears the entries for subsetted subtables. We thus have to */
184 /* recalculate the checksums where necessary. */
185
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900186 static FT_UInt32
187 tt_synth_sfnt_checksum( FT_Stream stream,
188 FT_ULong length )
189 {
190 FT_Error error;
191 FT_UInt32 checksum = 0;
192 int i;
193
194
195 if ( FT_FRAME_ENTER( length ) )
196 return 0;
197
198 for ( ; length > 3; length -= 4 )
199 checksum += (FT_UInt32)FT_GET_ULONG();
200
201 for ( i = 3; length > 0; length --, i-- )
202 checksum += (FT_UInt32)( FT_GET_BYTE() << ( i * 8 ) );
203
204 FT_FRAME_EXIT();
205
206 return checksum;
207 }
208
209
Werner Lemberg9871b842010-11-22 19:30:41 +0100210 /* XXX: This function should be in the `sfnt' module. */
211
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900212 static FT_ULong
213 tt_get_sfnt_checksum( TT_Face face,
214 FT_UShort i )
215 {
suzuki toshiya58cb3592011-05-01 00:47:43 +0900216#if 0 /* if we believe the written value, use following part. */
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900217 if ( face->dir_tables[i].CheckSum )
218 return face->dir_tables[i].CheckSum;
suzuki toshiya58cb3592011-05-01 00:47:43 +0900219#endif
Werner Lemberg9871b842010-11-22 19:30:41 +0100220
suzuki toshiya10385e32011-04-30 17:49:45 +0900221 if ( !face->goto_table )
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900222 return 0;
Werner Lemberg9871b842010-11-22 19:30:41 +0100223
suzuki toshiya10385e32011-04-30 17:49:45 +0900224 if ( face->goto_table( face,
225 face->dir_tables[i].Tag,
226 face->root.stream,
227 NULL ) )
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900228 return 0;
229
230 return (FT_ULong)tt_synth_sfnt_checksum( face->root.stream,
Werner Lemberg9871b842010-11-22 19:30:41 +0100231 face->dir_tables[i].Length );
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900232 }
233
234
235 typedef struct tt_sfnt_id_rec_
236 {
237 FT_ULong CheckSum;
238 FT_ULong Length;
Werner Lemberg9871b842010-11-22 19:30:41 +0100239
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900240 } tt_sfnt_id_rec;
241
242
243 static FT_Bool
244 tt_check_trickyness_sfnt_ids( TT_Face face )
245 {
Werner Lemberg9871b842010-11-22 19:30:41 +0100246#define TRICK_SFNT_IDS_PER_FACE 3
suzuki toshiya1e89d152011-04-30 17:55:57 +0900247#define TRICK_SFNT_IDS_NUM_FACES 13
Werner Lemberg9871b842010-11-22 19:30:41 +0100248
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900249 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
250 [TRICK_SFNT_IDS_PER_FACE] = {
Werner Lemberg9871b842010-11-22 19:30:41 +0100251
252#define TRICK_SFNT_ID_cvt 0
253#define TRICK_SFNT_ID_fpgm 1
254#define TRICK_SFNT_ID_prep 2
255
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900256 { /* MingLiU 1995 */
257 { 0x05bcf058, 0x000002e4 }, /* cvt */
258 { 0x28233bf1, 0x000087c4 }, /* fpgm */
259 { 0xa344a1ea, 0x000001e1 } /* prep */
260 },
261 { /* MingLiU 1996- */
262 { 0x05bcf058, 0x000002e4 }, /* cvt */
263 { 0x28233bf1, 0x000087c4 }, /* fpgm */
264 { 0xa344a1eb, 0x000001e1 } /* prep */
265 },
266 { /* DFKaiShu */
267 { 0x11e5ead4, 0x00000350 }, /* cvt */
268 { 0x5a30ca3b, 0x00009063 }, /* fpgm */
269 { 0x13a42602, 0x0000007e } /* prep */
270 },
271 { /* HuaTianKaiTi */
272 { 0xfffbfffc, 0x00000008 }, /* cvt */
273 { 0x9c9e48b8, 0x0000bea2 }, /* fpgm */
274 { 0x70020112, 0x00000008 } /* prep */
275 },
276 { /* HuaTianSongTi */
277 { 0xfffbfffc, 0x00000008 }, /* cvt */
278 { 0x0a5a0483, 0x00017c39 }, /* fpgm */
279 { 0x70020112, 0x00000008 } /* prep */
suzuki toshiya1e89d152011-04-30 17:55:57 +0900280 },
281 { /* NEC fadpop7.ttf */
282 { 0x00000000, 0x00000000 }, /* cvt */
283 { 0x40c92555, 0x000000e5 }, /* fpgm */
284 { 0xa39b58e3, 0x0000117c } /* prep */
285 },
286 { /* NEC fadrei5.ttf */
287 { 0x00000000, 0x00000000 }, /* cvt */
288 { 0x33c41652, 0x000000e5 }, /* fpgm */
289 { 0x26d6c52a, 0x00000f6a } /* prep */
290 },
291 { /* NEC fangot7.ttf */
292 { 0x00000000, 0x00000000 }, /* cvt */
293 { 0x6db1651d, 0x0000019d }, /* fpgm */
294 { 0x6c6e4b03, 0x00002492 } /* prep */
295 },
296 { /* NEC fangyo5.ttf */
297 { 0x00000000, 0x00000000 }, /* cvt */
298 { 0x40c92555, 0x000000e5 }, /* fpgm */
299 { 0xde51fad0, 0x0000117c } /* prep */
300 },
301 { /* NEC fankyo5.ttf */
302 { 0x00000000, 0x00000000 }, /* cvt */
303 { 0x85e47664, 0x000000e5 }, /* fpgm */
304 { 0xa6c62831, 0x00001caa } /* prep */
305 },
306 { /* NEC fanrgo5.ttf */
307 { 0x00000000, 0x00000000 }, /* cvt */
308 { 0x2d891cfd, 0x0000019d }, /* fpgm */
309 { 0xa0604633, 0x00001de8 } /* prep */
310 },
311 { /* NEC fangot5.ttc */
312 { 0x00000000, 0x00000000 }, /* cvt */
313 { 0x40aa774c, 0x000001cb }, /* fpgm */
314 { 0x9b5caa96, 0x00001f9a } /* prep */
315 },
316 { /* NEC fanmin3.ttc */
317 { 0x00000000, 0x00000000 }, /* cvt */
318 { 0x0d3de9cb, 0x00000141 }, /* fpgm */
319 { 0xd4127766, 0x00002280 } /* prep */
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900320 }
321 };
Werner Lemberg9871b842010-11-22 19:30:41 +0100322
Daniel Zimmermann3ad8f352011-05-24 06:22:32 +0200323 FT_ULong checksum;
324 int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES];
325 FT_Bool has_cvt, has_fpgm, has_prep;
326 FT_UShort i;
327 int j, k;
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900328
Werner Lemberg9871b842010-11-22 19:30:41 +0100329
330 FT_MEM_SET( num_matched_ids, 0,
331 sizeof( int ) * TRICK_SFNT_IDS_NUM_FACES );
suzuki toshiya1e89d152011-04-30 17:55:57 +0900332 has_cvt = FALSE;
333 has_fpgm = FALSE;
334 has_prep = FALSE;
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900335
336 for ( i = 0; i < face->num_tables; i++ )
337 {
338 checksum = 0;
Werner Lemberg9871b842010-11-22 19:30:41 +0100339
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900340 switch( face->dir_tables[i].Tag )
341 {
342 case TTAG_cvt:
343 k = TRICK_SFNT_ID_cvt;
suzuki toshiya1e89d152011-04-30 17:55:57 +0900344 has_cvt = TRUE;
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900345 break;
Werner Lemberg9871b842010-11-22 19:30:41 +0100346
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900347 case TTAG_fpgm:
348 k = TRICK_SFNT_ID_fpgm;
suzuki toshiya1e89d152011-04-30 17:55:57 +0900349 has_fpgm = TRUE;
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900350 break;
Werner Lemberg9871b842010-11-22 19:30:41 +0100351
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900352 case TTAG_prep:
353 k = TRICK_SFNT_ID_prep;
suzuki toshiya1e89d152011-04-30 17:55:57 +0900354 has_prep = TRUE;
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900355 break;
Werner Lemberg9871b842010-11-22 19:30:41 +0100356
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900357 default:
358 continue;
359 }
Werner Lemberg9871b842010-11-22 19:30:41 +0100360
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900361 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
362 if ( face->dir_tables[i].Length == sfnt_id[j][k].Length )
363 {
364 if ( !checksum )
365 checksum = tt_get_sfnt_checksum( face, i );
Werner Lemberg9871b842010-11-22 19:30:41 +0100366
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900367 if ( sfnt_id[j][k].CheckSum == checksum )
Werner Lemberg9871b842010-11-22 19:30:41 +0100368 num_matched_ids[j]++;
369
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900370 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
371 return TRUE;
372 }
373 }
374
suzuki toshiya1e89d152011-04-30 17:55:57 +0900375 for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ )
376 {
377 if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length )
378 num_matched_ids[j] ++;
379 if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length )
380 num_matched_ids[j] ++;
381 if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length )
382 num_matched_ids[j] ++;
383 if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE )
384 return TRUE;
385 }
386
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900387 return FALSE;
388 }
389
390
391 static FT_Bool
392 tt_check_trickyness( FT_Face face )
393 {
394 if ( !face )
395 return FALSE;
396
suzuki toshiya86b7b2f2011-04-26 03:46:12 +0900397 /* For first, check the face name for quick check. */
398 if ( face->family_name &&
399 tt_check_trickyness_family( face->family_name ) )
400 return TRUE;
401
Werner Lemberg9871b842010-11-22 19:30:41 +0100402 /* Type42 fonts may lack `name' tables, we thus try to identify */
403 /* tricky fonts by checking the checksums of Type42-persistent */
404 /* sfnt tables (`cvt', `fpgm', and `prep'). */
405 if ( tt_check_trickyness_sfnt_ids( (TT_Face)face ) )
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900406 return TRUE;
407
408 return FALSE;
409 }
410
411
David Turnerf9b8dec2000-06-16 19:34:52 +0000412 /*************************************************************************/
413 /* */
414 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +0000415 /* tt_face_init */
David Turnerd2b1f351999-12-16 23:11:37 +0000416 /* */
417 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +0000418 /* Initialize a given TrueType face object. */
David Turnerd2b1f351999-12-16 23:11:37 +0000419 /* */
420 /* <Input> */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000421 /* stream :: The source font stream. */
422 /* */
David Turnerd2b1f351999-12-16 23:11:37 +0000423 /* face_index :: The index of the font face in the resource. */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000424 /* */
425 /* num_params :: Number of additional generic parameters. Ignored. */
426 /* */
427 /* params :: Additional generic parameters. Ignored. */
428 /* */
429 /* <InOut> */
David Turnerd2b1f351999-12-16 23:11:37 +0000430 /* face :: The newly built face object. */
431 /* */
432 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +0000433 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +0000434 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000435 FT_LOCAL_DEF( FT_Error )
David Turnerb08fe2d2002-08-27 20:20:29 +0000436 tt_face_init( FT_Stream stream,
Werner Lemberg86ae11c2004-05-04 16:53:45 +0000437 FT_Face ttface, /* TT_Face */
Werner Lemberg4a2305c2001-06-28 07:17:51 +0000438 FT_Int face_index,
439 FT_Int num_params,
440 FT_Parameter* params )
David Turnerd2b1f351999-12-16 23:11:37 +0000441 {
Werner Lemberg91db04c2002-04-01 14:25:28 +0000442 FT_Error error;
443 FT_Library library;
David Turner4e7eeee2002-02-28 16:10:29 +0000444 SFNT_Service sfnt;
Werner Lemberg86ae11c2004-05-04 16:53:45 +0000445 TT_Face face = (TT_Face)ttface;
Werner Lemberg78575dc2000-06-12 19:36:41 +0000446
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000447
Werner Lembergb972a2a2008-12-11 08:55:48 +0000448 library = ttface->driver->root.library;
David Turner4e7eeee2002-02-28 16:10:29 +0000449 sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
Werner Lemberga929ba92000-06-25 06:47:11 +0000450 if ( !sfnt )
451 goto Bad_Format;
David Turnerc60c61c2000-05-12 15:26:58 +0000452
David Turnerd2b1f351999-12-16 23:11:37 +0000453 /* create input stream from resource */
David Turner7d3a2642002-03-20 10:49:31 +0000454 if ( FT_STREAM_SEEK( 0 ) )
David Turnerd2b1f351999-12-16 23:11:37 +0000455 goto Exit;
456
David Turnerd42c68e2000-01-27 13:56:02 +0000457 /* check that we have a valid TrueType file */
David Turner2e421312000-05-26 22:13:17 +0000458 error = sfnt->init_face( stream, face, face_index, num_params, params );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000459 if ( error )
460 goto Exit;
David Turnerc60c61c2000-05-12 15:26:58 +0000461
Werner Lemberg9f8309f2004-07-24 21:57:39 +0000462 /* We must also be able to accept Mac/GX fonts, as well as OT ones. */
463 /* The 0x00020000 tag is completely undocumented; some fonts from */
464 /* Arphic made for Chinese Windows 3.1 have this. */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000465 if ( face->format_tag != 0x00010000L && /* MS fonts */
Werner Lemberg9f8309f2004-07-24 21:57:39 +0000466 face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */
Werner Lemberg78575dc2000-06-12 19:36:41 +0000467 face->format_tag != TTAG_true ) /* Mac fonts */
David Turnerd42c68e2000-01-27 13:56:02 +0000468 {
Werner Lemberg78575dc2000-06-12 19:36:41 +0000469 FT_TRACE2(( "[not a valid TTF font]\n" ));
David Turner2e421312000-05-26 22:13:17 +0000470 goto Bad_Format;
David Turnerd42c68e2000-01-27 13:56:02 +0000471 }
472
David Turner6aa260c2006-08-25 22:45:13 +0000473#ifdef TT_USE_BYTECODE_INTERPRETER
Werner Lembergb972a2a2008-12-11 08:55:48 +0000474 ttface->face_flags |= FT_FACE_FLAG_HINTER;
Werner Lemberg7734a1f2005-10-05 15:18:29 +0000475#endif
476
477 /* If we are performing a simple font format check, exit immediately. */
David Turnerd2b1f351999-12-16 23:11:37 +0000478 if ( face_index < 0 )
479 return TT_Err_Ok;
480
David Turner2e421312000-05-26 22:13:17 +0000481 /* Load font directory */
482 error = sfnt->load_face( stream, face, face_index, num_params, params );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000483 if ( error )
484 goto Exit;
David Turnerd2b1f351999-12-16 23:11:37 +0000485
suzuki toshiya9f5dd612010-11-23 02:47:10 +0900486 if ( tt_check_trickyness( ttface ) )
Werner Lembergb972a2a2008-12-11 08:55:48 +0000487 ttface->face_flags |= FT_FACE_FLAG_TRICKY;
488
Wu, Chia-I (吳佳一)f5aa47b2006-02-14 06:40:10 +0000489 error = tt_face_load_hdmx( face, stream );
490 if ( error )
491 goto Exit;
492
Werner Lembergb972a2a2008-12-11 08:55:48 +0000493 if ( FT_IS_SCALABLE( ttface ) )
Werner Lemberga3f4da82003-04-29 13:23:47 +0000494 {
Werner Lemberg7f74a522002-07-26 09:09:10 +0000495
Graham Asher13217f22002-07-18 15:59:23 +0000496#ifdef FT_CONFIG_OPTION_INCREMENTAL
Werner Lemberg7f74a522002-07-26 09:09:10 +0000497
Werner Lembergb972a2a2008-12-11 08:55:48 +0000498 if ( !ttface->internal->incremental_interface )
Werner Lemberga3f4da82003-04-29 13:23:47 +0000499 error = tt_face_load_loca( face, stream );
500 if ( !error )
Werner Lembergd496b922007-12-04 21:49:59 +0000501 error = tt_face_load_cvt( face, stream );
502 if ( !error )
503 error = tt_face_load_fpgm( face, stream );
504 if ( !error )
505 error = tt_face_load_prep( face, stream );
Werner Lemberg7f74a522002-07-26 09:09:10 +0000506
Graham Asher11f0ab72002-07-24 13:58:21 +0000507#else
Werner Lemberg7f74a522002-07-26 09:09:10 +0000508
Werner Lemberga3f4da82003-04-29 13:23:47 +0000509 if ( !error )
Werner Lembergd496b922007-12-04 21:49:59 +0000510 error = tt_face_load_loca( face, stream );
511 if ( !error )
512 error = tt_face_load_cvt( face, stream );
513 if ( !error )
514 error = tt_face_load_fpgm( face, stream );
515 if ( !error )
516 error = tt_face_load_prep( face, stream );
Werner Lemberg7f74a522002-07-26 09:09:10 +0000517
Graham Asher11f0ab72002-07-24 13:58:21 +0000518#endif
Werner Lemberg7f74a522002-07-26 09:09:10 +0000519
Werner Lemberga3f4da82003-04-29 13:23:47 +0000520 }
Werner Lemberg78575dc2000-06-12 19:36:41 +0000521
Werner Lemberg046bf8b2006-10-03 08:43:42 +0000522#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
523 !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
Graham Asher3ea859f2003-04-25 11:40:46 +0000524
Graham Asher3ea859f2003-04-25 11:40:46 +0000525 {
David Turnerdf430e12006-10-01 00:09:35 +0000526 FT_Bool unpatented_hinting;
527 int i;
Graham Asher3ea859f2003-04-25 11:40:46 +0000528
Werner Lemberg046bf8b2006-10-03 08:43:42 +0000529
David Turnerdf430e12006-10-01 00:09:35 +0000530 /* Determine whether unpatented hinting is to be used for this face. */
531 unpatented_hinting = FT_BOOL
Werner Lemberg046bf8b2006-10-03 08:43:42 +0000532 ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL );
Werner Lemberga3f4da82003-04-29 13:23:47 +0000533
534 for ( i = 0; i < num_params && !face->unpatented_hinting; i++ )
535 if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
David Turnerdf430e12006-10-01 00:09:35 +0000536 unpatented_hinting = TRUE;
Graham Asher3ea859f2003-04-25 11:40:46 +0000537
David Turnerdf430e12006-10-01 00:09:35 +0000538 if ( !unpatented_hinting )
Werner Lembergb972a2a2008-12-11 08:55:48 +0000539 ttface->internal->ignore_unpatented_hinter = TRUE;
David Turner6aa260c2006-08-25 22:45:13 +0000540 }
541
Werner Lemberg046bf8b2006-10-03 08:43:42 +0000542#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
543 !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
Graham Asher3ea859f2003-04-25 11:40:46 +0000544
Werner Lemberga929ba92000-06-25 06:47:11 +0000545 /* initialize standard glyph loading routines */
David Turner994d7742000-06-25 04:49:19 +0000546 TT_Init_Glyph_Loading( face );
547
David Turnerd2b1f351999-12-16 23:11:37 +0000548 Exit:
549 return error;
Werner Lembergb48a6092000-07-09 19:15:30 +0000550
David Turner2e421312000-05-26 22:13:17 +0000551 Bad_Format:
Werner Lemberg1429db62001-04-02 23:54:01 +0000552 error = TT_Err_Unknown_File_Format;
David Turner2e421312000-05-26 22:13:17 +0000553 goto Exit;
David Turnerd2b1f351999-12-16 23:11:37 +0000554 }
555
556
David Turnerd2b1f351999-12-16 23:11:37 +0000557 /*************************************************************************/
558 /* */
559 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +0000560 /* tt_face_done */
David Turnerd2b1f351999-12-16 23:11:37 +0000561 /* */
562 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +0000563 /* Finalize a given face object. */
David Turnerd2b1f351999-12-16 23:11:37 +0000564 /* */
565 /* <Input> */
566 /* face :: A pointer to the face object to destroy. */
567 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +0000568 FT_LOCAL_DEF( void )
Werner Lemberg86ae11c2004-05-04 16:53:45 +0000569 tt_face_done( FT_Face ttface ) /* TT_Face */
David Turnerd2b1f351999-12-16 23:11:37 +0000570 {
Werner Lembergd03d8562008-10-01 22:39:05 +0000571 TT_Face face = (TT_Face)ttface;
572 FT_Memory memory;
573 FT_Stream stream;
574 SFNT_Service sfnt;
David Turnerd2b1f351999-12-16 23:11:37 +0000575
David Turnerc60c61c2000-05-12 15:26:58 +0000576
Werner Lembergd03d8562008-10-01 22:39:05 +0000577 if ( !face )
578 return;
579
Werner Lembergb972a2a2008-12-11 08:55:48 +0000580 memory = ttface->memory;
581 stream = ttface->stream;
Werner Lembergd03d8562008-10-01 22:39:05 +0000582 sfnt = (SFNT_Service)face->sfnt;
Werner Lemberg5811c7c2000-07-02 13:53:16 +0000583
Werner Lemberga929ba92000-06-25 06:47:11 +0000584 /* for `extended TrueType formats' (i.e. compressed versions) */
585 if ( face->extra.finalizer )
David Turner994d7742000-06-25 04:49:19 +0000586 face->extra.finalizer( face->extra.data );
Werner Lemberg78575dc2000-06-12 19:36:41 +0000587
588 if ( sfnt )
589 sfnt->done_face( face );
David Turnerd2b1f351999-12-16 23:11:37 +0000590
591 /* freeing the locations table */
David Turnere70d5532005-02-22 16:53:06 +0000592 tt_face_done_loca( face );
David Turnerd2b1f351999-12-16 23:11:37 +0000593
Wu, Chia-I (吳佳一)f5aa47b2006-02-14 06:40:10 +0000594 tt_face_free_hdmx( face );
595
David Turnerd2b1f351999-12-16 23:11:37 +0000596 /* freeing the CVT */
David Turnere459d742002-03-22 13:52:37 +0000597 FT_FREE( face->cvt );
David Turnerd2b1f351999-12-16 23:11:37 +0000598 face->cvt_size = 0;
599
David Turnerd2b1f351999-12-16 23:11:37 +0000600 /* freeing the programs */
David Turner7d3a2642002-03-20 10:49:31 +0000601 FT_FRAME_RELEASE( face->font_program );
602 FT_FRAME_RELEASE( face->cvt_program );
David Turnerd2b1f351999-12-16 23:11:37 +0000603 face->font_program_size = 0;
604 face->cvt_program_size = 0;
Werner Lemberg44bb3032004-04-25 20:15:11 +0000605
606#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
607 tt_done_blend( memory, face->blend );
608 face->blend = NULL;
609#endif
David Turnerd2b1f351999-12-16 23:11:37 +0000610 }
611
612
613 /*************************************************************************/
614 /* */
615 /* SIZE FUNCTIONS */
616 /* */
617 /*************************************************************************/
618
David Turner6aa260c2006-08-25 22:45:13 +0000619#ifdef TT_USE_BYTECODE_INTERPRETER
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +0000620
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000621 /*************************************************************************/
622 /* */
623 /* <Function> */
624 /* tt_size_run_fpgm */
625 /* */
626 /* <Description> */
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +0000627 /* Run the font program. */
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000628 /* */
629 /* <Input> */
Werner Lemberg18931a52011-02-01 07:08:43 +0100630 /* size :: A handle to the size object. */
631 /* */
632 /* pedantic :: Set if bytecode execution should be pedantic. */
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000633 /* */
634 /* <Return> */
635 /* FreeType error code. 0 means success. */
636 /* */
637 FT_LOCAL_DEF( FT_Error )
Werner Lemberg18931a52011-02-01 07:08:43 +0100638 tt_size_run_fpgm( TT_Size size,
639 FT_Bool pedantic )
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000640 {
641 TT_Face face = (TT_Face)size->root.face;
642 TT_ExecContext exec;
643 FT_Error error;
644
645
646 /* debugging instances have their own context */
647 if ( size->debug )
648 exec = size->context;
649 else
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +0000650 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000651
652 if ( !exec )
653 return TT_Err_Could_Not_Find_Context;
654
655 TT_Load_Context( exec, face, size );
656
Werner Lemberg18931a52011-02-01 07:08:43 +0100657 exec->callTop = 0;
658 exec->top = 0;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000659
660 exec->period = 64;
661 exec->phase = 0;
662 exec->threshold = 0;
663
664 exec->instruction_trap = FALSE;
Werner Lemberg18931a52011-02-01 07:08:43 +0100665 exec->F_dot_P = 0x10000L;
666
667 exec->pedantic_hinting = pedantic;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000668
669 {
670 FT_Size_Metrics* metrics = &exec->metrics;
671 TT_Size_Metrics* tt_metrics = &exec->tt_metrics;
672
673
674 metrics->x_ppem = 0;
675 metrics->y_ppem = 0;
676 metrics->x_scale = 0;
677 metrics->y_scale = 0;
678
679 tt_metrics->ppem = 0;
680 tt_metrics->scale = 0;
681 tt_metrics->ratio = 0x10000L;
682 }
683
684 /* allow font program execution */
685 TT_Set_CodeRange( exec,
686 tt_coderange_font,
687 face->font_program,
688 face->font_program_size );
689
690 /* disable CVT and glyph programs coderange */
691 TT_Clear_CodeRange( exec, tt_coderange_cvt );
692 TT_Clear_CodeRange( exec, tt_coderange_glyph );
693
694 if ( face->font_program_size > 0 )
695 {
696 error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
697
698 if ( !error )
Werner Lemberg6abb9232010-09-14 09:02:10 +0200699 {
700 FT_TRACE4(( "Executing `fpgm' table.\n" ));
701
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000702 error = face->interpreter( exec );
Werner Lemberg6abb9232010-09-14 09:02:10 +0200703 }
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000704 }
705 else
706 error = TT_Err_Ok;
707
708 if ( !error )
709 TT_Save_Context( exec, size );
710
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000711 return error;
712 }
713
714
715 /*************************************************************************/
716 /* */
717 /* <Function> */
718 /* tt_size_run_prep */
719 /* */
720 /* <Description> */
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +0000721 /* Run the control value program. */
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000722 /* */
723 /* <Input> */
Werner Lemberg18931a52011-02-01 07:08:43 +0100724 /* size :: A handle to the size object. */
725 /* */
726 /* pedantic :: Set if bytecode execution should be pedantic. */
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000727 /* */
728 /* <Return> */
729 /* FreeType error code. 0 means success. */
730 /* */
731 FT_LOCAL_DEF( FT_Error )
Werner Lemberg18931a52011-02-01 07:08:43 +0100732 tt_size_run_prep( TT_Size size,
733 FT_Bool pedantic )
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000734 {
735 TT_Face face = (TT_Face)size->root.face;
736 TT_ExecContext exec;
737 FT_Error error;
738
739
740 /* debugging instances have their own context */
741 if ( size->debug )
742 exec = size->context;
743 else
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +0000744 exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000745
746 if ( !exec )
747 return TT_Err_Could_Not_Find_Context;
748
749 TT_Load_Context( exec, face, size );
750
751 exec->callTop = 0;
752 exec->top = 0;
753
754 exec->instruction_trap = FALSE;
755
Werner Lemberg18931a52011-02-01 07:08:43 +0100756 exec->pedantic_hinting = pedantic;
757
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000758 TT_Set_CodeRange( exec,
759 tt_coderange_cvt,
760 face->cvt_program,
761 face->cvt_program_size );
762
763 TT_Clear_CodeRange( exec, tt_coderange_glyph );
764
765 if ( face->cvt_program_size > 0 )
766 {
767 error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
768
769 if ( !error && !size->debug )
Werner Lemberg6abb9232010-09-14 09:02:10 +0200770 {
771 FT_TRACE4(( "Executing `prep' table.\n" ));
772
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000773 error = face->interpreter( exec );
Werner Lemberg6abb9232010-09-14 09:02:10 +0200774 }
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000775 }
776 else
777 error = TT_Err_Ok;
778
779 /* save as default graphics state */
780 size->GS = exec->GS;
781
782 TT_Save_Context( exec, size );
783
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000784 return error;
785 }
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +0000786
David Turner6aa260c2006-08-25 22:45:13 +0000787#endif /* TT_USE_BYTECODE_INTERPRETER */
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000788
David Turnerd2b1f351999-12-16 23:11:37 +0000789
David Turner6aa260c2006-08-25 22:45:13 +0000790#ifdef TT_USE_BYTECODE_INTERPRETER
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +0000791
David Turner384be232007-01-05 15:32:01 +0000792 static void
793 tt_size_done_bytecode( FT_Size ftsize )
794 {
Werner Lembergf6294392007-01-06 07:47:45 +0000795 TT_Size size = (TT_Size)ftsize;
796 TT_Face face = (TT_Face)ftsize->face;
David Turner384be232007-01-05 15:32:01 +0000797 FT_Memory memory = face->root.memory;
798
Werner Lembergf6294392007-01-06 07:47:45 +0000799
David Turner384be232007-01-05 15:32:01 +0000800 if ( size->debug )
801 {
802 /* the debug context must be deleted by the debugger itself */
803 size->context = NULL;
804 size->debug = FALSE;
805 }
806
807 FT_FREE( size->cvt );
808 size->cvt_size = 0;
809
810 /* free storage area */
811 FT_FREE( size->storage );
812 size->storage_size = 0;
813
814 /* twilight zone */
815 tt_glyphzone_done( &size->twilight );
816
817 FT_FREE( size->function_defs );
818 FT_FREE( size->instruction_defs );
819
820 size->num_function_defs = 0;
821 size->max_function_defs = 0;
822 size->num_instruction_defs = 0;
823 size->max_instruction_defs = 0;
824
825 size->max_func = 0;
826 size->max_ins = 0;
827
828 size->bytecode_ready = 0;
829 size->cvt_ready = 0;
830 }
831
832
Werner Lembergf6294392007-01-06 07:47:45 +0000833 /* Initialize bytecode-related fields in the size object. */
834 /* We do this only if bytecode interpretation is really needed. */
David Turner384be232007-01-05 15:32:01 +0000835 static FT_Error
Werner Lemberg18931a52011-02-01 07:08:43 +0100836 tt_size_init_bytecode( FT_Size ftsize,
837 FT_Bool pedantic )
David Turner384be232007-01-05 15:32:01 +0000838 {
839 FT_Error error;
840 TT_Size size = (TT_Size)ftsize;
841 TT_Face face = (TT_Face)ftsize->face;
David Turnerd2b1f351999-12-16 23:11:37 +0000842 FT_Memory memory = face->root.memory;
David Turnerf9b8dec2000-06-16 19:34:52 +0000843 FT_Int i;
David Turnerd2b1f351999-12-16 23:11:37 +0000844
David Turnerf9b8dec2000-06-16 19:34:52 +0000845 FT_UShort n_twilight;
David Turner8f43c712000-02-02 12:16:19 +0000846 TT_MaxProfile* maxp = &face->max_profile;
David Turnerd2b1f351999-12-16 23:11:37 +0000847
Werner Lemberg78575dc2000-06-12 19:36:41 +0000848
David Turner384be232007-01-05 15:32:01 +0000849 size->bytecode_ready = 1;
850 size->cvt_ready = 0;
851
David Turnerd2b1f351999-12-16 23:11:37 +0000852 size->max_function_defs = maxp->maxFunctionDefs;
853 size->max_instruction_defs = maxp->maxInstructionDefs;
854
855 size->num_function_defs = 0;
856 size->num_instruction_defs = 0;
857
858 size->max_func = 0;
859 size->max_ins = 0;
860
861 size->cvt_size = face->cvt_size;
862 size->storage_size = maxp->maxStorage;
863
864 /* Set default metrics */
865 {
Werner Lemberg46e05c42009-07-17 22:49:34 +0200866 TT_Size_Metrics* metrics = &size->ttmetrics;
David Turnerd2b1f351999-12-16 23:11:37 +0000867
David Turnerd2b1f351999-12-16 23:11:37 +0000868
Werner Lemberg46e05c42009-07-17 22:49:34 +0200869 metrics->rotated = FALSE;
870 metrics->stretched = FALSE;
David Turnerd2b1f351999-12-16 23:11:37 +0000871
872 /* set default compensation (all 0) */
873 for ( i = 0; i < 4; i++ )
Werner Lemberg46e05c42009-07-17 22:49:34 +0200874 metrics->compensations[i] = 0;
David Turnerd2b1f351999-12-16 23:11:37 +0000875 }
876
Werner Lemberg78575dc2000-06-12 19:36:41 +0000877 /* allocate function defs, instruction defs, cvt, and storage area */
Werner Lemberg91db04c2002-04-01 14:25:28 +0000878 if ( FT_NEW_ARRAY( size->function_defs, size->max_function_defs ) ||
David Turnere459d742002-03-22 13:52:37 +0000879 FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
Werner Lemberg91db04c2002-04-01 14:25:28 +0000880 FT_NEW_ARRAY( size->cvt, size->cvt_size ) ||
881 FT_NEW_ARRAY( size->storage, size->storage_size ) )
David Turner384be232007-01-05 15:32:01 +0000882 goto Exit;
David Turnerd2b1f351999-12-16 23:11:37 +0000883
884 /* reserve twilight zone */
885 n_twilight = maxp->maxTwilightPoints;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000886
887 /* there are 4 phantom points (do we need this?) */
888 n_twilight += 4;
889
David Turnerb08fe2d2002-08-27 20:20:29 +0000890 error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
David Turnerd2b1f351999-12-16 23:11:37 +0000891 if ( error )
David Turner384be232007-01-05 15:32:01 +0000892 goto Exit;
David Turnerd2b1f351999-12-16 23:11:37 +0000893
894 size->twilight.n_points = n_twilight;
895
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000896 size->GS = tt_default_graphics_state;
897
David Turnerd2b1f351999-12-16 23:11:37 +0000898 /* set `face->interpreter' according to the debug hook present */
899 {
David Turnerf0df85b2000-06-22 00:17:42 +0000900 FT_Library library = face->root.driver->root.library;
David Turnerc60c61c2000-05-12 15:26:58 +0000901
Werner Lemberga929ba92000-06-25 06:47:11 +0000902
David Turnerd2b1f351999-12-16 23:11:37 +0000903 face->interpreter = (TT_Interpreter)
Werner Lemberg78575dc2000-06-12 19:36:41 +0000904 library->debug_hooks[FT_DEBUG_HOOK_TRUETYPE];
905 if ( !face->interpreter )
David Turnerd2b1f351999-12-16 23:11:37 +0000906 face->interpreter = (TT_Interpreter)TT_RunIns;
907 }
908
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +0000909 /* Fine, now run the font program! */
Werner Lemberg18931a52011-02-01 07:08:43 +0100910 error = tt_size_run_fpgm( size, pedantic );
David Turnerd2b1f351999-12-16 23:11:37 +0000911
David Turner384be232007-01-05 15:32:01 +0000912 Exit:
Werner Lembergf6294392007-01-06 07:47:45 +0000913 if ( error )
David Turner384be232007-01-05 15:32:01 +0000914 tt_size_done_bytecode( ftsize );
David Turnerd2b1f351999-12-16 23:11:37 +0000915
David Turner384be232007-01-05 15:32:01 +0000916 return error;
917 }
918
919
920 FT_LOCAL_DEF( FT_Error )
Werner Lemberg18931a52011-02-01 07:08:43 +0100921 tt_size_ready_bytecode( TT_Size size,
922 FT_Bool pedantic )
David Turner384be232007-01-05 15:32:01 +0000923 {
Werner Lembergf6294392007-01-06 07:47:45 +0000924 FT_Error error = TT_Err_Ok;
925
David Turner384be232007-01-05 15:32:01 +0000926
927 if ( !size->bytecode_ready )
928 {
Werner Lemberg18931a52011-02-01 07:08:43 +0100929 error = tt_size_init_bytecode( (FT_Size)size, pedantic );
David Turner384be232007-01-05 15:32:01 +0000930 if ( error )
931 goto Exit;
932 }
933
934 /* rescale CVT when needed */
935 if ( !size->cvt_ready )
936 {
937 FT_UInt i;
Werner Lembergb972a2a2008-12-11 08:55:48 +0000938 TT_Face face = (TT_Face)size->root.face;
David Turner384be232007-01-05 15:32:01 +0000939
940
941 /* Scale the cvt values to the new ppem. */
942 /* We use by default the y ppem to scale the CVT. */
943 for ( i = 0; i < size->cvt_size; i++ )
944 size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
945
Werner Lembergf6294392007-01-06 07:47:45 +0000946 /* all twilight points are originally zero */
David Turner384be232007-01-05 15:32:01 +0000947 for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
948 {
949 size->twilight.org[i].x = 0;
950 size->twilight.org[i].y = 0;
951 size->twilight.cur[i].x = 0;
952 size->twilight.cur[i].y = 0;
953 }
954
955 /* clear storage area */
956 for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
957 size->storage[i] = 0;
958
959 size->GS = tt_default_graphics_state;
960
Werner Lemberg18931a52011-02-01 07:08:43 +0100961 error = tt_size_run_prep( size, pedantic );
Werner Lemberg56ceaa42007-05-14 18:53:58 +0000962 if ( !error )
Werner Lemberga2f17cc2008-05-17 10:01:45 +0000963 size->cvt_ready = 1;
David Turner384be232007-01-05 15:32:01 +0000964 }
Werner Lemberga2f17cc2008-05-17 10:01:45 +0000965
David Turner384be232007-01-05 15:32:01 +0000966 Exit:
967 return error;
968 }
969
Werner Lemberg6ff2ff52007-05-24 19:39:14 +0000970#endif /* TT_USE_BYTECODE_INTERPRETER */
David Turner384be232007-01-05 15:32:01 +0000971
Werner Lembergf6294392007-01-06 07:47:45 +0000972
David Turner384be232007-01-05 15:32:01 +0000973 /*************************************************************************/
974 /* */
975 /* <Function> */
976 /* tt_size_init */
977 /* */
978 /* <Description> */
979 /* Initialize a new TrueType size object. */
980 /* */
981 /* <InOut> */
982 /* size :: A handle to the size object. */
983 /* */
984 /* <Return> */
985 /* FreeType error code. 0 means success. */
986 /* */
987 FT_LOCAL_DEF( FT_Error )
988 tt_size_init( FT_Size ttsize ) /* TT_Size */
989 {
990 TT_Size size = (TT_Size)ttsize;
991 FT_Error error = TT_Err_Ok;
992
993#ifdef TT_USE_BYTECODE_INTERPRETER
994 size->bytecode_ready = 0;
995 size->cvt_ready = 0;
996#endif
David Turner8f43c712000-02-02 12:16:19 +0000997
David Turnerd2b1f351999-12-16 23:11:37 +0000998 size->ttmetrics.valid = FALSE;
Werner Lembergf1c2b912006-01-13 14:53:28 +0000999 size->strike_index = 0xFFFFFFFFUL;
Wu, Chia-I (吳佳一)89fff9b2005-07-31 11:41:54 +00001000
David Turnerd2b1f351999-12-16 23:11:37 +00001001 return error;
David Turnerd2b1f351999-12-16 23:11:37 +00001002 }
1003
1004
1005 /*************************************************************************/
1006 /* */
1007 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +00001008 /* tt_size_done */
David Turnerd2b1f351999-12-16 23:11:37 +00001009 /* */
1010 /* <Description> */
1011 /* The TrueType size object finalizer. */
1012 /* */
1013 /* <Input> */
1014 /* size :: A handle to the target size object. */
1015 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +00001016 FT_LOCAL_DEF( void )
Werner Lemberg86ae11c2004-05-04 16:53:45 +00001017 tt_size_done( FT_Size ttsize ) /* TT_Size */
David Turnerd2b1f351999-12-16 23:11:37 +00001018 {
Werner Lembergf6294392007-01-06 07:47:45 +00001019 TT_Size size = (TT_Size)ttsize;
1020
Werner Lemberg8e3fc5e2005-08-03 21:17:53 +00001021
David Turner6aa260c2006-08-25 22:45:13 +00001022#ifdef TT_USE_BYTECODE_INTERPRETER
David Turner384be232007-01-05 15:32:01 +00001023 if ( size->bytecode_ready )
1024 tt_size_done_bytecode( ttsize );
David Turner8f43c712000-02-02 12:16:19 +00001025#endif
David Turnerd2b1f351999-12-16 23:11:37 +00001026
1027 size->ttmetrics.valid = FALSE;
1028 }
1029
1030
1031 /*************************************************************************/
1032 /* */
1033 /* <Function> */
Wu, Chia-I (吳佳一)fa7d6ab2006-01-13 12:21:31 +00001034 /* tt_size_reset */
David Turnerd2b1f351999-12-16 23:11:37 +00001035 /* */
1036 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +00001037 /* Reset a TrueType size when resolutions and character dimensions */
Wu, Chia-I (吳佳一)fa7d6ab2006-01-13 12:21:31 +00001038 /* have been changed. */
David Turnerd2b1f351999-12-16 23:11:37 +00001039 /* */
1040 /* <Input> */
1041 /* size :: A handle to the target size object. */
1042 /* */
Wu, Chia-I (吳佳一)fa7d6ab2006-01-13 12:21:31 +00001043 FT_LOCAL_DEF( FT_Error )
1044 tt_size_reset( TT_Size size )
David Turnerd2b1f351999-12-16 23:11:37 +00001045 {
Werner Lemberg91db04c2002-04-01 14:25:28 +00001046 TT_Face face;
1047 FT_Error error = TT_Err_Ok;
David Turnerd2b1f351999-12-16 23:11:37 +00001048 FT_Size_Metrics* metrics;
1049
Werner Lemberg78575dc2000-06-12 19:36:41 +00001050
Wu, Chia-I (吳佳一)fa7d6ab2006-01-13 12:21:31 +00001051 size->ttmetrics.valid = FALSE;
David Turnerd2b1f351999-12-16 23:11:37 +00001052
1053 face = (TT_Face)size->root.face;
1054
David Turnerba4511b2003-02-18 22:25:22 +00001055 metrics = &size->metrics;
David Turnerd2b1f351999-12-16 23:11:37 +00001056
Wu, Chia-I (吳佳一)fa7d6ab2006-01-13 12:21:31 +00001057 /* copy the result from base layer */
1058 *metrics = size->root.metrics;
1059
David Turnerd2b1f351999-12-16 23:11:37 +00001060 if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
1061 return TT_Err_Invalid_PPem;
1062
Werner Lembergf1c2b912006-01-13 14:53:28 +00001063 /* This bit flag, if set, indicates that the ppems must be */
1064 /* rounded to integers. Nearly all TrueType fonts have this bit */
1065 /* set, as hinting won't work really well otherwise. */
1066 /* */
Wu, Chia-I (吳佳一)fa7d6ab2006-01-13 12:21:31 +00001067 if ( face->header.Flags & 8 )
1068 {
1069 metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
1070 face->root.units_per_EM );
1071 metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
1072 face->root.units_per_EM );
1073
1074 metrics->ascender =
1075 FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
1076 metrics->descender =
1077 FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
1078 metrics->height =
1079 FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
1080 metrics->max_advance =
1081 FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
1082 metrics->x_scale ) );
1083 }
1084
David Turnerd2b1f351999-12-16 23:11:37 +00001085 /* compute new transformation */
1086 if ( metrics->x_ppem >= metrics->y_ppem )
1087 {
1088 size->ttmetrics.scale = metrics->x_scale;
1089 size->ttmetrics.ppem = metrics->x_ppem;
Werner Lemberg78575dc2000-06-12 19:36:41 +00001090 size->ttmetrics.x_ratio = 0x10000L;
David Turnerd2b1f351999-12-16 23:11:37 +00001091 size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
1092 0x10000L,
1093 metrics->x_ppem );
1094 }
1095 else
1096 {
1097 size->ttmetrics.scale = metrics->y_scale;
1098 size->ttmetrics.ppem = metrics->y_ppem;
1099 size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
1100 0x10000L,
1101 metrics->y_ppem );
Werner Lemberg78575dc2000-06-12 19:36:41 +00001102 size->ttmetrics.y_ratio = 0x10000L;
David Turnerd2b1f351999-12-16 23:11:37 +00001103 }
1104
David Turner6aa260c2006-08-25 22:45:13 +00001105#ifdef TT_USE_BYTECODE_INTERPRETER
David Turner384be232007-01-05 15:32:01 +00001106 size->cvt_ready = 0;
David Turner6aa260c2006-08-25 22:45:13 +00001107#endif /* TT_USE_BYTECODE_INTERPRETER */
David Turnerd2b1f351999-12-16 23:11:37 +00001108
1109 if ( !error )
1110 size->ttmetrics.valid = TRUE;
1111
1112 return error;
1113 }
1114
Werner Lemberg4b680072000-11-07 06:30:29 +00001115
David Turnerd2b1f351999-12-16 23:11:37 +00001116 /*************************************************************************/
1117 /* */
1118 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +00001119 /* tt_driver_init */
David Turnerd2b1f351999-12-16 23:11:37 +00001120 /* */
1121 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +00001122 /* Initialize a given TrueType driver object. */
David Turnerd2b1f351999-12-16 23:11:37 +00001123 /* */
1124 /* <Input> */
1125 /* driver :: A handle to the target driver object. */
1126 /* */
1127 /* <Return> */
Werner Lemberga929ba92000-06-25 06:47:11 +00001128 /* FreeType error code. 0 means success. */
David Turnerd2b1f351999-12-16 23:11:37 +00001129 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +00001130 FT_LOCAL_DEF( FT_Error )
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001131 tt_driver_init( FT_Module ttdriver ) /* TT_Driver */
David Turnerd2b1f351999-12-16 23:11:37 +00001132 {
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001133
David Turner6aa260c2006-08-25 22:45:13 +00001134#ifdef TT_USE_BYTECODE_INTERPRETER
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001135
1136 TT_Driver driver = (TT_Driver)ttdriver;
David Turnerc60c61c2000-05-12 15:26:58 +00001137
Werner Lemberga929ba92000-06-25 06:47:11 +00001138
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001139 if ( !TT_New_Context( driver ) )
1140 return TT_Err_Could_Not_Find_Context;
Werner Lembergb48a6092000-07-09 19:15:30 +00001141
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001142#else
1143
1144 FT_UNUSED( ttdriver );
1145
1146#endif
1147
1148 return TT_Err_Ok;
David Turnerd2b1f351999-12-16 23:11:37 +00001149 }
1150
1151
1152 /*************************************************************************/
1153 /* */
1154 /* <Function> */
David Turnerb08fe2d2002-08-27 20:20:29 +00001155 /* tt_driver_done */
David Turnerd2b1f351999-12-16 23:11:37 +00001156 /* */
1157 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +00001158 /* Finalize a given TrueType driver. */
David Turnerd2b1f351999-12-16 23:11:37 +00001159 /* */
1160 /* <Input> */
1161 /* driver :: A handle to the target TrueType driver. */
1162 /* */
David Turnerbc82f1b2002-03-01 02:26:22 +00001163 FT_LOCAL_DEF( void )
Werner Lemberg86ae11c2004-05-04 16:53:45 +00001164 tt_driver_done( FT_Module ttdriver ) /* TT_Driver */
David Turnerd2b1f351999-12-16 23:11:37 +00001165 {
David Turner6aa260c2006-08-25 22:45:13 +00001166#ifdef TT_USE_BYTECODE_INTERPRETER
Werner Lemberg86ae11c2004-05-04 16:53:45 +00001167 TT_Driver driver = (TT_Driver)ttdriver;
1168
Werner Lemberg78575dc2000-06-12 19:36:41 +00001169
David Turnerd2b1f351999-12-16 23:11:37 +00001170 /* destroy the execution context */
1171 if ( driver->context )
1172 {
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001173 TT_Done_Context( driver->context );
David Turnerd2b1f351999-12-16 23:11:37 +00001174 driver->context = NULL;
1175 }
David Turnerc5cdf8b2000-07-27 21:40:22 +00001176#else
Werner Lemberg3bcad432004-05-06 11:48:35 +00001177 FT_UNUSED( ttdriver );
David Turner8f43c712000-02-02 12:16:19 +00001178#endif
Werner Lemberg5811c7c2000-07-02 13:53:16 +00001179
David Turnerd2b1f351999-12-16 23:11:37 +00001180 }
1181
1182
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001183 /*************************************************************************/
1184 /* */
1185 /* <Function> */
1186 /* tt_slot_init */
1187 /* */
1188 /* <Description> */
Werner Lembergf1c2b912006-01-13 14:53:28 +00001189 /* Initialize a new slot object. */
Wu, Chia-I (吳佳一)0142e6a2005-08-16 01:54:59 +00001190 /* */
1191 /* <InOut> */
1192 /* slot :: A handle to the slot object. */
1193 /* */
1194 /* <Return> */
1195 /* FreeType error code. 0 means success. */
1196 /* */
1197 FT_LOCAL_DEF( FT_Error )
1198 tt_slot_init( FT_GlyphSlot slot )
1199 {
1200 return FT_GlyphLoader_CreateExtra( slot->internal->loader );
1201 }
1202
1203
David Turnerd2b1f351999-12-16 23:11:37 +00001204/* END */