2 * PostScript driver Type1 font functions
4 * Copyright 2002 Huw D M Davies for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "wine/debug.h"
29 #include "wine/port.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
34 DWORD glyph_sent_size
;
39 #define GLYPH_SENT_INC 128
41 /* Type 1 font commands */
52 TYPE1
*T1_download_header(PSDRV_PDEVICE
*physDev
, LPOUTLINETEXTMETRICA potm
,
58 char dict
[] = /* name, emsquare, fontbbox */
60 " /FontName /%s def\n"
61 " /Encoding 256 array 0 1 255{1 index exch /.notdef put} for def\n"
63 " /FontMatrix [1 %d div 0 0 1 %d div 0 0] def\n"
64 " /FontBBox [%d %d %d %d] def\n"
66 " /Private 7 dict begin\n"
67 " /RD {string currentfile exch readhexstring pop} def\n"
70 " /MinFeature {16 16} def\n"
71 " /BlueValues [] def\n"
72 " /password 5839 def\n"
74 " currentdict end def\n"
75 " currentdict dup /Private get begin\n"
76 " /CharStrings 256 dict begin\n"
77 " /.notdef 4 RD 8b8b0d0e ND\n"
78 " currentdict end put\n"
80 "currentdict end dup /FontName get exch definefont pop\n";
82 t1
= HeapAlloc(GetProcessHeap(), 0, sizeof(*t1
));
83 t1
->emsize
= potm
->otmEMSquare
;
85 t1
->glyph_sent_size
= GLYPH_SENT_INC
;
86 t1
->glyph_sent
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
88 sizeof(*(t1
->glyph_sent
)));
90 buf
= HeapAlloc(GetProcessHeap(), 0, sizeof(dict
) + strlen(ps_name
) +
93 sprintf(buf
, dict
, ps_name
, t1
->emsize
, t1
->emsize
,
94 potm
->otmrcFontBox
.left
, potm
->otmrcFontBox
.bottom
,
95 potm
->otmrcFontBox
.right
, potm
->otmrcFontBox
.top
);
97 PSDRV_WriteSpool(physDev
, buf
, strlen(buf
));
99 HeapFree(GetProcessHeap(), 0, buf
);
109 static STR
*str_init(int sz
)
111 STR
*str
= HeapAlloc(GetProcessHeap(), 0, sizeof(*str
));
113 str
->str
= HeapAlloc(GetProcessHeap(), 0, str
->max_len
);
118 static void str_free(STR
*str
)
120 HeapFree(GetProcessHeap(), 0, str
->str
);
121 HeapFree(GetProcessHeap(), 0, str
);
124 static void str_add_byte(STR
*str
, BYTE b
)
126 if(str
->len
== str
->max_len
) {
128 str
->str
= HeapReAlloc(GetProcessHeap(), 0, str
->str
, str
->max_len
);
130 str
->str
[str
->len
++] = b
;
133 static void str_add_num(STR
*str
, int num
)
135 if(num
<= 107 && num
>= -107)
136 str_add_byte(str
, num
+ 139);
137 else if(num
>= 108 && num
<= 1131) {
138 str_add_byte(str
, ((num
- 108) >> 8) + 247);
139 str_add_byte(str
, (num
- 108) & 0xff);
140 } else if(num
<= -108 && num
>= -1131) {
142 str_add_byte(str
, ((num
- 108) >> 8) + 251);
143 str_add_byte(str
, (num
- 108) & 0xff);
145 str_add_byte(str
, 0xff);
146 str_add_byte(str
, (num
>> 24) & 0xff);
147 str_add_byte(str
, (num
>> 16) & 0xff);
148 str_add_byte(str
, (num
>> 8) & 0xff);
149 str_add_byte(str
, (num
& 0xff));
153 static void str_add_point(STR
*str
, POINTFX
*pt
, POINT
*curpos
)
156 newpos
.x
= pt
->x
.value
+ ((pt
->x
.fract
>> 15) & 0x1);
157 newpos
.y
= pt
->y
.value
+ ((pt
->y
.fract
>> 15) & 0x1);
159 str_add_num(str
, newpos
.x
- curpos
->x
);
160 str_add_num(str
, newpos
.y
- curpos
->y
);
164 static void str_add_cmd(STR
*str
, enum t1_cmds cmd
)
166 str_add_byte(str
, (BYTE
)cmd
);
169 static int str_get_bytes(STR
*str
, BYTE
**b
)
175 BOOL
T1_download_glyph(PSDRV_PDEVICE
*physDev
, DOWNLOAD
*pdl
, DWORD index
,
183 HFONT old_font
, unscaled_font
;
187 TTPOLYGONHEADER
*pph
;
192 char glyph_def_begin
[] =
194 "/Private get begin\n"
195 "/CharStrings get begin\n"
197 char glyph_def_end
[] =
201 TRACE("%ld %s\n", index
, glyph_name
);
202 assert(pdl
->type
== Type1
);
203 t1
= pdl
->typeinfo
.Type1
;
205 if(index
< t1
->glyph_sent_size
) {
206 if(t1
->glyph_sent
[index
])
209 t1
->glyph_sent_size
= (index
/ GLYPH_SENT_INC
+ 1) * GLYPH_SENT_INC
;
210 t1
->glyph_sent
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
212 t1
->glyph_sent_size
* sizeof(*(t1
->glyph_sent
)));
215 GetObjectW(GetCurrentObject(physDev
->hdc
, OBJ_FONT
), sizeof(lf
), &lf
);
216 rc
.left
= rc
.right
= rc
.bottom
= 0;
218 DPtoLP(physDev
->hdc
, (POINT
*)&rc
, 2);
219 lf
.lfHeight
= -abs(rc
.top
- rc
.bottom
);
220 unscaled_font
= CreateFontIndirectW(&lf
);
221 old_font
= SelectObject(physDev
->hdc
, unscaled_font
);
222 len
= GetGlyphOutlineW(physDev
->hdc
, index
, GGO_GLYPH_INDEX
| GGO_BEZIER
,
224 if(len
== GDI_ERROR
) return FALSE
;
225 glyph_buf
= HeapAlloc(GetProcessHeap(), 0, len
);
226 GetGlyphOutlineW(physDev
->hdc
, index
, GGO_GLYPH_INDEX
| GGO_BEZIER
,
227 &gm
, len
, glyph_buf
, NULL
);
229 SelectObject(physDev
->hdc
, old_font
);
230 DeleteObject(unscaled_font
);
232 charstring
= str_init(100);
234 curpos
.x
= gm
.gmptGlyphOrigin
.x
;
237 str_add_num(charstring
, curpos
.x
);
238 str_add_num(charstring
, gm
.gmCellIncX
);
239 str_add_cmd(charstring
, hsbw
);
241 pph
= (TTPOLYGONHEADER
*)glyph_buf
;
242 while((char*)pph
< glyph_buf
+ len
) {
243 TRACE("contour len %ld\n", pph
->cb
);
244 ppc
= (TTPOLYCURVE
*)((char*)pph
+ sizeof(*pph
));
246 str_add_point(charstring
, &pph
->pfxStart
, &curpos
);
247 str_add_cmd(charstring
, rmoveto
);
249 while((char*)ppc
< (char*)pph
+ pph
->cb
) {
250 TRACE("line type %d cpfx = %d\n", ppc
->wType
, ppc
->cpfx
);
253 for(i
= 0; i
< ppc
->cpfx
; i
++) {
254 str_add_point(charstring
, ppc
->apfx
+ i
, &curpos
);
255 str_add_cmd(charstring
, rlineto
);
258 case TT_PRIM_CSPLINE
:
259 for(i
= 0; i
< ppc
->cpfx
/3; i
++) {
260 str_add_point(charstring
, ppc
->apfx
+ 3 * i
, &curpos
);
261 str_add_point(charstring
, ppc
->apfx
+ 3 * i
+ 1, &curpos
);
262 str_add_point(charstring
, ppc
->apfx
+ 3 * i
+ 2, &curpos
);
263 str_add_cmd(charstring
, rrcurveto
);
267 ERR("curve type = %d\n", ppc
->wType
);
270 ppc
= (TTPOLYCURVE
*)((char*)ppc
+ sizeof(*ppc
) +
271 (ppc
->cpfx
- 1) * sizeof(POINTFX
));
273 str_add_cmd(charstring
, closepath
);
274 pph
= (TTPOLYGONHEADER
*)((char*)pph
+ pph
->cb
);
276 str_add_cmd(charstring
, endchar
);
278 buf
= HeapAlloc(GetProcessHeap(), 0, sizeof(glyph_def_begin
) +
279 strlen(pdl
->ps_name
) + strlen(glyph_name
) + 100);
281 sprintf(buf
, "%%%%glyph %04lx\n", index
);
282 PSDRV_WriteSpool(physDev
, buf
, strlen(buf
));
284 len
= str_get_bytes(charstring
, &bytes
);
285 sprintf(buf
, glyph_def_begin
, pdl
->ps_name
, glyph_name
, len
);
286 PSDRV_WriteSpool(physDev
, buf
, strlen(buf
));
287 PSDRV_WriteBytes(physDev
, bytes
, len
);
288 sprintf(buf
, glyph_def_end
);
289 PSDRV_WriteSpool(physDev
, buf
, strlen(buf
));
290 str_free(charstring
);
292 t1
->glyph_sent
[index
] = TRUE
;
293 HeapFree(GetProcessHeap(), 0, glyph_buf
);
294 HeapFree(GetProcessHeap(), 0, buf
);
298 void T1_free(TYPE1
*t1
)
300 HeapFree(GetProcessHeap(), 0, t1
->glyph_sent
);
301 HeapFree(GetProcessHeap(), 0, t1
);