Release 980913
[wine/multimedia.git] / graphics / psdrv / font.c
blob6a058806fea2d3d27d86de581b1ce520eae27661
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_SetFont
184 BOOL32 PSDRV_SetFont( DC *dc )
186 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
187 BOOL32 ReEncode = FALSE;
189 PSDRV_WriteSetColor(dc, &physDev->font.color);
190 if(physDev->font.set) return TRUE;
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;
203 /***********************************************************************
204 * PSDRV_GetFontMetric
206 static UINT32 PSDRV_GetFontMetric(DC *dc, AFM *pafm, NEWTEXTMETRIC16 *pTM,
207 ENUMLOGFONTEX16 *pLF, INT16 size)
210 float scale = size / (pafm->FullAscender - pafm->Descender);
211 memset( pLF, 0, sizeof(*pLF) );
212 memset( pTM, 0, sizeof(*pTM) );
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;
223 /* convert pitch values */
225 pTM->tmPitchAndFamily = pafm->IsFixedPitch ? 0 : TMPF_FIXED_PITCH;
226 pTM->tmPitchAndFamily |= TMPF_DEVICE;
227 plf->lfPitchAndFamily = 0;
229 strncpy( plf->lfFaceName, pafm->FamilyName, LF_FACESIZE );
230 #undef plf
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;
239 *(INT32*)&pTM->tmFirstChar = 32;
241 /* return font type */
243 return DEVICE_FONTTYPE;
247 /***********************************************************************
248 * PSDRV_EnumDeviceFonts
250 BOOL32 PSDRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
251 DEVICEFONTENUMPROC proc, LPARAM lp )
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;
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;
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;
277 } else {
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;
290 return bRet;