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
;
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
);
37 if(lf
->lfWeight
> 550)
39 lstrcpy32A(FaceName
, lf
->lfFaceName
);
41 if(FaceName
[0] == '\0') {
42 switch(lf
->lfPitchAndFamily
& 0xf0) {
47 lstrcpy32A(FaceName
, "Times");
50 lstrcpy32A(FaceName
, "Helvetica");
53 lstrcpy32A(FaceName
, "Courier");
56 lstrcpy32A(FaceName
, "Symbol");
61 if(FaceName
[0] == '\0') {
62 switch(lf
->lfPitchAndFamily
& 0x0f) {
64 lstrcpy32A(FaceName
, "Times");
67 lstrcpy32A(FaceName
, "Courier");
72 for(family
= PSDRV_AFMFontList
; family
; family
= family
->next
) {
73 if(!lstrncmp32A(FaceName
, family
->FamilyName
,
74 strlen(family
->FamilyName
)))
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)) )
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 */
107 physDev
->font
.tm
.tmMaxCharWidth
= afm
->CharWidths
[77] * /* M */
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 :
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
);
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
));
146 /***********************************************************************
147 * PSDRV_GetTextExtentPoint
149 BOOL32
PSDRV_GetTextExtentPoint( DC
*dc
, LPCSTR str
, INT32 count
,
152 PSDRV_PDEVICE
*physDev
= (PSDRV_PDEVICE
*)dc
->physDev
;
156 size
->cy
= YDSTOLS(dc
, physDev
->font
.tm
.tmHeight
);
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
);
169 /***********************************************************************
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
;
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
);
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
)
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
)))
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
)) )
258 TRACE(psdrv
, "lfFaceName = NULL\n");
259 for(family
= PSDRV_AFMFontList
; family
; family
= family
->next
) {
261 TRACE(psdrv
, "Got '%s'\n", afm
->FontName
);
262 if( (b
= (*proc
)( (LPENUMLOGFONT16
)&lf
, &tm
,
263 PSDRV_GetFontMetric( dc
, afm
, &tm
, &lf
, 200 ), lp
)) )