1 /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: write_t2.c,v 1.7 2004/12/08 21:35:13 stefan Exp $ */
18
19 /*
20 Functions to serialize a type 1 font so that it can then be
21 passed to FreeType via the FAPI FreeType bridge.
22 Started by Graham Asher, 9th August 2002.
23 */
24
25 #include "wrfont.h"
26 #include "write_t2.h"
27 #include "ghost.h"
28 #include "gxfont.h"
29 #include "gxfont1.h"
30
31 #include <assert.h>
32
33 /*
34 Public structures and functions in this file are prefixed with FF_ because they are part of
35 the FAPI FreeType implementation.
36 */
37
write_4_byte_int(unsigned char * a_output,long a_int)38 static void write_4_byte_int(unsigned char* a_output,long a_int)
39 {
40 a_output[0] = (unsigned char)(a_int >> 24);
41 a_output[1] = (unsigned char)(a_int >> 16);
42 a_output[2] = (unsigned char)(a_int >> 8);
43 a_output[3] = (unsigned char)(a_int & 0xFF);
44 }
45
write_type2_int(WRF_output * a_output,long a_int)46 static void write_type2_int(WRF_output* a_output,long a_int)
47 {
48 if (a_int >= -107 && a_int <= 107)
49 WRF_wbyte(a_output,(unsigned char)(a_int + 139));
50 else if (a_int >= -32768 && a_int <= 32767)
51 {
52 if (a_int >= 108 && a_int <= 1131)
53 a_int += 63124;
54 else if (a_int >= -1131 && a_int <= -108)
55 a_int = -a_int + 64148;
56 else
57 WRF_wbyte(a_output,28);
58 WRF_wbyte(a_output,(unsigned char)(a_int >> 8));
59 WRF_wbyte(a_output,(unsigned char)(a_int & 0xFF));
60 }
61 else
62 {
63 unsigned char buffer[4];
64 WRF_wbyte(a_output,29);
65 write_4_byte_int(buffer,a_int);
66 WRF_wtext(a_output,buffer,4);
67 }
68 }
69
write_type2_float(WRF_output * a_output,double a_float)70 static void write_type2_float(WRF_output* a_output,double a_float)
71 {
72 char buffer[32];
73 const char* p = buffer;
74 int high = true;
75 char c = 0;
76 sprintf(buffer,"%f",a_float);
77 WRF_wbyte(a_output,30);
78 for (;;)
79 {
80 char n = 0;
81 if (*p >= '0' && *p <= '9')
82 n = (char)(*p - '0');
83 else if (*p == '.')
84 n = 0xA;
85 else if (*p == 'e' || *p == 'E')
86 {
87 if (p[1] == '-')
88 {
89 p++;
90 n = 0xC;
91 }
92 else
93 n = 0xB;
94 }
95 else if (*p == '-')
96 n = 0xE;
97 else if (*p == 0)
98 n = 0xF;
99 if (high)
100 {
101 if (*p == 0)
102 WRF_wbyte(a_output,0xFF);
103 else
104 c = (char)(n << 4);
105 }
106 else
107 {
108 c |= n;
109 WRF_wbyte(a_output,c);
110 }
111
112 if (*p == 0)
113 break;
114
115 high = !high;
116 p++;
117 }
118 }
119
write_header(WRF_output * a_output)120 static void write_header(WRF_output* a_output)
121 {
122 WRF_wtext(a_output,(const unsigned char*)"\x1\x0\x4\x1",4);
123 }
124
write_name_index(WRF_output * a_output)125 static void write_name_index(WRF_output* a_output)
126 {
127 /* Write a dummy name of 'x'. */
128 WRF_wtext(a_output,(const unsigned char*)"\x0\x1\x1\x1\x2""x",6);
129 }
130
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)131 static void write_word_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
132 int a_feature_count,bool a_two_byte_op,int a_op,int a_divisor)
133 {
134 if (a_feature_count > 0)
135 {
136 int i;
137 for (i = 0; i < a_feature_count; i++)
138 {
139 /* Get the value and convert it from unsigned to signed. */
140 short x = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
141 /* Divide by the divisor to bring it back to font units. */
142 x = (short)(x / a_divisor);
143 write_type2_int(a_output,x);
144 }
145 if (a_two_byte_op)
146 WRF_wbyte(a_output,12);
147 WRF_wbyte(a_output,(unsigned char)a_op);
148 }
149 }
150
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)151 static void write_delta_array_entry(FAPI_font* a_fapi_font,WRF_output* a_output,int a_feature_id,
152 bool a_two_byte_op,int a_op,int a_divisor)
153 {
154 int i;
155 /* NOTE that the feature index (a_feature_id) must be preceded by the count index for this to work. */
156 int count = a_fapi_font->get_word(a_fapi_font,a_feature_id - 1,0);
157 if (count > 0)
158 {
159 short prev_value = 0;
160 for (i = 0; i < count; i++)
161 {
162 /* Get the value and convert it from unsigned to signed. */
163 short value = a_fapi_font->get_word(a_fapi_font,a_feature_id,i);
164 /* Divide by the divisor to bring it back to font units. */
165 value = (short)(value / a_divisor);
166 write_type2_int(a_output,value - prev_value);
167 prev_value = value;
168 }
169 if (a_two_byte_op)
170 WRF_wbyte(a_output,12);
171 WRF_wbyte(a_output,(unsigned char)a_op);
172 }
173 }
174
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)175 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)
176 {
177 if (a_feature_count > 0)
178 {
179 int i;
180 for (i = 0; i < a_feature_count; i++)
181 {
182 double x = a_fapi_font->get_float(a_fapi_font,a_feature_id,i);
183 write_type2_float(a_output,x);
184 }
185 if (a_two_byte_op)
186 WRF_wbyte(a_output,12);
187 WRF_wbyte(a_output,(unsigned char)a_op);
188 }
189 }
190
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)191 static void write_font_dict_index(FAPI_font* a_fapi_font,WRF_output* a_output,
192 unsigned char** a_charset_offset_ptr,
193 unsigned char** a_charstrings_offset_ptr,
194 unsigned char** a_private_dict_length_ptr)
195 {
196 unsigned char* data_start = 0;
197 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). */
198 if (a_output->m_pos)
199 data_start = a_output->m_pos;
200 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontBBox,4,false,5,1);
201 write_float_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FontMatrix,6,true,7);
202 write_type2_int(a_output,0); /* 0 = Standard Encoding. */
203 WRF_wbyte(a_output,16); /* 16 = opcode for 'encoding'. */
204 *a_charset_offset_ptr = a_output->m_pos;
205 WRF_wtext(a_output,(const unsigned char *)"\x1d""xxxx",5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */
206 WRF_wbyte(a_output,15); /* opcode for 'charset' */
207 *a_charstrings_offset_ptr = a_output->m_pos;
208 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. */
209 WRF_wbyte(a_output,17); /* opcode for 'Charstrings' */
210 *a_private_dict_length_ptr = a_output->m_pos;
211 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. */
212 WRF_wbyte(a_output,18); /* opcode for 'Private' */
213 if (a_output->m_pos)
214 {
215 int last_offset = a_output->m_pos - data_start + 1;
216 data_start[-2] = (unsigned char)(last_offset >> 8);
217 data_start[-1] = (unsigned char)(last_offset & 0xFF);
218 }
219 }
220
221 /**
222 Write the character set. Return the number of characters.
223 For the moment this is always 1. The number cannot be obtained
224 via the FAPI interface, and FreeType doesn't need to know anything more
225 than the fact that there is at least one character.
226 */
write_charset(WRF_output * a_output,unsigned char * a_charset_offset_ptr)227 static int write_charset(WRF_output* a_output,unsigned char* a_charset_offset_ptr)
228 {
229 const int characters = 1;
230 int i = 0;
231
232 /* Write the offset to the start of the charset to the top dictionary. */
233 if (a_output->m_pos)
234 write_4_byte_int(a_charset_offset_ptr + 1,a_output->m_count);
235
236 /*
237 Write the charset. Write one less than the number of characters,
238 because the first one is assumed to be .notdef. For the moment
239 write all the others as .notdef (SID = 0) because we don't actually
240 need the charset at the moment.
241 */
242 WRF_wbyte(a_output,0); /* format = 0 */
243 for (i = 1; i < characters; i++)
244 {
245 WRF_wbyte(a_output,0);
246 WRF_wbyte(a_output,0);
247 }
248
249 return characters;
250 }
251
252 /**
253 Write a set of empty charstrings. The only reason for the existence of the charstrings index is to tell
254 FreeType how many glyphs there are.
255 */
write_charstrings_index(WRF_output * a_output,int a_characters,unsigned char * a_charstrings_offset_ptr)256 static void write_charstrings_index(WRF_output* a_output,int a_characters,unsigned char* a_charstrings_offset_ptr)
257 {
258 /* Write the offset to the charstrings index to the top dictionary. */
259 if (a_output->m_pos)
260 write_4_byte_int(a_charstrings_offset_ptr + 1,a_output->m_count);
261
262 /* Write the index. */
263 WRF_wbyte(a_output,(unsigned char)(a_characters >> 8));
264 WRF_wbyte(a_output,(unsigned char)(a_characters & 0xFF));
265 WRF_wbyte(a_output,1); /* offset size = 1. */
266 while (a_characters-- >= 0)
267 WRF_wbyte(a_output,1); /* offset = 1 */
268 }
269
write_subrs_index(FAPI_font * a_fapi_font,WRF_output * a_output)270 static void write_subrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
271 {
272 unsigned char* cur_offset = 0;
273 unsigned char* data_start = 0;
274 int i;
275 int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
276 assert(count >= 0);
277
278 WRF_wbyte(a_output,(unsigned char)(count >> 8));
279 WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
280
281 if (count == 0)
282 return;
283
284 WRF_wbyte(a_output,4); /* offset size = 4 bytes */
285 WRF_wtext(a_output,(const unsigned char *)"\x0\x0\x0\x1",4); /* first offset = 1 */
286
287 if (a_output->m_pos)
288 cur_offset = a_output->m_pos;
289
290 /* Write dummy bytes for the offsets at the end of each data item. */
291 for (i = 0; i < count; i++)
292 WRF_wtext(a_output,(const unsigned char *)"xxxx",4);
293
294 if (a_output->m_pos)
295 data_start = a_output->m_pos;
296
297 for (i = 0; i < count; i++)
298 {
299 long buffer_size = a_output->m_limit - a_output->m_count;
300 long length = a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
301 if (a_output->m_pos)
302 WRF_wtext(a_output,a_output->m_pos,length);
303 else
304 a_output->m_count += length;
305 if (cur_offset)
306 {
307 long pos = a_output->m_pos - data_start + 1;
308 write_4_byte_int(cur_offset,pos);
309 cur_offset += 4;
310 }
311 }
312 }
313
write_private_dict(FAPI_font * a_fapi_font,WRF_output * a_output,unsigned char * a_private_dict_length_ptr)314 static void write_private_dict(FAPI_font* a_fapi_font,WRF_output* a_output,unsigned char* a_private_dict_length_ptr)
315 {
316 /* Write the offset to the start of the private dictionary to the top dictionary. */
317 unsigned char* start = a_output->m_pos;
318 if (a_output->m_pos)
319 write_4_byte_int(a_private_dict_length_ptr + 6,a_output->m_count);
320
321 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueFuzz,1,true,11,16);
322
323 write_type2_float(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
324 WRF_wbyte(a_output,12);
325 WRF_wbyte(a_output,9);
326
327 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueShift,1,true,10,16);
328 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueValues,false,6,16);
329 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_OtherBlues,false,7,16);
330 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyBlues,false,8,16);
331 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyOtherBlues,false,9,16);
332 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_ForceBold,1,true,14,1);
333 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdHW,1,false,10,16);
334 write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdVW,1,false,11,16);
335 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapH,true,12,16);
336 write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapV,true,13,16);
337
338 /*
339 Write the default width and the nominal width. These values are not available via
340 the FAPI interface so we have to get a pointer to the Type 1 font structure and
341 extract them directly.
342 */
343 {
344 gs_font_type1* t1 = (gs_font_type1*)a_fapi_font->client_font_data;
345 write_type2_float(a_output,fixed2float(t1->data.defaultWidthX));
346 WRF_wbyte(a_output,20);
347 write_type2_float(a_output,fixed2float(t1->data.nominalWidthX));
348 WRF_wbyte(a_output,21);
349 }
350
351 /* Write the length in bytes of the private dictionary to the top dictionary. */
352 if (a_output->m_pos)
353 write_4_byte_int(a_private_dict_length_ptr + 1,a_output->m_pos - start);
354 }
355
356 /**
357 Write a Type 2 font in binary format and return its length in bytes.
358 If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
359 length is returned correctly.
360 */
FF_serialize_type2_font(FAPI_font * a_fapi_font,unsigned char * a_buffer,long a_buffer_size)361 long FF_serialize_type2_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
362 {
363 unsigned char* charset_offset_ptr = NULL;
364 unsigned char* charstrings_offset_ptr = NULL;
365 unsigned char* private_dict_length_ptr = NULL;
366 int characters = 0;
367
368 WRF_output output;
369 WRF_init(&output,a_buffer,a_buffer_size);
370
371 write_header(&output);
372 write_name_index(&output);
373 write_font_dict_index(a_fapi_font,&output,&charset_offset_ptr,&charstrings_offset_ptr,&private_dict_length_ptr);
374
375 /* Write an empty string index. */
376 WRF_wtext(&output,(const unsigned char *)"\x0\x0",2);
377
378 write_subrs_index(a_fapi_font,&output);
379 characters = write_charset(&output,charset_offset_ptr);
380 write_charstrings_index(&output,characters,charstrings_offset_ptr);
381 write_private_dict(a_fapi_font,&output,private_dict_length_ptr);
382
383 return output.m_count;
384 }
385