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 ),