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.
21 #include <numberset.h>
24 #define TTFAUTOHINT_STRING "; ttfautohint"
25 #define TTFAUTOHINT_STRING_WIDE "\0;\0 \0t\0t\0f\0a\0u\0t\0o\0h\0i\0n\0t"
27 // build string that gets appended to the `Version' field(s)
31 // return value 1 means allocation error, value 2 too long a string
34 build_version_string(Info_Data
* idata
)
36 // since we use `goto' we have to initialize variables before the jumps
38 unsigned char* data_wide
;
49 d
= sdscatprintf(d
, TTFAUTOHINT_STRING
" (v%s)", VERSION
);
55 d
= sdscatprintf(d
, " -l %d", idata
->hinting_range_min
);
56 d
= sdscatprintf(d
, " -r %d", idata
->hinting_range_max
);
57 d
= sdscatprintf(d
, " -G %d", idata
->hinting_limit
);
58 d
= sdscatprintf(d
, " -x %d", idata
->increase_x_height
);
59 if (idata
->fallback_stem_width
)
60 d
= sdscatprintf(d
, " -H %d", idata
->fallback_stem_width
);
61 d
= sdscatprintf(d
, " -D %s", idata
->default_script
);
62 d
= sdscatprintf(d
, " -f %s", idata
->fallback_script
);
63 if (idata
->deltas_name
)
64 d
= sdscatprintf(d
, " -m \"%s\"", idata
->deltas_name
);
71 if (idata
->gray_strong_stem_width
)
72 strong
[count
++] = 'g';
73 if (idata
->gdi_cleartype_strong_stem_width
)
74 strong
[count
++] = 'G';
75 if (idata
->dw_cleartype_strong_stem_width
)
76 strong
[count
++] = 'D';
78 d
= sdscatprintf(d
, " -w %s", strong
);
80 d
= sdscat(d
, " -w \"\"");
82 if (idata
->windows_compatibility
)
84 if (idata
->adjust_subglyphs
)
86 if (idata
->hint_composites
)
93 if (idata
->x_height_snapping_exceptions_string
)
95 // only set specific value of `ret' for an allocation error,
96 // since syntax errors are handled in TTF_autohint
97 number_range
* x_height_snapping_exceptions
;
98 const char* pos
= number_set_parse(
99 idata
->x_height_snapping_exceptions_string
,
100 &x_height_snapping_exceptions
,
104 if (x_height_snapping_exceptions
== NUMBERSET_ALLOCATION_ERROR
)
109 s
= number_set_show(x_height_snapping_exceptions
, 6, 0x7FFF);
110 number_set_free(x_height_snapping_exceptions
);
112 // ensure UTF16-BE version doesn't get too long
113 if (strlen(s
) > 0xFFFF / 2 - sdslen(d
))
119 d
= sdscatprintf(d
, " -X \"%s\"", s
);
129 data
= (unsigned char*)malloc(sdslen(d
) + 1);
135 memcpy(data
, d
, sdslen(d
) + 1);
138 idata
->data_len
= (unsigned short)sdslen(d
);
140 // prepare UTF16-BE version data
141 idata
->data_wide_len
= 2 * idata
->data_len
;
142 data_wide
= (unsigned char*)realloc(idata
->data_wide
,
143 idata
->data_wide_len
);
149 idata
->data_wide
= data_wide
;
152 dtw
= idata
->data_wide
;
153 for (unsigned short i
= 0; i
< idata
->data_len
; i
++)
167 free(idata
->data_wide
);
170 idata
->data_wide
= NULL
;
172 idata
->data_wide_len
= 0;
179 info(unsigned short platform_id
,
180 unsigned short encoding_id
,
181 unsigned short /* language_id */,
182 unsigned short name_id
,
187 Info_Data
* idata
= (Info_Data
*)user
;
188 unsigned char ttfautohint_string
[] = TTFAUTOHINT_STRING
;
189 unsigned char ttfautohint_string_wide
[] = TTFAUTOHINT_STRING_WIDE
;
191 // we use memmem, so don't count the trailing \0 character
192 size_t ttfautohint_string_len
= sizeof (TTFAUTOHINT_STRING
) - 1;
193 size_t ttfautohint_string_wide_len
= sizeof (TTFAUTOHINT_STRING_WIDE
) - 1;
196 unsigned short v_len
;
201 // if it is a version string, append our data
206 || (platform_id
== 3 && !(encoding_id
== 1
207 || encoding_id
== 10)))
209 // one-byte or multi-byte encodings
211 v_len
= idata
->data_len
;
212 s
= ttfautohint_string
;
213 s_len
= ttfautohint_string_len
;
218 // (two-byte) UTF-16BE for everything else
219 v
= idata
->data_wide
;
220 v_len
= idata
->data_wide_len
;
221 s
= ttfautohint_string_wide
;
222 s_len
= ttfautohint_string_wide_len
;
226 // if we already have an ttfautohint info string,
227 // remove it up to a following `;' character (or end of string)
228 unsigned char* s_start
= (unsigned char*)memmem(*str
, *len
, s
, s_len
);
231 unsigned char* s_end
= s_start
+ offset
;
232 unsigned char* limit
= *str
+ *len
;
234 while (s_end
< limit
)
242 if (*(s_end
- 1) == '\0') // UTF-16BE
253 while (s_end
< limit
)
254 *s_start
++ = *s_end
++;
256 *len
-= s_end
- s_start
;
259 // do nothing if the string would become too long
260 if (*len
> 0xFFFF - v_len
)
263 unsigned short len_new
= *len
+ v_len
;
264 unsigned char* str_new
= (unsigned char*)realloc(*str
, len_new
);
269 memcpy(*str
+ *len
, v
, v_len
);