/* Copyright 1991,1992,1993,1994,1995,1996,1997,1998,1999 Y&Y, Inc. Copyright 2007 TeX Users Group This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _WINDOWS #define _WINDOWS #endif #define NOCOMM #define NOSOUND #define NODRIVERS #define STRICT #include "windows.h" #include "windowsx.h" #include #include #include #include #include "dviwindo.h" #include "winextra.h" #include "winhead.h" #include "winbased.h" #pragma hdrstop #include /* needed for sqrt in WriteAFM... */ #include /* for _mkdir */ #include #include "atm.h" #include "atmpriv.h" /* #include "afmtotfm.h" */ #define OUT_SCREEN_OUTLINE_PRECIS 9 /* Allows OUtlineTextMetrics (et al) for currently selected printer DC T1 */ // #ifdef USEUNICODE // typedef struct { // char *glyphname; // unsigned short UID; // } UNICODE_MAP; // #endif #pragma warning(disable:4100) // unreferenced formal parameters #define AFMTOTFMDLL #define DEBUGFONTSEARCH #define DEBUGTABLES // #define DEBUGHEAP // #define DEBUGFONTCHECK // #define DEBUGFONTSELECT #define DEBUGREGISTRY #define DEBUGAFMNAME #define DEBUGWRITEAFM #define DEBUGCHARMETRICS /* #define DEBUGCOPY */ /* #define DEBUGATM */ /* #include */ /* for Registration Data Base HKEY_CLASSES_ROOT */ /* Copyright (C) 1991, 1992 Y&Y. All rights reserved. */ /* DO NOT COPY OR DISTRIBUTE! */ /**************************************************************************** PROGRAM: winfonts.c PURPOSE: Take some infrequently used code out of dviwindo.c Mostly for font display ****************************************************************************/ #define ITALICFUZZ 30 typedef struct{ short etmSize; /* size of structure */ short etmPointSize; /* nominal point size */ short etmOrientation; /* 0 => either, 1 => portrait, 2 => landscape */ short etmMasterHeight; /* font size for which extent table is exact */ short etmMinScale; /* min valid size */ short etmMaxScale; /* max valid size */ short etmMasterUnits; /* integer numberof units per em */ short etmCapHeight; /* height of upper case, typically of `H' */ short etmXHeight; /* height of lower case, typically of `x' */ short etmLowerCaseAscent; /* ascent of lower case, typically of `d' */ short etmLowerCaseDescent; /* descent of lower case, typically of `p' */ short etmSlant; /* clockwise angle in tenth of degree */ short etmSuperScript; /* offset of superscript from base (negative) */ short etmSubScript; /* offset of subscript from base (positive) */ short etmSuperScriptSize; short etmSubScriptSize; short etmUnderlineOffset; short etmUnderlineWidth; short etmDoubleUpperUnderlineOffset; short etmDoubleLowerUnderlineOffset; short etmDoubleUpperUnderlineWidth; short etmDoubleLowerUnderlineWidth; short etmStrikeOutOffset; short etmStrikeOutWidth; WORD etmKernPairs; /* number of character kerning pairs */ WORD etmKernTracks; /* number of kerning tracks */ } EXTTEXTMETRIC; /* typedef struct { union { BYTE each [2]; WORD both; } kpPair; short kpKernAmount; } KERNPAIR; */ /* used by GETPAIRKERNTABLE ExtEscape() */ typedef struct kernpair { /* unsigned int kppair; int kpamount; */ /* this is wrong in WIN32 */ WORD kpPair; short kpKernAmount; /* ??? */ } KERNPAIR; /* used by GETPAIRKERNTABLE ExtEscape() */ /* NOTE: above *DIFFERENT* from KERNINGPAIR struct used by GetKerningPairs */ /* typedef struct tagKERNINGPAIR { WORD wFirst; WORD wSecond; int iKernAmount; } KERNINGPAIR, FAR* LPKERNINGPAIR; */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* #define LF_FULLFACESIZE 64 */ /* Structure passed to FONTENUMPROC */ /* NOTE: NEWTEXTMETRIC is the same as TEXTMETRIC plus 4 new fields */ /* typedef struct tagNEWTEXTMETRIC { int tmHeight; int tmAscent; int tmDescent; int tmInternalLeading; int tmExternalLeading; int tmAveCharWidth; int tmMaxCharWidth; int tmWeight; BYTE tmItalic; BYTE tmUnderlined; BYTE tmStruckOut; BYTE tmFirstChar; BYTE tmLastChar; BYTE tmDefaultChar; BYTE tmBreakChar; BYTE tmPitchAndFamily; BYTE tmCharSet; int tmOverhang; int tmDigitizedAspectX; int tmDigitizedAspectY; DWORD ntmFlags; UINT ntmSizeEM; UINT ntmCellHeight; UINT ntmAvgWidth; } NEWTEXTMETRIC; typedef NEWTEXTMETRIC* PNEWTEXTMETRIC; typedef NEWTEXTMETRIC NEAR* NPNEWTEXTMETRIC; typedef NEWTEXTMETRIC FAR* LPNEWTEXTMETRIC; */ /* NEWTEXTMETRIC structure is same as TEXTMETRIC except for last four items */ /* These last four are only filled in for a TrueType font */ /* ntmFlags field flags */ /* #define NTM_REGULAR 0x00000040L */ /* #define NTM_BOLD 0x00000020L */ /* #define NTM_ITALIC 0x00000001L */ /* Structure passed to FONTENUMPROC */ /* typedef struct tagENUMLOGFONT { LOGFONT elfLogFont; char elfFullName[LF_FULLFACESIZE]; char elfStyle[LF_FACESIZE]; } ENUMLOGFONT, FAR* LPENUMLOGFONT; */ /* last element of LOGFONT is `Face Name' */ /* two members added to LOGFONT structure only for TrueType fonts */ /* EnumFonts font type values */ /* from wingdi.h */ /* In Windows 95 ATM fonts show up as DEVICE_FONTTYPE, *NOT* in NT */ /* Font Type of Type 1 fonts is 0 (zero!) in Windows NT (for now) UGH */ /* #define RASTER_FONTTYPE 0x0001 */ /* #define DEVICE_FONTTYPE 0X0002 */ /* #define TRUETYPE_FONTTYPE 0x0004 */ #define TTF_DONE 1 /* 98/Nov/20 */ #define PFM_DONE 2 /* 98/Nov/20 */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* Define a structure used to hold info about an app we */ /* start with ExecApp so that this info can be used again */ /* later to test if the app is still running */ // typedef struct _EXECAPPINFO { // HINSTANCE hInstance; /* The instance value */ // HWND hWnd; /* The main window handle */ // HTASK hTask; /* The task handle */ // } EXECAPPINFO, FAR *LPEXECAPPINFO; /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* Added 1995/August/2 for registry files - for Windows 95 and NT 4.0 */ /* For Windows NT need to replace "Windows" with "Windows NT" */ /* But in Windows NT regedt32.exe writes a different form of file anyway */ /* --- unless we have the New Shell */ /* char *szRegistryFonts= "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts"; */ // char szRegistryFonts[128]=""; /* constructed dynamically now */ char *szRegistryFonts=NULL; /* constructed dynamically now */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* The following are all in WINSEARC.C 1994/Dec/22 */ /* #define MyATMIsUp ATMIsUp */ /* in atm.h */ #define MyATMGetVersion ATMGetVersion #define MyATMFontSelected ATMFontSelected #define MyATMGetFontBBox ATMGetFontBBox #define MyATMGetOutline ATMGetOutline #define MyATMFontAvailable ATMFontAvailable #define MyATMSelectObject ATMSelectObject #define MyATMGetPostScriptName libATMGetPostScriptName #define MyATMGetFontPaths libATMGetFontPaths /* #define MyATMGetMenuName libATMGetMenuName */ /* in atmpriv.h */ /* #define MyATMSelectEncoding libATMSelectEncoding */ #define MyATMGetGlyphList libATMGetGlyphList /* #define MyATMMarkDC libATMMarkDC */ #define MyATMGetFontInfo libATMGetFontInfo #ifdef IGNORED extern WORD (WINAPI *MyATMGetVersion) (VOID); extern BOOL (WINAPI *MyATMFontSelected) (HDC); extern int (WINAPI *MyATMGetFontBBox) (HDC, LPATMBBox); extern int (WINAPI *MyATMGetOutline) (HDC, char, LPATMFixedMatrix, FARPROC, FARPROC, FARPROC, FARPROC, LPSTR); extern int (WINAPI *MyATMFontAvailable) (LPSTR, int, BYTE, BYTE, BYTE, BOOL FAR *); extern int (WINAPI *MyATMSelectObject) (HDC, HFONT, WORD, HFONT FAR *); /* the following needed the API BD_VERSION number */ extern int (WINAPI *MyATMGetPostScriptName) (int, LPSTR, LPSTR); extern int (WINAPI *MyATMGetGlyphList) (int, HDC, FARPROC, LPSTR); #endif /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ TEXTMETRIC TextMetric; /* used by font sample module */ /* int charwidths[MAXCHRS]; */ /* character widths for font */ short int charwidths[MAXCHRS]; /* character widths for font */ /* used by test function CHARWIDTHS */ /* int extwidths[MAXCHRS]; */ /* character widths for font - test only */ BOOL bTexFontFlag; /* non-zero if likely to be TeX font */ BOOL bCheckBoldFlag = 0; /* checked font desired is bold */ BOOL bCheckItalicFlag = 0; /* checked font desired is italic */ BOOL bCheckSymbolFlag = 0; /* font is symbol/decorative/math */ BOOL bCheckReencode = 0; /* reencode font being shown */ BOOL bSyntheticFlag = 0; /* synthesized font */ BOOL bShowHidden=0; /* info in AFM file on char without name */ /* BOOL redosizes = 0; */ int testcharset = 0; /* CharSet of selected font */ int testpitchandfamily = 0; /* PitchAndFamily of selected font */ int testwantttf = 0; /* test font is TTF if non-zero */ /* negative for decorative/symbol */ /* BYTE CharSet[MAXOUTLINEFONTS]; */ BYTE CharSet[MAXOUTLINEFACES]; /* 1995/July/12 */ /* BYTE PitchAndFamily[MAXOUTLINEFONTS]; */ BYTE PitchAndFamily[MAXOUTLINEFACES]; /* 1995/July/12 */ /* BYTE IsTTF[MAXOUTLINEFACES]; */ /* bit wasteful - use (TT) instead */ int nFaceIndex = 0; /* How many Faces */ int nTrueIndex = 0; /* How many TT Faces */ int nFullIndex = 0; /* index into Full Table - number loaded */ int nFileIndex = 0; /* index into File Table - number loaded */ /* int SizeIndex = 0; */ /* how many sizes */ int CurrentFace = 0; /* index of current font in FontList table */ /* int PreviousFont = 0; */ /* index of current font in FontList table */ /* int CurrentSize = 0; */ /* index of current size in SizeList table */ // LPSTR lpFaceNames=NULL; /* FAR pointer to start of Font Name Table */ LPSTR *lpFaceNames=NULL; /* pointer to Font Name Table */ // LPSTR lpCurrentName=NULL; /* pointer into Font Name Table */ // LPSTR lpPreviousName=NULL; /* pointer into Font Name Table */ LPSTR lpFullNames=NULL; /* table of FaceName+Style => FullName */ LPSTR lpFileNames=NULL; /* table of FaceName+Style => FileName */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ BOOL bTagFlag=0; /* on while searching for tag */ int tagx, tagy; /* spot marked for font info */ int taggedfont=-1; /* font selected when tagged */ int taggedchar=0; /* character tagged */ int taggedwidth=0; /* character width */ // int ltaggedwidth; /* the width of the tagged char*/ long ltaggedwidth; /* the width of the tagged char*/ int StyleBits; /* four flags orred to indicate which styles are available in this Face */ /* 1 => regular, 2 => italic, 4=> bold, 8 => bold-italic */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ BOOL bDoUnencodedGlyphs=1; /* a test 1995/July/20 */ BOOL bDoReencodeKern=1; /* another test 1995/July/20 */ BOOL bListUnencoded;/* non-zero => list unencoded rather than encoded glyph */ /* global used in Glyph Enumeration callback routine */ int nglyph; /* number of glyphs in enumeration so far */ int nencoded; /* number of encoded glyphs */ int nunencode; /* number of unencoded glyphs */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* Adobe Standard Encoding just for AFM output of text font */ char *standardencoding[] = { /* 1998/Aug/26 */ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", "asciitilde", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "exclamdown", "cent", "sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "", "endash", "dagger", "daggerdbl", "periodcentered", "", "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", "", "questiondown", "", "grave", "acute", "circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "", "ring", "cedilla", "", "hungarumlaut", "ogonek", "caron", "emdash", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "AE", "", "ordfeminine", "", "", "", "", "Lslash", "Oslash", "OE", "ordmasculine", "", "", "", "", "", "ae", "", "", "", "dotlessi", "", "", "lslash", "oslash", "oe", "germandbls", "", "", "", "", }; int standardcode(char *name) { /* 1998/Aug/26 */ int k; if (*name == '\0') return -1; /* sanity check */ for (k = 64; k < 128; k++) { if (strcmp(standardencoding[k], name) == 0) return k; } for (k = 32; k < 64; k++) { if (strcmp(standardencoding[k], name) == 0) return k; } for (k = 160; k < 256; k++) { if (strcmp(standardencoding[k], name) == 0) return k; } return -1; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ static char *modname = "WINFONTS"; /* static void winerror(char *mss) { HWND hFocus; char errmess[MAXMESSAGE]; if (strlen(mss) > (MAXMESSAGE - 32)) mss = "Error Message too long!"; strcpy(errmess, mss); if((hFocus = GetFocus()) == NULL) hFocus = hwnd; (void) MessageBox (hFocus, errmess, modname, MB_ICONSTOP | MB_OK); } */ static void winerror (char *message) { HWND hFocus; if ((hFocus = GetFocus()) == NULL) hFocus = hwnd; (void) MessageBox(hFocus, message, modname, MB_ICONSTOP | MB_OK); } /* static void wininfo(char *message) */ static void wininfoTFM (char *message, char *TFMname) { HWND hFocus; if ((hFocus = GetFocus()) == NULL) hFocus = hwnd; (void) MessageBox(hFocus, message, TFMname, MB_ICONINFORMATION | MB_OK); } static int wincancel (char *buff) { /* 1993/March/15 */ HWND hFocus; int flag; if ((hFocus = GetFocus()) == NULL) hFocus = hwnd; flag = MessageBox(hFocus, buff, modname, MB_ICONSTOP | MB_OKCANCEL); if (flag == IDCANCEL) return -1; else return 0; } static int wincancelTFM (char *buff, char *TFMname) { /* 1993/March/15 */ HWND hFocus; int flag; if ((hFocus = GetFocus()) == NULL) hFocus = hwnd; flag = MessageBox(hFocus, buff, TFMname, MB_ICONSTOP | MB_OKCANCEL); if (flag == IDCANCEL) return -1; else return 0; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* share common code to save space and ensure consistency */ char *SansPath (char *fname) { /* returns pointer to filename minus path */ char *s; if ((s = strrchr(fname, '\\')) != NULL || (s = strrchr(fname, '/')) != NULL || (s = strrchr(fname, ':')) != NULL) return (s+1); else return fname; } void FlushExtension (char *fname) { /* remove extension, newline if present */ char *s; /* if ((s = strchr(fname, '.')) != NULL) *s = '\0'; */ if ((s = strrchr(fname, '.')) != NULL) *s = '\0'; else if ((s = strchr(fname, '\n')) != NULL) *s = '\0'; } char *StripQuotes (char *name) { /* remove double quote around string */ char *s; if ((s = strchr(name+1, '\"')) != NULL) *s = '\0'; /* terminate final " */ if (*name == '\"') return (name+1); /* step over initial " */ else return name; } char *StripTrueType (char *name) { /* remove (TrueType) return NULL if not */ char *s; if ((s = strstr(name, "(TrueType)")) == NULL) return NULL; while (s > name && *(s-1) <= ' ') s--; *s = '\0'; return name; } void StripTTVersion (char *name) { /* remove version number if possible */ int c; if (*(name+6) != '_') return; /* not safe without _ before */ if (strlen(name) != 8) return; /* not full 8 character name */ c = *(name+7); if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) *(name+7) = '_'; } void StripUnderScores (char *name) { /* remove underscores from name */ char *s; if (*(name+7) != '_') return; /* not end in _ */ if (strlen(name) != 8) return; /* not full 8 character name */ s = name + 7; while (s > name && *(s-1) == '_') s--; *s = '\0'; } void UpperCase (char *name) { CharUpper(name); /* 96/Sep/29 */ /* AnsiUpper(name); */ } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ // LPSTR GrabFaceNames (void) { LPSTR *GrabFaceNames (void) { // LPSTR lpFaceNames=NULL; LPSTR *lpFaceNames=NULL; if (hFaceNames == NULL) winerror("No Fonts to grab"); else { // lpFaceNames = (LPSTR) GlobalLock(hFaceNames); lpFaceNames = (LPSTR *) GlobalLock(hFaceNames); if (lpFaceNames == NULL) { winerror("Unable to lock Fonts"); /* winerror("Unable to lock Face Names"); */ PostQuitMessage(0); /* pretty serious ! */ } } return lpFaceNames; } void ReleaseFaceNames (void) { int n; if (hFaceNames == NULL) { winerror("No Fonts to release"); return; } if ((n = GlobalUnlock(hFaceNames)) > 0) { /* if (bDebug) { sprintf(str, "%d\t", n); strcat(str, "Lock count Not Zero"); strcat(str, " - ReleaseFaceNames"); if (wincancel(str)) PostQuitMessage(0); } */ } else { lpFaceNames = NULL; // lpCurrentName = NULL; } } /* 256 * (32 + 8) = 10,240 byte - quite a chunck 1995/July/7 */ /* 512 * (32 + 8) = 20,480 byte - quite a chunck 1995/July/7 */ void AllocFaceNames (void) { /* grab space for FontNames - if needed */ unsigned long n; if (hFaceNames != NULL) return; /* already allocated */ /* entries are character strings of length MAXFACENAME */ // n = (unsigned long) MAXOUTLINEFACES * MAXFACENAME; // entries are pointers to character strings n = (unsigned long) MAXOUTLINEFACES * sizeof(LPSTR); /* hFaceNames = GlobalAlloc(GMEM_MOVEABLE, */ hFaceNames = GlobalAlloc(GHND, /* GMEM_MOVEABLE | GMEM_ZEROINIT */ /* (unsigned long) MAXOUTLINEFONTS * MAXFACENAME); */ n); if (hFaceNames == NULL) { winerror("Unable to allocate memory"); /* debug */ bFontSample = 0; /* sigh ... */ bCharacterSample = 0; PostQuitMessage(0); /* pretty serious ! */ } nFaceIndex = 0; nTrueIndex = 0; } void FreeFaces (void) { int k; if (hFaceNames == NULL) return; lpFaceNames = GrabFaceNames(); for (k = 0; k < MAXOUTLINEFACES; k++) { if (lpFaceNames[k] != NULL) { free(lpFaceNames[k]); lpFaceNames[k] = NULL; } } ReleaseFaceNames(); } /* called only from dviwindo.c */ void FreeFaceNames (void) { if (hFaceNames == NULL) { if (bDebug > 1) winerror("No Fonts to free"); return; } FreeFaces(); // 99/Nov/8 hFaceNames = GlobalFree(hFaceNames); hFaceNames = NULL; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* typedef struct { BYTE chFirst; BYTE chLast; } CHAR_RANGE_STRUCT; */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ char *FormatStyle (char *buffer, int boldflag, int italicflag) { sprintf(buffer, "%s%s%s,", (boldflag == 0 && italicflag == 0) ? "REGULAR" : "", boldflag ? "BOLD" : "", italicflag ? "ITALIC" : ""); return buffer + strlen(buffer); } char *FormatNameStyle (char *buffer, char *fname, int boldflag, int italicflag) { /* 1995/Aug/20 */ char *s; strcpy(buffer, fname); strcat(buffer, ","); s = buffer + strlen(buffer); return FormatStyle (s, boldflag, italicflag); /* returns pointer to null at end */ } char *FormatNewNameStyle (char *buffer, int m, char *szFaceName, int nStyle, char *szFileName) { char *s; sprintf(buffer, "%3d %s,%s%s%s=%s\n", m, szFaceName, (nStyle & NTM_REGULAR) ? "REGULAR" : "", (nStyle & NTM_BOLD) ? "BOLD" : "", (nStyle & NTM_ITALIC) ? "ITALIC" : "", szFileName); s = buffer + strlen(buffer); return s; } #ifdef IGNORED /* sprintf(buffer, "%s,%s%s%s ", fname, (boldflag == 0 && italicflag == 0) ? "REGULAR" : "", boldflag ? "BOLD" : "", italicflag ? "ITALIC" : ""); s = buffer + strlen(buffer); */ #endif /* somewhat expensive in space to keep this as global ? */ /* char szTTFName[LF_FACESIZE + MAXMSEXTRA]; */ /* Face Name */ char szFaceName[LF_FACESIZE]; /* Face Name */ char szFullName[LF_FULLFACESIZE]; /* Full Name */ BOOL bBoldFlag, bItalicFlag; /* Style Bits */ int nFullName; /* size of longest match */ /* For TT, the `Face Name' is what is listed in font menus */ /* For TT, the `Full Name' is what appears in WIN.INI */ /* Somehow need to get from `Face Name' to `Full Name' ??? */ /* See whether can find TrueType font with this name *//* 1992/Sep/17 */ /* returns length of string of name set up in szFullName */ /* returns zero if not found or fail some other way */ /* returns file name in str */ int FullFromFace (HDC, char *, int, int); /* defined at end */ char *ConstructFontKey0 (char *s) { // split off 2000 June 2 strcpy(s, "SOFTWARE\\Microsoft\\Windows"); if (bWinNT) strcat(str, " NT"); strcat(s, "\\CurrentVersion"); strcat(s, "\\Fonts"); return s; } char *ConstructFontKey (char *s) { // split off 2000 June 2 strcpy(s, "HKEY_LOCAL_MACHINE\\"); // strcat(s, "SOFTWARE\\Microsoft\\Windows"); // if (bWinNT) strcat(s, " NT"); // strcat(s, "\\CurrentVersion"); // strcat(s, "\\Fonts"); ConstructFontKey0(s + strlen(s)); return s; } /* See whether can find TrueType font with this name *//* 1992/Sep/17 */ /* returns length of string of name set up in szFullName */ /* bCheckBoldFlag and bCheckItalicFlag global pass information */ /* int TryForTrue (char *testfont, int boldflag, int italicflag) */ int TryForTrue (HDC hDC, char *testfont, int boldflag, int italicflag) { int lenstr; char szTrueType[LF_FULLFACESIZE + 12]; /* space for " (TrueType)" */ int m, nStyle=0, nStyleWant=0; LPSTR lpFileCurrent; /* 95/Sep/20 */ /* following is the *real* way to do this for TT fonts */ #ifdef DEBUGFONTSELECT if (bDebug > 1) OutputDebugString("TryForTrue\n"); #endif /* if (bWin95 && bUseRegEnumValue) */ /* 1995/Sep/20 */ if (bUseTTMapping) { /* default 1995/Sep/20 */ /* check whether table has been set up and if not, set it up ? */ if (hFileNames == NULL) SetupTTMapping(hDC); lpFileNames = GrabFileNames(); if (lpFileNames == NULL) return 0; /* super ugh ! */ /* need to set up szFullName also ? */ /* this returns length of string in szFullName - filename in str */ lenstr = FullFromFace(hDC, testfont, boldflag, italicflag); if (lenstr == 0) return 0; /* impossible */ lenstr = 0; *str = '\0'; if (!boldflag && !italicflag) nStyleWant |= NTM_REGULAR; else { if (boldflag) nStyleWant |= NTM_BOLD; if (italicflag) nStyleWant |= NTM_ITALIC; } /* if (strcmp(testfont, "Marlett") == 0) nStyleWant = 0;*/ /* 96/Oct/12 */ for (m = 0; m < nFileIndex; m++) { lpFileCurrent = lpFileNames + m * (LF_FACESIZE + 2 + MAXTFMNAME + 2); /* strcpy(szFaceName, lpFileCurrent); */ /* if (_stricmp(szFaceName, testfont) != 0) continue; */ if (strcmp(testfont, lpFileCurrent) != 0) continue; nStyle = *(lpFileCurrent + LF_FACESIZE + 1); #ifdef DEBUGFONTSELECT if (bDebug > 1) { sprintf(debugstr, "testfont %s nStyle %x nStyleWant %x\n", testfont, nStyle, nStyleWant); OutputDebugString(debugstr); } #endif if (nStyle != nStyleWant && nStyle != 0) continue; /* strcpy(szFileName, lpFileCurrent + LF_FACESIZE + 2); */ strcpy(str, lpFileCurrent + LF_FACESIZE + 2); /* if (bDebug > 1) OutputDebugString(str); */ lenstr = strlen(str); break; } ReleaseFileNames(); if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 1); OutputDebugString(debugstr); } return lenstr; } /* Get here if not Windows 95 or not using table made from registry data */ if (szRegistry == NULL) return 0; /* sanity - should not happen */ if (bTTUsable) { /* result - if any - of following is setup in szFullName */ lenstr = FullFromFace(hDC, testfont, boldflag, italicflag); /* if (bDebug > 1) { sprintf(debugstr, "FullFromFace\t%s\t%s\tlength %d\n", testfont, szFullName, lenstr); OutputDebugString(debugstr); } */ if (lenstr > 0) { // if we do have a FullName /* if (bDebug > 1) OutputDebugString(szFullName); */ /* try in [TTFonts] of win.ini first (as set up by SETUPTTF) */ strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("TTFonts", szFullName, "", str, sizeof(str)); if (lenstr > 0) { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 2); OutputDebugString(debugstr); } return lenstr; } /* try in [Fonts] of win.ini (as set up by SETUPTTF) */ // if (bTTFontSection) lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (lenstr > 0) { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 3); OutputDebugString(debugstr); } return lenstr; } if (bUseRegistryFile) { /* use ttfonts.reg --- 1995/Aug/18 */ if (szRegistryFonts == NULL) { // modified 2000 June 2 ConstructFontKey(str); szRegistryFonts = zstrdup(str); } /* First try " (TrueType)"=".ttf" style */ strcpy (szTrueType, "\""); strcat (szTrueType, szFullName); strcat (szTrueType, " (TrueType)"); strcat (szTrueType, "\""); lenstr = GetPrivateProfileString(szRegistryFonts, szTrueType, "", str, sizeof(str), szRegistry); if (lenstr > 0) { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 4); OutputDebugString(debugstr); } return lenstr; } /* Try also without the quotedbl, just in case user modified the file */ if (lenstr == 0) { strcpy (szTrueType, szFullName); strcat (szTrueType, " (TrueType)"); lenstr = GetPrivateProfileString(szRegistryFonts, szTrueType, "", str, sizeof(str), szRegistry); } /* The quotedbl's in the `value' are removed by GetPrivateProfileString */ if (lenstr > 0) { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 5); OutputDebugString(debugstr); } return lenstr; } } /* moved higher up to come before SetupTT */ /* else { strcat (szFullName, " (TrueType)"); lenstr = GetProfileString("TTFonts", szFullName, "", str, sizeof(str)); if (lenstr == 0 && bTTFontSection) lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (lenstr > 0) return lenstr; } */ } // end of we have a FUllName ... /* if (lenstr == 0) { if (bDebug > 1) { FormatNameStyle (debugstr, testfont, boldflag, italicflag); strcat(debugstr, " apparently not TT\n"); OutputDebugString(debugstr); } } */ if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 6); OutputDebugString(debugstr); } return lenstr; } /* we get to this old heuristic approach *ONLY* if bTTUsable is false */ /* `Demibold' instead of `Bold' */ /* `Oblique' instead of `Italic' */ /* `Regular' */ /* Medium ? */ /* following is a kludge to try all combinations */ /* flush eventually */ /* if (bDebug > 1) OutputDebugString("Heuristic Font Name Hack\n"); */ if (boldflag == 0 && italicflag == 0) { /* `regular' font */ strcpy(szFullName, testfont); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (*str != '\0') { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 6); OutputDebugString(debugstr); } return lenstr; } strcpy(szFullName, testfont); strcat(szFullName, " Regular"); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (*str != '\0') { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 7); OutputDebugString(debugstr); } return lenstr; } strcpy(szFullName, testfont); strcat(szFullName, " Medium"); /* 1995/Feb/4 */ strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (*str != '\0') { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 8); OutputDebugString(debugstr); } return lenstr; } /* kludge for Lucida Calligraphy Italic and Lucida Handwriting Italic */ strcpy(szFullName, testfont); strcat(szFullName, " Italic"); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 9); OutputDebugString(debugstr); } /* return lenstr; */ return -lenstr; /* indicate its fake */ } else { /* either bold or italic or both */ strcpy(szFullName, testfont); if (bCheckBoldFlag != 0) strcat(szFullName, " Bold"); if (bCheckItalicFlag != 0) strcat(szFullName, " Italic"); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (*str != '\0') { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 10); OutputDebugString(debugstr); } return lenstr; } strcpy(szFullName, testfont); if (bCheckBoldFlag != 0) strcat(szFullName, " Demibold"); if (bCheckItalicFlag != 0) strcat(szFullName, " Italic"); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (*str != '\0') { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 11); OutputDebugString(debugstr); } return lenstr; } strcpy(szFullName, testfont); if (bCheckBoldFlag != 0) strcat(szFullName, " Bold"); if (bCheckItalicFlag != 0) strcat(szFullName, " Oblique"); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (*str != '\0') { if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 12); OutputDebugString(debugstr); } return lenstr; } strcpy(szFullName, testfont); if (bCheckBoldFlag != 0) strcat(szFullName, " Demibold"); if (bCheckItalicFlag != 0) strcat(szFullName, " Oblique"); strcat(szFullName, " (TrueType)"); lenstr = GetProfileString("Fonts", szFullName, "", str, sizeof(str)); if (bDebug > 1) { sprintf(debugstr, "TryForTrue: `%s' (%d)", str, 13); OutputDebugString(debugstr); } return lenstr; } } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* see whether font really exists in specified form or synthesized */ /* uses Windows 3.0 functions */ /* check only TrueType if ttfflag == 1 */ /* check only Type 1 if ttfflag == 0 */ /* check both if ttfflag < 0 */ /* returns -1 if font name is an alias */ /* returns 0 if not synthetic */ /* returns 1 if synthetic */ /* int IsSynthetic(char *name, int bBoldFlag, int bItalicFlag) */ /* int IsSynthetic(char *name, int bBoldFlag, int bItalicFlag, int ttfflag) { */ /* ttfflag > 0 => try TT font only */ /* ttfflag == 0 => try T1 font only */ /* ttfflag < 0 => try T1 font and then TT */ /* ever used ? */ BOOL IsSynthetic (HDC hDC, char *name, int bBoldFlag, int bItalicFlag, int ttfflag) { int lenstr; char fontspec[LF_FACESIZE + MAXMSEXTRA]; int bFromOutline=0; /* 96/July/21 */ /* BOOL bFromOutline=0; */ /* if (bDebug > 1) { sprintf(debugstr, "ISSYNTHETIC: %s Bold %d Italic %d TTF %d\n", name, bBoldFlag, bItalicFlag, ttfflag); OutputDebugString(debugstr); } */ /* debugging 95/Mar/15 */ /* First try for Type 1 font installed in ATM */ if (ttfflag == 0 || ttfflag < 0) { if (bATMLoaded) { if (MyATMFontAvailable (name, bBoldFlag ? 700 : 400, /* (BYTE) bItalicFlag, 0, 0, &bFromOutline)) */ (BYTE) (bItalicFlag != 0), 0, 0, &bFromOutline)) { #ifdef DEBUGATM if (bDebug > 1) { char *s; s = FormatNameStyle (debugstr, name, bBoldFlag, bItalicFlag); sprintf(s, "From Outline: %d\n", bFromOutline); OutputDebugString(debugstr); } #endif if (bFromOutline == 0) return 1; /* synthesized */ /* else return 0; */ /* from outline */ } else { /* end of MyATMFontAvailable */ /* if (ttfflag == 0) goto tryttnow; *//* If ttfflag < 0, need try TT also ? */ return -1; /* ATM cannot render this font */ /* This usually means its an alias Helv, Modern, Roman, Tms Rmn */ } return 0; /* its presumably OK */ } /* end of ATM Loaded */ else { /* Type 1 font, but ATM not loaded */ strcpy(fontspec, name); if (bBoldFlag != 0 || bItalicFlag != 0) { strcat(fontspec, ","); if (bBoldFlag != 0) strcat(fontspec, "BOLD"); if (bItalicFlag != 0) strcat(fontspec, "ITALIC"); } /* winerror(fontspec); */ /* NOTE: fontname NOT case dependent */ /* problem because of comma */ if (bWinNT) lenstr = 0; /* no atm.ini in NT 97/Jan/25 */ else lenstr = GetPrivateProfileString("Fonts", fontspec, "", str, sizeof(str), "atm.ini"); /* winerror(str); */ /* if (lenstr > 0 && *str != '\0') return 0; */ if (lenstr > 0) return 0; /* found */ /* NOTE: there is no ATM.INI in Windows NT ! 97/Jan/21 */ if (bWinNT && bNewShell) return 0; /* until ATM exist ???? */ /* 97/Jan/21 */ /* if (bBoldFlag == 0 && bItalicFlag == 0) return 0; */ } return 1; /* not found, so must be synthetic */ } /* end of dealing with Type 1 font */ /* if (bBoldFlag == 0 && bItalicFlag == 0) return 0; */ /* Not ATM font, now try for TrueType font */ if (ttfflag == 1 || ttfflag < 0) { /* lenstr = TryForTrue(name, bBoldFlag, bItalicFlag); */ /* 1992/Sep/17 */ lenstr = TryForTrue(hDC, name, bBoldFlag, bItalicFlag); /* if (lenstr < 0) return 1; */ /* it is synthetic */ if (lenstr <= 0) return 1; /* it is synthetic */ /* strcpy(fontspec, name); if (bBoldFlag != 0 || bItalicFlag != 0) { if (bBoldFlag != 0) strcat(fontspec, " Bold"); if (bItalicFlag != 0) strcat(fontspec, " Italic"); } strcat(fontspec, " (TrueType)"); lenstr = GetProfileString("Fonts", fontspec, "", sizeof(str)); */ /* if (bDebug > 1) OutputDebugString(str); */ /* if (lenstr > 0 && *str != '\0') return 0; */ if (lenstr > 0) return 0; } /* end of dealing with TrueType font */ return 1; /* Apparently Synthesized */ } /* NOTE: fontname NOT case dependent ... */ /* problem because of comma */ /* if ATM font, can do this better see ATMFontAvailable below */ /* extern BOOL FAR PASCAL ATMFontAvailable ( LPSTR lpFacename, int nWeight, BYTE cItalic, BYTE cUnderline, BYTE cStrikeOut, BOOL FAR *lpFromOutline); */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* adjust size according to zoom */ unsigned int setsize (unsigned int fontsize, int zoom) { unsigned long size = fontsize; int k = zoom; if (k > 0) { while(k-- > 0) { if (bSmallStep == 0) /* 94/Apr/19 */ size = (((size * 11 + 5) / 10) * 11 + 5) / 10; else size = (((size * 21 + 10) / 20) * 21 + 10) / 20; } } else if (k < 0) { while(k++ < 0) { if (bSmallStep == 0) /* 94/Apr/19 */ size = (((size * 10 + 5) / 11) * 10 + 5) / 11; else size = (((size * 20 + 10) / 21) * 20 + 10) / 21; } } // sprintf(debugstr, "fontsize %d setsize %d zoom %d TestSize %d", // fontsize, size, zoom, TestSize); // wincancel(debugstr); // debugging only return (unsigned int) size; } void showcharset (char *buff, int charset) { char temp[12]; strcat (buff, " CharSet: "); switch (charset) { case ANSI_CHARSET: strcat(buff, "ANSI"); break; case DEFAULT_CHARSET: /* 1993/June/3 */ strcat(buff, "Default"); break; case SYMBOL_CHARSET: strcat(buff, "Symbol"); break; case SHIFTJIS_CHARSET: strcat(buff, "Kanji"); /* shiftjis */ break; case HANGEUL_CHARSET: /* 1993/June/3 */ strcat(buff, "Hanguel"); break; case CHINESEBIG5_CHARSET: /* 1993/June/3 */ strcat(buff, "Chinese"); break; case OEM_CHARSET: strcat(buff, "OEM"); break; default: /* strcat(buff, "Unknown"); */ sprintf(temp, "%d", charset); strcat(buff, temp); /* winerror("Unknown CharSet"); */ /* CharSet */ break; } } void showfamily (char *buff, int family) { char temp[12]; strcat(buff, ", Family: "); switch((family & 0xF0)) { case FF_DONTCARE: /* Don't care or don't know. */ strcat(buff, "DontCare"); /* (DontKnow)"); */ break; case FF_ROMAN: /* Variable stroke width, serif. */ strcat(buff, "Roman"); /* (variable width, serif)"); */ break; case FF_SWISS: /* Variable stroke width, sans-serifed. */ strcat(buff, "Swiss"); /* (variable width, sans-serif)"); */ break; case FF_MODERN: /* Constant stroke width, serifed or not. */ strcat(buff, "Modern"); /* (constant width)"); */ break; case FF_SCRIPT: /* Cursive, etc. */ strcat(buff, "Script"); /* (cursive)"); */ break; case FF_DECORATIVE: /* Old English, etc. */ strcat(buff, "Decorative"); /* (symbol)"); */ break; default: /* strcat(buff, "Unknown"); */ sprintf(temp, "%d", family); strcat(buff, temp); /* winerror("Unknown Family"); */ /* Family */ break; } } /* Used for setting up window title bar in ShowFont */ void ShowFontInfo (char *buff, int nChar) { /* HDC hDC, int size */ unsigned int size; int intsize, fracsize; char *s; /* if (bShowWidths != 0) size = METRICSIZE * 20; */ if (bShowWidths) size = metricsize * 20; else size = setsize(TestSize, wantedzoom); /* size = (size + 1) / 2; */ /* convert from TWIPS to 1/10 pt */ size = size * 5; /* convert from TWIPS to 1/100 pt ? */ /* intsize = (int) (size / 10); */ intsize = (int) (size / 100); /* fracsize = (int) (size - ((unsigned) intsize) * 10); */ fracsize = (int) (size - ((unsigned) intsize) * 100); if (fracsize == 0) sprintf(buff, "%s (%d pt) ", TestFont, intsize); /* else sprintf(buff, "%s (%d.%d pt) ", TestFont, intsize, fracsize); */ else sprintf(buff, "%s (%d.%02d pt) ", TestFont, intsize, fracsize); if (bTexFontFlag != 0) strcat(buff, "(map) "); if (bCheckBoldFlag > 0) strcat(buff, "Bold"); else if (bCheckBoldFlag < 0) strcat(buff, "Light"); if (bCheckItalicFlag != 0) strcat(buff, "Italic"); strcat(buff, " "); if (bSyntheticFlag) strcat(buff, "*SYNTHESIZED* "); /* 95/Mar/12 */ else { showcharset(buff, testcharset); /* 1993/June/3 */ showfamily(buff, testpitchandfamily); /* 1993/June/3 */ } // maybe add whether it is TrueType or not (if known) ? if (bCharacterSample && nChar >= 0) { s = buff + strlen(buff); sprintf(s, " (%d)", nChar); } /* if (bSyntheticFlag != 0) strcat(buff, " SYN"); */ /* if (bDebug > 1) if (bSyntheticFlag != 0) OutputDebugString(buff); */ /* (void) TextOut(hDC, 40, -40, buff, strlen(buff)); */ /* (void) SetMapMode(hDC, oldmapmode); */ } /* Draw character `bounding box' and baseline */ void DrawMarks (HDC hDC, long dvi_h, long dvi_v, long width, long avascent, long avdescent) { // long avinternal, long avexternal /* HPEN hOldPen; */ int xll, yll, xur, yur, ymd; // int yin, yex; /* not accessed ? */ POINT Box[7]; /* 1993/Jan/21 */ /* hOldPen = SelectObject(hDC, hBorderPen); */ xll = mapx(dvi_h); xur = mapx(dvi_h + width); yll = mapy(dvi_v + avdescent); yur = mapy(dvi_v - avascent); ymd = mapy(dvi_v); // yin = mapy(dvi_v - avascent + avinternal); // yex = mapy(dvi_v - avascent - avexternal); Box[0].x = xll; Box[0].y = ymd; Box[1].x = xll; Box[1].y = yur; Box[2].x = xur; Box[2].y = yur; Box[3].x = xur; Box[3].y = yll; Box[4].x = xll; Box[4].y = yll; Box[5].x = xll; Box[5].y = ymd; Box[6].x = xur; Box[6].y = ymd; Polyline(hDC, Box, 7); /* MUCH FASTER! 1993/Jan/21 */ } /* if ((UINT) hOldPen > 1) (void) SelectObject(hDC, hOldPen); */ /* check visibility to avoid wasting time */ /* don't use if bCopyFlag != 0 */ int CharBoxVisible (HDC hDC, long dvi_h, long dvi_v, long width, long avascent, long avdescent) { RECT TextRect; int xll, yll, xur, yur; BOOL visible; if (bCopyFlag != 0) return 1; xll = mapx(dvi_h); xur = mapx(dvi_h + width); /* if (xur == xll) xur += 20; */ yll = mapy(dvi_v + avdescent); yur = mapy(dvi_v - avascent); /* if (bDebug > 1) { sprintf(debugstr, "%d %d %d %d\n", xll, yll, xur, yur); OutputDebugString(debugstr); } */ /* Deal Windows 95 bug with very narrow boxes in RectVisible */ /* --- somewhat kludgy fix ... 1995/Aug/26 */ /* if (bWin95) */ if (bFixZeroWidth) { /* limit minimum width of rectangle */ /* if ((xur - xll) < (yur - yll)) xur = xll + (yur - yll); */ if ((xur - xll) < MinWidth) xur = xll + MinWidth; /* 95/Sep/3 */ } TextRect.left = xll; TextRect.right = xur; TextRect.bottom = yll; TextRect.top = yur; /* return RectVisible(hDC, &TextRect); */ /* we assume this doesn't get called when CopyFlag is on ... */ visible = RectVisible(hDC, &TextRect); /* if ((bCopyFlag == 0 && RectVisible(hdc, &TextRect) != 0) || (bCopyFlag != 0 && InterSectRect(&CopyClipRect, &TextRect) != 0)) visible = 1; else visible = 0; */ /* alternative - if we decide allowing CopyFlag */ return visible; } /* set for screen font - but also used for printer */ /* set for screen font - but kept around for MetaFileDC also */ /* font metric information (in DVI units) for actual font (not metric) */ long charw, charh, chara, chard, chari, chare; /* compute metrics for actual font from those for metric font */ long compsize (long x, int matsize) { /* adjust relative to METRICSIZE */ /* return ((x * (long) matsize) / METRICSIZE); */ /* return ((x * (long) matsize) / metricsize); */ return ((x * (long) matsize + metricsize/2) / metricsize); } /* should use real default char instead - just in case ? */ #ifdef USEUNICODE #define notdefUID 0xFFFF WCHAR encodeUID[]; /* table of mappings char code => UID */ #endif /* draw rectangular array of characters */ /* flag 1 bit => draw boxes flag 2 bit => draw character */ void ScanLayOut (HDC hDC, int matsize, int flag) { int i, j, k, kk; char buff[1]; long dvi_h, dvi_v, chrwdt; for (i = 0; i < 16; i++) { k = i << 4; /* i * 16 new */ for (j = 0; j < 16; j++) { /* k = i * 16 + j; */ /* if (bTexFontFlag != 0 && bATMBugFlag != 0) */ /* if (bTexFontFlag != 0) { */ /* 1993/Jan/24 */ if (bTexFontFlag && (k <=32 || k == 127)){/* 1995/Jun/23 */ kk = remaptable[k]; /* kk = (unsigned char) remaptable[k]; */ } else kk = k; /* buff[0] = (unsigned char) kk; */ buff[0] = (char) kk; dvi_h = oneinch + charw * j + (charw * j) / 5; dvi_v = oneinch + chara + charh * i + (charh * i) / 5; /* chrwdt = (long) charwidths[k]; */ chrwdt = (long) charwidths[kk]; /* new remapped */ chrwdt = (chrwdt * (long) matsize + 499) / 1000; // metricsize ? chrwdt = unmap((int) chrwdt); /* DVI units for metric */ /* if (bDebug && (k % 16) == 0) { sprintf(str, "%d %d %ld %ld", kk, charwidths[kk], compsize(chrwdt, matsize), chrwdt); winerror(str); } */ /* if (bCopyFlag != 0 || CharBoxVisible(hDC, dvi_h, dvi_v, */ if (CharBoxVisible(hDC, dvi_h, dvi_v, chrwdt, chara, chard)) { if (bShowBoxes && (flag & 1)) /* second pass */ DrawMarks(hDC, dvi_h, dvi_v, chrwdt, chara, chard); // chari, chare); if (flag & 2) { /* first pass */ #ifdef USEUNICODE /* Will trigger only for text fonts in NT or for TT in 95 with UseNewEncode */ /* if (bUseNewEncode && bFontEncoded) */ if (bFontEncoded) { WCHAR buffW[1]; buffW[0] = encodeUID[kk]; (void) TextOutW(hDC, mapx(dvi_h), mapy(dvi_v), buffW, 1); } else (void) TextOutA(hDC, mapx(dvi_h), mapy(dvi_v), buff, 1); #else (void) TextOut(hDC, mapx(dvi_h), mapy(dvi_v), buff, 1); #endif } } /* else { if (bDebug > 1) { sprintf(debugstr, "i %d j %d width %ld\n", i, j, chrwdt); OutputDebugString(debugstr); } } */ k++; /* new */ } /* show a row of table */ } /* show 16 rows of table */ } int DrawOutlineW(HWND, HDC, UINT); /* defined later */ /* show sample of font --- size is TestSize in TWIPS */ /* NOTE: this is called inside WM_PAINT */ /* We DO the remapping in this case for TeX fonts */ // if charcode >= 0 it is the character code in the current encoding // if charcode < 0 then show the whole array of characters void ShowFontSample (HWND hWnd, HDC hDC, int nChar) { HFONT hFont, hMetricFont, hFontOld=NULL; /* unsigned buff[1]; */ /* char buff[1]; */ /* int i, j, k, kk; */ int flag; int charwidth, charheight, charascent, chardescent; int charinternal, charexternal; long atsize; unsigned long old_dvi_num, old_dvi_den, old_dvi_mag; int old_wantedzoom; /* remembered view scale */ int matsize; HPEN hOldPen=NULL; WORD options; /* reset scale and map - do we always want to do this ? */ old_dvi_num = dvi_num; old_dvi_den = dvi_den; old_dvi_mag = dvi_mag; old_wantedzoom = wantedzoom; dvi_num = 25400000; dvi_den = 473628672; dvi_mag = 1000; setscale(wantedzoom); // ? /* bTexFontFlag = istexfont(TestFont); *//* overridden later ??? */ bTexFontFlag = 0; /* 1993/Jan/24 */ if (istexfont(TestFont) && bATMBugFlag) bTexFontFlag = 1; if (testwantttf && bTTRemap) bTexFontFlag = 1; /* 1993/Jan/24 */ /* if (bATMBugFlag > 1) bTexFontFlag = 1; */ /* 1993/March/15 */ if (bATMBugFlag == 2) bTexFontFlag = 1; /* 1993/July/6 */ /* if (bCopyFlag == 0) (void) SetMapMode(hDC, MM_TWIPS); */ /* set unit to twips */ /* Is this assuming standard dvi_num and dvi_den ??? */ /* atsize = (TestSize * 65536) / 20; */ atsize = (((long) TestSize) * 16384) / 5; /* mapped to DVI */ if (nChar < 0) matsize = mapd(atsize); /* mapped to TWIPS */ // else matsize = metricsize * 20; /* 1997/Jan/17 */ // else matsize = mapd(atsize); /* experiment */ // else matsize = mapd(atsize * 16); /* experiment */ // else matsize = mapd(((long) metricsize * 16384) / 5); /* experiment */ // else matsize = ((long) metricsize * 16384) / 5; /* experiment */ // else matsize = metricsize * 16; /* experiment */ else matsize = metricsize; /* experiment */ // if (TestSize != 10) matsize = matsize * TestSize / 10; // ??? // sprintf(debugstr, "TestSize %d matsize %ld", TestSize, matsize); // wincancel(debugstr); // debugging only /* if (matsize != (int) TestSize) { sprintf(str, "TestSize %d matsize %d", TestSize, matsize); winerror(str); } */ /* shouldn't matsize = TestSize now ??? */ hFont = createatmfont(TestFont, matsize, 0, bCheckBoldFlag, bCheckItalicFlag, testwantttf); if (hFont == NULL) { sprintf(debugstr, "Can't find font %s", TestFont); winerror(debugstr); } else { /* hMetricFont = createatmfont(TestFont, METRICSIZE, 0, */ hMetricFont = createatmfont(TestFont, metricsize, 0, bCheckBoldFlag, bCheckItalicFlag, testwantttf); if (hMetricFont == NULL) winerror("Can't create metric font"); else { /* SetupWindowText(hWnd); */ /* don't know about remap yet */ (void) SetBkMode(hDC, TRANSPARENT); /* background untouched */ (void) SetTextAlign(hDC, TA_BASELINE | TA_LEFT); /* ??? */ /* possibly use black pen on printer instead ??? */ hOldPen = SelectObject(hDC, hBorderPen); /* hFontOld = SelectObject(hDC, hFont); */ if (bATMReencoded) UnencodeFont(hDC, -1, 1); #ifdef DEBUGCOPY if (bDebug > 1) OutputDebugString("ATMSelectObject\n"); #endif /* if (!testwantttf && bATMPrefer && bATMLoaded) */ if (! testwantttf && bATMPrefer && bATMLoaded && ! bCopyFlag) { /* This is where we get an error if we are working in MetaFile DC ... */ if (bATMExactWidth) options = ATM_SELECT | ATM_USEEXACTWIDTH; else options = ATM_SELECT; (void) MyATMSelectObject (hDC, hMetricFont, options, &hFontOld); } else hFontOld = SelectObject(hDC, hMetricFont); /* select metric */ #ifdef USEUNICODE /* if (bUseNewEncode) bFontEncoded = bCheckReencode; */ /* new method only in Windows NT or for TT in 95 with UseNewEncode */ /* in Windows 95 ATM will be loaded and hence hEncoding != NULL */ if ((testwantttf && bUseNewEncodeTT) || (! testwantttf && bUseNewEncodeT1)) { bFontEncoded = bCheckReencode; } else bFontEncoded = 0; /* else */ /* 97/Jan/25 */ /* hEncoding will be NULL in Windows NT */ if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 1); /* 94/Dec/25 */ #else if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 1); /* 94/Dec/25 */ #endif /* will need to compensate for (matsize / 1000) scale factor */ /* if (bCopyFlag == 0) */ /* Try and deal with printer crock */ /* if (bCopyFlag == 0 && bPrintFlag == 0) */ if (! bCopyFlag && ! bPrintFlag && nChar < 0) { /* if((flag = GetCharWidth(hDC, 0, 255, charwidths)) == 0) */ flag = GetTextMetrics(hDC, &TextMetric); if (flag == 0) winerror("GetTextMetrics failed"); /* debug */ /* flag = GetWidth(hDC, 0, 255, charwidths); */ flag = GetWidth(hDC, 0, 255, charwidths); if (flag == 0) winerror("Can't get character widths"); /* new way to attempt to determine whether remapped or not */ /* this comes *after* getting widths ? */ bTexFontFlag = 0; /* default is to use unremapped */ if (isremapped(charwidths, TextMetric, bTexFontFlag) != 0 && bATMBugFlag) /* 1993/Jan/24 */ bTexFontFlag = 1; /* else bTeXFontFlag = 0; */ if (testwantttf && bTTRemap) bTexFontFlag = 1; /* if (bATMBugFlag > 1) bTexFontFlag = 1; *//* 1993/March/15 */ if (bATMBugFlag == 2) bTexFontFlag = 1; /* 1993/March/15 */ /* if (bTexFontFlag != 0) { sprintf(debugstr, "Ave %d Max %d First %d Last %d\n", TextMetric.tmAveCharWidth, TextMetric.tmMaxCharWidth, TextMetric.tmFirstChar, TextMetric.tmLastChar); if (bDebug > 1) OutputDebugString(debugstr); } */ charheight = TextMetric.tmHeight + TextMetric.tmExternalLeading; charwidth = TextMetric.tmMaxCharWidth; charascent = TextMetric.tmAscent; chardescent = TextMetric.tmDescent; charinternal = TextMetric.tmInternalLeading; charexternal = TextMetric.tmExternalLeading; if (bDebug > 1) { sprintf(debugstr, "Height %d ExtLead %d Max %d Asc %d Des %d", TextMetric.tmHeight, TextMetric.tmExternalLeading, charwidth, charascent, chardescent); OutputDebugString(debugstr); } /* since we use MaxWidth for cell spacing horizontally */ /* let us tweak it in extreme cases */ if (charwidth > 1000) charwidth = (charwidth + 1000) / 2; if (charwidth < 500) charwidth = (charwidth + 500) / 2; /* adjust for difference in size (matsize / METRICSIZE) */ /* compute for actual font based on metric font */ charwidth = (int) compsize((long) charwidth, matsize); charheight = (int) compsize((long) charheight, matsize); charascent = (int) compsize((long) charascent, matsize); chardescent = (int) compsize((long) chardescent, matsize); charinternal = (int) compsize((long) charinternal, matsize); charexternal = (int) compsize((long) charexternal, matsize); /* turn into DVI units */ /* use saved values if printing (?) */ if (! bPrintFlag) { charw = unmap(charwidth); charh = unmap(charheight); chara = unmap(charascent); chard = unmap(chardescent); chari = unmap(charinternal); chare = unmap(charexternal); } /* if (! bPrintFlag) { schara = chara; scharh = charh; scharw = charw; schard = chard; schari = chari; schare = chare; } */ } SetupWindowText(hWnd); /* now know about remapping or not */ if (bATMReencoded) UnencodeFont(hDC, -1, 1); if (! bCopyFlag) (void) SetMapMode(hDC, MM_TWIPS); /* here ? */ #ifdef DEBUGCOPY if (bDebug > 1) OutputDebugString("ATMSelectObject\n"); #endif /* if (! testwantttf && bATMPrefer && bATMLoaded) */ if (! testwantttf && bATMPrefer && bATMLoaded && ! bCopyFlag) { /* This is where we get an error if we are working in MetaFile DC ... */ if (bATMExactWidth) options = ATM_SELECT | ATM_USEEXACTWIDTH; else options = ATM_SELECT; (void) MyATMSelectObject (hDC, hFont, options, NULL); } else (void) SelectObject(hDC, hFont); /* switch to selected size */ #ifdef USEUNICODE /* if (bUseNewEncode) bFontEncoded = bCheckReencode; */ /* new method only in Windows NT or for TT in 95 with UseNewEncode */ /* in Windows 95 ATM will be loaded and hence hEncoding != NULL */ if ((testwantttf && bUseNewEncodeTT) || (! testwantttf && bUseNewEncodeT1)) bFontEncoded = bCheckReencode; else bFontEncoded = 0; /* else */ /* 97/Jan/25 */ /* hEncoding will be NULL in Windows NT */ if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 0); /* 94/Dec/25 */ #else if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 0); /* 94/Dec/25 */ #endif /* nChar = -1 for normal drawing character layout */ if (nChar < 0) { if (bShowBoxes) ScanLayOut(hDC, matsize, 1); /* bounding boxes */ ScanLayOut(hDC, matsize, 2); /* characters */ /* ScanLayOut(hDC, matsize, 3); */ /* do both at once */ } /* nChar flag is character code for drawing character */ else { int UID; // fixed 2000 May 27 if (bFontEncoded) UID = encodeUID[nChar]; else UID = nChar; DrawOutlineW(hWnd, hDC, UID); } if ((UINT) hOldPen > 1) /* moved here 92/April/16 */ (void) SelectObject(hDC, hOldPen); } /* end of was able to establish metric font */ if (bATMReencoded) UnencodeFont(hDC, -1, 0); /* moved up here ? */ if ((UINT) hFontOld > 1) /* avoid Windows 3.0 MetaFile problem */ (void) SelectObject(hDC, hFontOld); /* deselect hFont */ if ((UINT) hFont > 1) (void) DeleteObject(hFont); /* free up space */ if ((UINT) hMetricFont > 1) (void) DeleteObject(hMetricFont); /* free up space */ } /* end of font exists case */ dvi_num = old_dvi_num; dvi_den = old_dvi_den; dvi_mag = old_dvi_mag; wantedzoom = old_wantedzoom; setscale(wantedzoom); /* restore zoom */ /* if (bATMReencoded) UnencodeFont(hDC, -1, 0); */ /* too late here */ } /* bug in ATM when character code is zero ... */ unsigned int UseSize = 10 * 20; /* size on screen for char width display TWIPS */ /* use SetTextAlign(hDC, TA_RIGHT) for numbers ? */ /* the spacing here should be calculated using GetSystemMetrics */ /* instead of being wired in ... */ /* We DON'T do the remapping in this case */ void ShowCharWidths (HWND hWnd, HDC hDC) { HFONT hFont, hFontOld=NULL; HFONT hMetricFont, hUseFont; /* HFONT hFixedFont; */ unsigned int size; int i, j, k, flag; int charwidth, charheight, charascent, chardescent; long dvi_h, dvi_v; /* long chrwdt; */ WORD options; char txt[16]; /* avoid using str - 95/Jun/24 */ /* (void) SetMapMode(hDC, MM_TWIPS); */ /* set unit to twips */ /* NU */ size = setsize(UseSize, wantedzoom); /* matsize = mapd(size); */ /* mapped to TWIPS */ /* hUseFont = createatmfont("Courier", (int) size, 0, 0, 0); */ /* display */ hUseFont = createatmfont("Helvetica", (int) size, 0, 0, 0, 0); if (hUseFont == NULL) winerror("Can't find Helvetica"); /* debug */ /* hMetricFont = createatmfont("Helvetica", METRICSIZE, 0, 0, 0, 0); */ hMetricFont = createatmfont("Helvetica", metricsize, 0, 0, 0, 0); if (hMetricFont == NULL) winerror("Can't create metric font"); /* debug */ /* hFont = createatmfont(TestFont, METRICSIZE, 0, */ hFont = createatmfont(TestFont, metricsize, 0, bCheckBoldFlag, bCheckItalicFlag, testwantttf); if (hFont == NULL) winerror("Can't create test font"); else { if (bATMReencoded) UnencodeFont(hDC, -1, 1); if (! testwantttf && bATMPrefer && bATMLoaded) { if (bATMExactWidth) options = ATM_SELECT | ATM_USEEXACTWIDTH; else options = ATM_SELECT; (void) MyATMSelectObject (hDC, hFont, options, &hFontOld); } else hFontOld = SelectObject(hDC, hFont); /* select test font */ #ifdef USEUNICODE /* if (bUseNewEncode) bFontEncoded = bCheckReencode; */ /* new method only in Windows NT or for TT in 95 with UseNewEncode */ /* in Windows 95 ATM will be loaded and hence hEncoding != NULL */ if ((testwantttf && bUseNewEncodeTT) || (! testwantttf && bUseNewEncodeT1)) bFontEncoded = bCheckReencode; else bFontEncoded = 0; /* else */ /* 97/Jan/25 */ /* hEncoding will be NULL in Windows NT */ if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 0); /* 94/Dec/25 */ #else if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 0); /* 94/Dec/25 */ #endif /* if (bCopyFlag == 0) */ /* Try and deal with printer crock */ if (bCopyFlag == 0 && bPrintFlag == 0) { /* flag = GetCharWidth(hDC, 0, 255, charwidths); */ flag = GetWidth(hDC, 0, 255, charwidths); (void) SetMapMode(hDC, MM_TWIPS); /* set unit to twips */ /* NU */ } else flag = 1; if (flag == 0) winerror("Can't get character widths"); else { /* (void) SelectObject(hDC, hUseFont); *//* switch to display font */ if (bATMReencoded) UnencodeFont(hDC, -1, 1); if (! testwantttf && bATMPrefer && bATMLoaded) { if (bATMExactWidth) options = ATM_SELECT | ATM_USEEXACTWIDTH; else options = ATM_SELECT; (void) MyATMSelectObject (hDC, hMetricFont, options, NULL); } else (void) SelectObject(hDC, hMetricFont); /* get metrics */ #ifdef USEUNICODE /* if (bUseNewEncode) bFontEncoded = bCheckReencode; */ /* new method only in Windows NT or for TT in 95 with UseNewEncode */ /* in Windows 95 ATM will be loaded and hence hEncoding != NULL */ if ((testwantttf && bUseNewEncodeTT) || (! testwantttf && bUseNewEncodeT1)) bFontEncoded = bCheckReencode; else bFontEncoded = 0; /* else */ /* 97/Jan/25 */ /* hEncoding will be NULL in Windows NT */ if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 1); /* 94/Dec/25 */ #else if (bCheckReencode && ! testwantttf && hEncoding != NULL) ReencodeFont(hDC, -1, 1); /* 94/Dec/25 */ #endif if (bCopyFlag == 0) { flag = GetTextMetrics(hDC, &TextMetric); if (flag == 0) winerror("GetTextMetrics failed"); /* debug */ charheight = TextMetric.tmHeight + TextMetric.tmExternalLeading; /* charwidth = TextMetric.tmMaxCharWidth; */ charwidth = TextMetric.tmAveCharWidth; charascent = TextMetric.tmAscent; chardescent = TextMetric.tmDescent; /* charinternal = TextMetric.tmInternalLeading; */ /* charexternal = TextMetric.tmExternalLeading; */ /* adjust for difference in size (atsize / METRICSIZE) */ charwidth = (int) compsize((long) charwidth, size); charheight = (int) compsize((long) charheight, size); charascent = (int) compsize((long) charascent, size); chardescent = (int) compsize((long) chardescent, size); /* charinternal = (int) compsize((long) charinternal, size); */ /* charexternal = (int) compsize((long) charexternal, size); */ /* turn into DVI units */ /* use saved values when printing */ if (! bPrintFlag) { charw = unmap(charwidth); charh = unmap(charheight); chara = unmap(charascent); chard = unmap(chardescent); /* chari = unmap(charinternal); */ /* chare = unmap(charexternal); */ } /* if (bPrintFlag == 0) { schara = chara; scharh = charh; scharw = charw; schard = chard; } */ } /* if (! testwantttf && bATMPrefer && bATMLoaded) (void) MyATMForceCreate(); */ /* 94/Dec/22 NOT */ (void) SelectObject(hDC, hUseFont); /* switch to display font */ /* if (! testwantttf && bATMPrefer && bATMLoaded) (void) MyATMClearAllForce(); */ /* 95/Jan/15 NOT */ bTexFontFlag = 0; /* always get REAL widths ? */ SetupWindowText(hWnd); /* calls ShowFontInfo */ (void) SetTextAlign(hDC, TA_RIGHT); /* right justify numbers */ for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { k = i * 16 + j; /* k = remaptable[i * 16 + j]; */ dvi_h = oneinch + charw * (j + 1) * 6; /* 5 */ /* dvi_v = ONEINCH + chara + charh * (i * 15 / 10); */ dvi_v = oneinch + chara + charh * i + (charh * i) / 2; /* sprintf(str, "%5d ", charwidths[k]); */ sprintf(txt, "%5d ", charwidths[k]); /* if (bCopyFlag != 0 || CharBoxVisible(hDC, dvi_h, dvi_v, */ if (CharBoxVisible(hDC, dvi_h, dvi_v, /* 1L, chara, chard)) */ (chara + chard) * 5, chara, chard)) { /* 1993/June/5 */ (void) TextOut(hDC, mapx(dvi_h), mapy(dvi_v), /* str, (int) strlen(str)); */ txt, (int) strlen(txt)); } } /* end of do one row */ } /* end of do 16 rows */ if (bATMReencoded) UnencodeFont(hDC, -1, 0); /* moved here ? */ if ((UINT) hFontOld > 1) /* avoid Windows 3.0 MetaFile problem */ (void) SelectObject(hDC, hFontOld); /* deselect hFont */ if ((UINT) hFont > 1) (void) DeleteObject(hFont); /* test font */ } /* end of can get character widths */ if ((UINT) hUseFont > 1) (void) DeleteObject(hUseFont); /* free up space */ if ((UINT) hMetricFont > 1) (void) DeleteObject(hMetricFont); /* free up space */ } /* end of hFont was created case */ /* if (bATMReencoded) UnencodeFont(hDC, -1, 0); */ /* too late here */ } #define DEBUGVECTOR /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* _lopen defaults to OF_SHARE_COMPAT 0x0000 */ /* returns NULL if can't allocate memory --- or if user cancels */ /* or if can't find encoding vector */ /* This assumes that vectorname does *not* include `.vec' extension */ /* --- but it *may* include path */ /* tries various places for file */ /* Looks for encoding vector in: */ /* Fully qualified path, if given - then look *only* there */ /* In VECPATH directory */ /* In PREPATH directory */ /* In DVIWindo directory */ /* In c:\yandy\fonts\encoding */ /* In c:\dvipsone */ HFILE getencodingfile (char *vectorname) { #ifdef LONGNAMES HFILE vecfile; #else FILE *vecfile; #endif char filename[FILENAME_MAX]; /* use for file name */ char *s, *t; vecfile = BAD_FILE; /* first deal with case where path is specified */ /* 95/Feb/8 */ /* potential problem if path is not fully qualified \dvisourc\foo.vec ... */ if (strpbrk(vectorname, "\\/:") != NULL) { strcpy(filename, vectorname); /* if ((s = strrchr(filename, '.')) != NULL) *s = '\0'; */ /* s = filename + strlen(filename) - 1; */ strcat(filename, ".vec"); #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(filename); #endif vecfile = fopen(filename, "r"); } else { /* normal case, path was not specified */ /* if (szVecPath == NULL) winerror("NULL VecPath"); */ /* if (strcmp(szVecPath, "") != 0) */ /* if VECPATH defined in environment */ if (szVecPath != NULL) { t = szVecPath; /* deal with list of paths 1997/Nov/13 */ while (t != NULL) { strcpy(filename, t); if ((s = strchr(filename, ';')) != NULL) *s = '\0'; s = filename + strlen(filename) - 1; if (*s != '\\' && *s != '/') strcat(filename, "\\"); strcat(filename, vectorname); strcat(filename, ".vec"); #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(filename); #endif vecfile = fopen(filename, "r"); if (vecfile != BAD_FILE) break; if ((t = strchr(t, ';')) != NULL) t++; /* t = strchr(t, ';')+1; */ /* fixed 97/Dec/21 */ } } if (vecfile == BAD_FILE) { /* if (strcmp(PrePath, "") != 0) */ /* if PREPATH defined 95/May/8 */ if (szPrePath != NULL) { t = szPrePath; /* deal with list of paths 1997/Noc/13 */ while (t != NULL) { strcpy(filename, t); if ((s = strchr(filename, ';')) != NULL) *s = '\0'; s = filename + strlen(filename) - 1; if (*s != '\\' && *s != '/') strcat(filename, "\\"); strcat(filename, vectorname); strcat(filename, ".vec"); #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(filename); #endif vecfile = fopen(filename, "r"); if (vecfile != BAD_FILE) break; if ((t = strchr(t, ';')) != NULL) t++; /* t = strchr(t, ';')+1; */ } } } if (vecfile == BAD_FILE) { /* see if in DVIWindo directory */ strcpy(filename, szExeWindo); /* following added 1996/Jan/28 --- paranoia */ /* s = filename + strlen(filename) - 1; */ /* if (*s != '\\' && *s != '/') strcat(filename, "\\"); */ strcat(filename, vectorname); strcat(filename, ".vec"); #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(filename); #endif vecfile = fopen(filename, "r"); } if (vecfile == BAD_FILE) { /* in default vector directory - 96/Aug/29 */ strcpy(filename, "c:\\yandy\\fonts\\encoding\\"); strcat(filename, vectorname); strcat(filename, ".vec"); #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(filename); #endif vecfile = fopen(filename, "r"); } if (vecfile == BAD_FILE) { /* in default DVIPSONE directory - 95/Mar/1 */ // strcpy(filename, "c:\\dvipsone\\"); strcpy(filename, "c:\\yandy\\dvipsone\\"); // not much use... strcat(filename, vectorname); strcat(filename, ".vec"); #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(filename); #endif vecfile = fopen(filename, "r"); } } /* Also try `vec' sub-directory of DVIPSONE directory ??? */ if (vecfile == BAD_FILE) { sprintf(str, "Can't find %s encoding vector", vectorname); if (wincancel (str) != 0) { /* 1993/April/10 */ return BAD_FILE; /* user cancelled ... */ } // (void) WritePrivateProfileString(achPr, "Vector", "", achFile); (void) WritePrivateProfileString(achPr, "Vector", NULL, achFile); return BAD_FILE; /* too dangerous to continue 95/Mar/5 */ } /* We now have an encoding vector file open */ /* record vector file name in case of question about what gives */ (void) WritePrivateProfileString(achDiag, "Vector", filename, achFile); return vecfile; } // LPSTR getencodingsub (LPSTR lpEncoding, char *vectorname) { LPSTR *getencodingsub (LPSTR *lpVector, char *vectorname) { #ifdef LONGNAMES HFILE vecfile; #else FILE *vecfile; #endif char charname[FILENAME_MAX]; /* try and be safe */ int k; // LPSTR lpGlyph; /* bDebug = 2; */ /* DANGER !!! DEBUGGING ONLY */ vecfile = BAD_FILE; if (lpVector == NULL) return NULL; /* sanity check */ if (vectorname == NULL) return NULL; /* sanity check */ #ifdef DEBUGVECTOR if (bDebug > 1) OutputDebugString(vectorname); #endif for (k = 0; k < MAXCHRS; k++) { /* free any strings left over */ if (lpVector[k] != NULL) { free(lpVector[k]); lpVector[k] = NULL; } } if (strcmp(vectorname, "numeric") == 0) { // lpGlyph=lpVector; for (k = 0; k < MAXCHRS; k++) { // wsprintf(lpGlyph, "a%d", k); wsprintf(charname, "a%d", k); lpVector[k] = zstrdup(charname); // lpGlyph += MAXCHARNAME; } return lpVector; } /* special case 95/Jan/2 */ vecfile = getencodingfile(vectorname); if (vecfile == BAD_FILE) { for (k = 0; k < MAXCHRS; k++) { // wsprintf(lpGlyph, "a%d", k); wsprintf(charname, "a%d", k); lpVector[k] = zstrdup(charname); // lpGlyph += MAXCHARNAME; } return lpVector; } // for (k = 0; k < MAXCHRS; k++) { /* construct blank encoding */ // lpVector[k] = NULL; // } while (fgets(str, sizeof(str), vecfile) != NULL) { if (*str == '%' || *str == ';' || *str == '\n') continue; if (sscanf(str, "%d %s", &k, charname) == 2) { if (k >= 0 && k < MAXCHRS) { /* for safety sake ! */ // if (strlen(charname) < MAXCHARNAME) { // (void) strcpy(lpVector + k * MAXCHARNAME, charname); // if (lpVector[k] != NULL) free(lpVector[k]); if (lpVector[k] != NULL) free(lpVector[k]); lpVector[k] = zstrdup(charname); } } // for (k = 0; k < MAXCHRS; k++) { // if (lpVector[k] == NULL) // lpVector[k] = zstrdup(""); // } } fclose(vecfile); /* sprintf(str, "Found %d encodings", n); */ /* winerror(str); */ /* debug */ /* } */ /* (void) GlobalUnlock (hMemEncoding); */ /* return hMemEncoding; */ return lpVector; } /* called from winsearc.c in SetupEncoding */ /* called from winfonts.c in WriteAFMFile */ /* returns allocated array of glyph names MAXCHRS * MAXCHARNAME */ /* which should to be freed again later */ // switched to array of LPSTR pointers to strings 99/Nov/8 // which should to be freed again later HGLOBAL getencoding (char *vectorname) { HGLOBAL hMemEncoding; // LPSTR lpVector; LPSTR *lpVector; // hMemEncoding = // GlobalAlloc(GHND, /* GMEM_MOVEABLE | GMEM_ZEROINIT */ // (unsigned long) MAXCHRS * MAXCHARNAME); hMemEncoding = GlobalAlloc(GHND, (unsigned long) MAXCHRS * sizeof(LPSTR)); // 99/Nov/8 if (hMemEncoding == NULL) { winerror ("Unable to allocate memory"); return NULL; /* 1995/Jan/19 */ /* PostQuitMessage(0); */ /* ??? */ } lpVector = GlobalLock(hMemEncoding); if (lpVector == NULL) { winerror("Unable to allocate memory"); return NULL; } if (getencodingsub(lpVector, vectorname) == NULL) { /* modification to try for ansinew in this case 97/Dec/21 */ /* this means Windows ANSI will be set up if vector not found */ if (getencodingsub(lpVector, "ansinew") == NULL) { /* file not found & user cancelled */ (void) GlobalUnlock(hMemEncoding); /* (void) GlobalFree (hMemEncoding); */ hMemEncoding = GlobalFree(hMemEncoding); return NULL; } } (void) GlobalUnlock (hMemEncoding); return hMemEncoding; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* int (_FAR_ _cdecl *) (const void _FAR_ *, const void _FAR_ *)); */ /* compare used to qsort KERNPAIRs from GETKERNINGPAIR Escape */ int _cdecl compare(const void *kavoid, const void *kbvoid) { /* unsigned int botha, bothb; */ unsigned int aone, atwo, bone, btwo; /* const struct kernpair *ka, *kb; */ /* 1992/Oct/4 */ const KERNPAIR *ka, *kb; /* 1992/Oct/4 */ /* ka = (const struct kernpair *) kavoid; */ /* 1992/Oct/4 */ ka = (const KERNPAIR *) kavoid; /* 1992/Oct/4 */ /* kb = (const struct kernpair *) kbvoid; */ /* 1992/Oct/4 */ kb = (const KERNPAIR *) kbvoid; /* 1992/Oct/4 */ /* botha = ka->kpPair; bothb = kb->kpPair; */ /* aone = LOBYTE(botha); atwo = HIBYTE(botha); */ aone = LOBYTE(ka->kpPair); atwo = HIBYTE(ka->kpPair); /* bone = LOBYTE(bothb); btwo = HIBYTE(bothb); */ bone = LOBYTE(kb->kpPair); btwo = HIBYTE(kb->kpPair); if (aone < bone) return -1; else if (aone > bone) return +1; else if (atwo < btwo) return -1; else if (atwo > btwo) return +1; else return 0; } /* comparez used to qsort KERNINGPAIRs from GetKerningPairs(...) */ int _cdecl comparez(const void *kavoid, const void *kbvoid) { const KERNINGPAIR *ka, *kb; WORD aone, atwo, bone, btwo; ka = (const KERNINGPAIR *) kavoid; kb = (const KERNINGPAIR *) kbvoid; aone = ka->wFirst; atwo = ka->wSecond; bone = kb->wFirst; btwo = kb->wSecond; if (aone < bone) return -1; else if (aone > bone) return +1; else if (atwo < btwo) return -1; else if (atwo > btwo) return +1; else return 0; } /* comparex used to qsort ATMKernPairs from ATMGetInstanceInfo(...) */ int _cdecl comparex(const void *kavoid, const void *kbvoid) { const ATMKernPair *ka, *kb; WORD aone, atwo, bone, btwo; ka = (const ATMKernPair *) kavoid; kb = (const ATMKernPair *) kbvoid; aone = ka->char_1; atwo = ka->char_2; bone = kb->char_1; btwo = kb->char_2; if (aone < bone) return -1; else if (aone > bone) return +1; else if (atwo < btwo) return -1; else if (atwo > btwo) return +1; else return 0; } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ ATMFixed ATMx, ATMy; /* current point */ ATMFixed ATMxll, ATMyll, ATMxur, ATMyur; /* bounding box */ int firsttime=0; void UpDateBBox (LPATMFixedPoint lpFixPnt) { if (firsttime) { ATMxll = ATMxur = lpFixPnt->x; ATMyll = ATMyur = lpFixPnt->y; firsttime = 0; } else { if (lpFixPnt->x > ATMxur) ATMxur = lpFixPnt->x; if (lpFixPnt->x < ATMxll) ATMxll = lpFixPnt->x; if (lpFixPnt->y > ATMyur) ATMyur = lpFixPnt->y; if (lpFixPnt->y < ATMyll) ATMyll = lpFixPnt->y; } } int InBBox (LPATMFixedPoint lpFixPnt) { if (firsttime) return 0; /* sanity check */ if (lpFixPnt->x < ATMxll || lpFixPnt->x > ATMxur) return 0; if (lpFixPnt->y < ATMyll || lpFixPnt->y > ATMyur) return 0; return 1; /* point is in current BBox */ } #ifdef IGNORED ATMFixed ATMmul (ATMFixed a, ATMFixed b) { /* Multiply two ATM Fixed */ long ah, al, bh, bl; ATMFixed result; int sign=+1; if (a <= 0) { a = -a; sign = - sign; } if (b <= 0) { b = -b; sign = - sign; } ah = a >> 16; al = a - (ah << 16); bh = b >> 16; bh = b - (bh << 16); result = (ah * bh) << 16 + (ah * bl + al * bh) + (al * bl) >> 16; if (sign > 0) return result; else return - result; } #endif ATMFixed ATMRound (double x) { int sign = +1; ATMFixed result; if (x < 0) { x = -x; sign = -1; } result = (ATMFixed) (x * 65536.0 + 0.5); if (sign > 0) return result; return - result; } /* The following tries to find extrema in curveto's and use those */ /* Note that the *ends* have already been entered into current BBox */ /* Watch out for the 16.16 representation of coordinates */ /* Screw it --- lets just use floating point ... */ /* 95/June/28 */ int DoCurveto (ATMFixed x0, ATMFixed y0, ATMFixed x1, ATMFixed y1, ATMFixed x2, ATMFixed y2, ATMFixed x3, ATMFixed y3) { double ax, bx, cx, ay, by, cy; double delta, t, xs, ys, xr, yr; ATMFixedPoint ATMExt; /* ATMFixedPoint ATMPnt1, ATMPnt2; */ int flag=0; /* (x0, y0) and (x3, y3) have already been considered in current BBox */ /* quick exit if the other two control points are inside BBox also */ /* ATMPnt1.x = x1; ATMPnt1.y = y1; ATMPnt2.x = x2; ATMPnt2.y = y2; if (InBBox(&ATMPnt1) && InBBox(&ATMPnt2)) return 0; */ xs = (double) x0 / 65536.0; cx = (double) (3 * (x1 - x0)) / 65536.0; bx = (double) (3 * ((x2 - x1) - (x1 - x0))) / 65536.0; ax = (double) ((x3 - x2) - 2.0 * (x2 - x1) + (x1 - x0)) / 65536.0; ys = (double) y0 / 65536.0; cy = (double) (3 * (y1 - y0)) / 65536.0; by = (double) (3 * ((y2 - y1) - (y1 - y0))) / 65536.0; ay = (double) ((y3 - y2) - 2 * (y2 - y1) + (y1 - y0)) / 65536.0; /* Try for extrema in x first */ delta = (2 * bx * 2 * bx - 4 * 3 * ax * cx); if (ax != 0 && delta >= 0) { t = (- 2 * bx + sqrt (delta)) / (2 * 3 * ax); if (t > 0 && t < 1) { xr = (((ax * t + bx) * t + cx)) * t + xs; yr = (((ay * t + by) * t + cy)) * t + ys; ATMExt.x = ATMRound (xr); ATMExt.y = ATMRound (yr); UpDateBBox (&ATMExt); flag++; } t = (- 2 * bx - sqrt (delta)) / (2 * 3 * ax ); if (t > 0 && t < 1) { xr = (((ax * t + bx) * t + cx)) * t + xs; yr = (((ay * t + by) * t + cy)) * t + ys; ATMExt.x = ATMRound (xr); ATMExt.y = ATMRound (yr); UpDateBBox (&ATMExt); flag++; } } /* Try for extrema in y next */ delta = (2 * by * 2 * by - 4 * 3 * ay * cy); if (ay != 0.0 && delta >= 0) { t = (- 2 * by + sqrt (delta)) / (2 * 3 * ay); if (t > 0 && t < 1) { xr = (((ax * t + bx) * t + cx)) * t + xs; yr = (((ay * t + by) * t + cy)) * t + ys; ATMExt.x = ATMRound (xr); ATMExt.y = ATMRound (yr); UpDateBBox (&ATMExt); flag++; } t = (- 2 * by - sqrt (delta)) / (2 * 3 * ay); if (t > 0 && t < 1) { xr = (((ax * t + bx) * t + cx)) * t + xs; yr = (((ay * t + by) * t + cy)) * t + ys; ATMExt.x = ATMRound (xr); ATMExt.y = ATMRound (yr); UpDateBBox (&ATMExt); flag++; } } return flag; } /* In WIN32: change CALLBACK to ATMCALLBACK ? drop _export ? */ /* MyClosePath */ BOOL ATMCALLBACK MyClosePath (DWORD dwUserData) /* BOOL CALLBACK _export MyClosePath (LPSTR lpData) */ { return (TRUE); } /* dwUserData unreferenced */ /* MyMoveTo */ BOOL ATMCALLBACK MyMoveTo (LPATMFixedPoint lpFixPnt, DWORD dwUserData) /* BOOL CALLBACK _export MyMoveTo (LPATMFixedPoint lpFixPnt, LPSTR lpData) */ { UpDateBBox (lpFixPnt); ATMx = lpFixPnt->x; ATMy = lpFixPnt->y; /* current point */ return (TRUE); } /* dwUserData unreferenced */ /* MyLineTo */ BOOL ATMCALLBACK MyLineTo (LPATMFixedPoint lpFixPnt, DWORD dwUserData) /* BOOL CALLBACK _export MyLineTo (LPATMFixedPoint lpFixPnt, LPSTR lpData) */ { UpDateBBox (lpFixPnt); ATMx = lpFixPnt->x; ATMy = lpFixPnt->y; /* current point */ return (TRUE); } /* dwUserData unreferenced */ /* MyCurveTo */ BOOL ATMCALLBACK MyCurveTo (LPATMFixedPoint lpFixPnt1, LPATMFixedPoint lpFixPnt2, LPATMFixedPoint lpFixPnt3, DWORD dwUserData) /* BOOL CALLBACK _export MyCurveTo (LPATMFixedPoint lpFixPnt1, LPATMFixedPoint lpFixPnt2, LPATMFixedPoint lpFixPnt3, LPSTR lpData) */ { /* if (bUseControl) { UpDateBBox (lpFixPnt1); UpDateBBox (lpFixPnt2); } */ UpDateBBox (lpFixPnt3); if (bTraceCurveto) { /* trace all of curveto ? */ /* don't bother if the other two control points are inside BBox also */ if (!InBBox(lpFixPnt1) || !InBBox(lpFixPnt2)) { DoCurveto(ATMx, ATMy, lpFixPnt1->x, lpFixPnt1->y, lpFixPnt2->x, lpFixPnt2->y, lpFixPnt3->x, lpFixPnt3->y); } } ATMx = lpFixPnt3->x; ATMy = lpFixPnt3->y; /* current point */ return (TRUE); } /* dwUserData unreferenced */ /* int GetATMCharBBox (HDC hDC, char gCurChar, int FontSize) */ int GetATMCharBBox (HDC hDC, WORD gCurChar, int FontSize) { ATMFixedMatrix gMatrix; /* char szSecretMessage [] = "sdffkjhsdkfjh"; */ /* a joke, of course ! */ char *szSecretMessage = "sdffkjhsdkfjh"; /* a joke, of course ! */ int res; if (bATMLoaded == 0) return -1; /* error ! --- sanity text */ firsttime = 1; gMatrix.a = ATMINTTOFIXED(FontSize); gMatrix.b = gMatrix.c = 0; gMatrix.d = ATMINTTOFIXED(FontSize); gMatrix.tx = gMatrix.ty = 0; /* Now want MyATMGetOutlineA or MyATMGetOutlineW */ res = MyATMGetOutline (hDC, (char) gCurChar, &gMatrix, /* for now */ MyMoveTo, MyLineTo, MyCurveTo, MyClosePath, (DWORD) (LPSTR) szSecretMessage); /* ??? */ /* res = MyATMGetOutline (hDC, (char) gCurChar, &gMatrix, (FARPROC) MyMoveTo, (FARPROC) MyLineTo, (FARPROC) MyCurveTo, (FARPROC) MyClosePath, (LPSTR) szSecretMessage); */ /* in case there is nothing in the outline - e.g. `space' char */ if (firsttime) ATMxll = ATMyll = ATMxur = ATMyur = 0; #ifdef DEBUGATM if (res != ATM_NOERR) { if (bDebug > 1) { sprintf(debugstr, "ATMGetOutline returns %d for char %d\n", res, gCurChar); OutputDebugString(debugstr); } } #endif return res; /* ATM_NOERR == 0 if success */ } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* from winsearc.c */ /* following separated out 94/Dec/31 */ /* checks whether TextMetrics info agrees with font */ /* winansi is 0 if bCheckReencode non-zero and Encoding not ansinew */ int checkansiencode (int winansi, int charset, int family) { int failed=0; /* char buffer[128]; */ /* First deal with case were PFM metrics say its ANSI encoded */ /* but we try to use a different encoding vector ... */ if (winansi != 0 && szEncodingVector != NULL && (strcmp(szEncodingVector, "ansinew") != 0 && strcmp(szEncodingVector, "ansi") != 0)) { sprintf(debugstr, "Font claims to be ANSI encoded\n("); showcharset(debugstr, charset); /* 1993/Jun/3 */ showfamily(debugstr, family); /* 1993/Jun/3 */ strcat(debugstr, " )"); if (wincancel(debugstr) != 0) failed = 1; /* winerror("Font claims to be ANSI encoded"); */ /* winerror("May want to use `ansi' or `ansinew'"); */ } /* Next we deal with case were PFM metrics say it is *not* ANSI encoded */ /* but we try to use Windows ANSI encoding vector ... */ if (winansi == 0 && szEncodingVector != NULL && (strcmp(szEncodingVector, "ansinew") == 0 || strcmp(szEncodingVector, "ansi") == 0)) { sprintf(debugstr,"Font claims NOT to be ANSI encoded\n("); showcharset(debugstr, charset); /* 1993/Jun/3 */ showfamily(debugstr, family); /* 1993/Jun/3 */ strcat(debugstr, " )"); if (wincancel(debugstr) != 0) failed = 1; /* winerror("Font claims NOT to be ANSI encoded"); */ /* winerror("May want to NOT use `ansi' or `ansinew'"); */ } return failed; } /* Try and guess whether fixed pitch font */ /* separated out 94/Dec/31 */ /* BOOL IsItFixed (ABC abcwidths[], int charwidths[], int bABCFlag) */ BOOL IsItFixed (ABC abcwidths[], short int charwidths[], int bABCFlag) { int k; int charwidth; BOOL bFixedPitch = 1; if (bABCFlag != 0) { charwidth = abcwidths[65].abcA + (int) abcwidths[65].abcB + abcwidths[65].abcC; for (k = 33; k < 126; k++) /* if (charwidth != abcwidths[i].abcA + (int) abcwidths[i].abcB + abcwidths[i].abcC) */ if (charwidth != abcwidths[k].abcA + (int) abcwidths[k].abcB + abcwidths[k].abcC) { bFixedPitch = 0; break; } } else { charwidth = charwidths[65]; for (k = 33; k < 126; k++) /* if (charwidth != charwidths[i]) */ if (charwidth != charwidths[k]) { bFixedPitch = 0; break; } } return bFixedPitch; } /* LF_FACESIZE 32 needed for Face Name */ /* ATM_PSNAMESIZE 64 needed for PostScript FontName */ /* Use in WriteAFM */ /* Won't work in W2K */ /* Could use FullName in W2K - replace space with hyphen */ int GetPSFontName (char *TestFont, BOOL bCheckBoldFlag, BOOL bCheckItalicFlag, char *PSName) { ATMFontSpec FontSpec; /* char szFaceStyle[32+2]; */ int ret; strcpy(FontSpec.faceName, TestFont); /* strcpy(szFaceStyle, TestFont); */ strcpy(PSName, TestFont); /* in case of failure */ /* This assumes ATM_BOLD (2) ATM_ITALIC (1) */ FontSpec.styles = (WORD) (bCheckItalicFlag | (bCheckBoldFlag << 1)); /* szFaceStyle[32] = (char) (bCheckItalicFlag | (bCheckBoldFlag << 1)); szFaceStyle[33] = 0; */ if (bATMLoaded == 0) return 0; /* error! - sanity check */ ret = MyATMGetPostScriptName(BD_VERSION, &FontSpec, PSName); /* ret = MyATMGetPostScriptName(BD_VERSION, szFaceStyle, PSName); */ if (ret != ATM_NOERR) { if (bDebug > 1) { wsprintf(debugstr, "GetPostScriptName returns %d\n", ret); OutputDebugString(debugstr); } /* strcpy(PSName, TestFont); */ } return ret; } int bAFMTextFont; /* set when writing AFM file */ /* Separated out so can be reused */ #ifdef LONGNAMES // int DoATMCharMetrics(HFILE afmfile, HDC hDC, LPSTR lpEncoding, int codeflag) int DoATMCharMetrics (HFILE afmfile, HDC hDC, LPSTR *lpEncoding, int codeflag) #else // int DoATMCharMetrics(FILE *afmfile, HDC hDC, LPSTR lpEncoding, int codeflag) int DoATMCharMetrics (FILE *afmfile, HDC hDC, LPSTR *lpEncoding, int codeflag) #endif { int i, width, ncode, flag; int xll, yll, xur, yur; int nglyphs=0; LPSTR lpCharName; char buffer[128]; /* for AFM file line */ flag = GetWidth(hDC, 0, 255, charwidths); /* redundant ? */ if (bATMLoaded == 0) return 0; /* error! - sanity check */ for (i = 0; i < MAXCHRS; i++) { // lpCharName = lpEncoding + i * MAXCHARNAME; // if (*lpCharName == '\0') continue; if (lpEncoding[i] == NULL) continue; if (*lpEncoding[i] == '\0') continue; lpCharName = lpEncoding[i]; width = charwidths[i]; /* if (GetATMCharBBox(hDC, (char) i, 1000) != 0) */ if (GetATMCharBBox(hDC, (WORD) i, 1000) != 0) { continue; /* ignore failure of ATMGetOutline */ } xll = (int) (ATMxll >> 16); yll = (int) (ATMyll >> 16); xur = (int) (ATMxur >> 16); yur = (int) (ATMyur >> 16); if (codeflag) ncode = i; /* for encoded characters */ else ncode = -1; /* for unencoded characters */ if (bAFMTextFont) ncode = standardcode(lpCharName); /* use ASE 98/Aug/26 */ strcpy(str, lpCharName); /* fprintf(afmfile, "C %d ; WX %d ; N %s ; B %d %d %d %d ;\n", ncode, width, str, xll, yll, xur, yur); */ sprintf(buffer, "C %d ; WX %d ; N %s ; B %d %d %d %d ;\n", ncode, width, str, xll, yll, xur, yur); fputs(buffer, afmfile); nglyphs++; } return nglyphs; } /* GuessEncoding refers to the following globally defined vars */ /* testcharset, testpitchandfamily, testwantttf */ /* bCheckReencode, bCheckBoldFlag, bCheckItalicFlag */ /* and bUseNewEncode */ /* Rewritten 95/Feb/5 */ /* DAMN! */ /* Symbol charset = symbol family = decorative Type 1 NICE */ /* Zapf Chancery charset = ANSI family = roman --- Type 1 text */ /* Zapf Dingbats charset = ANSI family = decorative --- Type 1 */ /* Braggadocio charset = ANSI family = decorative --- TrueType text */ /* Algerian charset = ANSI family = decorative --- TrueType text */ /* converted LMS charset = ANSI family = decorative !!! UGH */ char *GuessEncoding (void) { /* 1994/Dec/31 */ int symbolflag, decorativeflag, dontcareflag; /* if ((testcharset == ANSI_CHARSET || testcharset == DEFAULT_CHARSET) && */ /* (testpitchandfamily & 0xF0) != FF_DECORATIVE) */ /* if (testwantttf || (bCheckReencode == 0)) return "ansinew"; */ /* else if (szReencodingVector == NULL) return "ansinew"; */ /* impossible */ /* else return szReencodingVector; */ /* szReencodingName ? */ /* }*/ /* symbol or decorative font */ /* else return "numeric"; */ /* if ((testcharset != ANSI_CHARSET && testcharset != DEFAULT_CHARSET)) symbolflag = 1; else symbolflag = 0; */ #ifdef DEBUGWRITEAFM if (bDebug > 1) { sprintf(debugstr, "CharSet %X PitchFamily %X TTF %d Reencode %d Encoding %s\n", testcharset, testpitchandfamily, testwantttf, bCheckReencode, (szReencodingVector == NULL) ? "" : szReencodingVector); OutputDebugString(debugstr); } #endif if (testcharset == ANSI_CHARSET) symbolflag = 0; else if (testcharset == DEFAULT_CHARSET) symbolflag = 0; else symbolflag = 1; if ((testpitchandfamily & 0xF0) == FF_DECORATIVE) decorativeflag = 1; else decorativeflag = 0; if ((testpitchandfamily & 0xF0) == FF_DONTCARE) dontcareflag = 1; else dontcareflag = 0; /* if the user explicitly asks for reencoding, lets not argue ! */ if (bCheckReencode == 0 && szReencodingVector != NULL) { /* 98/Feb/28 */ /* for all fonts look at CharSet if not ANSI */ if (symbolflag) return "numeric"; /* for Type 1 fonts look at the 'decorative' bit */ if (!testwantttf && decorativeflag) return "numeric"; /* Revised 97/Feb/5 to deal with auto converted math fonts */ if (bDecorative) { /* treat decorative TT font as non-text */ if (testwantttf && decorativeflag) return "numeric"; } /* Revised 97/Feb/16 to deal with auto converted fixed width non text fonts */ if (bDontCare) { /* treat decorative TT font as non-text */ if (testwantttf && dontcareflag) return "numeric"; } } /* plain vanilla text fonts (i.e. Windows ANSI encoded font) */ /* if TrueType font, or no reencoding specified by env var ENCODING */ /* if (testwantttf || bCheckReencode == 0 || szReencodingVector == NULL) return "ansinew"; */ if (bCheckReencode == 0) return "ansinew"; /* no reencoding */ if (szReencodingVector == NULL) return "ansinew"; /* can't do it */ #ifdef USEUNICODE /* can reencode TTF fonts if UseNewEncode != 0 */ if (testwantttf && !bUseNewEncodeTT) return "ansinew"; if (!testwantttf && !bUseNewEncodeT1 && (hEncoding == NULL)) return "ansinew"; /* 97/Jan/25 */ #else if (testwantttf) return "ansinew"; #endif /* For Type 1 fonts, if ENCODING= is set and ATM loaded return encoding */ /* For TrueType, if bUseNewEncode is set then reencode it ! */ return szReencodingVector; /* not NULL */ } /* write back into argument - the first in list of dirs */ int SetupTeXFirst(char *szTeXFirst, char *szTeXFonts) { /* separated 97/Apr/20 */ char *s; int nlen; *szTeXFirst = '\0'; /* if (strcmp(szTeXFonts, "") == 0) */ if (szTeXFonts == NULL) { sprintf(debugstr, "Please set up %s env var first", "TEXFONTS"); winerror(debugstr); return -1; } if ((s = strchr(szTeXFonts, ';')) != NULL) nlen = s - szTeXFonts; else nlen = strlen(szTeXFonts); strncpy(szTeXFirst, szTeXFonts, nlen); *(szTeXFirst+nlen) = '\0'; /* Terminate it */ /* Avoid double separator at end 96/Oct/12 */ s = szTeXFirst + strlen(szTeXFirst) - 1; if (*s == '\\') { /* Does it end in terminator ? */ if (s > szTeXFirst && *(s-1) == '\\') *s = '\0'; } return 0; } #ifdef AFMTOTFMDLL HINSTANCE hAFMtoTFM=NULL; int RunAFMtoTFMDLL (HWND hWnd, char *str) { int (* lpAFMtoTFM) (HWND, char *)=NULL; /* compare afmtotfm.h */ int ret, fault=0; if (bDebug > 1) OutputDebugString("RunAFMtoTFMDLL"); if (hAFMtoTFM == NULL) hAFMtoTFM = LoadLibrary("AFMtoTFM"); /* connect to AFMtoTFM.DLL */ if (hAFMtoTFM == NULL){ WriteError("Can't link to AFMtoTFM.DLL"); return -1; // error return } lpAFMtoTFM = (int (*) (HWND, char *)) GetProcAddress(hAFMtoTFM, "AFMtoTFM"); if (lpAFMtoTFM == NULL) { winerror("Can't find AFMtoTFM entry point"); fault++; } else { if (hConsoleWnd == NULL) // create console window if needed CreateConsole(hInst, hWnd); // for AFMtoTFM.DLL if (hConsoleWnd == NULL) { ShowLastError(); // no console window created fault++; } else { (void) EnableWindow(hWnd, FALSE); /* disable main Window ??? */ /* call AFMtoTFM with command line string */ ret = (* lpAFMtoTFM) (hConsoleWnd, str); (void) EnableWindow(hWnd, TRUE); /* reenable main Window ??? */ } /* can free library now since dviwindo takes care of modeless dialog */ } FreeLibrary(hAFMtoTFM); hAFMtoTFM = NULL; return fault; } void ShowLastError (void) { int err, nlen; err = GetLastError(); nlen = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // or 0 debugstr, sizeof(debugstr), NULL); if (nlen > 0) { winerror(debugstr); // sprintf(debugstr, "err %d nlen %d", err, nlen); // winerror(debugstr); } else { sprintf(debugstr, "FormatMessage failed on error %d", err, err); winerror(debugstr); } if (bDebug > 1) OutputDebugString(debugstr); /* sprintf(debugstr, "hInst %08X hWnd %08X", hInst, hWnd); winerror(debugstr); */ } #endif /* fname is Windows Face Name, presently not used here */ /* waitflag set if batchflag is set (i.e. when using WriteTFMs... */ int CallAFMtoTFM (HWND hWnd, char *fname, char *szAFMFileName, char *szEncodingVector, int waitflag) { int n, nCmdShow; HINSTANCE err; /* 95/Mar/31 */ char szTeXFirst[MAXFILENAME]; /* first path on TEXFONTS */ /* char *s; */ /* int nlen; */ HWND hFocus; /* 1995/Nov/1 */ /* SW_HIDE ? SW_MINIMIZE ? SW_SHOWMINIMIZED ? SW_SHOW ? */ /* recommend us of PIF file for AFMtoTFM ? */ /* nCmdShow = SW_SHOWMINIMIZED; */ /* 1997/Nov/30 change */ if (nCmdShowForce >= 0) nCmdShow = nCmdShowForce; /* 94/Mar/7 */ else nCmdShow = SW_SHOWMAXIMIZED; /* This is now dead - since we removed the check box ... */ if (bRunMinimized != 0) nCmdShow = SW_SHOWMINIMIZED; if (szEncodingVector == NULL) { sprintf(debugstr, "Please set up %s env var first", "ENCODING"); winerror(debugstr); return -1; } if (SetupTeXFirst(szTeXFirst, szTeXFonts) < 0) return -1; /* if (szTeXFonts == NULL) { sprintf(debugstr, "Please set up %s env var first", "TEXFONTS"); winerror(debugstr); return -1; } if ((s = strchr(szTeXFonts, ';')) != NULL) nlen = s - szTeXFonts; else nlen = strlen(szTeXFonts); strncpy(szTeXFirst, szTeXFonts, nlen); *(szTeXFirst+nlen) = '\0'; s = szTeXFirst + strlen(szTeXFirst) - 1; if (*s == '\\') { if (s > szTeXFirst && *(s-1) == '\\') *s = '\0'; } */ for (n = 0; n < 4; n++) { if (TaskInfo.hWnd == NULL) break; if (IsTaskActive() == 0) break; if ((hFocus = GetFocus()) == NULL) hFocus = hwnd; /* (void) MessageBox(GetFocus(), */ (void) MessageBox(hFocus, "Please wait for AFMtoTFM to finish", modname, MB_ICONASTERISK | MB_OK); } /* if (strcmp (szAFMtoTFM, "") != 0) */ /* if (strcmp (szAFMtoTFMcom, "") != 0) */ if (szAFMtoTFMcom != NULL) strcpy(str, szAFMtoTFMcom); /* call user supplied prog */ else strcpy(str, "AFMTOTFM"); /* revised 1995/June/26 */ strcat (str, " "); strcat (str, "-v "); if (strcmp(szEncodingVector, "numeric") == 0) { /* symbol/decorative */ /* wsprintf(str, "afmtotfm -v -O=%s %s", (LPSTR) szTeXFirst, (LPSTR) szAFMFileName); */ } else { /* plain text font using Windows ANSI as default */ /* strcat(str, "-adjx -c="); */ strcat(str, "-adx "); /* drop the `j' 98/Aug/17 */ strcat(str, "-c="); strcat(str, szEncodingVector); strcat(str, " "); /* wsprintf(str, "afmtotfm -vadjx -c=%s -O=%s %s", (LPSTR) szEncodingVector, (LPSTR) szTeXFirst, (LPSTR) szAFMFileName); */ } strcat(str, "-O="); strcat(str, szTeXFirst); strcat(str, " "); /* if (strcmp(szAFMtoTFM, "") != 0) */ /* 1995/June/26 */ if (szAFMtoTFM != NULL) { strcat(str, szAFMtoTFM); strcat(str, " "); if (bDebug > 1) OutputDebugString(str); } strcat (str, szAFMFileName); /* 1995/June/26 */ WritePrivateProfileString(achDiag, "LastAFMtoTFM", str, achFile); /* call AFMtoTFM.DLL --- drop through to the old way if it fails */ /* check afmtotfm.h for definition of AFMtoTFM entry point ! */ #ifdef AFMTOTFMDLL // if (bUseAFMtoTFMDLL) { if (bUseDLLs) { if (RunAFMtoTFMDLL(hWnd, str) == 0) return 0; // success // else drop through to the old way... } /* in any of the above failure cases we drop through to the old way */ #endif err = TryWinExec(str, nCmdShow, "AFMtoTFM"); /* in winprint.c */ /* optionally stop here and wait for it to finish ? */ if (err >= HINSTANCE_ERROR) { /* if (waitflag) */ /* experiment 97/Nov/30 */ (void) GetTaskWindow (err); /* optionally delete the AFM file again ? */ /* } */ return 0; } /* optionally delete the AFM file again ? */ return -1; } /* fname, waitflag unreferenced */ /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ /* For T1 fonts, ATM.INI lists: Face Name, Style=PFM file, PFB file */ /* NOTE: there is no ATM.INI in Windows NT ! 97/Jan/21 */ /* Can use ATMGetFontPaths for this ... */ /* Could also use ATMREG.ATM, but we only need this for enumerated fonts */ /* Now this also works for inactive fonts, by the way */ /* In W2K, should we check registry ? */ /* HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Type 1 Installer\Type 1 Fonts */ /* (hyphen -> space) T */ /* bCheckBoldFlag and bCheckItalicFlag global pass information */ /* called only from FileFromFace */ int TryForATM (char *fname, char *TestFont) { /* 1995/April/15 */ int flag=0; char *s; int ret; ATMFontSpec FontSpec; /* FaceName and Style */ ATMFontPathInfo FontPathInfo; /* pfb, pfm, mmm, pss file names 4*260 */ if (bDebug > 1) OutputDebugString("TryForATM"); /* The new way, using ATMGetFontPaths - try this first - if ATM loaded */ if (bATMLoaded) { /* 97/Jan/15 get here in Windows 95/98 only */ strcpy(FontSpec.faceName, TestFont); FontSpec.styles = 0; if (bCheckItalicFlag) FontSpec.styles |= ATM_ITALIC; if (bCheckBoldFlag) FontSpec.styles |= ATM_BOLD; /* put in empty strings in case it fails 96/Oct/12 ??? */ /* FontPathInfo.pfbPath[0] = '\0'; etc. */ ret = MyATMGetFontPaths(BD_VERSION, &FontSpec, &FontPathInfo); if (ret == ATM_NOERR) { #ifdef DEBUGFONTSELECT if (bDebug > 1) { OutputDebugString(FontPathInfo.pfbPath); OutputDebugString(FontPathInfo.pfmPath); OutputDebugString(FontPathInfo.mmmPath); OutputDebugString(FontPathInfo.pssPath); } #endif /* strcpy(fname, FontPathInfo.pfbPath); */ strcpy(fname, FontPathInfo.pfmPath); if (*fname != '\0') return 1; /* OK use PFM file name */ #ifdef IGNORED /* removed 97/Dec/2 */ strcpy(fname, FontPathInfo.mmmPath); if (*fname != '\0') return 1; /* OK use PFB file name */ #endif } } /* should the above fail for some reason, we just drop through */ #ifdef DEBUGAFMNAME if (bDebug > 1) { sprintf(debugstr, "After ATMGetFontPaths: %s\n", TestFont); OutputDebugString(debugstr); } #endif /* Next try ATMREG.ATM 97/Jan/21 */ if (bTryATMRegFlag) { ret = ReadATMReg(1); /* if (ret == 0) */ if (ret == 0 && *str != '\0') { strcpy(fname, str); return 1; /* success ! */ } if (ret < 0) bTryATMRegFlag = 0; /* don't try this again */ } #ifdef DEBUGAFMNAME if (bDebug > 1) { sprintf(debugstr, "After ReadATMReg: %s\n", TestFont); OutputDebugString(debugstr); } #endif /* Next try and see whether this is an ATM font */ strcpy(fname, TestFont); /* Following added to cope with common Alias --- 1993/April/10 */ if (strcmp(fname, "Times Roman") == 0) strcpy(fname, "Times"); if (bCheckBoldFlag != 0 || bCheckItalicFlag != 0) strcat(fname, ","); if (bCheckBoldFlag != 0) strcat(fname, "BOLD"); if (bCheckItalicFlag != 0) strcat(fname, "ITALIC"); #ifdef DEBUGAFMNAME if (bDebug > 1) OutputDebugString(fname); #endif if (bWinNT) *str = '\0'; /* there is no atm.ini in NT 97/Jan/25 */ else GetPrivateProfileString("fonts", fname, "", str, sizeof(str), "atm.ini"); /* NOTE: there is no ATM.INI in Windows NT ! 97/Jan/21 */ /* The following takes care of cases where base font is missing 95/Jan/2 */ if (*str == '\0' && bCheckItalicFlag == 0 && bCheckBoldFlag == 0) { strcat(fname, ","); strcat(fname, "ITALIC"); if (bWinNT) *str = '\0'; /* there is no atm.ini in NT 97/Jan/25 */ else GetPrivateProfileString("fonts", fname, "", str, sizeof(str), "atm.ini"); /* NOTE: there is no ATM.INI in Windows NT ! 97/Jan/21 */ if (*str == '\0') { /* Desperation 95/Jan/2 */ s = strchr(fname, ','); /* *s = '\0'; */ /* strcat(fname, ","); */ if (s != NULL) strcpy(s+1, "BOLD"); (void) GetPrivateProfileString("fonts", fname, "", str, sizeof(str), "atm.ini"); /* NOTE: there is no ATM.INI in Windows NT ! 97/Jan/21 */ } } if (*str != '\0') { /* something found ? */ /* if (!bATMLoaded) *atmfontflag = 1; */ /* only if ATM can't be asked*/ flag = 1; strcpy(fname, str); if ((s = strchr(fname, ',')) != NULL) *s = '\0'; } #ifdef DEBUGAFMNAME if (bDebug > 1) { sprintf(debugstr, "TryForATM: %s %s FLAG: %d\n", TestFont, fname, flag); OutputDebugString(debugstr); // wincancel(debugstr); } #endif if (bWinNT5) { // Try in registry? \Type 1 Installer\Type 1 Fonts } return flag; } /* For TT, the `Face Name' is what is listed in font menus */ /* For TT, the `Full Name' is what appears in WIN.INI */ /* Somehow need to get from `Face Name' to `Full Name' ??? Enumerate Fonts */ /* Called only from FileFromFace */ /* int TryForTTF (char *fname, char *TestFont) */ /* 1995/Apr/15 */ int TryForTTF (HDC hDC, char *fname, char *TestFont) { /* 1995/July/8 */ int flag=0; int lenstr; if (bDebug > 1) OutputDebugString("TryForATM"); *str = '\0'; /* See whether maybe a True Type font */ /* lenstr = TryForTrue(TestFont, bCheckBoldFlag, bCheckItalicFlag); */ lenstr = TryForTrue(hDC, TestFont, bCheckBoldFlag, bCheckItalicFlag); if (*str != '\0') { /* yes, it is TrueType */ /* *truetypeflag = 1; */ flag = 1; // strcpy(fname, str); strcpy(fname, removepath(str)); // 2000 June 2 /* This is where before we set up hMetric and did ABCMetrics */ } /* if (bDebug > 1) { sprintf(debugstr, "TryForTTF: %s %s FLAG: %d\n", TestFont, fname, flag); OutputDebugString(debugstr); } */ return flag; } /* Writes back into first argument ... */ /* 1995/July/19 */ void BadStyleMessage (char *szBuffer, char *szFont, char *szInfo) { char *s; sprintf(szBuffer, "Can't find file name for face `%s'\n", szFont); s = szBuffer + strlen(szBuffer); /* show style */ /* 1995/July/19 */ FormatStyle (s, bBoldFlag, bItalicFlag); /* sprintf(s, "%s%s%s", (bBoldFlag == 0 && bItalicFlag == 0) ? "REGULAR" : "", bBoldFlag ? "BOLD" : "", bItalicFlag ? "ITALIC" : ""); */ /* if (bBoldFlag == 0 && bItalicFlag == 0) strcat(buffer, "REGULAR"); if (bBoldFlag) strcat (buffer, "BOLD"); if (bItalicFlag) strcat (buffer, "ITALIC"); */ strcat (szBuffer, " style does not exist "); if (bDebug > 1) { if (testwantttf) strcat(szBuffer, "TT "); else strcat(szBuffer, "T1 "); strcat (szBuffer, szInfo); } } /* Complains if uncertain about TFM file name - may overwrite another */ int AvoidTrouble(char *TestFont, int bBoldFlag, int bItalicFlag) { /* char buffer[BUFLEN]; */ /* does it need to be this big ? */ char *s; FormatNameStyle (debugstr, TestFont, bBoldFlag, bItalicFlag); strcat(debugstr, "\n"); s = debugstr + strlen(debugstr); LoadString(hInst, BAD_STYLE, s, sizeof(debugstr) - strlen(debugstr)); if (wincancel(debugstr)) return 1; /* user decided to cancel */ else return 0; } /* Separated out 95/Feb/6 */ /* may write back into truetypeflag */ /* Check incoming value of truetypeflag to see atm.ini or win.ini first */ /* Rewritten 95/April/15 to select order of looking at atm.ini and win.ini */ /* Returns -1 if fails for some reason 1995/July/19 */ /* For Type 1 fonts, can use ATMGetFontPaths for this ... */ /* int FileFromFace (char *fname, char *TestFont, */ int FileFromFace (HDC hDC, char *fname, char *TestFont, int *atmfontflag, int *truetypeflag) { char afmfilename[MAXFILENAME]; /* use for both vector in and afm out .. */ char *s; int flag = 0; /* this gets set once we found a name */ /* int lenstr; */ #ifdef DEBUGAFMNAME if (bDebug > 1) { sprintf(debugstr, "FileFromFace %s ATM %d TTF %d\n", TestFont, *atmfontflag, *truetypeflag); OutputDebugString(debugstr); // wincancel(debugstr); // debugging only } #endif *fname = '\0'; /* 96/Oct/12 */ if (*truetypeflag == 0) { /* Try ATM.INI before WIN.INI */ if (TryForATM(fname, TestFont) != 0) { if (! bATMLoaded) *atmfontflag = 1; /* only if ATM can't be asked */ *truetypeflag = 0; flag = 1; } /* else if (TryForTTF(fname, TestFont) != 0) */ else if (TryForTTF(hDC, fname, TestFont) != 0) { *truetypeflag = 1; *atmfontflag = 0; flag = 1; } } else { /* Try WIN.INI before ATM.INI */ /* if (TryForTTF(fname, TestFont) != 0) */ if (TryForTTF(hDC, fname, TestFont) != 0) { *truetypeflag = 1; *atmfontflag = 0; flag = 1; } else if (TryForATM(fname, TestFont) != 0) { if (! bATMLoaded) *atmfontflag = 1; /* only if ATM can't be asked */ *truetypeflag = 0; flag = 1; } } #ifdef DEBUGAFMNAME if (bDebug > 1) { sprintf(debugstr, "FileFromFace %s ATM %d TTF %d\n", TestFont, *atmfontflag, *truetypeflag); OutputDebugString(debugstr); } #endif if (flag == 0) { /* font is neither ATM nor TrueType ... */ /* now look in dviwindo.fnt --- for private mapping */ /* NOTE: this does NOT look in .fnt of current DVI file */ /* NOTE: this does NOT look in dviwindo.fnt of current DVI file */ strcpy(fname, TestFont); /* same as for ATM.INI ... */ if (bCheckBoldFlag != 0 || bCheckItalicFlag != 0) strcat(fname, ","); if (bCheckBoldFlag != 0) strcat(fname, "BOLD"); if (bCheckItalicFlag != 0) strcat(fname, "ITALIC"); strcpy(afmfilename, szExeWindo); /* assuming has separator */ strcat(afmfilename, "dviwindo.fnt"); (void) GetPrivateProfileString("Fonts", fname, "", str, sizeof(str), afmfilename); if (*str == '\0') { /* backward compatability */ (void) GetPrivateProfileString("FontMapping", fname, "", str, sizeof(str), afmfilename); } if (*str == '\0') { strcpy(str, TestFont); /* Desperation 95/July/19 */ strcpy(fname, TestFont); /* Desperation */ if ((s = strchr(fname, '(')) != NULL) { *(s-1) = '\0'; /* (TT) */ } /* UGH! Not found there either - try and construct file name from font name */ /* BadStyleMessage(debugstr, TestFont, "A"); if (wincancel(debugstr) != 0) return -1; *//* FAIL 95/July/19 */ if (AvoidTrouble(TestFont, bCheckBoldFlag, bCheckItalicFlag)) { return -1; } /* heuristic - squezze out spaces */ /* problem with overlap of string ? */ /* problem with hyphens that became spaces and should stay spaces ? */ while ((s = strchr(fname, ' ')) != NULL) strcpy(s, s+1); /* limit filename to 8 characters - to avoid open error */ if (strlen(fname) > 8) fname[8] = '\0'; } /* end of not in dviwindo.fnt file case */ } /* end of not ATM and not TrueType case */ if (*fname == '\0') return -1; /* failed */ /* make up file name for AFM file */ /* remove path if any */ if ((s = strrchr(fname, '\\')) != NULL) strcpy(fname, s+1); if ((s = strrchr(fname, '/')) != NULL) strcpy(fname, s+1); if ((s = strrchr(fname, ':')) != NULL) strcpy(fname, s+1); /* remove extension of any */ if ((s = strrchr(fname, '.')) != NULL) *s = '\0'; return 0; /* success */ } /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */ // int GetGlyphList(HDC, LPSTR, int); int GetGlyphList(HDC, LPSTR *, int); /* segregated out 95/Apr/4 --- writes back into afmfilename */ /* expanded for case BasePath is defined 96/Aug/30 */ #ifdef LONGNAMES HFILE makeafmfilename(char *afmfilename, char *fname) #else FILE *makeafmfilename(char *afmfilename, char *fname) #endif { #ifdef LONGNAMES HFILE afmfile; #else FILE *afmfile; #endif char *s; afmfile = BAD_FILE; /* 95/Dec/1 */ /* If BasePath defined then construct c:\\yandy\\fonts\\afm 96/Aug/29 */ /* if (strcmp(szBasePath, "") != 0) */ if (szBasePath != NULL) { strcpy(afmfilename, szBasePath); s = afmfilename + strlen(afmfilename) - 1; if (*s == '\\' || *s == '/') *s = '0'; strcat (afmfilename, "\\fonts"); strcat (afmfilename, "\\afm"); strcat (afmfilename, "\\"); strcat (afmfilename, fname); /* assumed extensionless */ strcat (afmfilename, ".AFM"); afmfile = fopen(afmfilename, "w"); if (afmfile == BAD_FILE) { /* try and open */ if (bDebug > 1) OutputDebugString(afmfilename); /* try and create directory then ... assumes //fonts exists ... */ s = strrchr(afmfilename, '\\'); if (s != NULL) { *s = '\0'; /* is the following OK in WIN32 use CreateDirectory instead ? */ /* can this handle long file names in WIN16 ? */ if (_mkdir(afmfilename)) { if (bDebug > 1) { sprintf(debugstr, "_mkdir failed on %s", afmfilename); OutputDebugString(debugstr); } } *s = '\\'; } afmfile = fopen(afmfilename, "w"); } } /* If BasePath *not* defined, or if the above failed ... */ if (afmfile == BAD_FILE) { /* get path of executable */ /* assumes it has path separator at end */ strcpy (afmfilename, szExeWindo); /* go use AFM sub-directory */ /* if it exists 95/Feb/11 */ strcat (afmfilename, "afm\\"); /* concatenate desired font file name */ strcat (afmfilename, fname); /* add new extension */ strcat (afmfilename, ".AFM"); /* 1992/Sep/17 */ afmfile = fopen(afmfilename, "w"); if (afmfile == BAD_FILE) { /* try and open */ if (bDebug > 1) OutputDebugString(afmfilename); /* try and create directory then ... */ s = strrchr(afmfilename, '\\'); if (s != NULL) { *s = '\0'; /* is the following OK in WIN32 use CreateDirectory instead ? */ /* can this handle long file names in WIN16 ? */ if (_mkdir(afmfilename)) { if (bDebug > 1) { sprintf(debugstr, "_mkdir failed on %s", afmfilename); OutputDebugString(debugstr); } } *s = '\\'; } afmfile = fopen(afmfilename, "w"); if (afmfile == BAD_FILE) { /* try and open */ if (bDebug > 1) OutputDebugString(afmfilename); s = strstr(afmfilename, "afm"); /* c:\\dviwindo\\afm...*/ if (s != NULL) strcpy(s, s+4); /* strip out again */ afmfile = fopen(afmfilename, "w"); /* directly dviwindo dir */ if (afmfile == BAD_FILE) { sprintf(debugstr, "Unable to create %s", afmfilename); winerror (debugstr); /* failed = 1; */ /* goto cleanup; */ /* 94/Dec/31 */ /* return NULL; */ return BAD_FILE; /* 95/Dec/10 */ } } } } return afmfile; } void ShowhDCFontInfo(HDC, int); /* in winsearc.c */ /* Return allocated data structure and use in WriteATMFile ? */ /* Currently not use for a whole lot --- use more later ? */ /* HGLOBAL GetATMFontInfo(HDC hDC, WORD flags, int verboseflag) */ HGLOBAL GetATMFontInfo(HDC hDC, WORD flags) { WORD BufSize=0; char FaceName[LF_FACESIZE]; HGLOBAL hInfo; LPATMInstanceInfo lpInfo; /* WORD flags = 0; */ int ret; #ifdef DEBUGHEAP CheckHeap("GetATMFontInfo", 0); #endif if (!MyATMFontSelected(hDC)) return NULL; /* check if ATM font */ /* debugging change only 97/Feb/5 reinstate the above */ /* if (bATMLoaded && !MyATMFontSelected(hDC)) return NULL; */ #ifdef DEBUGHEAP CheckHeap("GetATMFontInfo", 0); #endif if (bDebug > 1) ShowhDCFontInfo (hDC, 1); /* in winsearc.c */ /* strcpy (FaceName, TestFont); */ /* flags = ATM_GETWIDTHS | ATM_GETKERNPAIRS; */ ret = -1; if (bATMLoaded) ret = MyATMGetFontInfo(BD_VERSION, hDC, flags, FaceName, NULL, &BufSize); if (ret != ATM_NOERR) { if (bDebug > 1) { sprintf(debugstr, "GetATMFontInfo returns %d %d\n", ret, BufSize); OutputDebugString(debugstr); } return NULL; /* failed */ } #ifdef DEBUGHEAP CheckHeap("GetATMFontInfo", 0); #endif hInfo = GlobalAlloc(GMEM_MOVEABLE, BufSize); lpInfo = GlobalLock(hInfo); if (lpInfo == NULL) { winerror("Unable to allocate memory"); return NULL; /* failed to allocate */ } ret = -1; if (bATMLoaded) ret = MyATMGetFontInfo(BD_VERSION, hDC, flags, FaceName, lpInfo, &BufSize); if (ret != ATM_NOERR) { if (bDebug > 1) { sprintf(debugstr, "GetATMFontInfo returns %d %d\n", ret, BufSize); OutputDebugString(debugstr); } GlobalUnlock(hInfo); GlobalFree(hInfo); return NULL; } #ifdef DEBUGATMINFO if (bDebug > 1) { /* now dump the information */ /* For ATMInstanceInfo.flags field see atmpriv.h */ /* 1 fixed-width, 2 serif, 4 PI, 8 Script, 20 ASE, 40 Italic, 4000 bold */ sprintf(debugstr, "FaceName %s Flags %0X BufSize %d\n", FaceName, lpInfo->flags, BufSize); OutputDebugString(debugstr); sprintf(debugstr, "%d chars %d kerns\n", lpInfo->num_chars, lpInfo->num_kern_pairs); OutputDebugString(debugstr); sprintf(debugstr, "FontBBox %d %d %d %d\n", lpInfo->font_bb_left, lpInfo->font_bb_bottom, lpInfo->font_bb_right, lpInfo->font_bb_top); OutputDebugString(debugstr); /* ATMInstanceInfo.encoding is 0 for text fonts and -1 (65535) for PI fonts */ sprintf(debugstr, "Missing %d Default %d Break %d Encoding %d\n", lpInfo->missing_width, lpInfo->default_char, lpInfo->break_char, lpInfo->encoding); OutputDebugString(debugstr); sprintf(debugstr, "stem_v %d stem_h %d cap_height %d x_height %d figure_height %d\n", lpInfo->stem_v, lpInfo->stem_h, lpInfo->cap_height, lpInfo->x_height, lpInfo->figure_height); OutputDebugString(debugstr); sprintf(debugstr, "Ascender %d Descender %d Leading %d\n", lpInfo->ascent, lpInfo->descent, lpInfo->leading); OutputDebugString(debugstr); sprintf(debugstr, "max_width %d avg_width %d italic_angle %d superior %d\n", lpInfo->max_width, lpInfo->avg_width, lpInfo->italic_angle, lpInfo->superior_baseline); OutputDebugString(debugstr); sprintf(debugstr, "Under_pos %d Under_thick %d Strike_off %d Strike_thick %d\n", lpInfo->underline_position, lpInfo->underline_thickness, lpInfo->StrikeOutOffset, lpInfo->StrikeOutThickness); OutputDebugString(debugstr); sprintf(debugstr, "widths_off %d kernpair_off %d\n", lpInfo->widthsOffset, lpInfo->kern_pairsOffset); OutputDebugString(debugstr); #ifdef IGNORED if (bDebug > 1) { LPWORD lpFontWidths; /* dump char widths */ /* missing characters have width 0 (char code 0 - 31) or Missing_width */ OutputDebugString("Char Widths\n"); lpFontWidths = (LPWORD) ((LPSTR) lpInfo + lpInfo->widthsOffset); for (k = 0; k < lpInfo->num_chars; k++) { if (lpFontWidths[k] == 0) continue; /* heuristic only */ sprintf(debugstr, "%d %d\n", k, lpFontWidths[k]); OutputDebugString(debugstr); } } #endif #ifdef IGNORED OutputDebugString("Kern Pairs\n"); lpKernPairs = (LPATMKernPair) ((LPSTR) lpInfo + lpInfo->kern_pairsOffset); /* dump kern pairs */ for (k = 0; k < lpInfo->num_kern_pairs; k++) { sprintf(debugstr, "%d %d %d\n", lpKernPairs[k].char_1, lpKernPairs[k].char_2, lpKernPairs[k].distance); OutputDebugString(debugstr); } #endif } #endif /* ifdef DEBUGATM */ GlobalUnlock(hInfo); /* GlobalFree(hInfo); */ return hInfo; } /**************************************************************************/ /* returns -1 if glyphname is *not* in encoding, otherwise char code */ // int isinencoding(LPSTR lpEncoding, char *glyphname) int isinencoding (LPSTR *lpEncoding, char *glyphname) { // LPSTR = lpEncoding; int i; for (i = 0; i < MAXCHRS; i++) { if (lpEncoding[i] == NULL) continue; // if (strcmp(s, glyphname) == 0) return i; if (strcmp(lpEncoding[i], glyphname) == 0) return i; // s += MAXCHARNAME; } return -1; /* not in currently selected encoding */ } #ifdef USEUNICODE /* Do this only in NT ? Do this only for TT fonts ? Or do for either one */ /* if (truetypeflag || bWinNT) ? */ /* if buffer == NULL just return the count */ /* used first to get total glyph count with buffer == NULL */ /* NOTE: this will not take into account repeated entries in encoding ... */ #ifdef LONGNAMES // int AddNamedGlyphs (HFILE afmfile, char *buffer, LPSTR lpEncoding, HDC hTestDC) int AddNamedGlyphs (HFILE afmfile, char *buffer, LPSTR *lpEncoding, HDC hTestDC) #else // int AddNamedGlyphs (FILE *afmfile, char *buffer, LPSTR lpEncoding, HDC hTestDC) int AddNamedGlyphs (FILE *afmfile, char *buffer, LPSTR *lpEncoding, HDC hTestDC) #endif { WORD UID; /* Unicode */ MAT2 Mat; /* Transformation matrix */ GLYPHMETRICS GMDefault; /* Glyph Metrics for default char */ DWORD nLenDefault; /* space needed for default char */ GLYPHMETRICS GM; /* Glyph Metrics structure */ DWORD nLen; int xll, yll, xur, yur; int ntable, i; int ncount = 0; int charwidth; int ncode; char *glyphname; /* Set up identity transformation matrix */ /* which is ignored GGO_NATIVE */ Mat.eM11.value=1; Mat.eM12.value=0; Mat.eM21.value=0; Mat.eM22.value=1; Mat.eM11.fract=0; Mat.eM12.fract=0; Mat.eM21.fract=0; Mat.eM22.fract=0; /* Get shape and size of default character for comparison */ // nLenDefault = GetGlyphOutlineW(hTestDC, // notdefUID, GGO_NATIVE, &GMDefault, 0, NULL, &Mat); // 2000 June 7 nLenDefault = GetGlyphOutlineW(hTestDC, notdefUID, GGO_METRICS, &GMDefault, 0, NULL, &Mat); if (bDebug > 1) { sprintf(debugstr, "default ret %d Inc %d %d Org %d %d Black %d %d", nLenDefault, GMDefault.gmCellIncX, GMDefault.gmCellIncY, GMDefault.gmptGlyphOrigin.x, GMDefault.gmptGlyphOrigin.y, GMDefault.gmBlackBoxX, GMDefault.gmBlackBoxY); OutputDebugString(debugstr); } /* ntable = sizeof(unicodeMap) / sizeof(unicodeMap[1]); *//* Adobe names */ ntable = sizeofUID(); /* in winsearc.c */ for (i = 0; i < ntable; i++) { UID = unicodeMap[i].UID; /* get Unicode number */ glyphname = unicodeMap[i].glyphname; if (buffer != NULL) { if (isinencoding(lpEncoding, glyphname) >= 0) continue; /* already done, ignore */ } /* get glyph metrics - returns size of buffer needed for outline */ // nLen = GetGlyphOutlineW(hTestDC, // UID, GGO_NATIVE, &GM, 0, NULL, &Mat); // 2000 June 7 nLen = GetGlyphOutlineW(hTestDC, UID, GGO_METRICS, &GM, 0, NULL, &Mat); /* ignore if there was some kind of error */ if (nLen <= 0) continue; // GDI_ERROR /* see whether appears to be the default character */ if (nLen == nLenDefault && GM.gmCellIncX == GMDefault.gmCellIncX && GM.gmBlackBoxX == GMDefault.gmBlackBoxX && GM.gmBlackBoxY == GMDefault.gmBlackBoxY && GM.gmptGlyphOrigin.x == GMDefault.gmptGlyphOrigin.x && GM.gmptGlyphOrigin.y == GMDefault.gmptGlyphOrigin.y) { continue; } if (buffer != NULL) { /* second pass actually want output */ charwidth = GM.gmCellIncX; xll = GM.gmptGlyphOrigin.x; yll = GM.gmptGlyphOrigin.y - GM.gmBlackBoxY; xur = GM.gmptGlyphOrigin.x + GM.gmBlackBoxX; yur = GM.gmptGlyphOrigin.y; #ifdef DEBUGCHARMETRICS if (bDebug > 1) { sprintf(debugstr, "%d UID %04X %s nLen %d width %d xll %d yll %d xur %d yur %d", i, UID, glyphname, nLen, charwidth, xll, yll, xur, yur); OutputDebugString(debugstr); } /* if (bDebug > 1) { sprintf(debugstr, "%d UID %04X %s nLen %d width %d xll %d yll %d xur %d yur %d", i, UID, glyphname, nLen, charwidth, xll, yll, xur, yur); OutputDebugString(debugstr); } */ #endif ncode = -1; if (bAFMTextFont) ncode = standardcode(glyphname); /* expect -1 */ sprintf(buffer, "C %d ; WX %d ; N ", ncode, charwidth); fputs(buffer, afmfile); sprintf(buffer, "%s ;", glyphname); fputs(buffer, afmfile); sprintf(buffer, " B %d %d %d %d ;\n", xll, yll, xur, yur); fputs(buffer, afmfile); } ncount++; } return ncount+1; /* add one for default char which was not counted */ } #endif /**************************************************************************/ void FreeVector(HGLOBAL); typedef short int far *LPSHORT; /* The core of it - a monster function by now both Type 1 and TrueType */ /* can be called directly from WriteAFMFileSafe (called from dviwindo.c) */ /* used in WriteTFM... batchflag == 0 and WriteAllTFMs... batchflag != 0 */ /* returns non-zero if some serious error in creating font or what */ /* returns -1 if failed or cancelled 1995/July/19 */ /* For Type 1 fonts, could use ATMGetFontInfo to get much of this */ /* including widths and kern pairs... */ int WriteAFMFile (HWND hWnd, HDC hDC, int bMakeTFM, int batchflag) { HFONT hFont=0, hFontOld=0; HDC hTestDC=NULL; int i, flag, ncount, ncheck; /* int k, n; */ int truetypeflag=0; /* may get set by FileFromFace ? */ int atmfontflag=0; /* may get set MyATMFontSelected (or FileFromFace) */ int nkerns=0, kern; int kcount; unsigned int chara, charb; int firstchar, lastchar; int charset, family, winansi; int slant, slantdecimal, slantdegree, slantsign; int charweight; int xheight, capheight, charascender, chardescender; /* from .etm */ int underoffset, underwidth; /* from .etm */ int charascent, chardescent, maxwidth, charheight; /* from .tm */ int xll, yll, xur, yur; /* for BBox */ char *s; int width; int failed = 0; int err; HGLOBAL hMemTemp=NULL; /* used only locally here 95/Dec/25 */ KERNPAIR *lpKernPairs=NULL; /* attempt at doing this right */ LPSTR *lpEncoding=NULL; /* pointer to array of pointers to char names */ WORD lpOutData = sizeof(EXTTEXTMETRIC); EXTTEXTMETRIC ExtTextMetrics; /* maybe allocate from memory ? */ int exttextflag=0; /* did we get extra data ? 96/Jan/8 */ int charwidth; /* following for TrueType fonts */ int outsize; /* HLOCAL hMetric=NULL; */ /* flushed 1995/July/27 */ OUTLINETEXTMETRIC *lpMetric=NULL; /* for TrueType only ? */ BOOL bABCFlag=0; /* non-zero if ABC metrics available */ BOOL bFixedPitch; ABC abcwidths[256]; /* above for TrueType fonts */ char afmfilename[MAXFILENAME]=""; /* use for vector in and afm out .. */ char fname[MAXFILENAME]=""; char szFontName[MAXFILENAME]=""; /* 98/Aug/25 */ // char charaname[MAXCHARNAME], charbname[MAXCHARNAME]; char charaname[MAXFILENAME], charbname[MAXFILENAME]; int ret; ATMBBox FontBBox; /* char szFaceStyle[32+2]; */ /* for ATM backdoor FaceName + style */ HGLOBAL hEncodingSaved; /* saved hEncoding */ int nEncodingBytesSaved; /* saved nEncodingBytes */ /* 96/July/21 */ /* LPINT lpKernAmount; */ /* LPSHORT lpKernAmount; */ WORD options; /* Following is for getting TT Char BBox */ GLYPHMETRICS GM; /* Glyph Metrics structure */ DWORD nLen=0; /* space needed for data */ #ifdef USEUNICODE GLYPHMETRICS GMDefault; /* Glyph Metrics for default char */ DWORD nLenDefault=0; /* space needed for default char */ #endif MAT2 Mat; /* Transformation matrix */ char buffer[128]; /* for AFM file line */ #ifdef LONGNAMES HFILE afmfile; #else FILE *afmfile; #endif HCURSOR hSaveCursor=NULL; /* shadow global version noninit ??? */ HGLOBAL hInfo=NULL; /* 1996/July/28 */ LPATMInstanceInfo lpInfo=NULL; /* 1996/July/28 */ int defaultchar; /* 1997/Jan/15 */ int bANSIFlag; /* 1997/Apr/20 */ afmfile = BAD_FILE; if (bTTUsable) { /* for TT Glyph Metrics 95/July/8 */ Mat.eM11.value=1; Mat.eM12.value=0; Mat.eM21.value=0; Mat.eM22.value=1; Mat.eM11.fract=0; Mat.eM12.fract=0; Mat.eM21.fract=0; Mat.eM22.fract=0; } /* Try and guess encoding `ansinew' or `numeric' for TT fonts */ /* User specified ENCODING, `ansinew' or FontSpecific for T1 fonts */ if (szEncodingVector != NULL) free (szEncodingVector); /* safe ? */ szEncodingVector = zstrdup(GuessEncoding()); /* 94/Dec/31 */ #ifdef DEBUGWRITEAFM if (bDebug > 1) OutputDebugString(szEncodingVector); #endif /* flush the following --- just confuses the user ... */ /* we'll just trust the Guess Encoding() to get the encoding right ... */ /* if (!bATMLoaded) */ /* We assume that for ATM and TT we can figure out encoding ... 95/July/8 */ /* Don't know for sure yet (but testwantttf?) whether its T1 or TT font ... */ /* if (!bATMLoaded && !bTTUsable) */ #ifdef USEUNICODE if ((!testwantttf && !bATMLoaded && !bUseNewEncodeT1) || (testwantttf && !bTTUsable)) { /* 97/Jan/21 */ #else if ((!testwantttf && !bATMLoaded) || (testwantttf && !bTTUsable)) { #endif // flag = DialogBox(hInst, "EncodingSelect", hWnd, (DLGPROC) EncodingDlg); flag = DialogBox(hInst, "EncodingSelect", hWnd, EncodingDlg); if (flag == 0) return -1; /* exit: user cancelled */ } /* file name in `encoding' */ if (hPrintDC != NULL) { /* use printer DC if printer has been selected */ if (bDebug > 1) OutputDebugString("Using PrintDC\n"); /* 95/July/8 */ hTestDC = hPrintDC; } else hTestDC = hDC; /* else use screen DC */ /* (void) SetMapMode(hTestDC, MM_TWIPS); *//* set unit to twips */ /* ??? */ /* if (bDebug > 1) { sprintf(debugstr, "%s BOLD: %d ITALIC: %d TTF: %d\n", TestFont, bCheckBoldFlag, bCheckItalicFlag, testwantttf); OutputDebugString(debugstr); } */ /* 1995/April/15 */ /* hFont = createatmfont(TestFont, METRICSIZE, 0, */ hFont = createatmfont(TestFont, metricsize, 0, bCheckBoldFlag, bCheckItalicFlag, testwantttf); if (hFont == NULL) { /* rewritten 94/Dec/31 */ failed = 1; winerror("Can't create test font"); /* very unlikely */ return failed; } /* winerror(szEncodingVector); */ /* debugging */ hMemTemp = getencoding(szEncodingVector); if (hMemTemp == NULL) { /* winerror ("Unable to allocate memory"); */ /* or user cancelled */ /* or unable to find encoding vector */ return -1; } if (batchflag == 0) { /* in batch mode already done */ bHourFlag = 1; hSaveCursor = SetCursor(hHourGlass); /* 1996/July/25 */ } if (bATMReencoded) UnencodeFont(hTestDC, -1, 1); if (!testwantttf && bATMPrefer && bATMLoaded) { if (bATMExactWidth) options = ATM_SELECT | ATM_USEEXACTWIDTH; else options = ATM_SELECT; (void) MyATMSelectObject (hTestDC, hFont, options, &hFontOld); } else hFontOld = SelectObject(hTestDC, hFont); /* select test font */ if (hFontOld == NULL) { failed = 1; /* winerror("Can't select font"); *//* unlikely ... */ if (wincancel("Can't create test font")) goto cleanup; } if (bUseATMFontInfo) { if (MyATMFontSelected(hTestDC)) { /* we don't presently use width from this call, but ... */ /* hInfo = GetATMFontInfo(hTestDC, ATM_GETWIDTHS | ATM_GETKERNPAIRS, 1); */ hInfo = GetATMFontInfo(hTestDC, ATM_GETWIDTHS | ATM_GETKERNPAIRS); if (hInfo != NULL) lpInfo = GlobalLock(hInfo); } } #ifdef USEUNICODE /* if (bUseNewEncode) bFontEncoded = bCheckReencode; */ /* new method only in Windows NT or for TT in 95 with UseNewEncode */ /* in Windows 95 ATM will be loaded and hence hEncoding != NULL */ if ((testwantttf && bUseNewEncodeTT) || (!testwantttf && bUseNewEncodeT1)) bFontEncoded = bCheckReencode; else bFontEncoded = 0; /* else */ /* hEncoding will be NULL in Windows NT */ if (bCheckReencode && !testwantttf && hEncoding != NULL) ReencodeFont(hTestDC, -1, 0); /* 94/Dec/25 */ #else if (bCheckReencode && !testwantttf && hEncoding != NULL) ReencodeFont(hTestDC, -1, 0); /* 94/Dec/25 */ #endif /* flag = GetCharWidth(hTestDC, 0, 255, charwidths); */ flag = GetWidth(hTestDC, 0, 255, charwidths); /* Use widths in hInfo ? but those are for unreencoded font ? */ if (flag == 0) { winerror("Can't get character widths"); failed = 1; goto cleanup; /* 94/Dec/31 */ } /* else */ if (GetTextMetrics(hTestDC, &TextMetric) == 0) { failed = 1; winerror("GetTextMetrics failed"); /* unlikely ... */ /* if (wincancel("GetTextMetrics failed")) */ goto cleanup; } charset = TextMetric.tmCharSet; /* family = TextMetric.tmPitchAndFamily >> 4; */ family = TextMetric.tmPitchAndFamily; /* 1993/June/3 */ /* debugging TextMetric fields */ #ifdef DEBUGWRITEAFM if (bDebug > 1) { sprintf(debugstr, "TestFont %s charset %X pitchandfamily %X (%s)\n", TestFont, charset, family, "TextMetric"); OutputDebugString(debugstr); } #endif /* if (charset == ANSI_CHARSET && */ /* 1993/June/3 */ /* if ((charset == ANSI_CHARSET || charset == DEFAULT_CHARSET) && (family & 0xF0) != FF_DECORATIVE) winansi = 1; else winansi = 0; */ winansi = 1; /* assume for a start its plain text font */ if (strcmp(szEncodingVector, "ansinew") == 0 || strcmp(szEncodingVector, "ansi") == 0) bANSIFlag = 1; else bANSIFlag = 0; if (charset != ANSI_CHARSET && charset != DEFAULT_CHARSET) winansi = 0; /* not plain text if charset not ANSI or DEFAULT */ if (!testwantttf && (family & 0xF0) == FF_DECORATIVE) winansi = 0; /* not plain text font if T1 and DECORATIVE */ /* Revised 97/Feb/5 to deal with auto converted math fonts */ if (bDecorative) { /* treat decorative TT font as non-text */ if (testwantttf && (family & 0xF0) == FF_DECORATIVE) winansi =0; } /* Revised 97/Feb/16 to deal with auto converted fixed width non text fonts */ if (bDontCare) { /* treat decorative TT font as non-text */ if (testwantttf && (family & 0xF0) == FF_DONTCARE) winansi = 0; } if (bDebug > 1) { sprintf(debugstr, "winansi %d vec %s charset %X family %X ttf %d", winansi, szEncodingVector, charset, family, testwantttf); OutputDebugString(debugstr); } /* if (winansi && testwantttf == 0 && bCheckReencode) winansi = 0; */ /* not ANSI if T1 and we reencode it 94/Dec/31 */ #ifdef USEUNICODE if ((bUseNewEncodeTT && testwantttf) || (bUseNewEncodeT1 && !testwantttf)) { /* if (bCheckReencode) winansi = 0; */ if (bCheckReencode && bANSIFlag == 0) winansi = 0; /* not ANSI if we reencode it 97/Jan/17 */ } /* else if (testwantttf == 0) */ /* T1 can be reencoded */ else if (testwantttf == 0 && hEncoding != NULL) { /* T1 can be reencoded */ /* if (bCheckReencode) winansi = 0; */ if (bCheckReencode && bANSIFlag == 0) winansi = 0; /* not ANSI if T1 and we reencode it 94/Dec/31 */ } #else if (testwantttf == 0) { /* only T1 can be reencoded */ /* if (bCheckReencode) winansi = 0; */ if (bCheckReencode && bANSIFlag == 0) winansi = 0; /* not ANSI if T1 and we reencode it 94/Dec/31 */ } #endif if (checkansiencode(winansi, charset, family)) { failed = 1; goto cleanup; /* 95/July/20 ? */ } memset (&ExtTextMetrics, 0, sizeof(EXTTEXTMETRIC)); /* clear out */ flag = ExtEscape(hTestDC, GETEXTENDEDTEXTMETRICS, sizeof(WORD), (LPSTR) &lpOutData, sizeof(EXTTEXTMETRIC), (LPSTR) &ExtTextMetrics); /* not sure about 3 rd & 4th argument ... */ /* flag = Escape(hTestDC, GETEXTENDEDTEXTMETRICS, sizeof(WORD), (LPSTR) &lpOutData, (LPSTR) &ExtTextMetrics); */ if (flag <= 0) { if (bDebug) winerror("GETEXTENDEDTEXTMETRICS Escape failed"); /* failed = 1; */ /* goto cleanup; */ /* 95/July/20 */ } else exttextflag = 1; /* did snag ExtendedTextMetrics information */ if (failed) goto cleanup; /* 94/Dec/31 */ /* Construct a useable AFM file name */ /* Use MyATMFontSelected to decide whether this is an ATM font */ if (bATMLoaded) atmfontflag = MyATMFontSelected(hTestDC); truetypeflag = testwantttf; /* *initial* only for FileFromFace 95/April/15 */ /* if (truetypeflag) atmfontflag = 1; else atmfontflag = 0; */ /* FileFromFace(fname, TestFont, &atmfontflag, &truetypeflag); */ err = FileFromFace(hDC, fname, TestFont, &atmfontflag, &truetypeflag); #ifdef DEBUGAFMNAME if (bDebug > 1) OutputDebugString(fname); #endif if (err) { failed = 1; /* 95/July/19 */ goto cleanup; } /* For TrueType fonts get ABC metric info while we are at it */ /* Better be true if we get here since Windows 3.0 does not have TT fonts */ /* Windows NT and W2K also supports this for Type 1 fonts */ if (truetypeflag || bWinNT) { /* get size of local space needed for metrics */ /* outsize = GetOutlineTextMetricsW(hTestDC, 0, NULL); */ outsize = GetOutlineTextMetrics(hTestDC, 0, NULL); /* but don't trust tmFirstChar, tmLastChar, tmDefaultChar */ if (outsize > 0) { /* hMetric = LocalAlloc (LHND, outsize); if (hMetric == NULL) { winerror("Unable to allocate memory"); outsize = 0; failed = 1; goto cleanup; } else { lpMetric = LocalLock (hMetric); if (lpMetric == NULL) goto cleanup; outsize = GetOutlineTextMetrics(hTestDC, outsize, lpMetric); } */ /* 1995/July/27 */ lpMetric = (OUTLINETEXTMETRIC *) LocalAlloc(LPTR, outsize); if (lpMetric == NULL) { winerror("Unable to allocate memory"); /* Take more drastic action ? */ outsize = 0; failed = 1; goto cleanup; } /* GetOutlineTextMetrics works with ATM 4.0 in Windows 95 also */ /* but we get here only with TT fonts presently ... */ else { /* outsize = GetOutlineTextMetricsW(hTestDC, outsize, lpMetric); */ outsize = GetOutlineTextMetrics(hTestDC, outsize, lpMetric); /* but don't trust tmFirstChar, tmLastChar, tmDefaultChar */ defaultchar = lpMetric->otmTextMetrics.tmDefaultChar; #ifdef DEBUGWRITEAFM if (b