Release 980628
[wine/gsoc-2012-control.git] / graphics / psdrv / font.c
blobfc7e5d562ff6a002eaa77554630a4170318df9db
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 AFM *afm;
26 FontFamily *family;
27 char FaceName[LF_FACESIZE];
30 TRACE(psdrv, "FaceName = '%s' Height = %d Italic = %d Weight = %d\n",
31 lf->lfFaceName, lf->lfHeight, lf->lfItalic, lf->lfWeight);
33 dc->w.hFont = hfont;
35 if(lf->lfItalic)
36 it = TRUE;
37 if(lf->lfWeight > 550)
38 bd = TRUE;
39 lstrcpy32A(FaceName, lf->lfFaceName);
41 if(FaceName[0] == '\0') {
42 switch(lf->lfPitchAndFamily & 0xf0) {
43 case FF_DONTCARE:
44 break;
45 case FF_ROMAN:
46 case FF_SCRIPT:
47 lstrcpy32A(FaceName, "Times");
48 break;
49 case FF_SWISS:
50 lstrcpy32A(FaceName, "Helvetica");
51 break;
52 case FF_MODERN:
53 lstrcpy32A(FaceName, "Courier");
54 break;
55 case FF_DECORATIVE:
56 lstrcpy32A(FaceName, "Symbol");
57 break;
61 if(FaceName[0] == '\0') {
62 switch(lf->lfPitchAndFamily & 0x0f) {
63 case VARIABLE_PITCH:
64 lstrcpy32A(FaceName, "Times");
65 break;
66 default:
67 lstrcpy32A(FaceName, "Courier");
68 break;
72 for(family = PSDRV_AFMFontList; family; family = family->next) {
73 if(!lstrncmp32A(FaceName, family->FamilyName,
74 strlen(family->FamilyName)))
75 break;
77 if(!family)
78 family = PSDRV_AFMFontList;
81 for(afm = family->afm; afm; afm = afm->next) {
82 if( (bd == (afm->Weight == FW_BOLD)) &&
83 (it == (afm->ItalicAngle != 0.0)) )
84 break;
86 if(!afm)
87 afm = family->afm; /* not ideal */
89 physDev->font.afm = afm;
90 physDev->font.size = YLSTODS(dc, lf->lfHeight);
91 if(physDev->font.size < 0) {
92 TRACE(psdrv, "physDev->font.size < 0\n");
93 physDev->font.size = abs(physDev->font.size);
94 TRACE(psdrv, "physDev->font.size now %d\n", physDev->font.size);
96 physDev->font.scale = physDev->font.size /
97 (afm->Ascender - afm->Descender);
99 physDev->font.escapement = lf->lfEscapement;
100 physDev->font.tm.tmHeight = physDev->font.size;
101 physDev->font.tm.tmAscent = afm->Ascender * physDev->font.scale;
102 physDev->font.tm.tmDescent = -afm->Descender * physDev->font.scale;
103 physDev->font.tm.tmInternalLeading = physDev->font.tm.tmHeight * 0.2;
104 physDev->font.tm.tmExternalLeading = physDev->font.tm.tmHeight * 0.2;
105 physDev->font.tm.tmAveCharWidth = afm->CharWidths[120] * /* x */
106 physDev->font.scale;
107 physDev->font.tm.tmMaxCharWidth = afm->CharWidths[77] * /* M */
108 physDev->font.scale;
109 physDev->font.tm.tmWeight = afm->Weight;
110 physDev->font.tm.tmItalic = afm->ItalicAngle != 0.0;
111 physDev->font.tm.tmUnderlined = lf->lfUnderline;
112 physDev->font.tm.tmStruckOut = lf->lfStrikeOut;
113 physDev->font.tm.tmFirstChar = 32;
114 physDev->font.tm.tmLastChar = 251;
115 physDev->font.tm.tmDefaultChar = 128;
116 physDev->font.tm.tmBreakChar = 32;
117 physDev->font.tm.tmPitchAndFamily = afm->IsFixedPitch ? 0 :
118 TMPF_FIXED_PITCH;
119 physDev->font.tm.tmPitchAndFamily |= TMPF_DEVICE;
120 physDev->font.tm.tmCharSet = ANSI_CHARSET;
121 physDev->font.tm.tmOverhang = 0;
122 physDev->font.tm.tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
123 physDev->font.tm.tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
125 physDev->font.set = FALSE;
127 TRACE(psdrv, "Selected PS font '%s' size %d weight %d\n",
128 physDev->font.afm->FontName, physDev->font.size,
129 physDev->font.tm.tmWeight );
131 return prevfont;
134 /***********************************************************************
135 * PSDRV_GetTextMetrics
137 BOOL32 PSDRV_GetTextMetrics(DC *dc, TEXTMETRIC32A *metrics)
139 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
141 memcpy(metrics, &(physDev->font.tm), sizeof(physDev->font.tm));
142 return TRUE;
146 /***********************************************************************
147 * PSDRV_GetTextExtentPoint
149 BOOL32 PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
150 LPSIZE32 size )
152 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
153 INT32 i;
154 float width;
156 size->cy = YDSTOLS(dc, physDev->font.tm.tmHeight);
157 width = 0.0;
159 for(i = 0; i < count && str[i]; i++)
160 width += physDev->font.afm->CharWidths[ (UINT32)str[i] ];
162 width *= physDev->font.scale;
163 size->cx = XDSTOLS(dc, width);
165 return TRUE;
169 /***********************************************************************
170 * PSDRV_SetFont
172 BOOL32 PSDRV_SetFont( DC *dc )
174 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
176 if(physDev->font.set) return TRUE;
178 PSDRV_WriteReencodeFont(dc);
179 PSDRV_WriteSetFont(dc);
180 physDev->font.set = TRUE;
181 return TRUE;
185 /***********************************************************************
186 * PSDRV_GetFontMetric
188 static UINT32 PSDRV_GetFontMetric(DC *dc, AFM *pafm, NEWTEXTMETRIC16 *pTM,
189 ENUMLOGFONTEX16 *pLF, INT16 size)
192 memset( pLF, 0, sizeof(*pLF) );
193 memset( pTM, 0, sizeof(*pTM) );
195 #define plf ((LPLOGFONT16)pLF)
196 plf->lfHeight = pTM->tmHeight = size;
197 plf->lfWidth = pTM->tmAveCharWidth = size * 0.7;
198 plf->lfWeight = pTM->tmWeight = pafm->Weight;
199 plf->lfItalic = pTM->tmItalic = pafm->ItalicAngle != 0.0;
200 plf->lfUnderline = pTM->tmUnderlined = 0;
201 plf->lfStrikeOut = pTM->tmStruckOut = 0;
202 plf->lfCharSet = pTM->tmCharSet = ANSI_CHARSET;
204 /* convert pitch values */
206 pTM->tmPitchAndFamily = pafm->IsFixedPitch ? 0 : TMPF_FIXED_PITCH;
207 pTM->tmPitchAndFamily |= TMPF_DEVICE;
208 plf->lfPitchAndFamily = 0;
210 lstrcpyn32A( plf->lfFaceName, pafm->FamilyName, LF_FACESIZE );
211 #undef plf
213 pTM->tmAscent = pTM->tmHeight * 0.2;
214 pTM->tmDescent = pTM->tmHeight - pTM->tmAscent;
215 pTM->tmInternalLeading = pTM->tmHeight * 0.2;
216 pTM->tmMaxCharWidth = pTM->tmHeight * 0.7;
217 pTM->tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
218 pTM->tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
220 *(INT32*)&pTM->tmFirstChar = 32;
222 /* return font type */
224 return DEVICE_FONTTYPE;
228 /***********************************************************************
229 * PSDRV_EnumDeviceFonts
231 BOOL32 PSDRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
232 DEVICEFONTENUMPROC proc, LPARAM lp )
234 ENUMLOGFONTEX16 lf;
235 NEWTEXTMETRIC16 tm;
236 BOOL32 b, bRet = 0;
237 AFM *afm;
238 FontFamily *family;
240 if( plf->lfFaceName[0] ) {
241 TRACE(psdrv, "lfFaceName = '%s'\n", plf->lfFaceName);
242 for(family = PSDRV_AFMFontList; family; family = family->next) {
243 if(!lstrncmp32A(plf->lfFaceName, family->FamilyName,
244 strlen(family->FamilyName)))
245 break;
247 if(family) {
248 for(afm = family->afm; afm; afm = afm->next) {
249 TRACE(psdrv, "Got '%s'\n", afm->FontName);
250 if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm,
251 PSDRV_GetFontMetric( dc, afm, &tm, &lf, 200 ), lp )) )
252 bRet = b;
253 else break;
256 } else {
258 TRACE(psdrv, "lfFaceName = NULL\n");
259 for(family = PSDRV_AFMFontList; family; family = family->next) {
260 afm = family->afm;
261 TRACE(psdrv, "Got '%s'\n", afm->FontName);
262 if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm,
263 PSDRV_GetFontMetric( dc, afm, &tm, &lf, 200 ), lp )) )
264 bRet = b;
265 else break;
268 return bRet;