2 * PostScript driver font functions
4 * Copyright 1998 Huw D M Davies
15 /***********************************************************************
16 * PSDRV_FONT_SelectObject
18 HFONT16 PSDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
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;
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);
38 if(lf->lfWeight > 550)
40 strcpy(FaceName, lf->lfFaceName);
42 if(FaceName[0] == '\0') {
43 switch(lf->lfPitchAndFamily & 0xf0) {
48 strcpy(FaceName, "Times");
51 strcpy(FaceName, "Helvetica");
54 strcpy(FaceName, "Courier");
57 strcpy(FaceName, "Symbol");
62 if(FaceName[0] == '\0') {
63 switch(lf->lfPitchAndFamily & 0x0f) {
65 strcpy(FaceName, "Times");
68 strcpy(FaceName, "Courier");
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))
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)) )
90 afmle = family->afmlist; /* not ideal */
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 */
113 physDev->font.tm.tmMaxCharWidth = afm->CharWidths[77] * /* M */
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 :
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);
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));
156 /***********************************************************************
157 * PSDRV_GetTextExtentPoint
159 BOOL32 PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
162 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
166 size->cy = YDSTOLS(dc, physDev->font.tm.tmHeight);
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);
181 /***********************************************************************
184 BOOL32 PSDRV_GetCharWidth( DC *dc, UINT32 firstChar, UINT32 lastChar,
187 PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
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;
199 /***********************************************************************
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"))
214 PSDRV_WriteReencodeFont(dc);
215 PSDRV_WriteSetFont(dc, ReEncode);
216 physDev->font.set = 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 );
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 )
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)))
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 ),
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 ),