/* * Postscript driver font functions * * Copyright 1998 Huw D M Davies * */ #include #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; }