1 /* Copyright (C) 2001-2006 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, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13
14 /* $Id: write_t2.c 10614 2010-01-18 08:41:20Z ken $ */
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
22 #include "wrfont.h"
23 #include "write_t2.h"
24 #include "ghost.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
write_4_byte_int(unsigned char * a_output,long a_int)33 static void write_4_byte_int(unsigned char* a_output,long a_int)
34 {
35 a_output[0] = (unsigned char)(a_int >> 24);
36 a_output[1] = (unsigned char)(a_int >> 16);
37 a_output[2] = (unsigned char)(a_int >> 8);
38 a_output[3] = (unsigned char)(a_int & 0xFF);
39 }
40
write_type2_int(WRF_output * a_output,long a_int)41 static void write_type2_int(WRF_output* a_output,long a_int)
42 {
43 if (a_int >= -107 && a_int <= 107)
44 WRF_wbyte(a_output,(unsigned char)(a_int + 139));
45 else if (a_int >= -32768 && a_int <= 32767)
46 {
47 if (a_int >= 108 && a_int <= 1131)
48 a_int += 63124;
49 else if (a_int >= -1131 && a_int <= -108)
50 a_int = -a_int + 64148;
51 else
52 WRF_wbyte(a_output,28);
53 WRF_wbyte(a_output,(unsigned char)(a_int >> 8));
54 WRF_wbyte(a_output,(unsigned char)(a_int & 0xFF));
55 }
56 else
57 {
58 unsigned char buffer[4];
59 WRF_wbyte(a_output,29);
60 write_4_byte_int(buffer,a_int);
61 WRF_wtext(a_output,buffer,4);
62 }
63 }
64
write_type2_float(WRF_output * a_output,double a_float)65 static void write_type2_float(WRF_output* a_output,double a_float)
66 {
67 char buffer[32];
68 const char* p = buffer;
69 int high = true;
70 char c = 0;
71 sprintf(buffer,"%f",a_float);
72 WRF_wbyte(a_output,30);
73 for (;;)
74 {
75 char n = 0;
76 if (*p >= '0' && *p <= '9')
77 n = (char)(*p - '0');
78 else if (*p == '.')
79 n = 0xA;
80 else if (*p == 'e' || *p == 'E')
81 {
82 if (p[1] == '-')
83 {
84 p++;
85 n = 0xC;
86 }
87 else
88 n = 0xB;
89 }
90 else if (*p == '-')
91 n = 0xE;
92 else if (*p == 0)
93 n = 0xF;
94 if (high)
95 {
96 if (*p == 0)
97 WRF_wbyte(a_output,0xFF);
98 else
99 c = (char)(n << 4);
100 }
101 else
102 {
103 c |= n;
104 WRF_wbyte(a_output,c);
105 }
106
107 if (*p == 0)
108 break;
109
110 high = !high;
111 p++;
112 }
113 }
114
write_header(WRF_output * a_output)115 static void write_header(WRF_output* a_output)
116 {
117 WRF_wtext(a_output,(const unsigned char*)"\x1\x0\x4\x1",4);
118 }
119
write_name_index(WRF_output * a_output)120 static void write_name_index(WRF_output* a_output)
121 {
122 /* Write a dummy name of 'x'. */
123 WRF_wtext(a_output,(const unsigned char*)"\x0\x1\x1\x1\x2""x",6);
124 }
125
write_word_entry(FAPI_font * a_fapi_font,WRF_output * a_output,int a_feature_id,int a_feature_count,bool a_two_byte_op,int a_op,int a_divisor)126 static void write_word_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
127 int a_feature_count,bool a_two_byte_op,int a_op,int a_divisor)
128 {
129 if (a_feature_count > 0)
130 {
131 int i;
132 for (i = 0; i < a_feature_count; i++)
133 {
134 /* Get the value and convert it from unsigned to signed. */
135 short x = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
136 /* Divide by the divisor to bring it back to font units. */
137 x = (short)(x / a_divisor);
138 write_type2_int(a_output,x);
139 }
140 if (a_two_byte_op)
141 WRF_wbyte(a_output,12);
142 WRF_wbyte(a_output,(unsigned char)a_op);
143 }
144 }
145
write_delta_array_entry(FAPI_font * a_fapi_font,WRF_output * a_output,int a_feature_id,bool a_two_byte_op,int a_op,int a_divisor)146 static void write_delta_array_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
147 bool a_two_byte_op,int a_op,int a_divisor)
148 {
149 int i;
150 /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */
151 int count = a_fapi_font->get_word(a_fapi_font,a_feature_id - 1,0);
152 if (count > 0)
153 {
154 short prev_value = 0;
155 for (i = 0; i < count; i++)
156 {
157 /* Get the value and convert it from unsigned to signed. */
158 short value = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
159 /* Divide by the divisor to bring it back to font units. */
160 value = (short)(value / a_divisor);
161 write_type2_int(a_output,value - prev_value);
162 prev_value = value;
163 }
164 if (a_two_byte_op)
165 WRF_wbyte(a_output,12);
166 WRF_wbyte(a_output,(unsigned char)a_op);
167 }
168 }
169
write_float_entry(FAPI_font * a_fapi_font,WRF_output * a_output,int a_feature_id,int a_feature_count,bool a_two_byte_op,int a_op)170 static void write_float_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,int a_feature_count,bool a_two_byte_op,int a_op)
171 {
172 if (a_feature_count > 0)
173 {
174 int i;
175 for (i = 0; i < a_feature_count; i++)
176 {
177 double x = a_fapi_font->get_float(a_fapi_font,a_feature_id,i);
178 write_type2_float(a_output,x);
179 }
180 if (a_two_byte_op)
181 WRF_wbyte(a_output,12);
182 WRF_wbyte(a_output,(unsigned char)a_op);
183 }
184 }
185
write_font_dict_index(FAPI_font * a_fapi_font,WRF_output * a_output,unsigned char ** a_charset_offset_ptr,unsigned char ** a_charstrings_offset_ptr,unsigned char ** a_private_dict_length_ptr)186 static void write_font_dict_index(FAPI_font* a_fapi_font,WRF_output* a_output,
187 unsigned char** a_charset_offset_ptr,
188 unsigned char** a_charstrings_offset_ptr,
189 unsigned char** a_private_dict_length_ptr)
190 {
191 unsigned char* data_start = 0;
192 WRF_wtext(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). */
193 if (a_output->m_pos)
194 data_start = a_output->m_pos;
195 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontBBox,4,false,5,1);
196 write_float_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontMatrix,6,true,7);
197 write_type2_int(a_output,0); /* 0 = Standard Encoding. */
198 WRF_wbyte(a_output,16); /* 16 = opcode for 'encoding'. */
199 *a_charset_offset_ptr = a_output->m_pos;
200 WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */
201 WRF_wbyte(a_output,15); /* opcode for 'charset' */
202 *a_charstrings_offset_ptr = a_output->m_pos;
203 WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */
204 WRF_wbyte(a_output,17); /* opcode for 'Charstrings' */
205 *a_private_dict_length_ptr = a_output->m_pos;
206 WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx\x1d""yyyy",10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */
207 WRF_wbyte(a_output,18); /* opcode for 'Private' */
208 if (a_output->m_pos)
209 {
210 int last_offset = a_output->m_pos - data_start + 1;
211 data_start[-2] = (unsigned char)(last_offset >> 8);
212 data_start[-1] = (unsigned char)(last_offset & 0xFF);
213 }
214 }
215
216 /**
217 Write the character set. Return the number of characters.
218 For the moment this is always 1. The number cannot be obtained
219 via the FAPI interface, and FreeType doesn't need to know anything more
220 than the fact that there is at least one character.
221 */
write_charset(WRF_output * a_output,unsigned char * a_charset_offset_ptr)222 static int write_charset(WRF_output* a_output,unsigned char* a_charset_offset_ptr)
223 {
224 const int characters = 1;
225 int i = 0;
226
227 /* Write the offset to the start of the charset to the top dictionary. */
228 if (a_output->m_pos)
229 write_4_byte_int(a_charset_offset_ptr + 1,a_output->m_count);
230
231 /*
232 Write the charset. Write one less than the number of characters,
233 because the first one is assumed to be .notdef. For the moment
234 write all the others as .notdef (SID = 0) because we don't actually
235 need the charset at the moment.
236 */
237 WRF_wbyte(a_output,0); /* format = 0 */
238 for (i = 1; i < characters; i++)
239 {
240 WRF_wbyte(a_output,0);
241 WRF_wbyte(a_output,0);
242 }
243
244 return characters;
245 }
246
247 /**
248 Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell
249 FreeType how many glyphs there are.
250 */
write_charstrings_index(WRF_output * a_output,int a_characters,unsigned char * a_charstrings_offset_ptr)251 static void write_charstrings_index(WRF_output* a_output,int a_characters,unsigned char* a_charstrings_offset_ptr)
252 {
253 /* Write the offset to the charstrings index to the top dictionary. */
254 if (a_output->m_pos)
255 write_4_byte_int(a_charstrings_offset_ptr + 1,a_output->m_count);
256
257 /* Write the index. */
258 WRF_wbyte(a_output,(unsigned char)(a_characters >> 8));
259 WRF_wbyte(a_output,(unsigned char)(a_characters & 0xFF));
260 WRF_wbyte(a_output,1); /* offset size = 1. */
261 while (a_characters-- >= 0)
262 WRF_wbyte(a_output,1); /* offset = 1 */
263 }
264
write_gsubrs_index(FAPI_font * a_fapi_font,WRF_output * a_output)265 static void write_gsubrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
266 {
267 unsigned char* cur_offset = 0;
268 unsigned char* data_start = 0;
269 int i;
270 int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_GlobalSubrs_count,0);
271
272 WRF_wbyte(a_output,(unsigned char)(count >> 8));
273 WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
274
275 if (count <= 0)
276 return;
277
278 WRF_wbyte(a_output,4); /* offset size = 4 bytes */
279 WRF_wtext(a_output,(const unsigned char *)"\x0\x0\x0\x1",4); /* first offset = 1 */
280
281 if (a_output->m_pos)
282 cur_offset = a_output->m_pos;
283
284 /* Write dummy bytes for the offsets at the end of each data item. */
285 for (i = 0; i < count; i++)
286 WRF_wtext(a_output,(const unsigned char *)"xxxx",4);
287
288 if (a_output->m_pos)
289 data_start = a_output->m_pos;
290
291 for (i = 0; i < count; i++)
292 {
293 long buffer_size = a_output->m_limit - a_output->m_count;
294 long length = a_fapi_font->get_gsubr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
295 if (a_output->m_pos)
296 WRF_wtext(a_output,a_output->m_pos,length);
297 else
298 a_output->m_count += length;
299 if (cur_offset)
300 {
301 long pos = a_output->m_pos - data_start + 1;
302 write_4_byte_int(cur_offset,pos);
303 cur_offset += 4;
304 }
305 }
306 }
307
write_subrs_index(FAPI_font * a_fapi_font,WRF_output * a_output)308 static void write_subrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
309 {
310 unsigned char* cur_offset = 0;
311 unsigned char* data_start = 0;
312 int i;
313 int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
314
315 WRF_wbyte(a_output,(unsigned char)(count >> 8));
316 WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
317
318 if (count <= 0)
319 return;
320
321 WRF_wbyte(a_output,4); /* offset size = 4 bytes */
322 WRF_wtext(a_output,(const unsigned char *)"\x0\x0\x0\x1",4); /* first offset = 1 */
323
324 if (a_output->m_pos)
325 cur_offset = a_output->m_pos;
326
327 /* Write dummy bytes for the offsets at the end of each data item. */
328 for (i = 0; i < count; i++)
329 WRF_wtext(a_output,(const unsigned char *)"xxxx",4);
330
331 if (a_output->m_pos)
332 data_start = a_output->m_pos;
333
334 for (i = 0; i < count; i++)
335 {
336 long buffer_size = a_output->m_limit - a_output->m_count;
337 long length = a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
338 if (a_output->m_pos)
339 WRF_wtext(a_output,a_output->m_pos,length);
340 else
341 a_output->m_count += length;
342 if (cur_offset)
343 {
344 long pos = a_output->m_pos - data_start + 1;
345 write_4_byte_int(cur_offset,pos);
346 cur_offset += 4;
347 }
348 }
349 }
350
write_private_dict(FAPI_font * a_fapi_font,WRF_output * a_output,unsigned char * a_private_dict_length_ptr)351 static void write_private_dict(FAPI_font* a_fapi_font,WRF_output* a_output,unsigned char* a_private_dict_length_ptr)
352 {
353 int count, initial = a_output->m_count;
354 /* Write the offset to the start of the private dictionary to the top dictionary. */
355 unsigned char* start = a_output->m_pos;
356 if (a_output->m_pos)
357 write_4_byte_int(a_private_dict_length_ptr + 6,a_output->m_count);
358
359 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueFuzz,1,true,11,16);
360
361 write_type2_float(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
362 WRF_wbyte(a_output,12);
363 WRF_wbyte(a_output,9);
364
365 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueShift,1,true,10,16);
366 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueValues,false,6,16);
367 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_OtherBlues,false,7,16);
368 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyBlues,false,8,16);
369 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyOtherBlues,false,9,16);
370 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_ForceBold,1,true,14,1);
371 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdHW,1,false,10,16);
372 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdVW,1,false,11,16);
373 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapH,true,12,16);
374 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapV,true,13,16);
375
376 /*
377 Write the default width and the nominal width. These values are not available via
378 the FAPI interface so we have to get a pointer to the Type 1 font structure and
379 extract them directly.
380 */
381 {
382 gs_font_type1* t1 = (gs_font_type1*)a_fapi_font->client_font_data;
383 write_type2_float(a_output,fixed2float(t1->data.defaultWidthX));
384 WRF_wbyte(a_output,20);
385 write_type2_float(a_output,fixed2float(t1->data.nominalWidthX));
386 WRF_wbyte(a_output,21);
387 }
388
389 count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
390 /* If we have local /Subrs we need to make a new dict ( see calling routine) and
391 * we also need to add an entry to the Provate dict with an offset to the /Subrs
392 * dict. This is complicated by the fact that the offset includes the data for
393 * the offset (its contained in the Private dict) and the size of the data depends
394 * on its value (because of number representation).
395 */
396 if (count) {
397 unsigned int n = 1, n1 = a_output->m_count - initial + 2; /* One for the operator, one for the first try at the data representation */
398
399 do {
400 n1 = a_output->m_count - initial + 1 + n;
401 switch (n) {
402 case 1:
403 if (n1 >= -107 && n <= 107) {
404 write_type2_int(a_output, n1);
405 n = 5;
406 }
407 break;
408 case 2:
409 if ((n1 >= 108 && n <= 1131) || (n1 >= -1131 && n1 <= -108)) {
410 write_type2_int(a_output, n1);
411 n = 5;
412 }
413 break;
414 case 3:
415 if (n1 >= -32768 && n <= 32767) {
416 write_type2_int(a_output, n1);
417 n = 5;
418 }
419 break;
420 case 4:
421 break;
422 case 5:
423 write_type2_int(a_output, n1);
424 break;
425 }
426 n++;
427 } while (n < 5);
428
429 WRF_wbyte(a_output,19);
430 }
431
432 /* Write the length in bytes of the private dictionary to the top dictionary. */
433 if (a_output->m_pos)
434 write_4_byte_int(a_private_dict_length_ptr + 1,a_output->m_pos - start);
435 }
436
437 /**
438 Write a Type 2 font in binary format and return its length in bytes.
439 If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
440 length is returned correctly.
441 */
FF_serialize_type2_font(FAPI_font * a_fapi_font,unsigned char * a_buffer,long a_buffer_size)442 long FF_serialize_type2_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
443 {
444 unsigned char* charset_offset_ptr = NULL;
445 unsigned char* charstrings_offset_ptr = NULL;
446 unsigned char* private_dict_length_ptr = NULL;
447 int characters = 0;
448
449 WRF_output output;
450 WRF_init(&output,a_buffer,a_buffer_size);
451
452 write_header(&output);
453 write_name_index(&output);
454 write_font_dict_index(a_fapi_font,&output,&charset_offset_ptr,&charstrings_offset_ptr,&private_dict_length_ptr);
455
456 /* Write an empty string index. */
457 WRF_wtext(&output,(const unsigned char *)"\x0\x0",2);
458
459 write_gsubrs_index(a_fapi_font,&output);
460 characters = write_charset(&output,charset_offset_ptr);
461 write_charstrings_index(&output,characters,charstrings_offset_ptr);
462 write_private_dict(a_fapi_font,&output,private_dict_length_ptr);
463 write_subrs_index(a_fapi_font,&output);
464
465 return output.m_count;
466 }
467