270 lines
7.8 KiB
C
270 lines
7.8 KiB
C
![]() |
/*
|
||
|
* Postscript driver font functions
|
||
|
*
|
||
|
* Copyright 1998 Huw D M Davies
|
||
|
*
|
||
|
*/
|
||
|
#include <string.h>
|
||
|
#include "windows.h"
|
||
|
#include "print.h"
|
||
|
#include "psdrv.h"
|
||
|
#include "debug.h"
|
||
|
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* PSDRV_FONT_SelectObject
|
||
|
*/
|
||
|
HFONT16 PSDRV_FONT_SelectObject( DC * dc, HFONT16 hfont,
|
||
|
FONTOBJ *font )
|
||
|
{
|
||
|
HFONT16 prevfont = dc->w.hFont;
|
||
|
PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
|
||
|
LOGFONT16 *lf = &(font->logfont);
|
||
|
BOOL32 bd = FALSE, it = FALSE;
|
||
|
AFM *afm;
|
||
|
FontFamily *family;
|
||
|
char FaceName[LF_FACESIZE];
|
||
|
|
||
|
|
||
|
TRACE(psdrv, "FaceName = '%s' Height = %d Italic = %d Weight = %d\n",
|
||
|
lf->lfFaceName, lf->lfHeight, lf->lfItalic, lf->lfWeight);
|
||
|
|
||
|
dc->w.hFont = hfont;
|
||
|
|
||
|
if(lf->lfItalic)
|
||
|
it = TRUE;
|
||
|
if(lf->lfWeight > 550)
|
||
|
bd = TRUE;
|
||
|
lstrcpy32A(FaceName, lf->lfFaceName);
|
||
|
|
||
|
if(FaceName[0] == '\0') {
|
||
|
switch(lf->lfPitchAndFamily & 0xf0) {
|
||
|
case FF_DONTCARE:
|
||
|
break;
|
||
|
case FF_ROMAN:
|
||
|
case FF_SCRIPT:
|
||
|
lstrcpy32A(FaceName, "Times");
|
||
|
break;
|
||
|
case FF_SWISS:
|
||
|
lstrcpy32A(FaceName, "Helvetica");
|
||
|
break;
|
||
|
case FF_MODERN:
|
||
|
lstrcpy32A(FaceName, "Courier");
|
||
|
break;
|
||
|
case FF_DECORATIVE:
|
||
|
lstrcpy32A(FaceName, "Symbol");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(FaceName[0] == '\0') {
|
||
|
switch(lf->lfPitchAndFamily & 0x0f) {
|
||
|
case VARIABLE_PITCH:
|
||
|
lstrcpy32A(FaceName, "Times");
|
||
|
break;
|
||
|
default:
|
||
|
lstrcpy32A(FaceName, "Courier");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(family = PSDRV_AFMFontList; family; family = family->next) {
|
||
|
if(!lstrncmp32A(FaceName, family->FamilyName,
|
||
|
strlen(family->FamilyName)))
|
||
|
break;
|
||
|
}
|
||
|
if(!family)
|
||
|
family = PSDRV_AFMFontList;
|
||
|
|
||
|
|
||
|
for(afm = family->afm; afm; afm = afm->next) {
|
||
|
if( (bd == (afm->Weight == FW_BOLD)) &&
|
||
|
(it == (afm->ItalicAngle != 0.0)) )
|
||
|
break;
|
||
|
}
|
||
|
if(!afm)
|
||
|
afm = family->afm; /* not ideal */
|
||
|
|
||
|
physDev->font.afm = afm;
|
||
|
physDev->font.size = YLSTODS(dc, lf->lfHeight);
|
||
|
if(physDev->font.size < 0) {
|
||
|
TRACE(psdrv, "physDev->font.size < 0\n");
|
||
|
physDev->font.size = abs(physDev->font.size);
|
||
|
TRACE(psdrv, "physDev->font.size now %d\n", physDev->font.size);
|
||
|
}
|
||
|
physDev->font.scale = physDev->font.size /
|
||
|
(afm->Ascender - afm->Descender);
|
||
|
|
||
|
physDev->font.escapement = lf->lfEscapement;
|
||
|
physDev->font.tm.tmHeight = physDev->font.size;
|
||
|
physDev->font.tm.tmAscent = afm->Ascender * physDev->font.scale;
|
||
|
physDev->font.tm.tmDescent = -afm->Descender * physDev->font.scale;
|
||
|
physDev->font.tm.tmInternalLeading = physDev->font.tm.tmHeight * 0.2;
|
||
|
physDev->font.tm.tmExternalLeading = physDev->font.tm.tmHeight * 0.2;
|
||
|
physDev->font.tm.tmAveCharWidth = afm->CharWidths[120] * /* x */
|
||
|
physDev->font.scale;
|
||
|
physDev->font.tm.tmMaxCharWidth = afm->CharWidths[77] * /* M */
|
||
|
physDev->font.scale;
|
||
|
physDev->font.tm.tmWeight = afm->Weight;
|
||
|
physDev->font.tm.tmItalic = afm->ItalicAngle != 0.0;
|
||
|
physDev->font.tm.tmUnderlined = lf->lfUnderline;
|
||
|
physDev->font.tm.tmStruckOut = lf->lfStrikeOut;
|
||
|
physDev->font.tm.tmFirstChar = 32;
|
||
|
physDev->font.tm.tmLastChar = 251;
|
||
|
physDev->font.tm.tmDefaultChar = 128;
|
||
|
physDev->font.tm.tmBreakChar = 32;
|
||
|
physDev->font.tm.tmPitchAndFamily = afm->IsFixedPitch ? 0 :
|
||
|
TMPF_FIXED_PITCH;
|
||
|
physDev->font.tm.tmPitchAndFamily |= TMPF_DEVICE;
|
||
|
physDev->font.tm.tmCharSet = ANSI_CHARSET;
|
||
|
physDev->font.tm.tmOverhang = 0;
|
||
|
physDev->font.tm.tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
|
||
|
physDev->font.tm.tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
|
||
|
|
||
|
physDev->font.set = FALSE;
|
||
|
|
||
|
TRACE(psdrv, "Selected PS font '%s' size %d weight %d\n",
|
||
|
physDev->font.afm->FontName, physDev->font.size,
|
||
|
physDev->font.tm.tmWeight );
|
||
|
|
||
|
return prevfont;
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
* PSDRV_GetTextMetrics
|
||
|
*/
|
||
|
BOOL32 PSDRV_GetTextMetrics(DC *dc, TEXTMETRIC32A *metrics)
|
||
|
{
|
||
|
PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
|
||
|
|
||
|
memcpy(metrics, &(physDev->font.tm), sizeof(physDev->font.tm));
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* PSDRV_GetTextExtentPoint
|
||
|
*/
|
||
|
BOOL32 PSDRV_GetTextExtentPoint( DC *dc, LPCSTR str, INT32 count,
|
||
|
LPSIZE32 size )
|
||
|
{
|
||
|
PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
|
||
|
INT32 i;
|
||
|
float width;
|
||
|
|
||
|
size->cy = YDSTOLS(dc, physDev->font.tm.tmHeight);
|
||
|
width = 0.0;
|
||
|
|
||
|
for(i = 0; i < count && str[i]; i++)
|
||
|
width += physDev->font.afm->CharWidths[ (UINT32)str[i] ];
|
||
|
|
||
|
width *= physDev->font.scale;
|
||
|
size->cx = XDSTOLS(dc, width);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* PSDRV_SetFont
|
||
|
*/
|
||
|
BOOL32 PSDRV_SetFont( DC *dc )
|
||
|
{
|
||
|
PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
|
||
|
|
||
|
if(physDev->font.set) return TRUE;
|
||
|
|
||
|
PSDRV_WriteReencodeFont(dc);
|
||
|
PSDRV_WriteSetFont(dc);
|
||
|
physDev->font.set = TRUE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***********************************************************************
|
||
|
* PSDRV_GetFontMetric
|
||
|
*/
|
||
|
static UINT32 PSDRV_GetFontMetric(DC *dc, AFM *pafm, NEWTEXTMETRIC16 *pTM,
|
||
|
ENUMLOGFONTEX16 *pLF, INT16 size)
|
||
|
|
||
|
{
|
||
|
memset( pLF, 0, sizeof(*pLF) );
|
||
|
memset( pTM, 0, sizeof(*pTM) );
|
||
|
|
||
|
#define plf ((LPLOGFONT16)pLF)
|
||
|
plf->lfHeight = pTM->tmHeight = size;
|
||
|
plf->lfWidth = pTM->tmAveCharWidth = size * 0.7;
|
||
|
plf->lfWeight = pTM->tmWeight = pafm->Weight;
|
||
|
plf->lfItalic = pTM->tmItalic = pafm->ItalicAngle != 0.0;
|
||
|
plf->lfUnderline = pTM->tmUnderlined = 0;
|
||
|
plf->lfStrikeOut = pTM->tmStruckOut = 0;
|
||
|
plf->lfCharSet = pTM->tmCharSet = ANSI_CHARSET;
|
||
|
|
||
|
/* convert pitch values */
|
||
|
|
||
|
pTM->tmPitchAndFamily = pafm->IsFixedPitch ? 0 : TMPF_FIXED_PITCH;
|
||
|
pTM->tmPitchAndFamily |= TMPF_DEVICE;
|
||
|
plf->lfPitchAndFamily = 0;
|
||
|
|
||
|
lstrcpyn32A( plf->lfFaceName, pafm->FamilyName, LF_FACESIZE );
|
||
|
#undef plf
|
||
|
|
||
|
pTM->tmAscent = pTM->tmHeight * 0.2;
|
||
|
pTM->tmDescent = pTM->tmHeight - pTM->tmAscent;
|
||
|
pTM->tmInternalLeading = pTM->tmHeight * 0.2;
|
||
|
pTM->tmMaxCharWidth = pTM->tmHeight * 0.7;
|
||
|
pTM->tmDigitizedAspectX = dc->w.devCaps->logPixelsY;
|
||
|
pTM->tmDigitizedAspectY = dc->w.devCaps->logPixelsX;
|
||
|
|
||
|
*(INT32*)&pTM->tmFirstChar = 32;
|
||
|
|
||
|
/* return font type */
|
||
|
|
||
|
return DEVICE_FONTTYPE;
|
||
|
|
||
|
}
|
||
|
|
||
|
/***********************************************************************
|
||
|
* PSDRV_EnumDeviceFonts
|
||
|
*/
|
||
|
BOOL32 PSDRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf,
|
||
|
DEVICEFONTENUMPROC proc, LPARAM lp )
|
||
|
{
|
||
|
ENUMLOGFONTEX16 lf;
|
||
|
NEWTEXTMETRIC16 tm;
|
||
|
BOOL32 b, bRet = 0;
|
||
|
AFM *afm;
|
||
|
FontFamily *family;
|
||
|
|
||
|
if( plf->lfFaceName[0] ) {
|
||
|
TRACE(psdrv, "lfFaceName = '%s'\n", plf->lfFaceName);
|
||
|
for(family = PSDRV_AFMFontList; family; family = family->next) {
|
||
|
if(!lstrncmp32A(plf->lfFaceName, family->FamilyName,
|
||
|
strlen(family->FamilyName)))
|
||
|
break;
|
||
|
}
|
||
|
if(family) {
|
||
|
for(afm = family->afm; afm; afm = afm->next) {
|
||
|
TRACE(psdrv, "Got '%s'\n", afm->FontName);
|
||
|
if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm,
|
||
|
PSDRV_GetFontMetric( dc, afm, &tm, &lf, 200 ), lp )) )
|
||
|
bRet = b;
|
||
|
else break;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
|
||
|
TRACE(psdrv, "lfFaceName = NULL\n");
|
||
|
for(family = PSDRV_AFMFontList; family; family = family->next) {
|
||
|
afm = family->afm;
|
||
|
TRACE(psdrv, "Got '%s'\n", afm->FontName);
|
||
|
if( (b = (*proc)( (LPENUMLOGFONT16)&lf, &tm,
|
||
|
PSDRV_GetFontMetric( dc, afm, &tm, &lf, 200 ), lp )) )
|
||
|
bRet = b;
|
||
|
else break;
|
||
|
}
|
||
|
}
|
||
|
return bRet;
|
||
|
}
|