Added RtlAllocateAndInitializeSid entry.
[wine] / graphics / psdrv / font.c
1 /*
2  *      PostScript driver font functions
3  *
4  *      Copyright 1998  Huw D M Davies
5  *
6  */
7 #include <string.h>
8 #include "windows.h"
9 #include "print.h"
10 #include "psdrv.h"
11 #include "debug.h"
12
13
14
15 /***********************************************************************
16  *           PSDRV_FONT_SelectObject
17  */
18 HFONT16 PSDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
19                                         FONTOBJ *font )
20 {
21     HFONT16 prevfont = dc->w.hFont;
22     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
23     LOGFONT16 *lf = &(font->logfont);
24     BOOL32 bd = FALSE, it = FALSE;
25     AFMLISTENTRY *afmle;
26     AFM *afm;
27     FONTFAMILY *family;
28     char FaceName[LF_FACESIZE];
29
30
31     TRACE(psdrv, "FaceName = '%s' Height = %d Italic = %d Weight = %d\n",
32           lf->lfFaceName, lf->lfHeight, lf->lfItalic, lf->lfWeight);
33
34     dc->w.hFont = hfont;
35
36     if(lf->lfItalic)
37         it = TRUE;
38     if(lf->lfWeight > 550)
39         bd = TRUE;
40     strcpy(FaceName, lf->lfFaceName);
41     
42     if(FaceName[0] == '\0') {
43         switch(lf->lfPitchAndFamily & 0xf0) {
44         case FF_DONTCARE:
45             break;
46         case FF_ROMAN:
47         case FF_SCRIPT:
48             strcpy(FaceName, "Times");
49             break;
50         case FF_SWISS:
51             strcpy(FaceName, "Helvetica");
52             break;
53         case FF_MODERN:
54             strcpy(FaceName, "Courier");
55             break;
56         case FF_DECORATIVE:
57             strcpy(FaceName, "Symbol");
58             break;
59         }
60     }
61
62     if(FaceName[0] == '\0') {
63         switch(lf->lfPitchAndFamily & 0x0f) {
64         case VARIABLE_PITCH:
65             strcpy(FaceName, "Times");
66             break;
67         default:
68             strcpy(FaceName, "Courier");
69             break;
70         }
71     }
72
73     TRACE(psdrv, "Trying to find facename '%s'\n", FaceName);
74
75     for(family = physDev->pi->Fonts; family; family = family->next) {
76         if(!strcmp(FaceName, family->FamilyName))
77             break;
78     }
79     if(!family)
80         family = physDev->pi->Fonts;
81
82     TRACE(psdrv, "Got family '%s'\n", family->FamilyName);
83
84     for(afmle = family->afmlist; afmle; afmle = afmle->next) {
85         if( (bd == (afmle->afm->Weight == FW_BOLD)) && 
86             (it == (afmle->afm->ItalicAngle != 0.0)) )
87                 break;
88     }
89     if(!afmle)
90         afmle = family->afmlist; /* not ideal */
91     
92     afm = afmle->afm;
93
94     physDev->font.afm = afm;
95     physDev->font.tm.tmHeight = YLSTODS(dc, lf->lfHeight);
96     if(physDev->font.tm.tmHeight < 0) {
97         physDev->font.tm.tmHeight *= - (afm->FullAscender - afm->Descender) /
98                                        (afm->Ascender - afm->Descender);
99         TRACE(psdrv, "Fixed -ve height to %d\n", physDev->font.tm.tmHeight);
100     }
101     physDev->font.size = physDev->font.tm.tmHeight * 1000.0 /
102                                 (afm->FullAscender - afm->Descender);
103     physDev->font.scale = physDev->font.size / 1000.0;
104     physDev->font.escapement = lf->lfEscapement;
105     physDev->font.tm.tmAscent = afm->FullAscender * physDev->font.scale;
106     physDev->font.tm.tmDescent = -afm->Descender * physDev->font.scale;
107     physDev->font.tm.tmInternalLeading = (afm->FullAscender - afm->Ascender)
108                                                 * physDev->font.scale;
109     physDev->font.tm.tmExternalLeading = (1000.0 - afm->FullAscender)
110                                                 * physDev->font.scale; /* ?? */
111     physDev->font.tm.tmAveCharWidth = afm->CharWidths[120] * /* x */
112                                                    physDev->font.scale;
113     physDev->font.tm.tmMaxCharWidth = afm->CharWidths[77] * /* M */
114                                            physDev->font.scale;
115     physDev->font.tm.tmWeight = afm->Weight;
116     physDev->font.tm.tmItalic = afm->ItalicAngle != 0.0;
117     physDev->font.tm.tmUnderlined = lf->lfUnderline;
118     physDev->font.tm.tmStruckOut = lf->lfStrikeOut;
119     physDev->font.tm.tmFirstChar = 32;
120     physDev->font.tm.tmLastChar = 251;
121     physDev->font.tm.tmDefaultChar = 128;
122     physDev->font.tm.tmBreakChar = 32;
123     physDev->font.tm.tmPitchAndFamily = afm->IsFixedPitch ? 0 :
124                                           TMPF_FIXED_PITCH;
125     physDev->font.tm.tmPitchAndFamily |= TMPF_DEVICE;
126     physDev->font.tm.tmCharSet = ANSI_CHARSET;
127     physDev->font.tm.tmOverhang = 0;
128     physDev->font.tm.tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
129     physDev->font.tm.tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
130
131     physDev->font.set = FALSE;
132
133     TRACE(psdrv, "Selected PS font '%s' size %d weight %d.\n", 
134           physDev->font.afm->FontName, physDev->font.size,
135           physDev->font.tm.tmWeight );
136     TRACE(psdrv, "H = %d As = %d Des = %d IL = %d EL = %d\n",
137           physDev->font.tm.tmHeight, physDev->font.tm.tmAscent,
138           physDev->font.tm.tmDescent, physDev->font.tm.tmInternalLeading,
139           physDev->font.tm.tmExternalLeading);
140
141     return prevfont;
142 }
143
144 /***********************************************************************
145  *           PSDRV_GetTextMetrics
146  */
147 BOOL32 PSDRV_GetTextMetrics(DC *dc, TEXTMETRIC32A *metrics)
148 {
149     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
150
151     memcpy(metrics, &(physDev->font.tm), sizeof(physDev->font.tm));
152     return TRUE;
153 }
154
155
156 /***********************************************************************
157  *           PSDRV_GetTextExtentPoint
158  */
159 BOOL32 PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
160                                   LPSIZE32 size )
161 {
162     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
163     INT32 i;
164     float width;
165
166     size->cy = YDSTOLS(dc, physDev->font.tm.tmHeight);
167     width = 0.0;
168
169     for(i = 0; i < count && str[i]; i++) {
170         width += physDev->font.afm->CharWidths[ *((unsigned char *)str + i) ];
171 /*      TRACE(psdrv, "Width after %dth char '%c' = %f\n", i, str[i], width);*/
172     }
173     width *= physDev->font.scale;
174     TRACE(psdrv, "Width after scale (%f) is %f\n", physDev->font.scale, width);
175     size->cx = XDSTOLS(dc, width);
176
177     return TRUE;
178 }
179
180
181 /***********************************************************************
182  *           PSDRV_SetFont
183  */
184 BOOL32 PSDRV_SetFont( DC *dc )
185 {
186     PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
187     BOOL32 ReEncode = FALSE;
188
189     PSDRV_WriteSetColor(dc, &physDev->font.color);
190     if(physDev->font.set) return TRUE;
191
192     if(physDev->font.afm->EncodingScheme && 
193        !strcmp(physDev->font.afm->EncodingScheme, "AdobeStandardEncoding"))
194         ReEncode = TRUE;
195     if(ReEncode)
196         PSDRV_WriteReencodeFont(dc);
197     PSDRV_WriteSetFont(dc, ReEncode);
198     physDev->font.set = TRUE;
199     return TRUE;
200 }
201
202
203 /***********************************************************************
204  *           PSDRV_GetFontMetric
205  */
206 static UINT32 PSDRV_GetFontMetric(DC *dc, AFM *pafm, NEWTEXTMETRIC16 *pTM, 
207               ENUMLOGFONTEX16 *pLF, INT16 size)
208
209 {
210     float scale = size / (pafm->FullAscender - pafm->Descender);
211     memset( pLF, 0, sizeof(*pLF) );
212     memset( pTM, 0, sizeof(*pTM) );
213
214 #define plf ((LPLOGFONT16)pLF)
215     plf->lfHeight    = pTM->tmHeight       = size;
216     plf->lfWidth     = pTM->tmAveCharWidth = pafm->CharWidths[120] * scale;
217     plf->lfWeight    = pTM->tmWeight       = pafm->Weight;
218     plf->lfItalic    = pTM->tmItalic       = pafm->ItalicAngle != 0.0;
219     plf->lfUnderline = pTM->tmUnderlined   = 0;
220     plf->lfStrikeOut = pTM->tmStruckOut    = 0;
221     plf->lfCharSet   = pTM->tmCharSet      = ANSI_CHARSET;
222
223     /* convert pitch values */
224
225     pTM->tmPitchAndFamily = pafm->IsFixedPitch ? 0 : TMPF_FIXED_PITCH;
226     pTM->tmPitchAndFamily |= TMPF_DEVICE;
227     plf->lfPitchAndFamily = 0;
228
229     strncpy( plf->lfFaceName, pafm->FamilyName, LF_FACESIZE );
230 #undef plf
231
232     pTM->tmAscent = pafm->FullAscender * scale;
233     pTM->tmDescent = -pafm->Descender * scale;
234     pTM->tmInternalLeading = (pafm->FullAscender - pafm->Ascender) * scale;
235     pTM->tmMaxCharWidth = pafm->CharWidths[77] * scale;
236     pTM->tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
237     pTM->tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
238
239     *(INT32*)&pTM->tmFirstChar = 32;
240
241     /* return font type */
242
243     return DEVICE_FONTTYPE;
244
245 }
246
247 /***********************************************************************
248  *           PSDRV_EnumDeviceFonts
249  */
250 BOOL32 PSDRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
251                                         DEVICEFONTENUMPROC proc, LPARAM lp )
252 {
253     ENUMLOGFONTEX16     lf;
254     NEWTEXTMETRIC16     tm;
255     BOOL32              b, bRet = 0;
256     AFMLISTENTRY        *afmle;
257     FONTFAMILY          *family;
258     PSDRV_PDEVICE       *physDev = (PSDRV_PDEVICE *)dc->physDev;
259
260     if( plf->lfFaceName[0] ) {
261         TRACE(psdrv, "lfFaceName = '%s'\n", plf->lfFaceName);
262         for(family = physDev->pi->Fonts; family; family = family->next) {
263             if(!strncmp(plf->lfFaceName, family->FamilyName, 
264                         strlen(family->FamilyName)))
265                 break;
266         }
267         if(family) {
268             for(afmle = family->afmlist; afmle; afmle = afmle->next) {
269                 TRACE(psdrv, "Got '%s'\n", afmle->afm->FontName);
270                 if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm, 
271                         PSDRV_GetFontMetric( dc, afmle->afm, &tm, &lf, 200 ),
272                                   lp )) )
273                      bRet = b;
274                 else break;
275             }
276         }
277     } else {
278
279         TRACE(psdrv, "lfFaceName = NULL\n");
280         for(family = physDev->pi->Fonts; family; family = family->next) {
281             afmle = family->afmlist;
282             TRACE(psdrv, "Got '%s'\n", afmle->afm->FontName);
283             if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm, 
284                    PSDRV_GetFontMetric( dc, afmle->afm, &tm, &lf, 200 ), 
285                               lp )) )
286                 bRet = b;
287             else break;
288         }
289     }
290     return bRet;
291 }