3 // Copyright (C) 2012-2014 by Werner Lemberg.
5 // This file is part of the ttfautohint library, and may only be used,
6 // modified, and distributed under the terms given in `COPYING'. By
7 // continuing to use, modify, or distribute this file you indicate that you
8 // have read `COPYING' and understand and accept it fully.
10 // The file `COPYING' mentioned in the previous paragraph is distributed
11 // with the ttfautohint library.
22 #define TTFAUTOHINT_STRING "; ttfautohint"
23 #define TTFAUTOHINT_STRING_WIDE "\0;\0 \0t\0t\0f\0a\0u\0t\0o\0h\0i\0n\0t"
25 // build string that gets appended to the `Version' field(s)
29 // return value 1 means allocation error, value 2 too long a string
32 build_version_string(Info_Data
* idata
)
38 unsigned char* data_new
;
39 unsigned short data_new_len
;
44 // 128 bytes certainly hold the following options except -X
45 data_new
= (unsigned char*)realloc(idata
->data
, 128);
51 idata
->data
= data_new
;
53 d
= (char*)idata
->data
;
54 d
+= sprintf(d
, TTFAUTOHINT_STRING
" (v%s)", VERSION
);
58 d
+= sprintf(d
, " -d");
62 d
+= sprintf(d
, " -l %d", idata
->hinting_range_min
);
63 d
+= sprintf(d
, " -r %d", idata
->hinting_range_max
);
64 d
+= sprintf(d
, " -G %d", idata
->hinting_limit
);
65 d
+= sprintf(d
, " -x %d", idata
->increase_x_height
);
66 d
+= sprintf(d
, " -D %s", idata
->default_script
);
67 d
+= sprintf(d
, " -f %s", idata
->fallback_script
);
74 if (idata
->gray_strong_stem_width
)
75 strong
[count
++] = 'g';
76 if (idata
->gdi_cleartype_strong_stem_width
)
77 strong
[count
++] = 'G';
78 if (idata
->dw_cleartype_strong_stem_width
)
79 strong
[count
++] = 'D';
81 d
+= sprintf(d
, " -w %s", strong
);
83 d
+= sprintf(d
, " -w \"\"");
85 if (idata
->windows_compatibility
)
86 d
+= sprintf(d
, " -W");
87 if (idata
->pre_hinting
)
88 d
+= sprintf(d
, " -p");
89 if (idata
->hint_composites
)
90 d
+= sprintf(d
, " -c");
92 d
+= sprintf(d
, " -s");
93 if (idata
->x_height_snapping_exceptions
)
94 d
+= sprintf(d
, " -X \"\""); // fill in data later
97 idata
->data_len
= d
- (char*)idata
->data
;
99 if (idata
->x_height_snapping_exceptions
)
101 s
= number_set_show(idata
->x_height_snapping_exceptions
, 6, 0x7FFF);
108 // ensure UTF16-BE version doesn't get too long
110 if (s_len
> 0xFFFF / 2 - 128)
119 // we now reallocate to the real size
120 // (plus one byte so that `sprintf' works)
121 data_new_len
= idata
->data_len
+ s_len
;
122 data_new
= (unsigned char*)realloc(idata
->data
, data_new_len
+ 1);
129 if (idata
->x_height_snapping_exceptions
)
131 // overwrite second doublequote and append it instead
132 d
= (char*)(data_new
+ idata
->data_len
- 1);
133 sprintf(d
, "%s\"", s
);
136 idata
->data
= data_new
;
137 idata
->data_len
= data_new_len
;
139 // prepare UTF16-BE version data
140 idata
->data_wide_len
= 2 * idata
->data_len
;
141 data_new
= (unsigned char*)realloc(idata
->data_wide
,
142 idata
->data_wide_len
);
148 idata
->data_wide
= data_new
;
150 d
= (char*)idata
->data
;
151 dw
= (char*)idata
->data_wide
;
152 for (unsigned short i
= 0; i
< idata
->data_len
; i
++)
165 free(idata
->data_wide
);
168 idata
->data_wide
= NULL
;
170 idata
->data_wide_len
= 0;
177 info(unsigned short platform_id
,
178 unsigned short encoding_id
,
179 unsigned short /* language_id */,
180 unsigned short name_id
,
185 Info_Data
* idata
= (Info_Data
*)user
;
186 unsigned char ttfautohint_string
[] = TTFAUTOHINT_STRING
;
187 unsigned char ttfautohint_string_wide
[] = TTFAUTOHINT_STRING_WIDE
;
189 // we use memmem, so don't count the trailing \0 character
190 size_t ttfautohint_string_len
= sizeof (TTFAUTOHINT_STRING
) - 1;
191 size_t ttfautohint_string_wide_len
= sizeof (TTFAUTOHINT_STRING_WIDE
) - 1;
194 unsigned short v_len
;
199 // if it is a version string, append our data
204 || (platform_id
== 3 && !(encoding_id
== 1
205 || encoding_id
== 10)))
207 // one-byte or multi-byte encodings
209 v_len
= idata
->data_len
;
210 s
= ttfautohint_string
;
211 s_len
= ttfautohint_string_len
;
216 // (two-byte) UTF-16BE for everything else
217 v
= idata
->data_wide
;
218 v_len
= idata
->data_wide_len
;
219 s
= ttfautohint_string_wide
;
220 s_len
= ttfautohint_string_wide_len
;
224 // if we already have an ttfautohint info string,
225 // remove it up to a following `;' character (or end of string)
226 unsigned char* s_start
= (unsigned char*)memmem(*str
, *len
, s
, s_len
);
229 unsigned char* s_end
= s_start
+ offset
;
230 unsigned char* limit
= *str
+ *len
;
232 while (s_end
< limit
)
240 if (*(s_end
- 1) == '\0') // UTF-16BE
251 while (s_end
< limit
)
252 *s_start
++ = *s_end
++;
254 *len
-= s_end
- s_start
;
257 // do nothing if the string would become too long
258 if (*len
> 0xFFFF - v_len
)
261 unsigned short len_new
= *len
+ v_len
;
262 unsigned char* str_new
= (unsigned char*)realloc(*str
, len_new
);
267 memcpy(*str
+ *len
, v
, v_len
);