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_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"))
196 PSDRV_WriteReencodeFont(dc);
197 PSDRV_WriteSetFont(dc, ReEncode);
198 physDev->font.set = 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 );
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 )
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)))
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 ),
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 ),