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