|
|
/************************************************************/ /* Windows Write, Copyright 1985-1992 Microsoft Corporation */ /************************************************************/
/* Fonts.c -- WRITE font routines */
#define NOVIRTUALKEYCODES
#define NOWINSTYLES
#define NOSYSMETRICS
#define NOMENUS
#define NOICON
#define NOKEYSTATE
#define NOSYSCOMMANDS
#define NORASTEROPS
#define NOSHOWWINDOW
#define NOATOM
#define NOBITMAP
#define NOBRUSH
#define NOCLIPBOARD
#define NOCOLOR
#define NOCREATESTRUCT
#define NODRAWTEXT
#define NOMEMMGR
#define NOMENUS
#define NOMETAFILE
#define NOMINMAX
#define NOMSG
#define NOOPENFILE
#define NOPEN
#define NOPOINT
#define NOREGION
#define NOSCROLL
#define NOSOUND
#define NOWH
#define NOWINOFFSETS
#define NOWNDCLASS
#define NOCOMM
#include <windows.h>
#include "mw.h"
#define NOUAC
#include "cmddefs.h"
#include "dlgdefs.h"
#include "propdefs.h"
#include "fontdefs.h"
#include "prmdefs.h"
#include "str.h"
#include "docdefs.h"
#ifdef DBCS
#include "kanji.h"
#endif
#ifdef JAPAN
CHAR szDefFFN0[10]; CHAR szDefFFN1[10]; #endif
extern struct DOD (**hpdocdod)[]; extern HANDLE hMmwModInstance; extern HANDLE hParentWw; extern int vfSeeSel; extern int docCur; extern HWND vhWndMsgBoxParent; extern int vfCursorVisible; extern HCURSOR vhcArrow;
int iszSizeEnum; int iszSizeEnumMac; int iszSizeEnumMax; extern CHAR szSystem[];
#ifdef DBCS_VERT
extern CHAR szAtSystem[]; // Use for '@' fontface checking.
#endif
int iffnEnum; int vfFontEnumFail; struct FFNTB **hffntbEnum = NULL;
#ifdef NEWFONTENUM
/* Changed because it is INCORRECT to filter out all non-ANSI
character sets. Also we've removed this aspect-ratio checking stuff ..pault */
#define FCheckFont(lptm) (1)
#else
BOOL FCheckFont(lptm) LPTEXTMETRIC lptm; { /* This routine returns TRUE iff the character set for this font is the
ANSI set and either this is a vector font or the aspect ratio is correct. */
extern int aspectXFont; extern int aspectYFont;
return ( #ifdef DBCS
lptm->tmCharSet == NATIVE_CHARSET #else
lptm->tmCharSet == ANSI_CHARSET #endif
&& ((lptm->tmPitchAndFamily & 0x6) == 0x2 || (lptm->tmDigitizedAspectX == aspectXFont && lptm->tmDigitizedAspectY == aspectYFont))); } #endif /* else-def-NEWFONTENUM */
/* FontFaceEnum used to be called for a number of reasons so it used
rg[] to pass in parameters to get it to do different things including aspect-ratio filtering. I've simplified this a great deal so Write will allow more things (this can be good or bad) ..pault */
BOOL far PASCAL FontFaceEnum(lplf, lptm, fty, lParam) LPLOGFONT lplf; LPTEXTMETRIC lptm; int fty; /* font type, passed through from the EnumFonts call: */ /* fty & RASTER_FONTTYPE == fRasterFont */ /* fty & DEVICE_FONTTYPE == fDeviceFont */ long lParam; { /* Callback routine to record all of the appropriate face names for the
current printer. "appropriate" is based on the params as follows:
* rgw[0]=0 normal mode, =enumQuickFaces indicates "streamlined mode" (i.e. ignore all the following params in this case), and = * rgw[1]=RASTER_FONTTYPE if only raster fonts are to be enumerated, * =DEVICE_FONTTYPE if only device fonts are to be enumerated, * =TRUETYPE_FONTTYPE if only TRUE_TYPE fonts are to be enumerated, * rgw[2]=desired font family code (e.g. we start out only wanting swiss, and later expand that) * rgw[3] indicates whether or not we must match rgw[2] * rgw[4]=max number of fonts we have room for
..pault 10/12/89*/
int *rgw = (int *)LOWORD(lParam);
/* Stop enumerating if we have enough fonts */
if ((*hffntbEnum)->iffnMac >= rgw[4]) /* we have all we need */ return(FALSE); #ifdef DENUMF
{ char rgch[100]; wsprintf(rgch,"FFEn: %s, devicebit %d rasterbit %d ",lplf->lfFaceName, fty&DEVICE_FONTTYPE, fty&RASTER_FONTTYPE); CommSz(rgch); } #endif
#ifdef JAPAN //T-HIROYN Win3.1
if (rgw[0] == enumQuickFaces) goto addenumj; if (rgw[0] == enumFaceNameJapan) { if (lplf->lfCharSet == NATIVE_CHARSET) { if (rgw[1] == 0 && (fty & DEVICE_FONTTYPE) && !(CchDiffer(lplf->lfFaceName,szDefFFN0,lstrlen(szDefFFN0)))) goto addenumj; // 12/15/92
#if 1
if (rgw[1] == 3 && (fty & TRUETYPE_FONTTYPE) && (lplf->lfPitchAndFamily & 0xf0) == FF_ROMAN ) goto addenumj;
if (rgw[1] == 4 && (fty & TRUETYPE_FONTTYPE)) goto addenumj; #endif
if (rgw[1] == 1 && !(CchDiffer(lplf->lfFaceName,szDefFFN1,lstrlen(szDefFFN1)))) goto addenumj; if (rgw[1] == 2 && (lplf->lfPitchAndFamily & 0xf0) == FF_ROMAN && (lplf->lfPitchAndFamily & 0x0f) == FIXED_PITCH) goto addenumj; /* Is this the right type of font? */ } goto retenumj; } if (rgw[0] == enumFaceNames && (fty & rgw[1])) { if( (rgw[3] == 0) || ( (lptm->tmPitchAndFamily&grpbitFamily) == rgw[2] ) ) goto addenumj; } goto retenumj;
addenumj: { #else
if ((rgw[0] == enumQuickFaces) || /* Is this the right type of font? */ ((fty & rgw[1]) && /* Does this font belong to the correct family? Well
when rgw[3] says: NEEDN'T MATCH then of course it does, and when rgw[3] says: MATCH then we check to see! */ ((rgw[3] == 0)||((lptm->tmPitchAndFamily&grpbitFamily) == rgw[2])))) {
#endif //JAPAN
CHAR rgb[ibFfnMax]; struct FFN *pffn = (struct FFN *)rgb;
bltbx(lplf->lfFaceName, (LPSTR)pffn->szFfn, umin(LF_FACESIZE, IchIndexLp((LPCH)lplf->lfFaceName, '\0')+1)); pffn->chs = lplf->lfCharSet; /* save this setting */
/* We're interested in this one */ if (FCheckFont(lptm) && (*hffntbEnum)->iffnMac < iffnEnumMax) { pffn->ffid = lplf->lfPitchAndFamily & grpbitFamily; #ifdef DENUMF
CommSz("(adding)"); #endif
if (!FAddEnumFont(pffn)) { /* Couldn't add it to the table. */ vfFontEnumFail = TRUE; return(FALSE); } } } #ifdef DENUMF
CommSz("\n\r"); #endif
#ifdef JAPAN //T-HIROYN Win3.1
retenumj: #endif
return(TRUE); }
FInitFontEnum(doc, cffnInteresting, fOrder) /* sets up for a font enumeration, where caller cares about
'cffnInteresting' fonts, and special stuff is done iff 'fOrder' (to help us pick good default font(s) on startup */
int doc, cffnInteresting, fOrder; { extern HDC vhDCPrinter; #ifdef INEFFLOCKDOWN
extern FARPROC lpFontFaceEnum; #else
FARPROC lpFontFaceEnum = NULL; #endif
int iffn, iffnMac; struct FFNTB **hffntb; struct FFN *pffn, **hffn; struct FFN ffn; CHAR rgb[ibFfnMax]; int rgw[5];
vfFontEnumFail = FALSE;
if (hffntbEnum != NULL) { return(FALSE); }
if (FNoHeap(hffntbEnum = HffntbAlloc())) { hffntbEnum = NULL; return(FALSE); }
/* First we list all the fonts used in the current doc's ffntb */
#ifdef DENUMF
CommSzNumNum("FINITFONTENUM: cffnInteresting,fOrder ",cffnInteresting,fOrder); #endif
#ifdef JAPAN //T-HIROYN Win3.1J
//Clear defalut KanjiFtc <-- use menu.c GetKanjiFtc();
{ extern int KanjiFtc; KanjiFtc = ftcNil; } #endif
if (doc != docNil) { hffntb = HffntbGet(doc); iffnMac = imin((*hffntb)->iffnMac, iffnEnumMax); pffn = (struct FFN *)rgb; for (iffn = 0; iffn < iffnMac; iffn++) { hffn = (*hffntb)->mpftchffn[iffn]; bltbyte((*hffn), pffn, CbFromPffn(*hffn)); if (!FAddEnumFont(pffn)) goto InitFailure; } if ((*hffntbEnum)->iffnMac >= cffnInteresting) { goto HaveCffnInteresting; } }
#if 0
/* Include the fonts from WIN.INI in the enumeration */ if (!FAddProfileFonts()) { goto InitFailure; } #endif
if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting;
if (vhDCPrinter == NULL) { GetPrinterDC(FALSE); Assert(vhDCPrinter); }
#ifndef INEFFLOCKDOWN
if (!(lpFontFaceEnum = MakeProcInstance(FontFaceEnum, hMmwModInstance))) { WinFailure(); goto InitFailure; } #endif
/* See what the system knows about!
If order ISN'T significant, we'll examine all fonts at once. */
if (!fOrder) { #ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(all) \n\r"); #endif
rgw[0] = enumQuickFaces; // means igonre the rest
#if 0
rgw[1] = RASTER_FONTTYPE; // ignored, why set?
rgw[2] = FF_SWISS; // ignored, why set?
rgw[3] = TRUE; // ignored, why set?
rgw[4] = cffnInteresting; // ignored, why set?
#endif
EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; else goto HaveCffnInteresting; /* got what we needed */ }
#ifdef JAPAN //T-HIROYN Win3.1
/* japanens write try in steps first
#1 KANJI_CHARSET device_fonttype mincho
//12/15/92
add KANJI_CHARSET TRUETYPE FF_ROMAN add KANJI_CHARSET TRUETYPE #2 KANJI_CHARSET hyoujyun mincho
#3 KANJI_CHARSET all font FF_ROMAN FIXED_PITCH
*/
rgw[0] = enumFaceNameJapan; /* #define in FONTDEFS.H */ rgw[1] = 0; rgw[2] = rgw[3] = 0; /* dummy */ rgw[4] = 32767;
EnumFonts(vhDCPrinter,0L,lpFontFaceEnum,(LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
// 12/15/92
#if 1
rgw[1] = 3; EnumFonts(vhDCPrinter,0L,lpFontFaceEnum,(LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */ rgw[1] = 4; EnumFonts(vhDCPrinter,0L,lpFontFaceEnum,(LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */ #endif
rgw[1] = 1; EnumFonts(vhDCPrinter,0L,lpFontFaceEnum,(LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
rgw[1] = 2; EnumFonts(vhDCPrinter,0L,lpFontFaceEnum,(LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
#endif /* JAPAN */
/* Ahh... but since we now know order IS significant, i.e. we are
trying to pick good default fonts for startup, we'll try in steps:
#1--any good TrueType fonts in the Swiss font family?
#2--any good TrueType fonts in the non-Swiss?
#3--any good device-based fonts in the Swiss font family?
#4-- " " " " non-Swiss?
#5--any non device-based fonts in the Swiss font family?
#6-- " " " " non-Swiss? */
#ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(Swiss truetype) \n\r"); #endif
rgw[0] = enumFaceNames; rgw[1] = TRUETYPE_FONTTYPE; rgw[2] = FF_SWISS; rgw[3] = TRUE; /* match swiss! */ rgw[4] = 32767;
EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
#ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(nonSwiss truetype) \n\r"); #endif
rgw[3] = FALSE; /* need not match swiss! */ EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
#ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(Swiss device) \n\r"); #endif
rgw[1] = DEVICE_FONTTYPE; rgw[3] = TRUE; /* match swiss! */ EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
#ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(nonSwiss device) \n\r"); #endif
rgw[3] = FALSE; /* need not match swiss */ EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
#ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(Swiss nondevice) \n\r"); #endif
rgw[1] = RASTER_FONTTYPE; rgw[3] = TRUE; /* match swiss! */ EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure; if ((*hffntbEnum)->iffnMac >= cffnInteresting) goto HaveCffnInteresting; /* got what we needed */
#ifdef DENUMF
CommSz("FINITFONTENUM: EnumFonts(Swiss nondevice) \n\r"); #endif
rgw[3] = FALSE; /* need not match swiss */ EnumFonts(vhDCPrinter, 0L, lpFontFaceEnum, (LPSTR)MAKELONG(&rgw[0], 0)); if (vfFontEnumFail) goto InitFailure;
HaveCffnInteresting: iffnEnum = 0; #ifndef INEFFLOCKDOWN
if (lpFontFaceEnum) FreeProcInstance(lpFontFaceEnum); #endif
#ifdef JAPAN //T-HIROYN Win3.1
if(docNil == doc && fOrder) SaveKanjiFfn(); #endif
return(TRUE);
InitFailure: FreeFfntb(hffntbEnum); hffntbEnum = NULL; #ifndef INEFFLOCKDOWN
if (lpFontFaceEnum) FreeProcInstance(lpFontFaceEnum); #endif
return(FALSE); }
void ResetFontTables(void) { /*
Free the pfce's. LoadFont will reallocate them with new information obtained below. */
FreeFonts(TRUE,TRUE);
/* This is a clumsy method that takes advantage of side effect of
resetting the data stored in the font tables */ FInitFontEnum(docNil, 32767, FALSE);
#ifdef JAPAN //T-HIROYN 92.08.18 Win3.1
//Printer Change ?
//Sync FontFaceName and CharSet
{ int iffn, iffnMac; int Eiffn, EiffnMac; struct FFNTB **hffntb; struct FFN ***mpftchffn; struct FFN ***Empftchffn; char msg[30];
hffntb = HffntbGet(docCur); if (hffntb != 0) { mpftchffn = (*hffntb)->mpftchffn; iffnMac = (*hffntb)->iffnMac;
Empftchffn = (*hffntbEnum)->mpftchffn; EiffnMac = (*hffntbEnum)->iffnMac;
for (iffn = 0; iffn < iffnMac; iffn++) { for (Eiffn = 0; Eiffn < EiffnMac; Eiffn++) { if (WCompSz((*mpftchffn[iffn])->szFfn, (*Empftchffn[Eiffn])->szFfn) == 0) { (*mpftchffn[iffn])->chs = (*Empftchffn[Eiffn])->chs; break; } } } } } #endif
EndFontEnum(); }
CHAR * (NEAR PchSkipSpacesPch( CHAR * ));
int WFromSzNumber( ppch ) CHAR **ppch; { /* Given an ASCII string containing a (base 10) number, return the number
represented. Ignores leading and trailing spaces. Does not accept negative numbers. */ /* 10/12/89 ..pault
Now increments the pointer to just past last digit converted */
unsigned w = 0; CHAR ch;
*ppch = PchSkipSpacesPch( *ppch ); while ( ((ch = (*(*ppch)++)) >= '0') && (ch <= '9') ) { w = (w * 10) + (ch - '0'); }
(*ppch)--; /* bumped one too far */ return w; }
CHAR * (NEAR PchSkipSpacesPch( pch )) CHAR *pch; { /* Return a pointer to the first character in the string
at pch that is either null or non-whitespace */
for ( ;; ) { #ifdef DBCS
/* DB Char space must be checked */ if (FKanjiSpace(*pch, *(pch + 1))) { pch += cchKanji; continue; } #endif /* DBCS */
switch (*pch) { default: return pch; case ' ': case 0x09: pch++; break; } } }
BOOL FEnumFont(pffn) /* returns the next font entry through pffn. Returns FALSE if no more */
struct FFN *pffn; { int cb; struct FFN **hffn;
if (iffnEnum >= (*hffntbEnum)->iffnMac) { return(FALSE); }
hffn = (*hffntbEnum)->mpftchffn[iffnEnum]; #ifdef DEBUG
cb = CchSz( (*hffn)->szFfn ); Assert( cb <= LF_FACESIZE ); cb = CbFfn( cb ); #else
cb = CbFfn(CchSz((*hffn)->szFfn)); #endif
bltbyte(*hffn, pffn, cb); iffnEnum++; return(TRUE); }
EndFontEnum() /* cleans up after a font enumeration */ { FreeFfntb(hffntbEnum); hffntbEnum = NULL; }
FAddEnumFont(pffn) /* code factoring for adding described font to enumeration table - filters
out "ghost fonts" and system font */
struct FFN *pffn; { #ifdef JAPAN
// It is required to do vertical writing with system font in JAPAN.
if ( pffn->szFfn[0] == chGhost) #else
if (WCompSz(pffn->szFfn, szSystem) == 0 || pffn->szFfn[0] == chGhost) #endif
return(TRUE); return(FEnsurePffn(hffntbEnum, pffn)); }
#ifdef JAPAN //T-HIROYN 92.08.18 Win3.1
BYTE scrFontChs; //I want to get true Charset
BOOL far PASCAL _export NFontFaceEnum(lplf, lptm, fty, lParam) LPLOGFONT lplf; LPTEXTMETRIC lptm; int fty; long lParam; { if (LOWORD(lParam) == 0) { scrFontChs = lplf->lfCharSet; return(FALSE); } return(TRUE); } #endif
#ifdef NEWFONTENUM
/* This stuff added for Win3 because we have to be able to determine
with which character set a font in a particular document is associated, since our file format does not store it. Naturally, WinWord added that to their file format! ..pault */
/* Look through the list of fonts sitting out there [i.e. FInitFontEnum
must have been called, and it is from HffntbForFn()] and make our best guess as to what CharSet it's supposed to have, since we don't store these in the doc font table! */
int ChsInferred( pffn ) struct FFN *pffn; { struct FFN *pffnCheck; char *sz = pffn->szFfn; #ifdef DBCS
int chs = NATIVE_CHARSET; #else
int chs = 0; #endif
int i, iMac = (*hffntbEnum)->iffnMac;
for (i = 0; i < iMac; i++) { pffnCheck = *(struct FFN **) ((*hffntbEnum)->mpftchffn[i]); if (WCompSz(pffnCheck->szFfn, sz) == 0) { #ifdef DIAG
if (pffnCheck->ffid != pffn->ffid) { CommSzSz("ChsInferred: matched fontname ",sz); CommSzNumNum(" but enum->ffid / doc->ffid", pffnCheck->ffid,pffn->ffid); } #endif
Assert(pffnCheck->ffid == pffn->ffid); chs = pffnCheck->chs; break; } }
#ifdef JAPAN //T-HIROYN 92.08.18 Win3.1
//I want to get true Charset
{ extern HDC vhMDC; /* memory DC compatible with the screen */ FARPROC NlpFontFaceEnum;
if(i == iMac) { if(vhMDC != NULL) { if (NlpFontFaceEnum = MakeProcInstance(NFontFaceEnum, hMmwModInstance)) { scrFontChs = chs; EnumFonts(vhMDC,(LPSTR)sz,NlpFontFaceEnum,(LPSTR) NULL); FreeProcInstance(NlpFontFaceEnum); if(chs != scrFontChs) chs = scrFontChs; } } } } #endif
return(chs); } #endif /* NEWFONTENUM */
#ifdef JAPAN //T-HIROYN Win3.1
CHAR saveKanjiDefFfn[ibFfnMax];
SaveKanjiFfn() { int i, iMac = (*hffntbEnum)->iffnMac;
struct FFN *pffn = (struct FFN *)saveKanjiDefFfn; struct FFN *hffn;
for (i = 0; i < iMac; i++) { hffn = *(struct FFN **) ((*hffntbEnum)->mpftchffn[i]); if (NATIVE_CHARSET == hffn->chs) { lstrcpy(pffn->szFfn, hffn->szFfn); pffn->ffid = hffn->ffid; pffn->chs = hffn->chs; break; } } } #endif
|