/src/ghostpdl/base/write_t2.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | /* |
17 | | Functions to serialize a type 1 font so that it can then be |
18 | | passed to FreeType via the FAPI FreeType bridge. |
19 | | Started by Graham Asher, 9th August 2002. |
20 | | */ |
21 | | #include "stdpre.h" |
22 | | #include "gzstate.h" |
23 | | #include "wrfont.h" |
24 | | #include "write_t2.h" |
25 | | #include "gxfont.h" |
26 | | #include "gxfont1.h" |
27 | | |
28 | | /* |
29 | | Public structures and functions in this file are prefixed with FF_ because they are part of |
30 | | the FAPI FreeType implementation. |
31 | | */ |
32 | | |
33 | | static void |
34 | | write_4_byte_int(unsigned char *a_output, long a_int) |
35 | 4.11M | { |
36 | 4.11M | a_output[0] = (unsigned char)(a_int >> 24); |
37 | 4.11M | a_output[1] = (unsigned char)(a_int >> 16); |
38 | 4.11M | a_output[2] = (unsigned char)(a_int >> 8); |
39 | 4.11M | a_output[3] = (unsigned char)(a_int & 0xFF); |
40 | 4.11M | } |
41 | | |
42 | | static void |
43 | | write_type2_int(gs_fapi_font * a_fapi_font, WRF_output * a_output, long a_int) |
44 | 516k | { |
45 | 516k | if (a_int >= -107 && a_int <= 107) |
46 | 352k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int + 139)); |
47 | 164k | else if (a_int >= -32768 && a_int <= 32767) { |
48 | 164k | if (a_int >= 108 && a_int <= 1131) |
49 | 81.6k | a_int += 63124; |
50 | 82.3k | else if (a_int >= -1131 && a_int <= -108) |
51 | 63.9k | a_int = -a_int + 64148; |
52 | 18.3k | else |
53 | 18.3k | WRF_wbyte(a_fapi_font->memory, a_output, 28); |
54 | 164k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int >> 8)); |
55 | 164k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int & 0xFF)); |
56 | 164k | } else { |
57 | 0 | unsigned char buffer[4]; |
58 | |
|
59 | 0 | WRF_wbyte(a_fapi_font->memory, a_output, 29); |
60 | 0 | write_4_byte_int(buffer, a_int); |
61 | 0 | WRF_wtext(a_fapi_font->memory, a_output, buffer, 4); |
62 | 0 | } |
63 | 516k | } |
64 | | |
65 | | static void |
66 | | write_type2_float(gs_fapi_font * a_fapi_font, WRF_output * a_output, float a_float) |
67 | 216k | { |
68 | 216k | char buffer[32]; |
69 | 216k | const char *p = buffer; |
70 | 216k | int high = true; |
71 | 216k | char c = 0; |
72 | | |
73 | 216k | gs_snprintf(buffer, sizeof(buffer), "%f", a_float); |
74 | 216k | WRF_wbyte(a_fapi_font->memory, a_output, 30); |
75 | 2.00M | for (;;) { |
76 | 2.00M | char n = 0; |
77 | | |
78 | 2.00M | if (*p >= '0' && *p <= '9') |
79 | 1.57M | n = (char)(*p - '0'); |
80 | 434k | else if (*p == '.') |
81 | 216k | n = 0xA; |
82 | 217k | else if (*p == 'e' || *p == 'E') { |
83 | 0 | if (p[1] == '-') { |
84 | 0 | p++; |
85 | 0 | n = 0xC; |
86 | 0 | } else |
87 | 0 | n = 0xB; |
88 | 217k | } else if (*p == '-') |
89 | 208 | n = 0xE; |
90 | 216k | else if (*p == 0) |
91 | 216k | n = 0xF; |
92 | 2.00M | if (high) { |
93 | 1.10M | if (*p == 0) |
94 | 213k | WRF_wbyte(a_fapi_font->memory, a_output, 0xFF); |
95 | 895k | else |
96 | 895k | c = (char)(n << 4); |
97 | 1.10M | } else { |
98 | 895k | c |= n; |
99 | 895k | WRF_wbyte(a_fapi_font->memory, a_output, c); |
100 | 895k | } |
101 | | |
102 | 2.00M | if (*p == 0) |
103 | 216k | break; |
104 | | |
105 | 1.78M | high = !high; |
106 | 1.78M | p++; |
107 | 1.78M | } |
108 | 216k | } |
109 | | |
110 | | static void |
111 | | write_header(gs_fapi_font * a_fapi_font, WRF_output * a_output) |
112 | 24.1k | { |
113 | 24.1k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1\x0\x4\x1", 4); |
114 | 24.1k | } |
115 | | |
116 | | static void |
117 | | write_name_index(gs_fapi_font * a_fapi_font, WRF_output * a_output) |
118 | 24.1k | { |
119 | | /* Write a dummy name of 'x'. */ |
120 | 24.1k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x1\x1\x1\x2" "x", 6); |
121 | 24.1k | } |
122 | | |
123 | | static int |
124 | | write_word_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output, |
125 | | int a_feature_id, int a_feature_count, bool a_two_byte_op, |
126 | | int a_op, int a_divisor) |
127 | 144k | { |
128 | 144k | int code = 0; |
129 | | |
130 | 144k | if (a_feature_count > 0) { |
131 | 144k | int i; |
132 | | |
133 | 361k | for (i = 0; i < a_feature_count; i++) { |
134 | | /* Get the value and convert it from unsigned to signed. */ |
135 | 216k | short x; |
136 | 216k | code = a_fapi_font->get_word(a_fapi_font, a_feature_id, i, (unsigned short *)&x); |
137 | 216k | if (code < 0) |
138 | 0 | return code; |
139 | | |
140 | | /* Divide by the divisor to bring it back to font units. */ |
141 | 216k | x = (short)(x / a_divisor); |
142 | 216k | write_type2_int(a_fapi_font, a_output, x); |
143 | 216k | } |
144 | 144k | if (a_two_byte_op) |
145 | 72.3k | WRF_wbyte(a_fapi_font->memory, a_output, 12); |
146 | 144k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op); |
147 | 144k | } |
148 | 144k | return code; |
149 | 144k | } |
150 | | |
151 | | static int |
152 | | write_delta_array_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output, |
153 | | int a_feature_id, bool a_two_byte_op, int a_op, |
154 | | int a_divisor) |
155 | 144k | { |
156 | 144k | int i, code; |
157 | | |
158 | | /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */ |
159 | 144k | unsigned short count; |
160 | | |
161 | 144k | code = a_fapi_font->get_word(a_fapi_font, a_feature_id - 1, 0, &count); |
162 | | |
163 | 144k | if (code >= 0 && count > 0) { |
164 | 54.0k | short prev_value = 0; |
165 | | |
166 | 328k | for (i = 0; i < count; i++) { |
167 | | /* Get the value and convert it from unsigned to signed. */ |
168 | 274k | short value; |
169 | 274k | code = a_fapi_font->get_word(a_fapi_font, a_feature_id, i, (unsigned short *)&value); |
170 | 274k | if (code < 0) |
171 | 0 | return code; |
172 | | |
173 | | /* Divide by the divisor to bring it back to font units. */ |
174 | 274k | value = (short)(value / a_divisor); |
175 | 274k | write_type2_int(a_fapi_font, a_output, value - prev_value); |
176 | 274k | prev_value = value; |
177 | 274k | } |
178 | 54.0k | if (a_two_byte_op) |
179 | 16.9k | WRF_wbyte(a_fapi_font->memory, a_output, 12); |
180 | 54.0k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op); |
181 | 54.0k | } |
182 | 144k | return code; |
183 | 144k | } |
184 | | |
185 | | static int |
186 | | write_float_entry(gs_fapi_font * a_fapi_font, WRF_output * a_output, |
187 | | int a_feature_id, int a_feature_count, bool a_two_byte_op, |
188 | | int a_op) |
189 | 24.1k | { |
190 | 24.1k | if (a_feature_count > 0) { |
191 | 24.1k | int i, code; |
192 | 24.1k | float x; |
193 | | |
194 | 168k | for (i = 0; i < a_feature_count; i++) { |
195 | 144k | code = a_fapi_font->get_float(a_fapi_font, a_feature_id, i, &x); |
196 | 144k | if (code < 0) |
197 | 0 | return code; |
198 | | |
199 | 144k | write_type2_float(a_fapi_font, a_output, x); |
200 | 144k | } |
201 | 24.1k | if (a_two_byte_op) |
202 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 12); |
203 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op); |
204 | 24.1k | } |
205 | 24.1k | return 0; |
206 | 24.1k | } |
207 | | |
208 | | static int |
209 | | write_font_dict_index(gs_fapi_font * a_fapi_font, WRF_output * a_output, |
210 | | unsigned char **a_charset_offset_ptr, |
211 | | unsigned char **a_charstrings_offset_ptr, |
212 | | unsigned char **a_private_dict_length_ptr) |
213 | 24.1k | { |
214 | 24.1k | unsigned char *data_start = 0; |
215 | 24.1k | int code; |
216 | | |
217 | 24.1k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x1\x2\x0\x1\x0\x0", 7); /* count = 1, offset size = 2, first offset = 1, last offset = 0 (to be filled in later). */ |
218 | 24.1k | if (a_output->m_pos) |
219 | 12.0k | data_start = a_output->m_pos; |
220 | 24.1k | code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontBBox, 4, false, 5, 1); |
221 | 24.1k | if (code < 0) |
222 | 0 | return code; |
223 | | |
224 | 24.1k | code = write_float_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontMatrix, 6, true, 7); |
225 | 24.1k | if (code < 0) |
226 | 0 | return code; |
227 | | |
228 | 24.1k | write_type2_int(a_fapi_font, a_output, 0); /* 0 = Standard Encoding. */ |
229 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 16); /* 16 = opcode for 'encoding'. */ |
230 | 24.1k | *a_charset_offset_ptr = a_output->m_pos; |
231 | 24.1k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */ |
232 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 15); /* opcode for 'charset' */ |
233 | 24.1k | *a_charstrings_offset_ptr = a_output->m_pos; |
234 | 24.1k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */ |
235 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 17); /* opcode for 'Charstrings' */ |
236 | 24.1k | *a_private_dict_length_ptr = a_output->m_pos; |
237 | 24.1k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx\x1d" "yyyy", 10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */ |
238 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 18); /* opcode for 'Private' */ |
239 | 24.1k | if (a_output->m_pos) { |
240 | 12.0k | int last_offset = a_output->m_pos - data_start + 1; |
241 | | |
242 | 12.0k | data_start[-2] = (unsigned char)(last_offset >> 8); |
243 | 12.0k | data_start[-1] = (unsigned char)(last_offset & 0xFF); |
244 | 12.0k | } |
245 | 24.1k | return 0; |
246 | 24.1k | } |
247 | | |
248 | | /** |
249 | | Write the character set. Return the number of characters. |
250 | | For the moment this is always 1. The number cannot be obtained |
251 | | via the FAPI interface, and FreeType doesn't need to know anything more |
252 | | than the fact that there is at least one character. |
253 | | */ |
254 | | static int |
255 | | write_charset(gs_fapi_font * a_fapi_font, WRF_output * a_output, unsigned char *a_charset_offset_ptr) |
256 | 24.1k | { |
257 | 24.1k | const int characters = 2; /* .notdef + one other */ |
258 | 24.1k | int i = 0; |
259 | | |
260 | | /* Write the offset to the start of the charset to the top dictionary. */ |
261 | 24.1k | if (a_output->m_pos) { |
262 | 12.0k | write_4_byte_int(a_charset_offset_ptr + 1, a_output->m_count); |
263 | 12.0k | } |
264 | | /* |
265 | | Write the charset. Write one less than the number of characters, |
266 | | because the first one is assumed to be .notdef. For the moment |
267 | | write all the others as .notdef (SID = 0) because we don't actually |
268 | | need the charset at the moment. |
269 | | */ |
270 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 0); /* format = 0 */ |
271 | 48.2k | for (i = 1; i < characters; i++) { |
272 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 0); |
273 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 0); |
274 | 24.1k | } |
275 | | |
276 | 24.1k | return characters; |
277 | 24.1k | } |
278 | | |
279 | | /** |
280 | | Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell |
281 | | FreeType how many glyphs there are. |
282 | | */ |
283 | | static void |
284 | | write_charstrings_index(gs_fapi_font * a_fapi_font, WRF_output * a_output, int a_characters, |
285 | | unsigned char *a_charstrings_offset_ptr) |
286 | 24.1k | { |
287 | | /* Write the offset to the charstrings index to the top dictionary. */ |
288 | 24.1k | if (a_output->m_pos) { |
289 | 12.0k | write_4_byte_int(a_charstrings_offset_ptr + 1, a_output->m_count); |
290 | 12.0k | } |
291 | | |
292 | | /* Write the index. */ |
293 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters >> 8)); |
294 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters & 0xFF)); |
295 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 1); /* offset size = 1. */ |
296 | 96.4k | while (a_characters-- >= 0) |
297 | 72.3k | WRF_wbyte(a_fapi_font->memory, a_output, 1); /* offset = 1 */ |
298 | 24.1k | } |
299 | | |
300 | | static int |
301 | | write_gsubrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output) |
302 | 24.1k | { |
303 | 24.1k | unsigned char *cur_offset = 0; |
304 | 24.1k | unsigned char *data_start = 0; |
305 | 24.1k | int i; |
306 | 24.1k | unsigned short count; |
307 | 24.1k | int code = a_fapi_font->get_word(a_fapi_font, |
308 | 24.1k | gs_fapi_font_feature_GlobalSubrs_count, |
309 | 24.1k | 0, &count); |
310 | | |
311 | 24.1k | if (code < 0) |
312 | 0 | return code; |
313 | | |
314 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8)); |
315 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF)); |
316 | | |
317 | 24.1k | if (count <= 0) |
318 | 21.2k | return 0; |
319 | | |
320 | 2.81k | WRF_wbyte(a_fapi_font->memory, a_output, 4); /* offset size = 4 bytes */ |
321 | 2.81k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */ |
322 | | |
323 | 2.81k | if (a_output->m_pos) |
324 | 1.38k | cur_offset = a_output->m_pos; |
325 | | |
326 | | /* Write dummy bytes for the offsets at the end of each data item. */ |
327 | 8.00M | for (i = 0; i < count; i++) |
328 | 8.00M | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4); |
329 | | |
330 | 2.81k | if (a_output->m_pos) |
331 | 1.38k | data_start = a_output->m_pos; |
332 | | |
333 | 7.98M | for (i = 0; i < count; i++) { |
334 | 7.98M | long buffer_size = a_output->m_limit - a_output->m_count < 0 ? 0 : a_output->m_limit - a_output->m_count; |
335 | 7.98M | int length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos, buffer_size); |
336 | | |
337 | 7.98M | if (length < 0) |
338 | 92 | return length; |
339 | | |
340 | 7.98M | if (a_output->m_pos) |
341 | 3.98M | a_output->m_pos += length; |
342 | | |
343 | 7.98M | a_output->m_count += length; |
344 | 7.98M | if (cur_offset) { |
345 | 3.98M | long pos = a_output->m_pos - data_start + 1; |
346 | | |
347 | 3.98M | write_4_byte_int(cur_offset, pos); |
348 | 3.98M | cur_offset += 4; |
349 | 3.98M | } |
350 | 7.98M | } |
351 | 2.72k | return 0; |
352 | 2.81k | } |
353 | | |
354 | | static int |
355 | | write_subrs_index(gs_fapi_font * a_fapi_font, WRF_output * a_output) |
356 | 24.1k | { |
357 | 24.1k | unsigned char *cur_offset = 0; |
358 | 24.1k | unsigned char *data_start = 0; |
359 | 24.1k | int i; |
360 | 24.1k | unsigned short count; |
361 | 24.1k | int code = |
362 | 24.1k | a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count, |
363 | 24.1k | 0, &count); |
364 | | |
365 | 24.1k | if (code < 0) |
366 | 0 | return code; |
367 | | |
368 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8)); |
369 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF)); |
370 | | |
371 | 24.1k | if (count <= 0) |
372 | 23.3k | return 0; |
373 | | |
374 | 796 | WRF_wbyte(a_fapi_font->memory, a_output, 4); /* offset size = 4 bytes */ |
375 | 796 | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */ |
376 | | |
377 | 796 | if (a_output->m_pos) |
378 | 372 | cur_offset = a_output->m_pos; |
379 | | |
380 | | /* Write dummy bytes for the offsets at the end of each data item. */ |
381 | 169k | for (i = 0; i < count; i++) |
382 | 168k | WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4); |
383 | | |
384 | 796 | if (a_output->m_pos) |
385 | 372 | data_start = a_output->m_pos; |
386 | | |
387 | 158k | for (i = 0; i < count; i++) { |
388 | 158k | long buffer_size = a_output->m_limit - a_output->m_count; |
389 | 158k | int length = a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos, buffer_size); |
390 | | |
391 | 158k | if (length < 0) |
392 | 52 | return length; |
393 | | |
394 | 158k | if (a_output->m_pos) |
395 | 77.7k | a_output->m_pos += length; |
396 | | |
397 | 158k | a_output->m_count += length; |
398 | 158k | if (cur_offset) { |
399 | 77.7k | long pos = a_output->m_pos - data_start + 1; |
400 | | |
401 | 77.7k | write_4_byte_int(cur_offset, pos); |
402 | 77.7k | cur_offset += 4; |
403 | 77.7k | } |
404 | 158k | } |
405 | 744 | return 0; |
406 | 796 | } |
407 | | |
408 | | static int |
409 | | write_private_dict(gs_fapi_font * a_fapi_font, WRF_output * a_output, |
410 | | unsigned char *a_private_dict_length_ptr) |
411 | 24.1k | { |
412 | 24.1k | int code, initial = a_output->m_count; |
413 | 24.1k | unsigned short count; |
414 | | /* Write the offset to the start of the private dictionary to the top dictionary. */ |
415 | 24.1k | unsigned char *start = a_output->m_pos; |
416 | 24.1k | unsigned long lval; |
417 | 24.1k | gs_font_type1 *t1 = (gs_font_type1 *) a_fapi_font->client_font_data; |
418 | | |
419 | 24.1k | if (a_output->m_pos) |
420 | 12.0k | write_4_byte_int(a_private_dict_length_ptr + 6, a_output->m_count); |
421 | | |
422 | 24.1k | code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueFuzz, 1, |
423 | 24.1k | true, 11, 16); |
424 | 24.1k | if (code < 0) |
425 | 0 | return code; |
426 | 24.1k | code = a_fapi_font->get_long(a_fapi_font, gs_fapi_font_feature_BlueScale, 0, &lval); |
427 | 24.1k | if (code < 0) |
428 | 0 | return code; |
429 | | |
430 | 24.1k | write_type2_float(a_fapi_font, a_output, (float)((double)lval/65536.0)); |
431 | | |
432 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 12); |
433 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 9); |
434 | | |
435 | 24.1k | code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueShift, 1, |
436 | 24.1k | true, 10, 16); |
437 | 24.1k | if (code < 0) |
438 | 0 | return code; |
439 | | |
440 | 24.1k | code = write_delta_array_entry(a_fapi_font, a_output, |
441 | 24.1k | gs_fapi_font_feature_BlueValues, false, 6, 16); |
442 | 24.1k | if (code < 0) |
443 | 0 | return code; |
444 | | |
445 | 24.1k | code = write_delta_array_entry(a_fapi_font, a_output, |
446 | 24.1k | gs_fapi_font_feature_OtherBlues, false, 7, 16); |
447 | 24.1k | if (code < 0) |
448 | 0 | return code; |
449 | | |
450 | 24.1k | code = write_delta_array_entry(a_fapi_font, a_output, |
451 | 24.1k | gs_fapi_font_feature_FamilyBlues, false, 8, 16); |
452 | 24.1k | if (code < 0) |
453 | 0 | return code; |
454 | | |
455 | 24.1k | code = write_delta_array_entry(a_fapi_font, a_output, |
456 | 24.1k | gs_fapi_font_feature_FamilyOtherBlues, false, 9, |
457 | 24.1k | 16); |
458 | 24.1k | if (code < 0) |
459 | 0 | return code; |
460 | | |
461 | 24.1k | code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_ForceBold, 1, |
462 | 24.1k | true, 14, 1); |
463 | 24.1k | if (code < 0) |
464 | 0 | return code; |
465 | | |
466 | 24.1k | code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdHW, 1, |
467 | 24.1k | false, 10, 16); |
468 | 24.1k | if (code < 0) |
469 | 0 | return code; |
470 | | |
471 | 24.1k | code = write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_StdVW, 1, |
472 | 24.1k | false, 11, 16); |
473 | 24.1k | if (code < 0) |
474 | 0 | return code; |
475 | | |
476 | 24.1k | code = write_delta_array_entry(a_fapi_font, a_output, |
477 | 24.1k | gs_fapi_font_feature_StemSnapH, true, 12, 16); |
478 | 24.1k | if (code < 0) |
479 | 0 | return code; |
480 | | |
481 | 24.1k | code = write_delta_array_entry(a_fapi_font, a_output, |
482 | 24.1k | gs_fapi_font_feature_StemSnapV, true, 13, 16); |
483 | 24.1k | if (code < 0) |
484 | 0 | return code; |
485 | | |
486 | | /* |
487 | | Write the default width and the nominal width. These values are not available via |
488 | | the FAPI interface so we have to get a pointer to the Type 1 font structure and |
489 | | extract them directly. |
490 | | */ |
491 | 24.1k | write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.defaultWidthX)); |
492 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 20); |
493 | | |
494 | 24.1k | write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.nominalWidthX)); |
495 | 24.1k | WRF_wbyte(a_fapi_font->memory, a_output, 21); |
496 | | |
497 | 24.1k | code = |
498 | 24.1k | a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count, |
499 | 24.1k | 0, &count); |
500 | 24.1k | if (code < 0) |
501 | 0 | return code; |
502 | | |
503 | | /* If we have local /Subrs we need to make a new dict ( see calling routine) and |
504 | | * we also need to add an entry to the Provate dict with an offset to the /Subrs |
505 | | * dict. This is complicated by the fact that the offset includes the data for |
506 | | * the offset (its contained in the Private dict) and the size of the data depends |
507 | | * on its value (because of number representation). |
508 | | */ |
509 | 24.1k | if (count) { |
510 | 796 | int n = 1, n1; |
511 | | |
512 | 832 | do { |
513 | 832 | n1 = a_output->m_count - initial + 1 + n; /* one for the operator, plus the size needed for the representation */ |
514 | 832 | switch (n) { |
515 | 796 | case 1: |
516 | 796 | if (n1 >= -107 && n1 <= 107) { |
517 | 760 | write_type2_int(a_fapi_font, a_output, n1); |
518 | 760 | n = 5; |
519 | 760 | } |
520 | 796 | break; |
521 | 36 | case 2: |
522 | 36 | if ((n1 >= 108 && n1 <= 1131) |
523 | 36 | || (n1 >= -1131 && n1 <= -108)) { |
524 | 36 | write_type2_int(a_fapi_font, a_output, n1); |
525 | 36 | n = 5; |
526 | 36 | } |
527 | 36 | break; |
528 | 0 | case 3: |
529 | 0 | if (n1 >= -32768 && n1 <= 32767) { |
530 | 0 | write_type2_int(a_fapi_font, a_output, n1); |
531 | 0 | n = 5; |
532 | 0 | } |
533 | 0 | break; |
534 | 0 | case 4: |
535 | 0 | break; |
536 | 0 | case 5: |
537 | 0 | write_type2_int(a_fapi_font, a_output, n1); |
538 | 0 | break; |
539 | 832 | } |
540 | 832 | n++; |
541 | 832 | } |
542 | 832 | while (n < 5); |
543 | | |
544 | 796 | WRF_wbyte(a_fapi_font->memory, a_output, 19); |
545 | 796 | } |
546 | | |
547 | | /* Write the length in bytes of the private dictionary to the top dictionary. */ |
548 | 24.1k | if (a_output->m_pos) |
549 | 12.0k | write_4_byte_int(a_private_dict_length_ptr + 1, |
550 | 12.0k | a_output->m_pos - start); |
551 | 24.1k | return 0; |
552 | 24.1k | } |
553 | | |
554 | | /** |
555 | | Write a Type 2 font in binary format and return its length in bytes. |
556 | | If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total |
557 | | length is returned correctly. |
558 | | */ |
559 | | long |
560 | | gs_fapi_serialize_type2_font(gs_fapi_font * a_fapi_font, |
561 | | unsigned char *a_buffer, long a_buffer_size) |
562 | 24.1k | { |
563 | 24.1k | unsigned char *charset_offset_ptr = NULL; |
564 | 24.1k | unsigned char *charstrings_offset_ptr = NULL; |
565 | 24.1k | unsigned char *private_dict_length_ptr = NULL; |
566 | 24.1k | int characters = 0; |
567 | 24.1k | int code; |
568 | | |
569 | 24.1k | WRF_output output; |
570 | | |
571 | 24.1k | WRF_init(&output, a_buffer, a_buffer_size); |
572 | | |
573 | 24.1k | write_header(a_fapi_font, &output); |
574 | 24.1k | write_name_index(a_fapi_font, &output); |
575 | 24.1k | code = write_font_dict_index(a_fapi_font, &output, &charset_offset_ptr, |
576 | 24.1k | &charstrings_offset_ptr, &private_dict_length_ptr); |
577 | 24.1k | if (code < 0) |
578 | 0 | return (long)code; |
579 | | |
580 | | /* Write an empty string index. */ |
581 | 24.1k | WRF_wtext(a_fapi_font->memory, &output, (const unsigned char *)"\x0\x0", 2); |
582 | | |
583 | 24.1k | write_gsubrs_index(a_fapi_font, &output); |
584 | 24.1k | code = characters = write_charset(a_fapi_font, &output, charset_offset_ptr); |
585 | 24.1k | if (code < 0) |
586 | 0 | return (long)code; |
587 | | |
588 | 24.1k | write_charstrings_index(a_fapi_font, &output, characters, charstrings_offset_ptr); |
589 | | |
590 | 24.1k | code = write_private_dict(a_fapi_font, &output, private_dict_length_ptr); |
591 | 24.1k | if (code < 0) |
592 | 0 | return (long)code; |
593 | | |
594 | 24.1k | code = write_subrs_index(a_fapi_font, &output); |
595 | | |
596 | 24.1k | if (code < 0) |
597 | 52 | return (long)code; |
598 | | |
599 | 24.0k | return output.m_count; |
600 | 24.1k | } |