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_t1.c,v 1.5 2004/12/08 21:35:13 stefan Exp $ */
18
19 /*
20 Functions to serialize a type 1 font as PostScript code that can then be
21 passed to FreeType via the FAPI FreeType bridge.
22 Started by Graham Asher, 26th July 2002.
23 */
24
25 #include "wrfont.h"
26 #include "write_t1.h"
27
28 #include <assert.h>
29
30 /*
31 Public structures and functions in this file are prefixed with FF_ because they are part of
32 the FAPI FreeType implementation.
33 */
34
write_word_entry(FAPI_font * a_fapi_font,WRF_output * a_output,const char * a_name,int a_index,int a_divisor)35 static void write_word_entry(FAPI_font* a_fapi_font,WRF_output* a_output,const char* a_name,int a_index,int a_divisor)
36 {
37 short x;
38 WRF_wbyte(a_output,'/');
39 WRF_wstring(a_output,a_name);
40 WRF_wbyte(a_output,' ');
41 /* Get the value and convert it from unsigned to signed by assigning it to a short. */
42 x = a_fapi_font->get_word(a_fapi_font,a_index,0);
43 /* Divide by the divisor to bring it back to font units. */
44 x = (short)(x / a_divisor);
45 WRF_wint(a_output,x);
46 WRF_wstring(a_output," def\n");
47 }
48
write_array_entry_with_count(FAPI_font * a_fapi_font,WRF_output * a_output,const char * a_name,int a_index,int a_count,int a_divisor)49 static void write_array_entry_with_count(FAPI_font* a_fapi_font,WRF_output* a_output,const char* a_name,int a_index,int a_count,int a_divisor)
50 {
51 int i;
52
53 assert(a_count >= 0);
54 if (a_count == 0)
55 return;
56
57 WRF_wbyte(a_output,'/');
58 WRF_wstring(a_output,a_name);
59 WRF_wstring(a_output," [");
60 for (i = 0; i < a_count; i++)
61 {
62 /* Get the value and convert it from unsigned to signed by assigning it to a short. */
63 short x = a_fapi_font->get_word(a_fapi_font,a_index,i);
64 /* Divide by the divisor to bring it back to font units. */
65 x = (short)(x / a_divisor);
66 WRF_wint(a_output,x);
67 WRF_wbyte(a_output,(byte)(i == a_count - 1 ? ']' : ' '));
68 }
69 WRF_wstring(a_output," def\n");
70 }
71
72
write_array_entry(FAPI_font * a_fapi_font,WRF_output * a_output,const char * a_name,int a_index,int a_divisor)73 static void write_array_entry(FAPI_font* a_fapi_font,WRF_output* a_output,const char* a_name,int a_index,int a_divisor)
74 {
75 /* NOTE that the feature index must be preceded by the count index for this to work. */
76 int count = a_fapi_font->get_word(a_fapi_font,a_index - 1,0);
77 write_array_entry_with_count(a_fapi_font,a_output,a_name,a_index,count,a_divisor);
78 }
79
write_subrs(FAPI_font * a_fapi_font,WRF_output * a_output)80 static void write_subrs(FAPI_font* a_fapi_font,WRF_output* a_output)
81 {
82 int i;
83 int count = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_Subrs_count,0);
84 assert(count >= 0);
85 if (count == 0)
86 return;
87
88 WRF_wstring(a_output,"/Subrs ");
89 WRF_wint(a_output,count);
90 WRF_wstring(a_output," array\n");
91
92 for (i = 0; i < count; i++)
93 {
94 long length = a_fapi_font->get_subr(a_fapi_font,i,0,0);
95 long buffer_size;
96 WRF_wstring(a_output,"dup ");
97 WRF_wint(a_output,i);
98 WRF_wbyte(a_output,' ');
99 WRF_wint(a_output,length);
100 WRF_wstring(a_output," RD ");
101
102 /* Get the subroutine into the buffer and encrypt it in place. */
103 buffer_size = a_output->m_limit - a_output->m_count;
104 if (buffer_size >= length)
105 {
106 a_fapi_font->get_subr(a_fapi_font,i,a_output->m_pos,(ushort)length);
107 WRF_wtext(a_output,a_output->m_pos,length);
108 }
109 else
110 a_output->m_count += length;
111
112 WRF_wstring(a_output," NP\n");
113 }
114
115 WRF_wstring(a_output,"ND\n");
116 }
117
write_private_dictionary(FAPI_font * a_fapi_font,WRF_output * a_output)118 static void write_private_dictionary(FAPI_font* a_fapi_font,WRF_output* a_output)
119 {
120 assert(!a_output->m_encrypt);
121 a_output->m_encrypt = true;
122
123 /* Write 4 bytes that must encrypt to at least one character that cannot be a valid hexadecimal character. */
124 WRF_wstring(a_output,"XXXX");
125
126 /*+ to do: correct size of dictionary from 8. */
127 WRF_wstring(a_output,"dup /Private 8 dict dup begin\n");
128
129 WRF_wstring(a_output,"/MinFeature {16 16} def\n");
130 WRF_wstring(a_output,"/password 5839 def\n");
131 WRF_wstring(a_output,"/lenIV -1 def\n"); /* indicate that /subrs are not encoded. */
132 write_word_entry(a_fapi_font,a_output,"BlueFuzz",FAPI_FONT_FEATURE_BlueFuzz,16);
133
134 WRF_wstring(a_output,"/BlueScale ");
135 WRF_wfloat(a_output,a_fapi_font->get_long(a_fapi_font,FAPI_FONT_FEATURE_BlueScale,0) / 65536.0);
136 WRF_wstring(a_output," def\n");
137
138 write_word_entry(a_fapi_font,a_output,"BlueShift",FAPI_FONT_FEATURE_BlueShift,16);
139 write_array_entry(a_fapi_font,a_output,"BlueValues",FAPI_FONT_FEATURE_BlueValues,16);
140 write_array_entry(a_fapi_font,a_output,"OtherBlues",FAPI_FONT_FEATURE_OtherBlues,16);
141 write_array_entry(a_fapi_font,a_output,"FamilyBlues",FAPI_FONT_FEATURE_FamilyBlues,16);
142 write_array_entry(a_fapi_font,a_output,"FamilyOtherBlues",FAPI_FONT_FEATURE_FamilyOtherBlues,16);
143 write_word_entry(a_fapi_font,a_output,"ForceBold",FAPI_FONT_FEATURE_ForceBold,1);
144 write_array_entry_with_count(a_fapi_font,a_output,"StdHW",FAPI_FONT_FEATURE_StdHW,1,16);
145 write_array_entry_with_count(a_fapi_font,a_output,"StdVW",FAPI_FONT_FEATURE_StdVW,1,16);
146 write_array_entry(a_fapi_font,a_output,"StemSnapH",FAPI_FONT_FEATURE_StemSnapH,16);
147 write_array_entry(a_fapi_font,a_output,"StemSnapV",FAPI_FONT_FEATURE_StemSnapV,16);
148
149 write_subrs(a_fapi_font,a_output);
150 }
151
write_main_dictionary(FAPI_font * a_fapi_font,WRF_output * a_output)152 static void write_main_dictionary(FAPI_font* a_fapi_font,WRF_output* a_output)
153 {
154 int i;
155 WRF_wstring(a_output,"5 dict begin\n");
156
157 WRF_wstring(a_output,"/FontType 1 def\n");
158
159 WRF_wstring(a_output,"/FontMatrix [");
160 for (i = 0; i < 6; i++)
161 {
162 WRF_wfloat(a_output,a_fapi_font->get_float(a_fapi_font,FAPI_FONT_FEATURE_FontMatrix,i));
163 WRF_wbyte(a_output,(byte)(i == 5 ? ']' : ' '));
164 }
165 WRF_wbyte(a_output,'\n');
166
167 /* For now, specify standard encoding - I think GS will pass glyph indices so doesn't matter. */
168 WRF_wstring(a_output,"/Encoding StandardEncoding def\n");
169
170 WRF_wstring(a_output,"/FontBBox {");
171 for (i = 0; i < 4; i++)
172 {
173 short x = a_fapi_font->get_word(a_fapi_font,FAPI_FONT_FEATURE_FontBBox,i);
174 WRF_wint(a_output,x);
175 WRF_wbyte(a_output,(byte)(i == 3 ? '}' : ' '));
176 }
177 WRF_wbyte(a_output,'\n');
178 WRF_wstring(a_output,"currentdict end\ncurrentfile eexec\n");
179 write_private_dictionary(a_fapi_font,a_output);
180 }
181
182 /**
183 Write a Type 1 font in textual format and return its length in bytes.
184 If a_buffer_size is less than the total length, only a_buffer_size bytes are written, but the total
185 length is returned correctly.
186
187 The PostScript is non-standard. The main dictionary contains no /Charstrings dictionary. This
188 is supplied to FreeType using the incremental interface, There is also no /PaintType entry. This is required
189 by PostScript but FreeType doesn't use it.
190 */
FF_serialize_type1_font(FAPI_font * a_fapi_font,unsigned char * a_buffer,long a_buffer_size)191 long FF_serialize_type1_font(FAPI_font* a_fapi_font,unsigned char* a_buffer,long a_buffer_size)
192 {
193 WRF_output output;
194 WRF_init(&output,a_buffer,a_buffer_size);
195
196 /* Leading comment identifying a Type 1 font. */
197 WRF_wstring(&output,"%!PS-AdobeFont-1\n");
198
199 write_main_dictionary(a_fapi_font,&output);
200 return output.m_count;
201 }
202