Avoid local WINAPI function pointers in _invoke.
[wine] / dlls / wineps / download.c
1 /*
2  *      PostScript driver downloadable font functions
3  *
4  *      Copyright 2002  Huw D M Davies for CodeWeavers
5  *
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.
10  *
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.
15  *
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
19  */
20 #include <string.h>
21 #include <stdlib.h>
22 #include <assert.h>
23 #include <stdio.h>
24
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "wingdi.h"
28 #include "winspool.h"
29
30 #include "gdi.h"
31 #include "psdrv.h"
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
35
36
37 /****************************************************************************
38  *  get_download_name
39  */
40 static void get_download_name(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA
41                               potm, char **str)
42 {
43     int len;
44     char *p;
45     len = strlen((char*)potm + (ptrdiff_t)potm->otmpFullName) + 1;
46     *str = HeapAlloc(GetProcessHeap(),0,len);
47     strcpy(*str, (char*)potm + (ptrdiff_t)potm->otmpFullName);
48
49     p = *str;
50     while((p = strchr(p, ' ')))
51         *p = '_';
52
53     return;
54 }
55
56 /****************************************************************************
57  *  is_font_downloaded
58  */
59 static DOWNLOAD *is_font_downloaded(PSDRV_PDEVICE *physDev, char *ps_name)
60 {
61     DOWNLOAD *pdl;
62
63     for(pdl = physDev->downloaded_fonts; pdl; pdl = pdl->next)
64         if(!strcmp(pdl->ps_name, ps_name))
65             break;
66     return pdl;
67 }
68
69 /****************************************************************************
70  *  PSDRV_SelectDownloadFont
71  *
72  *  Set up physDev->font for a downloadable font
73  *
74  */
75 BOOL PSDRV_SelectDownloadFont(PSDRV_PDEVICE *physDev)
76 {
77     char *ps_name;
78     LPOUTLINETEXTMETRICA potm;
79     DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
80
81     potm = HeapAlloc(GetProcessHeap(), 0, len);
82     GetOutlineTextMetricsA(physDev->hdc, len, potm);
83     get_download_name(physDev, potm, &ps_name);
84
85     physDev->font.fontloc = Download;
86     physDev->font.fontinfo.Download = is_font_downloaded(physDev, ps_name);
87
88     physDev->font.size = INTERNAL_YWSTODS(physDev->dc, /* ppem */
89                                           potm->otmTextMetrics.tmAscent +
90                                           potm->otmTextMetrics.tmDescent -
91                                           potm->otmTextMetrics.tmInternalLeading);
92     physDev->font.underlineThickness = potm->otmsUnderscoreSize;
93     physDev->font.underlinePosition = potm->otmsUnderscorePosition;
94     physDev->font.strikeoutThickness = potm->otmsStrikeoutSize;
95     physDev->font.strikeoutPosition = potm->otmsStrikeoutPosition;
96
97     HeapFree(GetProcessHeap(), 0, ps_name);
98     HeapFree(GetProcessHeap(), 0, potm);
99     return TRUE;
100 }
101
102 /****************************************************************************
103  *  PSDRV_WriteSetDownloadFont
104  *
105  *  Write setfont for download font.
106  *
107  */
108 BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev)
109 {
110     char *ps_name;
111     LPOUTLINETEXTMETRICA potm;
112     DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
113     DOWNLOAD *pdl;
114
115     assert(physDev->font.fontloc == Download);
116
117     potm = HeapAlloc(GetProcessHeap(), 0, len);
118     GetOutlineTextMetricsA(physDev->hdc, len, potm);
119
120     get_download_name(physDev, potm, &ps_name);
121
122     if(physDev->font.fontinfo.Download == NULL) {
123         pdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pdl));
124         pdl->ps_name = HeapAlloc(GetProcessHeap(), 0, strlen(ps_name)+1);
125         strcpy(pdl->ps_name, ps_name);
126         pdl->next = NULL;
127
128         if(physDev->pi->ppd->TTRasterizer == RO_Type42) {
129             pdl->typeinfo.Type42 = T42_download_header(physDev, potm,
130                                                        ps_name);
131             pdl->type = Type42;
132         }
133         if(pdl->typeinfo.Type42 == NULL) {
134             pdl->typeinfo.Type1 = T1_download_header(physDev, potm, ps_name);
135             pdl->type = Type1;
136         }
137         pdl->next = physDev->downloaded_fonts;
138         physDev->downloaded_fonts = pdl;
139         physDev->font.fontinfo.Download = pdl;
140     }
141
142
143     PSDRV_WriteSetFont(physDev, ps_name, physDev->font.size,
144                        physDev->font.escapement);
145
146     HeapFree(GetProcessHeap(), 0, ps_name);
147     HeapFree(GetProcessHeap(), 0, potm);
148     return TRUE;
149 }
150
151 void get_glyph_name(HDC hdc, WORD index, char *name)
152 {
153   /* FIXME */
154     sprintf(name, "g%04x", index);
155     return;
156 }
157
158 /****************************************************************************
159  *  PSDRV_WriteDownloadGlyphShow
160  *
161  *  Download and write out a number of glyphs
162  *
163  */
164 BOOL PSDRV_WriteDownloadGlyphShow(PSDRV_PDEVICE *physDev, WORD *glyphs,
165                                   UINT count)
166 {
167     UINT i;
168     char g_name[MAX_G_NAME + 1];
169     assert(physDev->font.fontloc == Download);
170
171     switch(physDev->font.fontinfo.Download->type) {
172     case Type42:
173     for(i = 0; i < count; i++) {
174         get_glyph_name(physDev->hdc, glyphs[i], g_name);
175         T42_download_glyph(physDev, physDev->font.fontinfo.Download,
176                            glyphs[i], g_name);
177         PSDRV_WriteGlyphShow(physDev, g_name);
178     }
179     break;
180
181     case Type1:
182     for(i = 0; i < count; i++) {
183         get_glyph_name(physDev->hdc, glyphs[i], g_name);
184         T1_download_glyph(physDev, physDev->font.fontinfo.Download,
185                           glyphs[i], g_name);
186         PSDRV_WriteGlyphShow(physDev, g_name);
187     }
188     break;
189
190     default:
191         ERR("Type = %d\n", physDev->font.fontinfo.Download->type);
192         assert(0);
193     }
194     return TRUE;
195 }
196
197 /****************************************************************************
198  *  PSDRV_EmptyDownloadList
199  *
200  *  Clear the list of downloaded fonts
201  *
202  */
203 BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev)
204 {
205     DOWNLOAD *pdl, *old;
206     if(physDev->font.fontloc == Download) {
207         physDev->font.set = FALSE;
208         physDev->font.fontinfo.Download = NULL;
209     }
210
211     pdl = physDev->downloaded_fonts;
212     physDev->downloaded_fonts = NULL;
213     while(pdl) {
214         switch(pdl->type) {
215         case Type42:
216             T42_free(pdl->typeinfo.Type42);
217             break;
218
219         case Type1:
220             T1_free(pdl->typeinfo.Type1);
221             break;
222
223         default:
224             ERR("Type = %d\n", pdl->type);
225             assert(0);
226         }
227
228         HeapFree(GetProcessHeap(), 0, pdl->ps_name);
229         old = pdl;
230         pdl = pdl->next;
231         HeapFree(GetProcessHeap(), 0, old);
232     }
233     return TRUE;
234 }