4 * Copyright (C) 2012-2015 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.
20 typedef struct Lang_Tag_Record_
26 typedef struct Name_Record_
28 FT_UShort platform_id
;
29 FT_UShort encoding_id
;
30 FT_UShort language_id
;
37 typedef struct Naming_Table_
40 FT_UShort string_offset
;
43 Name_Record
* name_records
;
45 FT_UShort lang_tag_count
;
46 Lang_Tag_Record
* lang_tag_records
;
51 parse_name_header(FT_Byte
** curp
,
65 n
->format
= *(p
++) << 8;
67 n
->name_count
= *(p
++) << 8;
68 n
->name_count
+= *(p
++);
69 n
->string_offset
= *(p
++) << 8;
70 n
->string_offset
+= *(p
++);
72 n
->name_records
= NULL
;
73 n
->lang_tag_records
= NULL
;
75 /* all name strings must be between `startp' and `endp' */
76 startp
= buf
+ 6 + 12 * n
->name_count
;
79 /* format 1 also has language tag records */
87 return FT_Err_Invalid_Table
;
89 n
->lang_tag_count
= *(q
++) << 8;
90 n
->lang_tag_count
+= *q
;
92 startp
+= 2 + 4 * n
->lang_tag_count
;
95 n
->lang_tag_count
= 0;
98 return FT_Err_Invalid_Table
;
109 parse_name_records(FT_Byte
** curp
,
125 /* allocate name records array */
126 n
->name_records
= (Name_Record
*)calloc(1, n
->name_count
127 * sizeof (Name_Record
));
128 if (!n
->name_records
)
129 return FT_Err_Out_Of_Memory
;
131 /* walk over all name records */
133 for (i
= 0; i
< n
->name_count
; i
++)
135 Name_Record
* r
= &n
->name_records
[count
];
142 r
->platform_id
= *(p
++) << 8;
143 r
->platform_id
+= *(p
++);
144 r
->encoding_id
= *(p
++) << 8;
145 r
->encoding_id
+= *(p
++);
146 r
->language_id
= *(p
++) << 8;
147 r
->language_id
+= *(p
++);
148 r
->name_id
= *(p
++) << 8;
149 r
->name_id
+= *(p
++);
151 r
->len
= *(p
++) << 8;
154 offset
= *(p
++) << 8;
157 s
= buf
+ n
->string_offset
+ offset
;
159 /* ignore invalid entries */
160 if (s
< startp
|| s
+ r
->len
> endp
)
163 /* mac encoding or non-Unicode Windows encoding? */
164 if (r
->platform_id
== 1
165 || (r
->platform_id
== 3 && !(r
->encoding_id
== 1
166 || r
->encoding_id
== 10)))
168 /* one-byte or multi-byte encodings */
170 /* skip everything after a NULL byte (if any) */
171 for (l
= 0; l
< r
->len
; l
++)
175 /* ignore zero-length entries */
183 /* (two-byte) UTF-16BE for everything else */
185 /* we need an even number of bytes */
188 /* ignore entries which contain only NULL bytes */
189 for (l
= 0; l
< r
->len
; l
++)
196 r
->str
= (FT_Byte
*)malloc(r
->len
);
198 return FT_Err_Out_Of_Memory
;
199 memcpy(r
->str
, s
, r
->len
);
203 /* we ignore the return value of `font->info' */
204 font
->info(r
->platform_id
,
216 /* let the user modify `name' table entries */
217 if (font
->info
&& font
->info_post
)
218 /* we ignore the return value of `font->info_post' */
219 font
->info_post(font
->info_data
);
221 /* shrink name record array if necessary */
222 n
->name_records
= (Name_Record
*)realloc(n
->name_records
,
223 count
* sizeof (Name_Record
));
224 n
->name_count
= count
;
231 parse_lang_tag_records(FT_Byte
** curp
,
243 if (!n
->lang_tag_count
)
246 /* allocate language tags array */
247 n
->lang_tag_records
= (Lang_Tag_Record
*)calloc(
248 1, n
->lang_tag_count
* sizeof (Lang_Tag_Record
));
249 if (!n
->lang_tag_records
)
250 return FT_Err_Out_Of_Memory
;
252 /* walk over all language tag records (if any) */
253 for (i
= 0; i
< n
->lang_tag_count
; i
++)
255 Lang_Tag_Record
* r
= &n
->lang_tag_records
[i
];
261 r
->len
= *(p
++) << 8;
264 offset
= *(p
++) << 8;
267 s
= buf
+ n
->string_offset
+ offset
;
269 /* ignore an invalid entry -- */
270 /* contrary to name records, we can't simply remove it */
271 /* because references to it should still work */
272 /* (we don't apply more fixes */
273 /* since ttfautohint is not a TrueType sanitizing tool) */
274 if (s
< startp
|| s
+ r
->len
> endp
)
277 /* we don't massage the data since we only make a copy */
278 r
->str
= (FT_Byte
*)malloc(r
->len
);
280 return FT_Err_Out_Of_Memory
;
282 memcpy(r
->str
, s
, r
->len
);
289 /* we build a non-optimized `name' table, this is, */
290 /* we don't fold strings `foo' and `foobar' into one string */
293 build_name_table(Naming_Table
* n
,
294 SFNT_Table
* name_table
)
297 FT_Byte
* buf_new_resized
;
298 FT_ULong buf_new_len
;
306 FT_UShort string_offset
;
307 FT_ULong data_offset
;
311 /* we reallocate the array to its real size later on */
312 buf_new_len
= 6 + 12 * n
->name_count
;
314 buf_new_len
+= 2 + 4 * n
->lang_tag_count
;
316 buf_new
= (FT_Byte
*)malloc(buf_new_len
);
318 return FT_Err_Out_Of_Memory
;
320 /* note that the OpenType specification says that `string_offset' is the */
321 /* `offset to the start of string storage (from start of table)', */
322 /* but this isn't enforced by the major rendering engines */
323 /* as long as the final string offsets are valid */
324 string_offset
= (buf_new_len
<= 0xFFFF) ? buf_new_len
: 0xFFFF;
328 *(p
++) = HIGH(n
->format
);
329 *(p
++) = LOW(n
->format
);
330 *(p
++) = HIGH(n
->name_count
);
331 *(p
++) = LOW(n
->name_count
);
332 *(p
++) = HIGH(string_offset
);
333 *(p
++) = LOW(string_offset
);
338 for (i
= 0; i
< n
->name_count
; i
++)
340 Name_Record
* r
= &n
->name_records
[i
];
343 *(p
++) = HIGH(r
->platform_id
);
344 *(p
++) = LOW(r
->platform_id
);
345 *(p
++) = HIGH(r
->encoding_id
);
346 *(p
++) = LOW(r
->encoding_id
);
347 *(p
++) = HIGH(r
->language_id
);
348 *(p
++) = LOW(r
->language_id
);
349 *(p
++) = HIGH(r
->name_id
);
350 *(p
++) = LOW(r
->name_id
);
352 *(p
++) = HIGH(r
->len
);
353 *(p
++) = LOW(r
->len
);
355 /* the offset field gets filled in later */
363 *(p
++) = HIGH(n
->lang_tag_count
);
364 *(p
++) = LOW(n
->lang_tag_count
);
366 for (i
= 0; i
< n
->lang_tag_count
; i
++)
368 Lang_Tag_Record
* r
= &n
->lang_tag_records
[i
];
371 *(p
++) = HIGH(r
->len
);
372 *(p
++) = LOW(r
->len
);
374 /* the offset field gets filled in later */
381 if (buf_new_len
+ data_len
> 2 * 0xFFFF)
383 /* the table would become too large, so we do nothing */
388 data_offset
= buf_new_len
;
390 /* reallocate the buffer to fit its real size */
391 buf_new_len
+= data_len
;
392 /* make the allocated buffer length a multiple of 4 */
393 len
= (buf_new_len
+ 3) & ~3;
395 buf_new_resized
= (FT_Byte
*)realloc(buf_new
, len
);
396 if (!buf_new_resized
)
399 return FT_Err_Out_Of_Memory
;
401 buf_new
= buf_new_resized
;
403 base
= buf_new
+ string_offset
;
404 p
= buf_new
+ data_offset
;
408 /* the first name record offset */
409 q
= &buf_new
[6 + 10];
410 for (i
= 0; i
< n
->name_count
; i
++)
412 Name_Record
* r
= &n
->name_records
[i
];
417 *(q
+ 1) = LOW(p
- base
);
420 memcpy(p
, r
->str
, r
->len
);
428 /* the first language tag record offset */
429 q
= &buf_new
[6 + 12 * n
->name_count
+ 2 + 2];
430 for (i
= 0; i
< n
->lang_tag_count
; i
++)
432 Lang_Tag_Record
* r
= &n
->lang_tag_records
[i
];
437 *(q
+ 1) = LOW(p
- base
);
440 memcpy(p
, r
->str
, r
->len
);
447 /* pad end of buffer with zeros */
448 switch (buf_new_len
% 4)
460 /* we are done; replace the old buffer with the new one */
461 free(name_table
->buf
);
463 name_table
->buf
= buf_new
;
464 name_table
->len
= buf_new_len
;
470 /* we handle the `name' table as optional; */
471 /* if there are problems not related to allocation, */
472 /* simply return (or continue, if possible) without signaling an error, */
473 /* and the original `name' table is not modified */
476 TA_sfnt_update_name_table(SFNT
* sfnt
,
481 SFNT_Table
* name_table
;
494 if (sfnt
->name_idx
== MISSING
)
497 name_table
= &font
->tables
[sfnt
->name_idx
];
498 buf
= name_table
->buf
;
499 buf_len
= name_table
->len
;
501 if (name_table
->processed
)
506 error
= parse_name_header(&p
, &n
, buf_len
, &startp
, &endp
);
510 /* due to the structure of the `name' table, */
511 /* we must parse it completely, apply our changes, */
512 /* and rebuild it from scratch */
513 error
= parse_name_records(&p
, &n
, buf
, startp
, endp
, font
);
517 error
= parse_lang_tag_records(&p
, &n
, buf
, startp
, endp
);
521 error
= build_name_table(&n
, name_table
);
525 name_table
->checksum
= TA_table_compute_checksum(name_table
->buf
,
529 for (i
= 0; i
< n
.name_count
; i
++)
530 free(n
.name_records
[i
].str
);
531 for (i
= 0; i
< n
.lang_tag_count
; i
++)
532 free(n
.lang_tag_records
[i
].str
);
534 free(n
.name_records
);
535 free(n
.lang_tag_records
);
537 name_table
->processed
= 1;
542 /* end of taname.c */