1196 lines
38 KiB
C
1196 lines
38 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
/* loadfont.c - MW font support code */
|
|||
|
|
|||
|
#define NOWINMESSAGES
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOCTLMGR
|
|||
|
#define NOCLIPBOARD
|
|||
|
#include <windows.h>
|
|||
|
|
|||
|
#include "mw.h"
|
|||
|
#include "propdefs.h"
|
|||
|
#include "macro.h"
|
|||
|
#define NOUAC
|
|||
|
#include "cmddefs.h"
|
|||
|
#include "wwdefs.h"
|
|||
|
#include "fontdefs.h"
|
|||
|
#include "docdefs.h"
|
|||
|
|
|||
|
#ifdef DBCS
|
|||
|
#include "dbcs.h"
|
|||
|
#include "kanji.h"
|
|||
|
#endif
|
|||
|
|
|||
|
extern HDC vhMDC;
|
|||
|
extern HDC vhDCPrinter;
|
|||
|
extern struct CHP vchpNormal;
|
|||
|
extern int vifceMac;
|
|||
|
extern union FCID vfcidScreen;
|
|||
|
extern union FCID vfcidPrint;
|
|||
|
extern struct FCE rgfce[ifceMax];
|
|||
|
extern struct FCE *vpfceMru;
|
|||
|
extern struct FCE *vpfceScreen;
|
|||
|
extern struct FCE *vpfcePrint;
|
|||
|
extern struct FMI vfmiScreen;
|
|||
|
extern struct FMI vfmiPrint;
|
|||
|
#ifdef SYSENDMARK
|
|||
|
extern struct FMI vfmiSysScreen;
|
|||
|
#endif /* KANJI */
|
|||
|
|
|||
|
|
|||
|
extern int dxpLogInch;
|
|||
|
extern int dypLogInch;
|
|||
|
extern int dxaPrPage;
|
|||
|
extern int dyaPrPage;
|
|||
|
extern int dxpPrPage;
|
|||
|
extern int dypPrPage;
|
|||
|
extern int ypSubSuperPr;
|
|||
|
extern BOOL vfPrinterValid;
|
|||
|
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
BOOL NEAR DogoneTrashTest(HDC hdc, struct FCE *pfce, BOOL fPrint);
|
|||
|
#endif
|
|||
|
|
|||
|
NEAR LoadFcid(union FCID *, struct CHP *);
|
|||
|
void NEAR SelectWriteFont(int, HFONT *);
|
|||
|
struct FCE * (PfceFcidScan(union FCID *));
|
|||
|
struct FCE * (PfceLruGet(void));
|
|||
|
#ifdef SMFONT
|
|||
|
void NEAR FillWidthTable(HDC, int [], TEXTMETRIC *);
|
|||
|
#endif /* SMFONT */
|
|||
|
|
|||
|
#ifdef JAPAN // added 11 Jun. 1992 by Hiraisi
|
|||
|
void fnCheckWriting( LPLOGFONT );
|
|||
|
#endif
|
|||
|
|
|||
|
LoadFont( doc, pchp, mdFont )
|
|||
|
/* loads the font specified in pchp for this doc. mdFont tells us how the
|
|||
|
font will be used (printer, screen, screen modulo printer,... */
|
|||
|
|
|||
|
int doc;
|
|||
|
register struct CHP *pchp;
|
|||
|
int mdFont;
|
|||
|
|
|||
|
{
|
|||
|
register int wFcid;
|
|||
|
struct CHP *pchpT;
|
|||
|
union FCID fcid;
|
|||
|
|
|||
|
Assert(doc != docNil);
|
|||
|
|
|||
|
pchpT = pchp;
|
|||
|
if (pchp == NULL)
|
|||
|
pchp = &vchpNormal;
|
|||
|
|
|||
|
fcid.strFcid.hps = pchp->hps;
|
|||
|
fcid.strFcid.ftc = pchp->ftc;
|
|||
|
fcid.strFcid.doc = doc;
|
|||
|
#ifdef ENABLE
|
|||
|
wFcid = pchp->psWidth;
|
|||
|
wFcid |= bitPrintFcid;
|
|||
|
if (pchp->fItalic)
|
|||
|
wFcid |= bitItalicFcid;
|
|||
|
if (pchp->fBold)
|
|||
|
wFcid |= bitBoldFcid;
|
|||
|
if (pchp->fUline)
|
|||
|
wFcid |= bitUlineFcid;
|
|||
|
if (pchp->fFixedPitch)
|
|||
|
wFcid |= bitFixedPitchFcid;
|
|||
|
fcid.strFcid.wFcid = wFcid;
|
|||
|
#else
|
|||
|
/* Super-nitpick-optimization (but worth it because LoadFont can take
|
|||
|
10% of display refresh time): bits being cleared is more
|
|||
|
common than set, and a "jump not taken" plus an "or di, xxxx" is 8
|
|||
|
cycles, vs the above "jump taken" which is 16 */
|
|||
|
|
|||
|
wFcid = pchp->psWidth + bitPrintFcid + bitItalicFcid + bitBoldFcid +
|
|||
|
bitUlineFcid + bitFixedPitchFcid;
|
|||
|
if (!pchp->fItalic)
|
|||
|
wFcid &= ~bitItalicFcid;
|
|||
|
if (!pchp->fBold)
|
|||
|
wFcid &= ~bitBoldFcid;
|
|||
|
if (!pchp->fUline)
|
|||
|
wFcid &= ~bitUlineFcid;
|
|||
|
if (!pchp->fFixedPitch)
|
|||
|
wFcid &= ~bitFixedPitchFcid;
|
|||
|
fcid.strFcid.wFcid = wFcid;
|
|||
|
#endif
|
|||
|
|
|||
|
switch (mdFont)
|
|||
|
{
|
|||
|
/* fall throughs are intentional! */
|
|||
|
|
|||
|
default:
|
|||
|
break;
|
|||
|
|
|||
|
case mdFontChk: /* sets font as constrained by printer avail */
|
|||
|
case mdFontPrint: /* like mdFontScreen, but for the printer */
|
|||
|
/* don't want to jam the chp props back */
|
|||
|
pchpT = NULL;
|
|||
|
|
|||
|
case mdFontJam: /* like mdFontChk, but jams props into chp */
|
|||
|
|
|||
|
/* get printer font loaded */
|
|||
|
LoadFcid(&fcid, pchpT);
|
|||
|
|
|||
|
if (mdFont == mdFontPrint)
|
|||
|
/* don't need screen font */
|
|||
|
return;
|
|||
|
|
|||
|
case mdFontScreen: /* sets font for random screen chars */
|
|||
|
/* get screen font loaded */
|
|||
|
fcid.strFcid.wFcid &= ~bitPrintFcid;
|
|||
|
LoadFcid(&fcid, (struct CHP *)NULL);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NEAR LoadFcid(pfcid, pchp)
|
|||
|
/* loads described font and associates it with the appropriate dc's */
|
|||
|
|
|||
|
union FCID *pfcid;
|
|||
|
struct CHP *pchp;
|
|||
|
{
|
|||
|
register struct FCE *pfce;
|
|||
|
int fPrint;
|
|||
|
int fTouchAndGo;
|
|||
|
int fGetMetrics;
|
|||
|
int fNewFont;
|
|||
|
struct FFN **hffnSave;
|
|||
|
LOGFONT lf;
|
|||
|
|
|||
|
#ifdef SYSENDMARK
|
|||
|
fPrint = pfcid->strFcid.wFcid & bitPrintFcid;
|
|||
|
|
|||
|
/* Since this ftc came from CHP, we have lost the first 2 bits. */
|
|||
|
if (pfcid->strFcid.ftc == (bitFtcChp & ftcSystem)) {
|
|||
|
/* If vpfceScreen == NULL already, the standard system font
|
|||
|
has already been selected. So, save some time here. */
|
|||
|
if (vpfceScreen != NULL) {
|
|||
|
/* Gives you the standard system font for the screen. */
|
|||
|
ResetFont(FALSE);
|
|||
|
}
|
|||
|
bltbyte(&vfmiSysScreen, &vfmiScreen, sizeof(struct FMI));
|
|||
|
#if defined(KANJI) && defined(DFONT)
|
|||
|
/* CommSz("System Font!\r\n"); */
|
|||
|
KTS();
|
|||
|
#endif
|
|||
|
return;
|
|||
|
}
|
|||
|
else if (fPrint)
|
|||
|
#else
|
|||
|
if ((fPrint = pfcid->strFcid.wFcid & bitPrintFcid))
|
|||
|
#endif /* if-else-def KANJI */
|
|||
|
{
|
|||
|
if (pfcid->lFcid == vfcidPrint.lFcid)
|
|||
|
{
|
|||
|
pfce = vpfcePrint;
|
|||
|
fTouchAndGo = TRUE;
|
|||
|
goto EstablishFont;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pfcid->lFcid == vfcidScreen.lFcid)
|
|||
|
{
|
|||
|
pfce = vpfceScreen;
|
|||
|
fTouchAndGo = TRUE;
|
|||
|
goto EstablishFont;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* failed at the "trivial" comparisons - look through list */
|
|||
|
fTouchAndGo = FALSE;
|
|||
|
pfce = vpfceMru;
|
|||
|
do
|
|||
|
{
|
|||
|
if (pfce->fcidRequest.lFcid == pfcid->lFcid)
|
|||
|
{
|
|||
|
/* found a match */
|
|||
|
fGetMetrics = FALSE;
|
|||
|
goto EstablishFont;
|
|||
|
}
|
|||
|
pfce = pfce->pfceNext;
|
|||
|
}
|
|||
|
while (pfce != vpfceMru);
|
|||
|
|
|||
|
/* failed at the "easy" search - look for name text & property match */
|
|||
|
fGetMetrics = TRUE;
|
|||
|
if (fNewFont = (pfce = PfceFcidScan(pfcid)) == NULL)
|
|||
|
{
|
|||
|
/* this font isn't in our list - we have to create it */
|
|||
|
int wFcid = pfcid->strFcid.wFcid;
|
|||
|
int dyaHeight;
|
|||
|
int cwAlloc;
|
|||
|
int ich;
|
|||
|
struct FFN **hffnT;
|
|||
|
struct FFN **MpFcidHffn();
|
|||
|
|
|||
|
pfce = PfceLruGet(); /* disposes of a font to make room */
|
|||
|
|
|||
|
bltbc(&lf, 0, sizeof(LOGFONT));
|
|||
|
dyaHeight = pfcid->strFcid.hps * (czaPoint / 2);
|
|||
|
if (fPrint)
|
|||
|
{
|
|||
|
lf.lfHeight = -MultDiv(dyaHeight, dypPrPage, dyaPrPage);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* In the Z version we have tried the idea of using a
|
|||
|
positive value for selection based on cell height
|
|||
|
rather than character height because of weirdness
|
|||
|
with the Courier screen font -- but it seemed to
|
|||
|
mess too many things up (like make all other fonts
|
|||
|
a bit too small and it didn't always make Courier
|
|||
|
work right). I believe Win Word *is* using this
|
|||
|
trick but only when selecting Courier fonts. It
|
|||
|
seems to me like there has got to be a different
|
|||
|
cause of this anamoly. ..pault 9/22/89 */
|
|||
|
|
|||
|
lf.lfHeight = -MultDiv(dyaHeight, dypLogInch, czaInch);
|
|||
|
if (wFcid & grpbitPsWidthFcid)
|
|||
|
{
|
|||
|
// Sync Win3.0 //T-HIROYN
|
|||
|
#ifdef JAPAN
|
|||
|
#ifdef KKBUGFIX // added by Hiraisi (BUG#1980)
|
|||
|
lf.lfWidth = 0;
|
|||
|
#else
|
|||
|
lf.lfWidth = MultDiv((wFcid & grpbitPsWidthFcid) * czaPoint,
|
|||
|
dxpLogInch, czaInch);
|
|||
|
#endif
|
|||
|
#else
|
|||
|
//lf.lfWidth = MultDiv((wFcid & grpbitPsWidthFcid) * czaPoint,
|
|||
|
//dxpLogInch, czaInch);
|
|||
|
lf.lfWidth = 0;
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (wFcid & bitItalicFcid)
|
|||
|
{
|
|||
|
lf.lfItalic = 1;
|
|||
|
}
|
|||
|
if (wFcid & bitUlineFcid)
|
|||
|
{
|
|||
|
lf.lfUnderline = 1;
|
|||
|
}
|
|||
|
lf.lfWeight = wFcid & bitBoldFcid ? FW_BOLD : FW_NORMAL;
|
|||
|
|
|||
|
hffnSave = MpFcidHffn(pfcid);
|
|||
|
|
|||
|
#ifdef JAPAN
|
|||
|
// When we need system font, we want rather variable pitch than fixed,
|
|||
|
// since fixed pitch system font is probably same as terminal font.
|
|||
|
// So we specify VARIABLE_PITCH especialy for system font.
|
|||
|
|
|||
|
{
|
|||
|
extern char szSystem[];
|
|||
|
extern char szAtSystem[];
|
|||
|
|
|||
|
if( WCompSz(szSystem,(*hffnSave)->szFfn) == 0
|
|||
|
|| WCompSz(szAtSystem,(*hffnSave)->szFfn) == 0 )// Add '@'systemfont
|
|||
|
lf.lfPitchAndFamily = (*hffnSave)->ffid | VARIABLE_PITCH ;
|
|||
|
else
|
|||
|
lf.lfPitchAndFamily
|
|||
|
= ((*hffnSave)->ffid) | ((wFcid & bitPrintFcid) ?
|
|||
|
DEFAULT_PITCH : ((wFcid & bitFixedPitchFcid) ? FIXED_PITCH :
|
|||
|
VARIABLE_PITCH));
|
|||
|
}
|
|||
|
#else
|
|||
|
lf.lfPitchAndFamily = ((*hffnSave)->ffid) | ((wFcid & bitPrintFcid) ?
|
|||
|
DEFAULT_PITCH : ((wFcid & bitFixedPitchFcid) ? FIXED_PITCH :
|
|||
|
VARIABLE_PITCH));
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(NEWFONTENUM) && !defined(KANJI)
|
|||
|
lf.lfCharSet = (*hffnSave)->chs; /* pass the character set that
|
|||
|
enumfonts told us this fontname
|
|||
|
was associated with ..pault */
|
|||
|
#else
|
|||
|
/*T-HIROYN from 3.0 loadfont.c*/
|
|||
|
#if defined(NEWFONTENUM) && defined(JAPAN)
|
|||
|
lf.lfCharSet = (*hffnSave)->chs; /* pass the character set that
|
|||
|
enumfonts told us this fontname
|
|||
|
was associated with ..pault */
|
|||
|
#endif /* NEWFONTENUM and JAPAN */
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
ich = 0;
|
|||
|
if ((*hffnSave)->szFfn[0] == chGhost)
|
|||
|
{
|
|||
|
ich++;
|
|||
|
}
|
|||
|
bltszLimit(&(*hffnSave)->szFfn[ich], lf.lfFaceName, LF_FACESIZE);
|
|||
|
|
|||
|
#ifdef KOREA
|
|||
|
if ( (*hffnSave)->szFfn[ich] > 0xA0 ||
|
|||
|
( (*hffnSave)->szFfn[ich]=='@' && (*hffnSave)->szFfn[ich+1] > 0xA0 ) ||
|
|||
|
( WCompSz(lf.lfFaceName,"terminal")==0 ) ||
|
|||
|
( WCompSz(lf.lfFaceName,"@terminal")==0 ) ||
|
|||
|
( WCompSz(lf.lfFaceName,"system")==0 ) ||
|
|||
|
( WCompSz(lf.lfFaceName,"@system")==0 ) )
|
|||
|
|
|||
|
lf.lfCharSet = HANGEUL_CHARSET;
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(DFONT) || defined (PRDRVTEST)
|
|||
|
{
|
|||
|
char rgch[100];
|
|||
|
wsprintf(rgch, "Creating %s font: %s,\t\th %d, w %d, charset %d\n\r",
|
|||
|
(LPSTR)(fPrint ? "prt" : "scr"), (LPSTR)lf.lfFaceName,
|
|||
|
lf.lfHeight, lf.lfWidth, (int)(lf.lfCharSet));
|
|||
|
CommSz(rgch);
|
|||
|
|
|||
|
CommSzNum(" Requested weight: ", lf.lfWeight);
|
|||
|
CommSzNum(" Requested italics: ", lf.lfItalic);
|
|||
|
CommSzNum(" Requested underline: ", lf.lfUnderline);
|
|||
|
CommSzNum(" Requested family: ", lf.lfPitchAndFamily >> 4);
|
|||
|
CommSzNum(" Requested pitch: ", lf.lfPitchAndFamily & 3);
|
|||
|
}
|
|||
|
#endif /* DFONT */
|
|||
|
|
|||
|
#ifdef JAPAN // added 11 Jun. 1992 by Hiraisi
|
|||
|
{
|
|||
|
extern BOOL fPrinting; // Specifies printing doc.
|
|||
|
// PrintDoc function had set this flag.
|
|||
|
extern BOOL fWriting; // Specifies printing direction.
|
|||
|
// TRUE vertically or FALSE horizontally.
|
|||
|
// This flag had been set in the PRINT DIALOG.
|
|||
|
|
|||
|
if( fPrinting && fWriting )
|
|||
|
fnCheckWriting( (LPLOGFONT)&lf );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if ((pfce->hfont = CreateFontIndirect((LPLOGFONT)&lf)) == NULL)
|
|||
|
{
|
|||
|
pfce->hfont = GetStockObject( fPrint && vfPrinterValid ?
|
|||
|
DEVICE_DEFAULT_FONT : SYSTEM_FONT );
|
|||
|
Assert( pfce->hfont );
|
|||
|
/* if the above fails, I don't know what we can do */
|
|||
|
|
|||
|
WinFailure(); /* report the failure so we give the user notice
|
|||
|
for weird behavior to follow */
|
|||
|
}
|
|||
|
|
|||
|
#ifdef DFONT
|
|||
|
CommSzNum("Font handle: ", pfce->hfont);
|
|||
|
#endif /* DFONT */
|
|||
|
|
|||
|
pfce->fcidRequest = *pfcid;
|
|||
|
cwAlloc = CwFromCch(CbFfn(CchSz((*hffnSave)->szFfn)));
|
|||
|
if (FNoHeap(hffnT = (struct FFN **)HAllocate(cwAlloc)))
|
|||
|
{
|
|||
|
FreePfce(pfce);
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
blt((*hffnSave), (*hffnT), cwAlloc);
|
|||
|
}
|
|||
|
pfce->hffn = hffnT;
|
|||
|
}
|
|||
|
|
|||
|
EstablishFont:
|
|||
|
if ((pfce != vpfceMru) && (pfce != vpfceMru->pfceNext))
|
|||
|
{
|
|||
|
/* make this the mru font cache entry */
|
|||
|
/* Only do it if pfce is not already one of the first 2 mru fonts */
|
|||
|
/* since we generally ask for the things in groups of 2 */
|
|||
|
|
|||
|
/* pull it out of its current place */
|
|||
|
pfce->pfceNext->pfcePrev = pfce->pfcePrev;
|
|||
|
pfce->pfcePrev->pfceNext = pfce->pfceNext;
|
|||
|
|
|||
|
/* insert it at mru position */
|
|||
|
pfce->pfceNext = vpfceMru;
|
|||
|
pfce->pfcePrev = vpfceMru->pfcePrev;
|
|||
|
pfce->pfceNext->pfcePrev = pfce;
|
|||
|
pfce->pfcePrev->pfceNext = pfce;
|
|||
|
vpfceMru = pfce;
|
|||
|
|
|||
|
#ifndef JAPAN // added by Hiraisi(BUG#4645/WIN31)
|
|||
|
#ifndef DISCARDABLE_FONTS
|
|||
|
/* KLUDGE ALERT: To accomodate Windows inability to make synthesized
|
|||
|
fonts discardable, we will now throw out the third font in the LRU chain
|
|||
|
if it is taller than 16 points. (Ain't this a doozey...) */
|
|||
|
{
|
|||
|
register struct FCE *pfceThird = vpfceMru->pfceNext->pfceNext;
|
|||
|
|
|||
|
if (pfceThird->fcidRequest.lFcid != fcidNil &&
|
|||
|
#ifdef OLD
|
|||
|
pfceThird->fcidActual.strFcid.hps > 32)
|
|||
|
#else
|
|||
|
pfceThird->fcidActual.strFcid.hps > 48)
|
|||
|
#endif /* if-else-def OLD */
|
|||
|
{
|
|||
|
/* Free this particular font. */
|
|||
|
FreePfce(pfceThird);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif /* not DISCARDABLE_FONTS */
|
|||
|
#endif // not JAPAN
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if (!fTouchAndGo)
|
|||
|
{
|
|||
|
/* we have this font in our cache, but we need to select it */
|
|||
|
SelectWriteFont(fPrint, &pfce->hfont);
|
|||
|
|
|||
|
/**
|
|||
|
I wish I knew why this is needed, but I don't want to spend
|
|||
|
more time on it. For some reason the font width table
|
|||
|
(pfce->rgdxp) is getting either trashed or is simply
|
|||
|
incorrect when first obtained. I suspect it is a GDI bug
|
|||
|
because it only happens the first time you use certain fonts
|
|||
|
(at least in Write) during a given session of Windows.
|
|||
|
The DogoneTrashTest detects the problem and fixes it.
|
|||
|
It is slow though, unfortunately.
|
|||
|
(7.25.91) v-dougk.
|
|||
|
**/
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
if (!fGetMetrics)
|
|||
|
DogoneTrashTest(fPrint ? vhDCPrinter : vhMDC, pfce, fPrint);
|
|||
|
#endif
|
|||
|
|
|||
|
if (fGetMetrics)
|
|||
|
{
|
|||
|
register union FCID *pfcidT = &pfce->fcidActual;
|
|||
|
HDC hDCMetrics = fPrint ? vhDCPrinter : vhMDC;
|
|||
|
TEXTMETRIC tm;
|
|||
|
|
|||
|
Assert(hDCMetrics);
|
|||
|
if (hDCMetrics == NULL)
|
|||
|
return;
|
|||
|
|
|||
|
GetTextMetrics(hDCMetrics, (LPTEXTMETRIC)&tm);
|
|||
|
if (fNewFont)
|
|||
|
{
|
|||
|
/* We need all of the metrics for this guy. */
|
|||
|
CHAR szFace[LF_FACESIZE];
|
|||
|
int wFcid;
|
|||
|
int dypHeight;
|
|||
|
int dxpch;
|
|||
|
|
|||
|
#if defined(DFONT) || defined(PRDRVTEST)
|
|||
|
{
|
|||
|
char rgch[100];
|
|||
|
GetTextFace(hDCMetrics, LF_FACESIZE, (LPSTR)szFace);
|
|||
|
wsprintf(rgch, " Actual fname: %s,\t\th %d, w %d, charset %d\n\r",
|
|||
|
(LPSTR)szFace, tm.tmHeight-tm.tmInternalLeading,
|
|||
|
tm.tmAveCharWidth, (int)(tm.tmCharSet));
|
|||
|
CommSz(rgch);
|
|||
|
}
|
|||
|
CommSzNum(" Actual width: ", tm.tmAveCharWidth);
|
|||
|
CommSzNum(" Actual leading: ", tm.tmInternalLeading +
|
|||
|
tm.tmExternalLeading);
|
|||
|
CommSzNum(" Actual weight: ", tm.tmWeight);
|
|||
|
CommSzNum(" Actual italics: ", tm.tmItalic);
|
|||
|
CommSzNum(" Actual underline: ", tm.tmUnderlined);
|
|||
|
CommSzNum(" Actual font family: ", tm.tmPitchAndFamily >>
|
|||
|
4);
|
|||
|
CommSzNum(" Actual pitch: ", tm.tmPitchAndFamily & 1);
|
|||
|
#endif /* DFONT */
|
|||
|
|
|||
|
SetTextJustification(hDCMetrics, 0, 0);
|
|||
|
pfce->fmi.dxpOverhang = tm.tmOverhang;
|
|||
|
#if defined(KOREA)
|
|||
|
if ((tm.tmPitchAndFamily & 1) == 0)
|
|||
|
pfce->fmi.dxpSpace = tm.tmAveCharWidth;
|
|||
|
else
|
|||
|
#endif
|
|||
|
pfce->fmi.dxpSpace = LOWORD(GetTextExtent(hDCMetrics,
|
|||
|
(LPSTR)" ", 1)) - tm.tmOverhang;
|
|||
|
#ifdef PRDRVTEST
|
|||
|
{
|
|||
|
/* Just so no printers or printer driver manufacturers
|
|||
|
get funky on us! ..pault */
|
|||
|
int dxpSpace = pfce->fmi.dxpSpace + tm.tmOverhang;
|
|||
|
|
|||
|
CommSzNum(" GetTextExtent(space) ", LOWORD(GetTextExtent(hDCMetrics, (LPSTR)" ", 1)));
|
|||
|
if (dxpSpace < 1 || dxpSpace > tm.tmMaxCharWidth+tm.tmOverhang)
|
|||
|
{
|
|||
|
pfce->fmi.dxpSpace = tm.tmAveCharWidth;
|
|||
|
CommSzNum(" ...resetting to ",pfce->fmi.dxpSpace);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
pfce->fmi.dypAscent = tm.tmAscent;
|
|||
|
pfce->fmi.dypDescent = tm.tmDescent;
|
|||
|
pfce->fmi.dypBaseline = tm.tmAscent;
|
|||
|
pfce->fmi.dypLeading = tm.tmExternalLeading;
|
|||
|
#ifdef DBCS
|
|||
|
pfce->fmi.dypIntLeading = tm.tmInternalLeading;
|
|||
|
//#ifdef KOREA
|
|||
|
// if (tm.tmPitchAndFamily & 1) /* Is variable pitch ? */
|
|||
|
// pfce->fmi.dxpDBCS = dxpNil;
|
|||
|
// else
|
|||
|
//#endif
|
|||
|
{
|
|||
|
#if defined(TAIWAN) || defined(KOREA) || defined(PRC) //fix Italic display error, for Bug# 3362, MSTC - pisuih, 3/4/93
|
|||
|
CHAR rgchT[cchDBCS << 1];
|
|||
|
int dxpOverhang;
|
|||
|
#else
|
|||
|
CHAR rgchT[cchDBCS];
|
|||
|
#endif //TAIWAN
|
|||
|
int dxpDBCS;
|
|||
|
|
|||
|
rgchT[0] = rgchT[1] = bKanji1Min;
|
|||
|
|
|||
|
dxpDBCS = LOWORD(GetTextExtent(hDCMetrics,
|
|||
|
(LPSTR) rgchT, cchDBCS));
|
|||
|
|
|||
|
#if defined(TAIWAN) || defined(KOREA) || defined(PRC) //fix Italic display error, for Bug# 3362, MSTC - pisuih, 3/4/93
|
|||
|
rgchT[2] = rgchT[3] = bKanji1Min;
|
|||
|
dxpOverhang = (dxpDBCS << 1) - LOWORD( GetTextExtent(
|
|||
|
hDCMetrics, (LPSTR) rgchT, cchDBCS << 1 ));
|
|||
|
|
|||
|
//for compatible with SBCS's overhang
|
|||
|
dxpDBCS += (pfce->fmi.dxpOverhang - dxpOverhang);
|
|||
|
#endif //TAIWAN
|
|||
|
|
|||
|
pfce->fmi.dxpDBCS =
|
|||
|
#if defined(JAPAN) || defined(KOREA) || defined(PRC) //Win3.1 BYTE-->WORD
|
|||
|
pfce->fmi.dxpDBCS =
|
|||
|
(WORD) ((0 <= dxpDBCS && dxpDBCS < dxpNil) ? dxpDBCS : dxpNil);
|
|||
|
#elif TAIWAN //Win3.1 BYTE-->WORD
|
|||
|
pfce->fmi.dxpDBCS =
|
|||
|
(WORD) ((0 <= dxpDBCS && dxpDBCS < dxpNil) ? dxpDBCS : dxpNil);
|
|||
|
#else
|
|||
|
pfce->fmi.dxpDBCS =
|
|||
|
(BYTE) ((0 <= dxpDBCS && dxpDBCS < dxpNil) ? dxpDBCS : dxpNil);
|
|||
|
#endif
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef SMFONT
|
|||
|
FillWidthTable(hDCMetrics, pfce->rgdxp, &tm);
|
|||
|
#ifdef DEBUG
|
|||
|
if (DogoneTrashTest(hDCMetrics, pfce, fPrint))
|
|||
|
OutputDebugString("That was an immediate check\n\r");
|
|||
|
#endif
|
|||
|
|
|||
|
#else /* not SMFONT */
|
|||
|
/* Fill the width table. If this is a fixed font and the width
|
|||
|
fits in a byte, then go ahead and fill the width table with the
|
|||
|
width; otherwise, put dxpNil in the table. */
|
|||
|
dxpch = (tm.tmPitchAndFamily & 1 || tm.tmAveCharWidth >= dxpNil)
|
|||
|
? dxpNil : tm.tmAveCharWidth;
|
|||
|
bltc(pfce->rgdxp, dxpch, chFmiMax - chFmiMin);
|
|||
|
#endif /* SMFONT */
|
|||
|
|
|||
|
if ((*hffnSave)->ffid == FF_DONTCARE && (tm.tmPitchAndFamily &
|
|||
|
grpbitFamily) != FF_DONTCARE)
|
|||
|
{
|
|||
|
/* Hey! maybe we've discovered a family for this orphan
|
|||
|
font? */
|
|||
|
GetTextFace(hDCMetrics, LF_FACESIZE, (LPSTR)szFace);
|
|||
|
if (WCompSz((*hffnSave)->szFfn, szFace) == 0)
|
|||
|
{
|
|||
|
/* name matches - jam family in */
|
|||
|
(*hffnSave)->ffid = tm.tmPitchAndFamily & grpbitFamily;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* jam back the properties we found */
|
|||
|
dypHeight = tm.tmHeight - tm.tmInternalLeading;
|
|||
|
if (fPrint)
|
|||
|
{
|
|||
|
/* Save the height of this font. */
|
|||
|
pfcidT->strFcid.hps = umin((MultDiv(dypHeight, dyaPrPage,
|
|||
|
dypPrPage) + (czaPoint / 4)) / (czaPoint / 2), 0xff);
|
|||
|
|
|||
|
#ifdef APLLW
|
|||
|
/* Save the width of this font if it is a fixed pitch
|
|||
|
device font. */
|
|||
|
wFcid = ((tm.tmPitchAndFamily & 0x09) == 0x08) ?
|
|||
|
#else
|
|||
|
/* Save the width of this font if it is a device font. */
|
|||
|
#ifdef KOREA /* give width info for all (like excel) to select DuBae shape */
|
|||
|
wFcid = (1==1) ?
|
|||
|
#else
|
|||
|
wFcid = (tm.tmPitchAndFamily & 0x08) ?
|
|||
|
#endif
|
|||
|
|
|||
|
#endif /* if-else-def APLLW */
|
|||
|
umin((MultDiv(tm.tmAveCharWidth, dxaPrPage, dxpPrPage) +
|
|||
|
(czaPoint / 2)) / czaPoint, psWidthMax) : 0;
|
|||
|
wFcid |= bitPrintFcid;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pfcidT->strFcid.hps = umin((MultDiv(dypHeight, czaInch,
|
|||
|
dypLogInch) + (czaPoint / 4)) / (czaPoint / 2), 0xff);
|
|||
|
wFcid = 0;
|
|||
|
}
|
|||
|
|
|||
|
if (tm.tmWeight > (FW_NORMAL + FW_BOLD) / 2)
|
|||
|
{
|
|||
|
wFcid |= bitBoldFcid;
|
|||
|
}
|
|||
|
|
|||
|
if (tm.tmItalic)
|
|||
|
{
|
|||
|
wFcid |= bitItalicFcid;
|
|||
|
}
|
|||
|
|
|||
|
if (tm.tmUnderlined)
|
|||
|
{
|
|||
|
wFcid |= bitUlineFcid;
|
|||
|
}
|
|||
|
|
|||
|
if ((tm.tmPitchAndFamily & bitPitch) == 0)
|
|||
|
{
|
|||
|
wFcid |= bitFixedPitchFcid;
|
|||
|
}
|
|||
|
|
|||
|
pfcidT->strFcid.wFcid = wFcid;
|
|||
|
}
|
|||
|
|
|||
|
/* Set the document and the font code. */
|
|||
|
pfcidT->strFcid.doc = pfce->fcidRequest.strFcid.doc;
|
|||
|
if (fPrint)
|
|||
|
{
|
|||
|
CHAR rgb[ibFfnMax];
|
|||
|
struct FFN *pffn = (struct FFN *)&rgb[0];
|
|||
|
|
|||
|
/* Get the font code for this font. */
|
|||
|
GetTextFace(vhDCPrinter, LF_FACESIZE, (LPSTR)pffn->szFfn);
|
|||
|
if (WCompSz(pffn->szFfn, (*pfce->hffn)->szFfn) == 0)
|
|||
|
{
|
|||
|
/* The face name is the same as what we requested; so, the
|
|||
|
font code should be the same. */
|
|||
|
pfcidT->strFcid.ftc = pfce->fcidRequest.strFcid.ftc;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* Well, we've got to go hunting for the font code. */
|
|||
|
int ftc;
|
|||
|
|
|||
|
pffn->ffid = tm.tmPitchAndFamily & grpbitFamily;
|
|||
|
#ifdef NEWFONTENUM
|
|||
|
pffn->chs = tm.tmCharSet;
|
|||
|
#endif
|
|||
|
ftc = FtcScanDocFfn(pfcidT->strFcid.doc, pffn);
|
|||
|
if (ftc == ftcNil)
|
|||
|
{
|
|||
|
/* Make the first character of the face name a sentinal
|
|||
|
to mark that this font was not requested by the user. */
|
|||
|
bltszLimit(pffn->szFfn, &pffn->szFfn[1], LF_FACESIZE);
|
|||
|
pffn->szFfn[0] = chGhost;
|
|||
|
ftc = FtcChkDocFfn(pfcidT->strFcid.doc, pffn);
|
|||
|
}
|
|||
|
pfcidT->strFcid.ftc = ftc;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pfcidT->strFcid.ftc = pfce->fcidRequest.strFcid.ftc;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (fPrint)
|
|||
|
{
|
|||
|
vpfcePrint = pfce;
|
|||
|
vfcidPrint = pfce->fcidRequest;
|
|||
|
bltbyte(&pfce->fmi, &vfmiPrint, sizeof(struct FMI));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
vpfceScreen = pfce;
|
|||
|
vfcidScreen = pfce->fcidRequest;
|
|||
|
bltbyte(&pfce->fmi, &vfmiScreen, sizeof(struct FMI));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (pfce->fcidRequest.lFcid != pfce->fcidActual.lFcid)
|
|||
|
{
|
|||
|
/* all's not as we asked for - feed properties back to caller */
|
|||
|
pfcid->lFcid = pfce->fcidActual.lFcid;
|
|||
|
if (pchp != NULL)
|
|||
|
{ /* JamChpFcid(pchp, pfcid) bring in line for speed */
|
|||
|
register struct CHP *pchpT = pchp;
|
|||
|
int wFcid = pfcid->strFcid.wFcid;
|
|||
|
|
|||
|
pchpT->ftc = pfcid->strFcid.ftc;
|
|||
|
pchpT->hps = pfcid->strFcid.hps;
|
|||
|
pchpT->psWidth = wFcid & grpbitPsWidthFcid;
|
|||
|
|
|||
|
pchpT->fBold = pchpT->fItalic = pchpT->fUline = pchpT->fFixedPitch =
|
|||
|
FALSE;
|
|||
|
|
|||
|
if (wFcid & bitBoldFcid)
|
|||
|
{
|
|||
|
pchpT->fBold = TRUE;
|
|||
|
}
|
|||
|
if (wFcid & bitItalicFcid)
|
|||
|
{
|
|||
|
pchpT->fItalic = TRUE;
|
|||
|
}
|
|||
|
if (wFcid & bitUlineFcid)
|
|||
|
{
|
|||
|
pchpT->fUline = TRUE;
|
|||
|
}
|
|||
|
if (wFcid & bitFixedPitchFcid)
|
|||
|
{
|
|||
|
pchpT->fFixedPitch = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void NEAR SelectWriteFont(fPrint, phfont)
|
|||
|
int fPrint;
|
|||
|
HFONT *phfont;
|
|||
|
{
|
|||
|
extern HWND hParentWw;
|
|||
|
extern int wwMac;
|
|||
|
extern struct WWD rgwwd[];
|
|||
|
|
|||
|
if (fPrint)
|
|||
|
{
|
|||
|
|
|||
|
#ifdef DFONT
|
|||
|
CommSzNum("Selecting printer font: ", *phfont);
|
|||
|
#endif /* DFONT */
|
|||
|
|
|||
|
/* The printer DC should be valid. */
|
|||
|
if (vhDCPrinter == NULL)
|
|||
|
{
|
|||
|
/* This case can occur from ResetFont when closing */
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* Establish the font with the printer DC. */
|
|||
|
if (SelectObject(vhDCPrinter, *phfont) == NULL)
|
|||
|
{
|
|||
|
if (SelectObject(vhDCPrinter, GetStockObject(vfPrinterValid ?
|
|||
|
DEVICE_DEFAULT_FONT : SYSTEM_FONT)) == NULL)
|
|||
|
{
|
|||
|
if (vfPrinterValid)
|
|||
|
{
|
|||
|
/* This is a real printer DC; delete it. */
|
|||
|
DeleteDC(vhDCPrinter);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* This is really the screen DC; it must be released. */
|
|||
|
ReleaseDC(hParentWw, vhDCPrinter);
|
|||
|
}
|
|||
|
vhDCPrinter = NULL;
|
|||
|
}
|
|||
|
WinFailure();
|
|||
|
if (vhDCPrinter == NULL)
|
|||
|
{
|
|||
|
GetPrinterDC(FALSE);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* Establish it with screen and memory DC's. */
|
|||
|
register int ww;
|
|||
|
register struct WWD *pwwd;
|
|||
|
|
|||
|
#ifdef DFONT
|
|||
|
CommSzNum("Selecting screen font: ", *phfont);
|
|||
|
#endif /* DFONT */
|
|||
|
|
|||
|
/* The current memory DC had best be active. */
|
|||
|
if (vhMDC == NULL)
|
|||
|
{
|
|||
|
/* this case occurs from ResetFont when Write is closed */
|
|||
|
return;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* Select the font into the memory DC. */
|
|||
|
if (SelectObject(vhMDC, *phfont) == NULL)
|
|||
|
{
|
|||
|
|
|||
|
Assert(*phfont != GetStockObject(SYSTEM_FONT));
|
|||
|
*phfont = GetStockObject(SYSTEM_FONT);
|
|||
|
Assert( *phfont );
|
|||
|
#ifdef DEBUG
|
|||
|
Assert( SelectObject( vhMDC, *phfont ) );
|
|||
|
#else /* not DEBUG */
|
|||
|
SelectObject(vhMDC, *phfont );
|
|||
|
#endif /* not DEBUG */
|
|||
|
|
|||
|
WinFailure();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Select the font into all of the window DC's. */
|
|||
|
for (ww = 0, pwwd = &rgwwd[0]; ww < wwMac; ww++, pwwd++)
|
|||
|
{
|
|||
|
if (pwwd->hDC != NULL)
|
|||
|
{
|
|||
|
if (SelectObject(pwwd->hDC, *phfont) == NULL)
|
|||
|
{
|
|||
|
HFONT hSysFont = GetStockObject(SYSTEM_FONT);
|
|||
|
int wwT;
|
|||
|
struct WWD *pwwdT;
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
Assert(*phfont != hSysFont);
|
|||
|
Assert(SelectObject(vhMDC, hSysFont) != NULL);
|
|||
|
#else /* not DEBUG */
|
|||
|
SelectObject(vhMDC, hSysFont);
|
|||
|
#endif /* not DEBUG */
|
|||
|
*phfont = hSysFont;
|
|||
|
|
|||
|
for (wwT = 0, pwwdT = &rgwwd[0]; wwT <= ww; wwT++, pwwdT++)
|
|||
|
{
|
|||
|
if (pwwdT->hDC != NULL)
|
|||
|
{
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
Assert(SelectObject(pwwdT->hDC, hSysFont) != NULL);
|
|||
|
#else /* not DEBUG */
|
|||
|
SelectObject(pwwdT->hDC, hSysFont);
|
|||
|
#endif /* not DEBUG */
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
WinFailure();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
ResetFont(fPrint)
|
|||
|
BOOL fPrint;
|
|||
|
{
|
|||
|
/* This routine sets to NULL the currently selected printer or screen font,
|
|||
|
depending on the value of fPrint. */
|
|||
|
|
|||
|
extern HFONT vhfSystem;
|
|||
|
HFONT hfont;
|
|||
|
|
|||
|
#ifdef DFONT
|
|||
|
CommSzSz("Resetting the ", (fPrint ? "printer font." : "screen font."));
|
|||
|
#endif /* DEBUG */
|
|||
|
|
|||
|
#ifdef JAPAN /* T-YOSHIO win 3.1 */
|
|||
|
hfont = GetStockObject(fPrint && vfPrinterValid ?
|
|||
|
DEVICE_DEFAULT_FONT : ANSI_VAR_FONT);
|
|||
|
#else
|
|||
|
hfont = GetStockObject(fPrint && vfPrinterValid ?
|
|||
|
DEVICE_DEFAULT_FONT : SYSTEM_FONT);
|
|||
|
#endif
|
|||
|
|
|||
|
SelectWriteFont( fPrint, &hfont );
|
|||
|
if (fPrint)
|
|||
|
{
|
|||
|
vpfcePrint = NULL;
|
|||
|
vfcidPrint.lFcid = fcidNil;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
vpfceScreen = NULL;
|
|||
|
vfcidScreen.lFcid = fcidNil;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL OurGetCharWidth(hdc, chFirst, chLast, lpw)
|
|||
|
HDC hdc;
|
|||
|
CHAR chFirst, chLast;
|
|||
|
LPINT lpw;
|
|||
|
{
|
|||
|
int i;
|
|||
|
BYTE b;
|
|||
|
|
|||
|
for (i = chFirst; i <= chLast; i++)
|
|||
|
{
|
|||
|
/*T-HIROYN from 3.0 loadfont.c */
|
|||
|
#ifdef DBCS /* KenjiK '90-11-26 */
|
|||
|
if(IsDBCSLeadByte(i))
|
|||
|
{
|
|||
|
*(lpw++) = dxpNil;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
b = i;
|
|||
|
*(lpw++) = LOWORD(GetTextExtent(hdc, (LPSTR)&b, 1));
|
|||
|
}
|
|||
|
}
|
|||
|
#else
|
|||
|
b = i;
|
|||
|
*(lpw++) = LOWORD(GetTextExtent(hdc, (LPSTR)&b, 1));
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
return(fTrue);
|
|||
|
}
|
|||
|
|
|||
|
#ifdef SMFONT
|
|||
|
/* Note: we put widths in here that represent true char widths,
|
|||
|
not considering bold/italics Overhang. This is because of the
|
|||
|
following formula for string widths:
|
|||
|
|
|||
|
strwidth = overhang +
|
|||
|
summation [ (gettextextent_or_getcharwidth - overhang) ]
|
|||
|
|
|||
|
..pault 9/22/89 */
|
|||
|
|
|||
|
void NEAR FillWidthTable(hdc, rgdxp, ptm)
|
|||
|
HDC hdc;
|
|||
|
int rgdxp[];
|
|||
|
TEXTMETRIC *ptm;
|
|||
|
{
|
|||
|
int rgWidth[chFmiMax - chFmiMin];
|
|||
|
if ((ptm->tmPitchAndFamily & 1) == 0)
|
|||
|
{
|
|||
|
#ifdef PRDRVTEST
|
|||
|
CommSzNum(" * Fixed pitch font! tmAveCharWidth==",ptm->tmMaxCharWidth);
|
|||
|
#endif
|
|||
|
#if defined(DBCS) && !defined(KOREA) /* was in JAPAN */
|
|||
|
bltc(rgdxp, (WORD)dxpNil, chFmiMax - chFmiMin);
|
|||
|
#else
|
|||
|
bltc(rgdxp, (WORD)ptm->tmAveCharWidth, chFmiMax - chFmiMin);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/* Attempt to get the width table from the DC. */
|
|||
|
else
|
|||
|
{
|
|||
|
int *pdxpMax = &rgdxp[chFmiMax - chFmiMin];
|
|||
|
register int *pWidth;
|
|||
|
register int *pdxp;
|
|||
|
int dxpOverhang = ptm->tmOverhang;
|
|||
|
|
|||
|
#ifdef DBCS /* was in JAPAN; KenjiK '90-11-26 */
|
|||
|
//92.10.26 T-HIROYN
|
|||
|
//Win3.1J if(OurGetCharWidth(hdc, chFmiMin, chFmiMax - 1, (LPINT)rgWidth))
|
|||
|
if( (GetDeviceCaps(hdc, DRIVERVERSION) > 0x300) ?
|
|||
|
GetCharWidth(hdc, chFmiMin, chFmiMax - 1, (LPINT)rgWidth) :
|
|||
|
OurGetCharWidth(hdc, chFmiMin, chFmiMax - 1, (LPINT)rgWidth) )
|
|||
|
#else
|
|||
|
if (GetCharWidth(hdc, chFmiMin, chFmiMax - 1, (LPINT)rgWidth))
|
|||
|
#endif
|
|||
|
|
|||
|
{
|
|||
|
#if defined(JAPAN) || defined(KOREA) // added by Hiraisi (BUG#2690)
|
|||
|
int ch = chFmiMin;
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef PRDRVTEST
|
|||
|
CommSz(" * GetCharWidth() supported\n\r");
|
|||
|
#endif
|
|||
|
|
|||
|
/* Remove the overhang factor from individual char widths
|
|||
|
(see formula for widths of character strings above) */
|
|||
|
for (pWidth = &rgWidth[0], pdxp = &rgdxp[0];
|
|||
|
pdxp != pdxpMax; pWidth++, pdxp++)
|
|||
|
{
|
|||
|
#ifdef DBCS /* was in JAPAN */
|
|||
|
#if defined(JAPAN) || defined(KOREA) // added by Hiraisi (BUG#2690)
|
|||
|
if(!IsDBCSLeadByte(ch++))
|
|||
|
{
|
|||
|
#endif
|
|||
|
if(*pWidth == dxpNil)
|
|||
|
/*T-HIROYN *pdxp = (CHAR)dxpNil;*/
|
|||
|
*pdxp = dxpNil;
|
|||
|
else
|
|||
|
*pdxp = (*pWidth - dxpOverhang);
|
|||
|
#if defined(JAPAN) || defined(KOREA) // added by Hiraisi (BUG#2690)
|
|||
|
}
|
|||
|
else
|
|||
|
*pdxp = dxpNil;
|
|||
|
#endif
|
|||
|
#else
|
|||
|
*pdxp = (*pWidth - dxpOverhang);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* There is no easy way, put dxpNil in the table. It looks like each
|
|||
|
char has a bogus width but FormatLine will make individual calls to
|
|||
|
GetTextExtent() and replace the dxpNil on an as-needed basis ..pault */
|
|||
|
|
|||
|
#ifdef PRDRVTEST
|
|||
|
CommSz(" * GetCharWidth() not supported!\n\r");
|
|||
|
#endif
|
|||
|
bltc(rgdxp, (WORD)dxpNil, chFmiMax - chFmiMin);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifdef PRDRVTEST
|
|||
|
/* Take a quick look through to see if this printer is returning any
|
|||
|
char widths that seem odd -- report those! This should
|
|||
|
end my searching for WRITE problems which are really caused by bad
|
|||
|
printer-driver return values! */
|
|||
|
{
|
|||
|
BOOL fReported = fFalse;
|
|||
|
int rgch[cchMaxSz];
|
|||
|
int i,w;
|
|||
|
BYTE b;
|
|||
|
for (i = chFmiMin; i < chFmiMax; i++)
|
|||
|
{
|
|||
|
b = i;
|
|||
|
w = LOWORD(GetTextExtent(hdc, (LPSTR)&b, 1));
|
|||
|
if (w < 1)
|
|||
|
{
|
|||
|
wsprintf(rgch," GetTextExtent(ascii %d) return value %d is invalid\n\r",b,(int)w);
|
|||
|
CommSz(rgch);
|
|||
|
if (!fReported)
|
|||
|
{
|
|||
|
CommSz("");
|
|||
|
fReported = fTrue;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (w > (ptm->tmMaxCharWidth + ptm->tmOverhang))
|
|||
|
{
|
|||
|
wsprintf(rgch," GetTextExtent(ascii %d) return value %d exceeds tmMaxCharWidth %d\n\r",
|
|||
|
b,(int)w,(int)(ptm->tmMaxCharWidth + ptm->tmOverhang));
|
|||
|
CommSz(rgch);
|
|||
|
if (!fReported)
|
|||
|
{
|
|||
|
CommSz("");
|
|||
|
fReported = fTrue;
|
|||
|
}
|
|||
|
}
|
|||
|
else if ((rgdxp[i] != dxpNil) && (rgdxp[i] > (ptm->tmMaxCharWidth + ptm->tmOverhang)))
|
|||
|
{
|
|||
|
wsprintf(rgch," GetCharWidth(ascii %d) return value %d questionable, exceeds tmMaxCW %d\n\r",
|
|||
|
b, (int)(rgdxp[i]), (int)(ptm->tmMaxCharWidth + ptm->tmOverhang));
|
|||
|
CommSz(rgch);
|
|||
|
if (!fReported)
|
|||
|
{
|
|||
|
CommSz("");
|
|||
|
fReported = fTrue;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif /* PRDRVTEST */
|
|||
|
|
|||
|
}
|
|||
|
#endif /* SMFONT */
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
BOOL NEAR DogoneTrashTest(HDC hdc, struct FCE *pfce, BOOL fPrint)
|
|||
|
{
|
|||
|
#if 1
|
|||
|
int i,width;
|
|||
|
int *pdxpMax = pfce->rgdxp + chFmiMax - chFmiMin;
|
|||
|
int dxpOverhang = pfce->fmi.dxpOverhang;
|
|||
|
register int *rgdxp;
|
|||
|
int rgdxpNew[chFmiMax - chFmiMin];
|
|||
|
register int *dxpNew;
|
|||
|
|
|||
|
return 0;
|
|||
|
for (i=chFmiMin,
|
|||
|
rgdxp = pfce->rgdxp;
|
|||
|
i < chFmiMax; rgdxp++, ++i)
|
|||
|
{
|
|||
|
width = LOWORD(GetTextExtent(hdc,&i,1));
|
|||
|
if (*rgdxp != (width - dxpOverhang))
|
|||
|
{
|
|||
|
#ifdef DEBUG
|
|||
|
{
|
|||
|
char msg[120];
|
|||
|
wsprintf(msg,"widths have changed! Getting new width. (%s)\n\r",
|
|||
|
(LPSTR)(fPrint ? "PrinterDc" : "ScreenDC"));
|
|||
|
OutputDebugString(msg);
|
|||
|
}
|
|||
|
#endif
|
|||
|
GetCharWidth(hdc, chFmiMin, chFmiMax - 1, (LPINT)rgdxpNew);
|
|||
|
for (dxpNew = rgdxpNew,
|
|||
|
rgdxp = pfce->rgdxp;
|
|||
|
rgdxp != pdxpMax; dxpNew++, rgdxp++)
|
|||
|
*rgdxp = (*dxpNew - dxpOverhang);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
#else
|
|||
|
int rgdxpNew[chFmiMax - chFmiMin];
|
|||
|
int *pdxpMax = pfce->rgdxp + chFmiMax - chFmiMin;
|
|||
|
int dxpOverhang = pfce->fmi.dxpOverhang;
|
|||
|
register int *dxpNew;
|
|||
|
register int *rgdxp;
|
|||
|
if (GetCharWidth(hdc, chFmiMin, chFmiMax - 1, (LPINT)rgdxpNew))
|
|||
|
{
|
|||
|
/* Remove the overhang factor from individual char widths
|
|||
|
(see formula for widths of character strings above) */
|
|||
|
for (dxpNew = rgdxpNew,
|
|||
|
rgdxp = pfce->rgdxp;
|
|||
|
rgdxp != pdxpMax; dxpNew++, rgdxp++)
|
|||
|
{
|
|||
|
if (*rgdxp != (*dxpNew - dxpOverhang))
|
|||
|
{
|
|||
|
#ifdef DEBUG
|
|||
|
{
|
|||
|
char msg[120];
|
|||
|
wsprintf(msg,"widths have changed! Getting new width. (%s)\n\r",
|
|||
|
(LPSTR)(fPrint ? "PrinterDc" : "ScreenDC"));
|
|||
|
OutputDebugString(msg);
|
|||
|
}
|
|||
|
#endif
|
|||
|
for (dxpNew = rgdxpNew,
|
|||
|
rgdxp = pfce->rgdxp;
|
|||
|
rgdxp != pdxpMax; dxpNew++, rgdxp++)
|
|||
|
*rgdxp = (*dxpNew - dxpOverhang);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef JAPAN // added 11 Jun. 1992 by Hiraisi
|
|||
|
|
|||
|
int FAR PASCAL _export fnFontHook( lf, tm, nType, lpData )
|
|||
|
LPLOGFONT lf;
|
|||
|
LPTEXTMETRIC tm;
|
|||
|
short nType;
|
|||
|
LPSTR lpData;
|
|||
|
{
|
|||
|
if( lf->lfFaceName[0] == '@' &&
|
|||
|
lf->lfEscapement == 0 ){ /* @facename is found */
|
|||
|
return( FALSE );
|
|||
|
}
|
|||
|
|
|||
|
return( TRUE );
|
|||
|
}
|
|||
|
|
|||
|
void fnCheckWriting( LPLOGFONT lf )
|
|||
|
{
|
|||
|
extern HANDLE hMmwModInstance;
|
|||
|
FARPROC lpfnFontHook;
|
|||
|
char cFaceName[LF_FACESIZE+1] = "@";
|
|||
|
|
|||
|
lstrcat( (LPSTR)cFaceName, lf->lfFaceName );
|
|||
|
lpfnFontHook = MakeProcInstance(fnFontHook, hMmwModInstance);
|
|||
|
if( !EnumFonts( vhDCPrinter, cFaceName, lpfnFontHook, NULL ) )
|
|||
|
lstrcpy( (LPSTR)lf->lfFaceName, (LPSTR)cFaceName );
|
|||
|
FreeProcInstance( lpfnFontHook );
|
|||
|
}
|
|||
|
|
|||
|
#endif
|