Create X11 palette on DirectDrawSurface::SetPalette, not before (we
[wine.git] / graphics / psdrv / font.c
blobba73a42a4e0062ea64a5a94bbbfb27fa595fafd2
1 /*
2 * PostScript driver font functions
4 * Copyright 1998 Huw D M Davies
6 */
7 #include <string.h>
8 #include "windows.h"
9 #include "print.h"
10 #include "psdrv.h"
11 #include "debug.h"
15 /***********************************************************************
16 * PSDRV_FONT_SelectObject
18 HFONT16 PSDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
19 FONTOBJ *font )
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];
31 TRACE(psdrv, "FaceName = '%s' Height = %d Italic = %d Weight = %d\n",
32 lf->lfFaceName, lf->lfHeight, lf->lfItalic, lf->lfWeight);
34 dc->w.hFont = hfont;
36 if(lf->lfItalic)
37 it = TRUE;
38 if(lf->lfWeight > 550)
39 bd = TRUE;
40 strcpy(FaceName, lf->lfFaceName);
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;
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;
73 TRACE(psdrv, "Trying to find facename '%s'\n", FaceName);
75 for(family = physDev->pi->Fonts; family; family = family->next) {
76 if(!strcmp(FaceName, family->FamilyName))
77 break;
79 if(!family)
80 family = physDev->pi->Fonts;
82 TRACE(psdrv, "Got family '%s'\n", family->FamilyName);
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;
89 if(!afmle)
90 afmle = family->afmlist; /* not ideal */
92 afm = afmle->afm;
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);
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;
131 physDev->font.set = FALSE;
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);
141 return prevfont;
144 /***********************************************************************
145 * PSDRV_GetTextMetrics
147 BOOL32 PSDRV_GetTextMetrics(DC *dc, TEXTMETRIC32A *metrics)
149 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
151 memcpy(metrics, &(physDev->font.tm), sizeof(physDev->font.tm));
152 return TRUE;
156 /***********************************************************************
157 * PSDRV_GetTextExtentPoint
159 BOOL32 PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
160 LPSIZE32 size )
162 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
163 INT32 i;
164 float width;
166 size->cy = YDSTOLS(dc, physDev->font.tm.tmHeight);
167 width = 0.0;
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);*/
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);
177 return TRUE;
181 /***********************************************************************
182 * PSDRV_GetCharWidth
184 BOOL32 PSDRV_GetCharWidth( DC *dc, UINT32 firstChar, UINT32 lastChar,
185 LPINT32 buffer )
187 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
188 UINT32 i;
190 TRACE(psdrv, "first = %d last = %d\n", firstChar, lastChar);
192 for( i = firstChar; i <= lastChar; i++ )
193 *buffer++ = physDev->font.afm->CharWidths[i] * physDev->font.scale;
195 return TRUE;
199 /***********************************************************************
200 * PSDRV_SetFont
202 BOOL32 PSDRV_SetFont( DC *dc )
204 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
205 BOOL32 ReEncode = FALSE;
207 PSDRV_WriteSetColor(dc, &physDev->font.color);
208 if(physDev->font.set) return TRUE;
210 if(physDev->font.afm->EncodingScheme &&
211 !strcmp(physDev->font.afm->EncodingScheme, "AdobeStandardEncoding"))
212 ReEncode = TRUE;
213 if(ReEncode)
214 PSDRV_WriteReencodeFont(dc);
215 PSDRV_WriteSetFont(dc, ReEncode);
216 physDev->font.set = TRUE;
217 return TRUE;
221 /***********************************************************************
222 * PSDRV_GetFontMetric
224 static UINT32 PSDRV_GetFontMetric(DC *dc, AFM *pafm, NEWTEXTMETRIC16 *pTM,
225 ENUMLOGFONTEX16 *pLF, INT16 size)
228 float scale = size / (pafm->FullAscender - pafm->Descender);
229 memset( pLF, 0, sizeof(*pLF) );
230 memset( pTM, 0, sizeof(*pTM) );
232 #define plf ((LPLOGFONT16)pLF)
233 plf->lfHeight = pTM->tmHeight = size;
234 plf->lfWidth = pTM->tmAveCharWidth = pafm->CharWidths[120] * scale;
235 plf->lfWeight = pTM->tmWeight = pafm->Weight;
236 plf->lfItalic = pTM->tmItalic = pafm->ItalicAngle != 0.0;
237 plf->lfUnderline = pTM->tmUnderlined = 0;
238 plf->lfStrikeOut = pTM->tmStruckOut = 0;
239 plf->lfCharSet = pTM->tmCharSet = ANSI_CHARSET;
241 /* convert pitch values */
243 pTM->tmPitchAndFamily = pafm->IsFixedPitch ? 0 : TMPF_FIXED_PITCH;
244 pTM->tmPitchAndFamily |= TMPF_DEVICE;
245 plf->lfPitchAndFamily = 0;
247 strncpy( plf->lfFaceName, pafm->FamilyName, LF_FACESIZE );
248 #undef plf
250 pTM->tmAscent = pafm->FullAscender * scale;
251 pTM->tmDescent = -pafm->Descender * scale;
252 pTM->tmInternalLeading = (pafm->FullAscender - pafm->Ascender) * scale;
253 pTM->tmMaxCharWidth = pafm->CharWidths[77] * scale;
254 pTM->tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
255 pTM->tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
257 *(INT32*)&pTM->tmFirstChar = 32;
259 /* return font type */
261 return DEVICE_FONTTYPE;
265 /***********************************************************************
266 * PSDRV_EnumDeviceFonts
268 BOOL32 PSDRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
269 DEVICEFONTENUMPROC proc, LPARAM lp )
271 ENUMLOGFONTEX16 lf;
272 NEWTEXTMETRIC16 tm;
273 BOOL32 b, bRet = 0;
274 AFMLISTENTRY *afmle;
275 FONTFAMILY *family;
276 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
278 if( plf->lfFaceName[0] ) {
279 TRACE(psdrv, "lfFaceName = '%s'\n", plf->lfFaceName);
280 for(family = physDev->pi->Fonts; family; family = family->next) {
281 if(!strncmp(plf->lfFaceName, family->FamilyName,
282 strlen(family->FamilyName)))
283 break;
285 if(family) {
286 for(afmle = family->afmlist; afmle; afmle = afmle->next) {
287 TRACE(psdrv, "Got '%s'\n", afmle->afm->FontName);
288 if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm,
289 PSDRV_GetFontMetric( dc, afmle->afm, &tm, &lf, 200 ),
290 lp )) )
291 bRet = b;
292 else break;
295 } else {
297 TRACE(psdrv, "lfFaceName = NULL\n");
298 for(family = physDev->pi->Fonts; family; family = family->next) {
299 afmle = family->afmlist;
300 TRACE(psdrv, "Got '%s'\n", afmle->afm->FontName);
301 if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm,
302 PSDRV_GetFontMetric( dc, afmle->afm, &tm, &lf, 200 ),
303 lp )) )
304 bRet = b;
305 else break;
308 return bRet;