1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
14
/* $Id: write_t2.c 8022 2007-06-05 22:23:38Z giles $ */
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.
29
Public structures and functions in this file are prefixed with FF_ because they are part of
30
the FAPI FreeType implementation.
33
static void write_4_byte_int(unsigned char* a_output,long a_int)
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);
41
static void write_type2_int(WRF_output* a_output,long a_int)
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)
47
if (a_int >= 108 && a_int <= 1131)
49
else if (a_int >= -1131 && a_int <= -108)
50
a_int = -a_int + 64148;
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));
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);
65
static void write_type2_float(WRF_output* a_output,double a_float)
68
const char* p = buffer;
71
sprintf(buffer,"%f",a_float);
72
WRF_wbyte(a_output,30);
76
if (*p >= '0' && *p <= '9')
80
else if (*p == 'e' || *p == 'E')
97
WRF_wbyte(a_output,0xFF);
104
WRF_wbyte(a_output,c);
115
static void write_header(WRF_output* a_output)
117
WRF_wtext(a_output,(const unsigned char*)"\x1\x0\x4\x1",4);
120
static void write_name_index(WRF_output* a_output)
122
/* Write a dummy name of 'x'. */
123
WRF_wtext(a_output,(const unsigned char*)"\x0\x1\x1\x1\x2""x",6);
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)
129
if (a_feature_count > 0)
132
for (i = 0; i < a_feature_count; i++)
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);
141
WRF_wbyte(a_output,12);
142
WRF_wbyte(a_output,(unsigned char)a_op);
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)
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);
154
short prev_value = 0;
155
for (i = 0; i < count; i++)
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);
165
WRF_wbyte(a_output,12);
166
WRF_wbyte(a_output,(unsigned char)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)
172
if (a_feature_count > 0)
175
for (i = 0; i < a_feature_count; i++)
177
double x = a_fapi_font->get_float(a_fapi_font,a_feature_id,i);
178
write_type2_float(a_output,x);
181
WRF_wbyte(a_output,12);
182
WRF_wbyte(a_output,(unsigned char)a_op);
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)
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). */
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' */
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);
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.
222
static int write_charset(WRF_output* a_output,unsigned char* a_charset_offset_ptr)
224
const int characters = 1;
227
/* Write the offset to the start of the charset to the top dictionary. */
229
write_4_byte_int(a_charset_offset_ptr + 1,a_output->m_count);
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.
237
WRF_wbyte(a_output,0); /* format = 0 */
238
for (i = 1; i < characters; i++)
240
WRF_wbyte(a_output,0);
241
WRF_wbyte(a_output,0);
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.
251
static void write_charstrings_index(WRF_output* a_output,int a_characters,unsigned char* a_charstrings_offset_ptr)
253
/* Write the offset to the charstrings index to the top dictionary. */
255
write_4_byte_int(a_charstrings_offset_ptr + 1,a_output->m_count);
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 */
265
static void write_subrs_index(FAPI_font* a_fapi_font,WRF_output* a_output)
267
unsigned char* cur_offset = 0;
268
unsigned char* data_start = 0;
270
int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
272
WRF_wbyte(a_output,(unsigned char)(count >> 8));
273
WRF_wbyte(a_output,(unsigned char)(count & 0xFF));
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 */
282
cur_offset = a_output->m_pos;
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);
289
data_start = a_output->m_pos;
291
for (i = 0; i < count; i++)
293
long buffer_size = a_output->m_limit - a_output->m_count;
294
long length = a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)buffer_size);
296
WRF_wtext(a_output,a_output->m_pos,length);
298
a_output->m_count += length;
301
long pos = a_output->m_pos - data_start + 1;
302
write_4_byte_int(cur_offset,pos);
308
static void write_private_dict(FAPI_font* a_fapi_font,WRF_output* a_output,unsigned char* a_private_dict_length_ptr)
310
/* Write the offset to the start of the private dictionary to the top dictionary. */
311
unsigned char* start = a_output->m_pos;
313
write_4_byte_int(a_private_dict_length_ptr + 6,a_output->m_count);
315
write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueFuzz,1,true,11,16);
317
write_type2_float(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
318
WRF_wbyte(a_output,12);
319
WRF_wbyte(a_output,9);
321
write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueShift,1,true,10,16);
322
write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_BlueValues,false,6,16);
323
write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_OtherBlues,false,7,16);
324
write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyBlues,false,8,16);
325
write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_FamilyOtherBlues,false,9,16);
326
write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_ForceBold,1,true,14,1);
327
write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdHW,1,false,10,16);
328
write_word_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StdVW,1,false,11,16);
329
write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapH,true,12,16);
330
write_delta_array_entry(a_fapi_font,a_output,FAPI_FONT_FEATURE_StemSnapV,true,13,16);
333
Write the default width and the nominal width. These values are not available via
334
the FAPI interface so we have to get a pointer to the Type 1 font structure and
335
extract them directly.
338
gs_font_type1* t1 = (gs_font_type1*)a_fapi_font->client_font_data;
339
write_type2_float(a_output,fixed2float(t1->data.defaultWidthX));
340
WRF_wbyte(a_output,20);
341
write_type2_float(a_output,fixed2float(t1->data.nominalWidthX));
342
WRF_wbyte(a_output,21);
345
/* Write the length in bytes of the private dictionary to the top dictionary. */
347
write_4_byte_int(a_private_dict_length_ptr + 1,a_output->m_pos - start);
351
Write a Type 2 font in binary format and return its length in bytes.
352
If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
353
length is returned correctly.
355
long FF_serialize_type2_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
357
unsigned char* charset_offset_ptr = NULL;
358
unsigned char* charstrings_offset_ptr = NULL;
359
unsigned char* private_dict_length_ptr = NULL;
363
WRF_init(&output,a_buffer,a_buffer_size);
365
write_header(&output);
366
write_name_index(&output);
367
write_font_dict_index(a_fapi_font,&output,&charset_offset_ptr,&charstrings_offset_ptr,&private_dict_length_ptr);
369
/* Write an empty string index. */
370
WRF_wtext(&output,(const unsigned char *)"\x0\x0",2);
372
write_subrs_index(a_fapi_font,&output);
373
characters = write_charset(&output,charset_offset_ptr);
374
write_charstrings_index(&output,characters,charstrings_offset_ptr);
375
write_private_dict(a_fapi_font,&output,private_dict_length_ptr);
377
return output.m_count;