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