1724 lines
39 KiB
C
1724 lines
39 KiB
C
/***
|
|
**
|
|
** Module: T1Instal
|
|
**
|
|
** Description:
|
|
** This is the Win32 DLL (t1instal.dll) interface to the
|
|
** font converter. All window specific code is located in
|
|
** this module and the error hadler module (errors.c).
|
|
**
|
|
** Author: Michael Jansson
|
|
** Created: 12/18/93
|
|
**
|
|
***/
|
|
|
|
/***** INCLUDES */
|
|
|
|
#include "windows.h"
|
|
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <limits.h>
|
|
#include <ctype.h>
|
|
|
|
#undef IN
|
|
|
|
#include "titott.h"
|
|
#include "types.h"
|
|
#include "t1local.h"
|
|
#include "t1instal.h"
|
|
#include "fileio.h"
|
|
#include "safemem.h"
|
|
#include "t1msg.h"
|
|
|
|
#undef UNICODE
|
|
|
|
|
|
/* The CopyrightCheck/MAYBEOK case always succeeds for now. */
|
|
#define MAYBEOK SUCCESS
|
|
|
|
|
|
/***** LOCAL TYPES */
|
|
struct callFrame {
|
|
const void (STDCALL *Progress)(short, void*);
|
|
void *arg;
|
|
int last;
|
|
int done;
|
|
};
|
|
|
|
|
|
static short lastCP = FALSE;
|
|
static char lastVendor[256] = "Unknown.";
|
|
|
|
/***** CONSTANTS */
|
|
#define MIN_PROGRESS 3
|
|
#define DELIMITERS " ,"
|
|
#define COPYSIGN 169
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define DFFACE 139
|
|
#define DFDRIVERINFO 101
|
|
|
|
#define VERSTR "Converter: Windows Type 1 Installer V1.0d.\n" \
|
|
"Font: V"
|
|
|
|
const char version[] = "\n$VER: 1.0d\n";
|
|
|
|
#ifndef NOANSIWINMAC
|
|
const char *winmac[] = {
|
|
"A",
|
|
"AE",
|
|
"Aacute",
|
|
"Acircumflex",
|
|
"Adieresis",
|
|
"Agrave",
|
|
"Aring",
|
|
"Atilde",
|
|
"B",
|
|
"C",
|
|
"Cacute",
|
|
"Ccaron",
|
|
"Ccedilla",
|
|
"D",
|
|
"Delta",
|
|
"E",
|
|
"Eacute",
|
|
"Ecircumflex",
|
|
"Edieresis",
|
|
"Egrave",
|
|
"Eth",
|
|
"F",
|
|
"G",
|
|
"Gbreve",
|
|
"H",
|
|
"I",
|
|
"Iacute",
|
|
"Icircumflex",
|
|
"Idieresis",
|
|
"Idot",
|
|
"Igrave",
|
|
"J",
|
|
"K",
|
|
"L",
|
|
"Lslash",
|
|
"M",
|
|
"N",
|
|
"Ntilde",
|
|
"O",
|
|
"OE",
|
|
"Oacute",
|
|
"Ocircumflex",
|
|
"Odieresis",
|
|
"Ograve",
|
|
"Oslash",
|
|
"Otilde",
|
|
"P",
|
|
"Q",
|
|
"R",
|
|
"S",
|
|
"Scaron",
|
|
"Scedilla",
|
|
"T",
|
|
"Thorn",
|
|
"U",
|
|
"Uacute",
|
|
"Ucircumflex",
|
|
"Udieresis",
|
|
"Ugrave",
|
|
"V",
|
|
"W",
|
|
"X",
|
|
"Y",
|
|
"Yacute",
|
|
"Ydieresis",
|
|
"Z",
|
|
"a",
|
|
"aacute",
|
|
"acircumflex",
|
|
"acute",
|
|
"adieresis",
|
|
"ae",
|
|
"agrave",
|
|
"ampersand",
|
|
"approxequal",
|
|
"aring",
|
|
"asciicircum",
|
|
"asciitilde",
|
|
"asterisk",
|
|
"at",
|
|
"atilde",
|
|
"b",
|
|
"backslash",
|
|
"bar",
|
|
"braceleft",
|
|
"braceright",
|
|
"bracketleft",
|
|
"bracketright",
|
|
"breve",
|
|
"brokenbar",
|
|
"bullet",
|
|
"c",
|
|
"cacute",
|
|
"caron",
|
|
"ccaron",
|
|
"ccedilla",
|
|
"cedilla",
|
|
"cent",
|
|
"circumflex",
|
|
"colon",
|
|
"comma",
|
|
"copyright",
|
|
"currency",
|
|
"d",
|
|
"dagger",
|
|
"daggerdbl",
|
|
"degree",
|
|
"dieresis",
|
|
"divide",
|
|
"dmacron",
|
|
"dollar",
|
|
"dotaccent",
|
|
"dotlessi",
|
|
"e",
|
|
"eacute",
|
|
"ecircumflex",
|
|
"edieresis",
|
|
"egrave",
|
|
"eight",
|
|
"ellipsis",
|
|
"emdash",
|
|
"endash",
|
|
"equal",
|
|
"eth",
|
|
"exclam",
|
|
"exclamdown",
|
|
"f",
|
|
"fi",
|
|
"five",
|
|
"fl",
|
|
"florin",
|
|
"four",
|
|
"fraction",
|
|
"franc",
|
|
"g",
|
|
"gbreve",
|
|
"germandbls",
|
|
"grave",
|
|
"greater",
|
|
"greaterequal",
|
|
"guillemotleft",
|
|
"guillemotright",
|
|
"guilsinglleft",
|
|
"guilsinglright",
|
|
"h",
|
|
"hungerumlaut",
|
|
"hyphen",
|
|
"i",
|
|
"iacute",
|
|
"icircumflex",
|
|
"idieresis",
|
|
"igrave",
|
|
"infinity",
|
|
"integral",
|
|
"j",
|
|
"k",
|
|
"l",
|
|
"less",
|
|
"lessequal",
|
|
"logicalnot",
|
|
"lozenge",
|
|
"lslash",
|
|
"m",
|
|
"macron",
|
|
"middot",
|
|
"minus",
|
|
"mu",
|
|
"multiply",
|
|
"n",
|
|
"nbspace",
|
|
"nine",
|
|
"notequal",
|
|
"ntilde",
|
|
"numbersign",
|
|
"o",
|
|
"oacute",
|
|
"ocircumflex",
|
|
"odieresis",
|
|
"oe",
|
|
"ogonek",
|
|
"ograve",
|
|
"ohm",
|
|
"one",
|
|
"onehalf",
|
|
"onequarter",
|
|
"onesuperior",
|
|
"ordfeminine",
|
|
"ordmasculine",
|
|
"oslash",
|
|
"otilde",
|
|
"overscore",
|
|
"p",
|
|
"paragraph",
|
|
"parenleft",
|
|
"parenright",
|
|
"partialdiff",
|
|
"percent",
|
|
"period",
|
|
"periodcentered",
|
|
"perthousand",
|
|
"pi",
|
|
"plus",
|
|
"plusminus",
|
|
"product",
|
|
"q",
|
|
"question",
|
|
"questiondown",
|
|
"quotedbl",
|
|
"quotedblbase",
|
|
"quotedblleft",
|
|
"quotedblright",
|
|
"quoteleft",
|
|
"quoteright",
|
|
"quotesinglbase",
|
|
"quotesingle",
|
|
"r",
|
|
"radical",
|
|
"registered",
|
|
"ring",
|
|
"s",
|
|
"scaron",
|
|
"scedilla",
|
|
"section",
|
|
"semicolon",
|
|
"seven",
|
|
"sfthyphen",
|
|
"six",
|
|
"slash",
|
|
"space",
|
|
"sterling",
|
|
"summation",
|
|
"t",
|
|
"thorn",
|
|
"three",
|
|
"threequarters",
|
|
"threesuperior",
|
|
"tilde",
|
|
"trademark",
|
|
"two",
|
|
"twosuperior",
|
|
"u",
|
|
"uacute",
|
|
"ucircumflex",
|
|
"udieresis",
|
|
"ugrave",
|
|
"underscore",
|
|
"v",
|
|
"w",
|
|
"x",
|
|
"y",
|
|
"yacute",
|
|
"ydieresis",
|
|
"yen",
|
|
"z",
|
|
"zero"
|
|
};
|
|
|
|
#define GLYPHFILTER &win
|
|
const struct GlyphFilter win = {
|
|
sizeof(winmac) / sizeof(winmac[0]),
|
|
winmac
|
|
};
|
|
|
|
#else
|
|
#define GLYPHFILER (struct GlyphFilter *)0
|
|
#endif /* NOANSIWINMAC */
|
|
|
|
|
|
/***** PROTOTYPES */
|
|
extern int __cdecl sprintf(char *, const char *, ...);
|
|
|
|
|
|
/***** MACROS */
|
|
|
|
#define ReadLittleEndianDword(file,dw) { \
|
|
dw = (DWORD)io_ReadOneByte(file) ; \
|
|
dw |= (DWORD)io_ReadOneByte(file) << 8; \
|
|
dw |= (DWORD)io_ReadOneByte(file) << 16; \
|
|
dw |= (DWORD)io_ReadOneByte(file) << 24; \
|
|
}
|
|
|
|
#ifndef try
|
|
#define try __try
|
|
#define except __except
|
|
#endif
|
|
|
|
|
|
/***** GLOBALS */
|
|
HANDLE hInst;
|
|
|
|
|
|
|
|
/***** STATIC FUNCTIONS */
|
|
|
|
|
|
/***
|
|
** Function: Decrypt
|
|
**
|
|
** Description:
|
|
** Decrypt a byte.
|
|
***/
|
|
static DWORD CSum(char *str)
|
|
{
|
|
DWORD sum = 0;
|
|
|
|
while (*str)
|
|
sum += *str++;
|
|
|
|
return sum;
|
|
}
|
|
|
|
|
|
/***
|
|
** Function: Decrypt
|
|
**
|
|
** Description:
|
|
** Decrypt a byte.
|
|
***/
|
|
static char *Encrypt(char *str, char *out)
|
|
{
|
|
const USHORT c1 = 52845;
|
|
const USHORT c2 = 22719;
|
|
UBYTE cipher;
|
|
USHORT r = 8366;
|
|
int i;
|
|
|
|
for (i=0; i<(int)strlen(str); i++) {
|
|
cipher = (UBYTE)(str[i] ^ (r>>8));
|
|
r = (USHORT)((cipher + r) * c1 + c2);
|
|
out[i] = (char)((cipher & 0x3f) + ' ');
|
|
|
|
/* Unmap 'bad' characters, that the Registry DB doesn't like. */
|
|
if (out[i]=='=' || out[i]==' ' || out[i]=='@' || out[i]=='"')
|
|
out[i] = 'M';
|
|
}
|
|
out[i] = '\0';
|
|
|
|
return out;
|
|
}
|
|
|
|
|
|
static char *stristr(char *src, char *word)
|
|
{
|
|
int len = strlen(word);
|
|
char *tmp = src;
|
|
|
|
while (*src) {
|
|
if (!_strnicmp(src, word, len))
|
|
break;
|
|
src++;
|
|
}
|
|
|
|
return src;
|
|
}
|
|
|
|
|
|
/***
|
|
** Function: GetCompany
|
|
**
|
|
** Description:
|
|
** Extract the company name out of a copyright string.
|
|
***/
|
|
char *GetCompany(char *buf)
|
|
{
|
|
char *company = NULL;
|
|
int done = FALSE;
|
|
UBYTE *token;
|
|
UBYTE *tmp1;
|
|
UBYTE *tmp2;
|
|
UBYTE *tmp3;
|
|
UBYTE *tmp4;
|
|
int i;
|
|
|
|
token = buf;
|
|
|
|
while (token && !done) {
|
|
|
|
/* Locate the start of the copyright string. */
|
|
tmp1 = stristr(token, "copyright");
|
|
tmp2 = stristr(token, "(c)");
|
|
tmp3 = stristr(token, " c ");
|
|
if ((tmp4 = strchr(token, COPYSIGN))==NULL)
|
|
tmp4 = &token[strlen(token)];
|
|
if (*tmp1==0 && *tmp2==0 && *tmp3==0 && *tmp4==0) {
|
|
token = NULL;
|
|
break;
|
|
} else if (tmp1<tmp2 && tmp1<tmp3 && tmp1<tmp4)
|
|
token = tmp1;
|
|
else if (tmp2<tmp3 && tmp2<tmp4)
|
|
token = tmp2;
|
|
else if (tmp3<tmp4)
|
|
token = tmp3;
|
|
else
|
|
token = tmp4;
|
|
|
|
/* Skip the leading copyright strings/character. */
|
|
if (token[0]==COPYSIGN && token[1]!='\0') {
|
|
token += 2;
|
|
} else if (!_strnicmp(token, "copyright", strlen("copyright"))) {
|
|
token += strlen("copyright");
|
|
} else {
|
|
token += strlen("(c)");
|
|
}
|
|
|
|
/* Skip blanks. */
|
|
while(*token && isspace(*token) || *token==',')
|
|
token++;
|
|
|
|
/* Another copyright word? */
|
|
if (!_strnicmp((char*)token, "(c)", strlen("(c)")) ||
|
|
!_strnicmp((char*)token, "copyright", strlen("copyright")) ||
|
|
token[0]==COPYSIGN)
|
|
continue;
|
|
|
|
/* Skip the years. */
|
|
company = token;
|
|
if (isdigit(token[0])) {
|
|
while (isdigit(*company) || isspace(*company) ||
|
|
ispunct(*company) || (*company)=='-')
|
|
company++;
|
|
|
|
if (*company=='\0')
|
|
break;
|
|
|
|
/* Skip strings like "by", up to the beginning of a name that */
|
|
/* starts with an upper case letter. */
|
|
while (*company && (company[0]<'A' || company[0]>'Z'))
|
|
company++;
|
|
|
|
done = TRUE;
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
/* Did we find it? */
|
|
if (company) {
|
|
while (*company && isspace(*company))
|
|
company++;
|
|
|
|
|
|
if (*company=='\0') {
|
|
company=NULL;
|
|
} else {
|
|
|
|
/* Terminate the company name. */
|
|
if ((token = (UBYTE*)strchr(company, '.'))!=NULL) {
|
|
|
|
/* Period as an initial delimiter, e.g. James, A. B. ?*/
|
|
if (token[-1]>='A' && token[-1]<='Z') {
|
|
if (strchr((char*)&token[1], '.'))
|
|
token = (UBYTE*)strchr((char*)&token[1], '.');
|
|
|
|
/* Check for "James A. Bently, " */
|
|
else if (strchr((char*)&token[1], ',')) {
|
|
token = (UBYTE*)strchr((char*)&token[1], ',');
|
|
token[0] = '.';
|
|
}
|
|
}
|
|
token[1] = '\0';
|
|
} else {
|
|
/* Name ending with a ';'? */
|
|
if ((token = (UBYTE*)strrchr(company, ';'))) {
|
|
*token = '\0';
|
|
}
|
|
}
|
|
|
|
/* Truncate some common strings. */
|
|
tmp1 = stristr(company, "all rights reserved");
|
|
*tmp1 = '\0';
|
|
|
|
/* Remove trailing punctuation character. */
|
|
for (i=strlen(company)-1; i>0 &&
|
|
(ispunct(company[i]) || isspace(company[i])); i--) {
|
|
company[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return company;
|
|
}
|
|
|
|
|
|
|
|
|
|
/**** FUNCTIONS */
|
|
|
|
/***
|
|
** Function: ConvertAnyway
|
|
**
|
|
** Description:
|
|
** Ask the user if it is ok to convert.
|
|
***/
|
|
static errcode ConvertAnyway(const char *vendor, const char *facename)
|
|
{
|
|
char tmp[256];
|
|
char msg[1024];
|
|
errcode answer;
|
|
|
|
if (vendor==NULL || strlen(vendor)==0) {
|
|
LoadString(hInst, IDS_RECOGNIZE1, tmp, sizeof(tmp));
|
|
sprintf(msg, tmp, facename);
|
|
} else {
|
|
LoadString(hInst, IDS_RECOGNIZE2, tmp, sizeof(tmp));
|
|
sprintf(msg, tmp, facename, vendor);
|
|
}
|
|
LoadString(hInst, IDS_MAINMSG, tmp, sizeof(tmp));
|
|
strcat(msg, tmp);
|
|
LoadString(hInst, IDS_CAPTION, tmp, sizeof(tmp));
|
|
answer = (errcode)MessageBox(NULL, msg, tmp, QUERY);
|
|
SetLastError(0);
|
|
|
|
return answer;
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
** Function: CheckCopyright
|
|
**
|
|
** Description:
|
|
** This is the callback function that verifies that
|
|
** the converted font is copyrighted by a company who
|
|
** has agreed to having their fonts converted by
|
|
** this software. These companies are registered in the
|
|
** registry data base.
|
|
***/
|
|
|
|
|
|
static errcode CheckCopyright(const char *facename,
|
|
const char *copyright,
|
|
const char *notice)
|
|
{
|
|
#ifdef NOCOPYRIGHTS
|
|
return SKIP;
|
|
#else
|
|
HKEY key;
|
|
char tmp[256];
|
|
char *company = NULL;
|
|
char buf[1024];
|
|
int done = FALSE;
|
|
short result = FAILURE;
|
|
|
|
|
|
/* Access the REG data base. */
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY_TYPE1COPYRIGHTS, 0,
|
|
KEY_QUERY_VALUE, &key)==ERROR_SUCCESS) {
|
|
|
|
|
|
/* Look for the company name in the /notice string. */
|
|
if (notice && notice[0]) {
|
|
strcpy(buf, notice);
|
|
company = GetCompany(buf);
|
|
}
|
|
|
|
/* Look in the /copyright string if the company name was not found. */
|
|
if (company==NULL && copyright && copyright[0]) {
|
|
strcpy(buf, copyright);
|
|
company = GetCompany(buf);
|
|
}
|
|
|
|
|
|
#ifdef SHOWCOPYRIGHTS
|
|
LogError(MSG_INFO, MSG_Copyright, company);
|
|
Encrypt(company, tmp);
|
|
sprintf(&tmp[strlen(tmp)], "(%d)\n", CSum(tmp));
|
|
LogError(MSG_INFO, MSG_Encoding, tmp);
|
|
#else
|
|
|
|
/* Did not find a company name? */
|
|
if (company==NULL &&
|
|
((notice==NULL || notice[0]=='\0'||
|
|
strstr(notice, "Copyright")==NULL) &&
|
|
(copyright==NULL || copyright[0]=='\0' ||
|
|
strstr(copyright, "Copyright")==NULL))) {
|
|
|
|
/* No known copyright. */
|
|
LogError(MSG_WARNING, MSG_NOCOPYRIGHT, NULL);
|
|
result = MAYBEOK;
|
|
|
|
/* Strange copyright format? */
|
|
} else if (company==NULL || company[0]=='\0') {
|
|
if (notice || notice[0])
|
|
LogError(MSG_WARNING, MSG_BADFORMAT, notice);
|
|
else
|
|
LogError(MSG_WARNING, MSG_BADFORMAT, copyright);
|
|
|
|
result = MAYBEOK;
|
|
|
|
/* Found copyright! */
|
|
} else {
|
|
DWORD size;
|
|
DWORD csum;
|
|
|
|
size = 4;
|
|
if (RegQueryValueEx(key, Encrypt(company, tmp), NULL, NULL,
|
|
(LPBYTE)&csum, &size)==ERROR_SUCCESS) {
|
|
|
|
/* A positive match -> ok to convert. */
|
|
if (CSum(tmp)==csum) {
|
|
LogError(MSG_INFO, MSG_COPYRIGHT, company);
|
|
result = SUCCESS;
|
|
} else {
|
|
LogError(MSG_ERROR, MSG_BADCOPYRIGHT, company);
|
|
result = SKIP;
|
|
}
|
|
} else {
|
|
LogError(MSG_WARNING, MSG_BADCOPYRIGHT, company);
|
|
result = MAYBEOK;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
RegCloseKey(key);
|
|
|
|
/* Give the user the final word. */
|
|
if (result==FAILURE) {
|
|
if (ConvertAnyway(company, facename)==TRUE)
|
|
result = SUCCESS;
|
|
}
|
|
|
|
|
|
/* No copyright key in the registry? */
|
|
} else {
|
|
LogError(MSG_ERROR, MSG_NODB, NULL);
|
|
result = FAILURE;
|
|
}
|
|
|
|
|
|
return result;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
** Function: NTCheckCopyright
|
|
**
|
|
** Description:
|
|
** This is the callback function that verifies that
|
|
** the converted font is copyrighted by a company who
|
|
** has agreed to having their fonts converted by
|
|
** this software. These companies are registered in the
|
|
** registry data base.
|
|
***/
|
|
static errcode NTCheckCopyright(const char *facename,
|
|
const char *copyright,
|
|
const char *notice)
|
|
{
|
|
HKEY key;
|
|
char tmp[256];
|
|
char *company = NULL;
|
|
char buf[1024];
|
|
int done = FALSE;
|
|
short result = FAILURE;
|
|
|
|
|
|
/* Access the REG data base. */
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, SUBKEY_TYPE1COPYRIGHTS, 0,
|
|
KEY_QUERY_VALUE, &key)==ERROR_SUCCESS) {
|
|
|
|
|
|
/* Look for the company name in the /notice string. */
|
|
if (notice && notice[0]) {
|
|
strcpy(buf, notice);
|
|
company = GetCompany(buf);
|
|
}
|
|
|
|
/* Look in the /copyright string if the company name was not found. */
|
|
if (company==NULL && copyright && copyright[0]) {
|
|
strcpy(buf, copyright);
|
|
company = GetCompany(buf);
|
|
}
|
|
|
|
/* Did not find a company name? */
|
|
if (company==NULL &&
|
|
((notice==NULL || notice[0]=='\0'||
|
|
strstr(notice, "Copyright")==NULL) &&
|
|
(copyright==NULL || copyright[0]=='\0' ||
|
|
strstr(copyright, "Copyright")==NULL))) {
|
|
|
|
/* No known copyright. */
|
|
result = MAYBE;
|
|
|
|
/* Strange copyright format? */
|
|
} else if (company==NULL || company[0]=='\0') {
|
|
result = MAYBE;
|
|
|
|
/* Found copyright! */
|
|
} else {
|
|
DWORD size;
|
|
DWORD csum;
|
|
|
|
/* remember for future use. */
|
|
strncpy(lastVendor, company, 256);
|
|
lastVendor[MIN(255, strlen(company))] = '\0';
|
|
|
|
size = 4;
|
|
if (RegQueryValueEx(key, Encrypt(company, tmp), NULL, NULL,
|
|
(LPBYTE)&csum, &size)==ERROR_SUCCESS) {
|
|
|
|
/* A positive match -> ok to convert. */
|
|
if (CSum(tmp)==csum) {
|
|
result = SUCCESS;
|
|
} else {
|
|
result = FAILURE;
|
|
}
|
|
} else {
|
|
result = MAYBE;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
|
|
|
|
/* No copyright key in the registry? */
|
|
} else {
|
|
result = FAILURE;
|
|
}
|
|
|
|
|
|
lastCP = result;
|
|
|
|
return FAILURE;
|
|
}
|
|
|
|
|
|
/***
|
|
** Function: _Progress
|
|
**
|
|
** Description:
|
|
** This is the internal progress callback function that
|
|
** computes an percentage-done number, based on the
|
|
** number of converted glyphs.
|
|
***/
|
|
static void _Progress(short type, void *generic, void *arg)
|
|
{
|
|
struct callFrame *f = arg;
|
|
|
|
/* Processing glyphs or wrapping up? */
|
|
if (type==0 || type==1)
|
|
f->done++;
|
|
else
|
|
f->done = MIN(sizeof(winmac)/sizeof(winmac[0]), f->done+10);
|
|
|
|
if ((f->done-f->last)>MIN_PROGRESS) {
|
|
f->Progress((short)(f->done*100/(sizeof(winmac)/sizeof(winmac[0]))),
|
|
f->arg);
|
|
f->last = f->done;
|
|
}
|
|
|
|
UNREFERENCED_PARAMETER(type);
|
|
UNREFERENCED_PARAMETER(generic);
|
|
SetLastError(0L);
|
|
}
|
|
|
|
static BOOL ReadStringFromOffset(struct ioFile *file,
|
|
const DWORD dwOffset,
|
|
char *pszString,
|
|
int cLen,
|
|
BOOL bStrip)
|
|
{
|
|
BOOL result = TRUE;
|
|
DWORD offset;
|
|
|
|
/* Get offset to string. */
|
|
io_FileSeek(file, dwOffset);
|
|
|
|
/* Read the offset. */
|
|
|
|
ReadLittleEndianDword(file, offset);
|
|
|
|
/* Get the string. */
|
|
(void)io_FileSeek(file, offset);
|
|
if (io_FileError(file) != SUCCESS) {
|
|
result = FALSE;
|
|
} else {
|
|
int i;
|
|
|
|
i=0;
|
|
while (io_FileError(file)==SUCCESS && i<cLen) {
|
|
pszString[i] = (UBYTE)io_ReadOneByte(file);
|
|
if (pszString[i]=='\0')
|
|
break;
|
|
|
|
/* Replace all dashes with spaces. */
|
|
if (bStrip && pszString[i]=='-')
|
|
pszString[i]=' ';
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
/**** FUNCTIONS */
|
|
|
|
/***
|
|
** Function: ConvertTypeFaceA
|
|
**
|
|
** Description:
|
|
** Convert a T1 font into a TT font file. This is the
|
|
** simplified interface used by the Win32 DLL, with the
|
|
** ANSI interface.
|
|
***/
|
|
short STDCALL ConvertTypefaceAInternal(const char *type1,
|
|
const char *metrics,
|
|
const char *truetype,
|
|
const void (STDCALL *Progress)(short, void*),
|
|
void *arg)
|
|
{
|
|
struct callFrame f;
|
|
struct callProgress p;
|
|
struct T1Arg t1Arg;
|
|
struct TTArg ttArg;
|
|
short status;
|
|
|
|
|
|
/* Check parameters. */
|
|
if (type1==NULL || metrics==NULL)
|
|
return FAILURE;
|
|
|
|
/* Set up arguments to ConvertTypefaceA() */
|
|
t1Arg.filter = GLYPHFILTER;
|
|
t1Arg.upem = (short)2048;
|
|
t1Arg.name = (char *)type1;
|
|
t1Arg.metrics = (char *)metrics;
|
|
ttArg.precision = (short)50;
|
|
ttArg.name = (char *)truetype;
|
|
ttArg.tag = VERSTR;
|
|
|
|
/* Use progress gauge */
|
|
if (Progress) {
|
|
LogError(MSG_INFO, MSG_STARTING, type1);
|
|
|
|
f.Progress = Progress;
|
|
f.done = 0;
|
|
f.last = 0;
|
|
f.arg = arg;
|
|
p.arg = &f;
|
|
p.cb = _Progress;
|
|
status = ConvertT1toTT(&ttArg, &t1Arg, CheckCopyright, &p);
|
|
Progress(100, arg);
|
|
} else {
|
|
status = ConvertT1toTT(&ttArg, &t1Arg, CheckCopyright, NULL);
|
|
}
|
|
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
short STDCALL ConvertTypefaceA(const char *type1,
|
|
const char *metrics,
|
|
const char *truetype,
|
|
const void (STDCALL *Progress)(short, void*),
|
|
void *arg)
|
|
{
|
|
|
|
short bRet;
|
|
|
|
try
|
|
{
|
|
bRet = ConvertTypefaceAInternal(type1,
|
|
metrics,
|
|
truetype,
|
|
Progress,
|
|
arg);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
#if 0
|
|
ASSERTGDI(
|
|
GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR,
|
|
"ttfd!ttfdSemLoadFontFile, strange exception code\n"
|
|
);
|
|
#endif
|
|
|
|
bRet = BADINPUTFILE;
|
|
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
short STDCALL FindPfb (
|
|
char *pszPFM,
|
|
char *achPFB
|
|
);
|
|
|
|
|
|
/***
|
|
** Function: CheckPfmA
|
|
**
|
|
** Description:
|
|
** This function determines if there is a pfm/pfb pair of
|
|
** files that makes up an Adobe Type 1 font, and determins
|
|
** the descriptive face name of it.
|
|
**
|
|
** Returns: 16-bit encoded value indicating error and type of file where
|
|
** error occurred. (see fvscodes.h) for definitions.
|
|
** The following table lists the "status" portion of the codes
|
|
** returned.
|
|
**
|
|
** FVS_SUCCESS
|
|
** FVS_INVALID_FONTFILE
|
|
** FVS_FILE_OPEN_ERR
|
|
** FVS_INVALID_ARG
|
|
** FVS_FILE_IO_ERR
|
|
** FVS_BAD_VERSION
|
|
***/
|
|
|
|
short STDCALL CheckPfmA(
|
|
char *pszPFM,
|
|
DWORD cjDesc,
|
|
char *pszDesc,
|
|
DWORD cjPFB,
|
|
char *pszPFB
|
|
)
|
|
{
|
|
struct ioFile *file;
|
|
char szDriver[MAX_PATH];
|
|
short result = FVS_MAKE_CODE(FVS_SUCCESS, FVS_FILE_UNK);
|
|
short ver;
|
|
|
|
char achPFB[MAX_PATH];
|
|
|
|
char *psz_PFB;
|
|
DWORD cjPFB1;
|
|
|
|
if (pszPFB)
|
|
{
|
|
psz_PFB = pszPFB;
|
|
cjPFB1 = cjPFB;
|
|
}
|
|
else
|
|
{
|
|
psz_PFB = (char *)achPFB;
|
|
cjPFB1 = MAX_PATH;
|
|
}
|
|
|
|
/* Check parameter. */
|
|
if (pszPFM==NULL || ((strlen(pszPFM)+3) >= cjPFB1))
|
|
return FVS_MAKE_CODE(FVS_INVALID_ARG, FVS_FILE_UNK);
|
|
|
|
// check if pfb file exists and find the path to it:
|
|
|
|
result = FindPfb(pszPFM, psz_PFB);
|
|
if (FVS_STATUS(result) != FVS_SUCCESS)
|
|
return result;
|
|
|
|
/****
|
|
* Locate the pszDescriptive name of the font.
|
|
*/
|
|
|
|
if ((file = io_OpenFile(pszPFM, READONLY))==NULL)
|
|
return FVS_MAKE_CODE(FVS_FILE_OPEN_ERR, FVS_FILE_PFM);
|
|
|
|
(void)io_ReadOneByte(file); /* Skip the revision number. */
|
|
ver = (short)io_ReadOneByte(file);
|
|
|
|
if (ver > 3) {
|
|
/* ERROR - unsupported format */
|
|
result = FVS_MAKE_CODE(FVS_BAD_VERSION, FVS_FILE_PFM);
|
|
} else {
|
|
|
|
/* Read the driver name. */
|
|
if (!ReadStringFromOffset(file, DFDRIVERINFO, szDriver,
|
|
sizeof(szDriver), FALSE))
|
|
{
|
|
result = FVS_MAKE_CODE(FVS_FILE_IO_ERR, FVS_FILE_PFM);
|
|
}
|
|
/* Is it "PostScript" ? */
|
|
else if (_stricmp(szDriver, "PostScript"))
|
|
{
|
|
result = FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_PFM);
|
|
}
|
|
/* Only get description if asked to do so. */
|
|
else if (pszDesc && !ReadStringFromOffset(file, DFFACE, pszDesc, cjDesc, TRUE))
|
|
{
|
|
result = FVS_MAKE_CODE(FVS_FILE_IO_ERR, FVS_FILE_PFM);
|
|
}
|
|
}
|
|
|
|
(void)io_CloseFile(file);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/***
|
|
** Function: DllMain
|
|
**
|
|
** Description:
|
|
** Main function of the DLL. Use to cache the module handle,
|
|
** which is needed to pop-up messages and peek in the registry.
|
|
***/
|
|
BOOL WINAPI DllMain(PVOID hmod,
|
|
ULONG ulReason,
|
|
PCONTEXT pctx OPTIONAL)
|
|
{
|
|
if (ulReason == DLL_PROCESS_ATTACH) {
|
|
hInst = hmod;
|
|
DisableThreadLibraryCalls(hInst);
|
|
}
|
|
|
|
|
|
UNREFERENCED_PARAMETER(pctx);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***
|
|
** Function: CheckCopyrightsA
|
|
**
|
|
** Description:
|
|
** This function verifies that it is ok to convert the font. This is
|
|
** done by faking an installation.
|
|
***/
|
|
short STDCALL CheckCopyrightAInternal(const char *szPFB,
|
|
const DWORD wSize,
|
|
char *szVendor)
|
|
{
|
|
struct T1Arg t1Arg;
|
|
struct TTArg ttArg;
|
|
|
|
/* Set up arguments to ConvertTypefaceA() */
|
|
t1Arg.metrics = NULL;
|
|
t1Arg.upem = (short)2048;
|
|
t1Arg.filter = GLYPHFILTER;
|
|
t1Arg.name = szPFB;
|
|
ttArg.precision = (short)200;
|
|
ttArg.tag = NULL;
|
|
ttArg.name = "NIL:";
|
|
lastCP = FAILURE;
|
|
strcpy(lastVendor, "");
|
|
(void)ConvertT1toTT(&ttArg, &t1Arg, NTCheckCopyright, NULL);
|
|
strncpy(szVendor, lastVendor, wSize);
|
|
szVendor[MIN(wSize, strlen(lastVendor))] = '\0';
|
|
|
|
return lastCP;
|
|
}
|
|
|
|
|
|
short STDCALL CheckCopyrightA(const char *szPFB,
|
|
const DWORD wSize,
|
|
char *szVendor)
|
|
{
|
|
short iRet;
|
|
|
|
try
|
|
{
|
|
iRet = CheckCopyrightAInternal(szPFB,wSize,szVendor);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
iRet = BADINPUTFILE;
|
|
}
|
|
return iRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* short STDCALL CheckInfA (
|
|
*
|
|
* If pfm and inf files are in the same directory only pfm is recognized
|
|
* and inf file is ignored.
|
|
*
|
|
* History:
|
|
* 27-Apr-1994 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
*
|
|
* Returns: 16-bit encoded value indicating error and type of file where
|
|
* error occurred. (see fvscodes.h) for definitions.
|
|
* The following table lists the "status" portion of the codes
|
|
* returned.
|
|
*
|
|
* FVS_SUCCESS
|
|
* FVS_INVALID_FONTFILE
|
|
* FVS_FILE_OPEN_ERR
|
|
* FVS_FILE_BUILD_ERR
|
|
* FVS_FILE_EXISTS
|
|
* FVS_INSUFFICIENT_BUF
|
|
*
|
|
\**************************************************************************/
|
|
|
|
|
|
short CreatePFM(char *pszINF, char *pszAFM, char *pszPFM);
|
|
BOOL bGetDescFromInf(char * pszINF, DWORD cjDesc, char *pszDesc);
|
|
|
|
BOOL bFileExists(char *pszFile)
|
|
{
|
|
HFILE hf;
|
|
|
|
if ((hf = _lopen(pszFile, OF_READ)) != -1)
|
|
{
|
|
_lclose(hf);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
short STDCALL CheckInfA (
|
|
char *pszINF,
|
|
DWORD cjDesc,
|
|
char *pszDesc,
|
|
DWORD cjPFM,
|
|
char *pszPFM,
|
|
DWORD cjPFB,
|
|
char *pszPFB,
|
|
BOOL *pbCreatedPFM,
|
|
char *pszFontPath
|
|
)
|
|
{
|
|
char achPFM[MAX_PATH];
|
|
char achPFB[MAX_PATH];
|
|
char achAFM[MAX_PATH];
|
|
|
|
DWORD cjKey;
|
|
char *pszParent = NULL; // points to the where parent dir of the inf file is
|
|
char *pszBare = NULL; // "bare" .inf name, initialization essential
|
|
short result = FVS_MAKE_CODE(FVS_SUCCESS, FVS_FILE_UNK);
|
|
BOOL bAfmExists = FALSE;
|
|
BOOL bPfbExists = FALSE;
|
|
|
|
//
|
|
// This is a real hack use of pbCreatedPFM.
|
|
// It's the best solution with the time we have.
|
|
//
|
|
BOOL bCheckForExistingPFM = *pbCreatedPFM;
|
|
|
|
*pbCreatedPFM = FALSE;
|
|
|
|
// example:
|
|
// if pszINF -> "c:\psfonts\fontinfo\foo_____.inf"
|
|
// then pszParent -> "fontinfo\foo_____.inf"
|
|
|
|
cjKey = strlen(pszINF) + 1;
|
|
|
|
if (cjKey < 5) // 5 = strlen(".pfm") + 1;
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_INF);
|
|
|
|
// check if a pfm file exists in the SAME directory.
|
|
// Use the buffer on the stack to produce the path for the pfm file:
|
|
|
|
strcpy(achPFM, pszINF);
|
|
strcpy(&achPFM[cjKey - 5],".PFM");
|
|
|
|
// try to open pfm file to check if it exists:
|
|
|
|
if (bCheckForExistingPFM && bFileExists(achPFM))
|
|
{
|
|
// we found the pfm file, therefore we do not report this .inf file.
|
|
|
|
return FVS_MAKE_CODE(FVS_FILE_EXISTS, FVS_FILE_PFM);
|
|
}
|
|
|
|
// pfm file is NOT found, go on to check if .afm and .pfb files exists:
|
|
// We will first check if .afm and .pfb files exists in the same dir as .inf
|
|
|
|
strcpy(achAFM, pszINF);
|
|
strcpy(&achAFM[cjKey - 5],".AFM");
|
|
|
|
strcpy(achPFB, pszINF);
|
|
strcpy(&achPFB[cjKey - 5],".PFB");
|
|
|
|
bAfmExists = bFileExists(achAFM);
|
|
bPfbExists = bFileExists(achPFB);
|
|
|
|
if (!bAfmExists || !bPfbExists)
|
|
{
|
|
// we did not find the .afm and .pfb files in the same dir as .inf
|
|
// we will check two more directories for the .afm and .pfb files
|
|
// 1) the parent directory of the .inf file for .pfb file
|
|
// 2) the afm subdirectory of the .inf parent directory for .afm file
|
|
//
|
|
// This is meant to handle the standard configuration of files produced
|
|
// on user's hard drive by unlocking fonts from Adobe's CD or from a
|
|
// previous installation of atm manager on this machine.
|
|
// This configuration is as follows:
|
|
// c:\psfonts\ *.pfb files are here
|
|
// c:\psfonts\afm *.afm files are here
|
|
// c:\psfonts\fontinfo *.inf files are here
|
|
// c:\psfonts\pfm *.pfm files that are created on the fly
|
|
// are PUT here by atm.
|
|
// We will instead put the files in windows\system dir where all other
|
|
// fonts are, it may not be possible to write pmf files on the media
|
|
// from where we are installing fonts
|
|
|
|
pszBare = &pszINF[cjKey - 5];
|
|
for ( ; pszBare > pszINF; pszBare--)
|
|
{
|
|
if ((*pszBare == '\\') || (*pszBare == ':'))
|
|
{
|
|
pszBare++; // found it
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check if full path to .inf file was passed in or a bare
|
|
// name itself was passed in to look for .inf file in the current dir
|
|
|
|
if ((pszBare > pszINF) && (pszBare[-1] == '\\'))
|
|
{
|
|
// skip '\\' and search backwards for another '\\':
|
|
|
|
for (pszParent = &pszBare[-2]; pszParent > pszINF; pszParent--)
|
|
{
|
|
if ((*pszParent == '\\') || (*pszParent == ':'))
|
|
{
|
|
pszParent++; // found it
|
|
break;
|
|
}
|
|
}
|
|
|
|
// create .pfb file name in the .inf parent directory:
|
|
|
|
strcpy(&achPFB[pszParent - pszINF], pszBare);
|
|
strcpy(&achPFB[strlen(achPFB) - 4], ".PFB");
|
|
|
|
// create .afm file name in the afm subdirectory of the .inf
|
|
// parent directory:
|
|
|
|
strcpy(&achAFM[pszParent - pszINF], "afm\\");
|
|
strcpy(&achAFM[pszParent - pszINF + 4], pszBare);
|
|
strcpy(&achAFM[strlen(achAFM) - 4], ".AFM");
|
|
|
|
}
|
|
else if (pszBare == pszINF)
|
|
{
|
|
// bare name was passed in, to check for the inf file in the "." dir:
|
|
|
|
strcpy(achPFB, "..\\");
|
|
strcpy(&achPFB[3], pszBare); // 3 == strlen("..\\")
|
|
strcpy(&achPFB[strlen(achPFB) - 4], ".PFB");
|
|
|
|
strcpy(achAFM, "..\\afm\\");
|
|
strcpy(&achAFM[7], pszBare); // 7 == strlen("..\\afm\\")
|
|
strcpy(&achAFM[strlen(achAFM) - 4], ".AFM");
|
|
}
|
|
else
|
|
{
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_UNK);
|
|
}
|
|
|
|
// check again if we can find the files, if not fail.
|
|
|
|
if (!bAfmExists && !bFileExists(achAFM))
|
|
return FVS_MAKE_CODE(FVS_FILE_OPEN_ERR, FVS_FILE_AFM);
|
|
if (!bPfbExists && !bFileExists(achPFB))
|
|
return FVS_MAKE_CODE(FVS_FILE_OPEN_ERR, FVS_FILE_PFB);
|
|
}
|
|
|
|
// now we have paths to .inf .afm and .pfb files. Now let us see
|
|
// what the caller wants from us:
|
|
|
|
if (pszDesc)
|
|
{
|
|
// we need to return description string in the buffer supplied
|
|
|
|
if (!bGetDescFromInf(pszINF, (DWORD)cjDesc, pszDesc))
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_INF);
|
|
}
|
|
|
|
// copy pfb file path out if requested
|
|
|
|
if (pszPFB)
|
|
{
|
|
if ((strlen(achPFB) + 1) < cjPFB)
|
|
strcpy(pszPFB,achPFB);
|
|
else
|
|
return FVS_MAKE_CODE(FVS_INSUFFICIENT_BUF, FVS_FILE_UNK);
|
|
}
|
|
|
|
// the caller wants a pfm file created from inf,afm files
|
|
// For now and probably for ever we will put this file in
|
|
// the %windir%\system, or %windir%\fonts for the secure system.
|
|
|
|
if (pszPFM)
|
|
{
|
|
UINT cjSystemDir;
|
|
char *pszAppendHere; // append "bare" name here
|
|
|
|
// copy the first directory of the font path into the buffer provided
|
|
// It is expected that this routine will get something like
|
|
// "c:\foo" pointing to font path
|
|
|
|
strcpy(achPFM,pszFontPath);
|
|
pszAppendHere = &achPFM[strlen(pszFontPath) - 1];
|
|
|
|
if (*pszAppendHere != '\\')
|
|
{
|
|
pszAppendHere++;
|
|
*pszAppendHere = '\\';
|
|
}
|
|
pszAppendHere++;
|
|
|
|
// find bare name of the .inf file if we do not have already:
|
|
|
|
if (!pszBare)
|
|
{
|
|
pszBare = &pszINF[cjKey - 5];
|
|
for ( ; pszBare > pszINF; pszBare--)
|
|
{
|
|
if ((*pszBare == '\\') || (*pszBare == ':'))
|
|
{
|
|
pszBare++; // found it
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// append Bare name to the %windir%system\ path
|
|
|
|
strcpy(pszAppendHere, pszBare);
|
|
|
|
// finally change .inf extension to .pfm extension
|
|
|
|
strcpy(&pszAppendHere[strlen(pszAppendHere) - 4], ".PFM");
|
|
|
|
// copy out:
|
|
|
|
strcpy(pszPFM, achPFM);
|
|
|
|
result = CreatePFM(pszINF, achAFM, pszPFM);
|
|
*pbCreatedPFM = (FVS_STATUS(result) == FVS_SUCCESS);
|
|
|
|
if (!(*pbCreatedPFM))
|
|
return result;
|
|
}
|
|
|
|
return FVS_MAKE_CODE(FVS_SUCCESS, FVS_FILE_UNK);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* short STDCALL CheckType1AInternal
|
|
*
|
|
* Effects: See if we are going to report this as a valid type 1 font
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
* 29-Apr-1994 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
*
|
|
* Returns: 16-bit encoded value indicating error and type of file where
|
|
* error occurred. (see fvscodes.h) for definitions.
|
|
* The following table lists the "status" portion of the codes
|
|
* returned.
|
|
*
|
|
* FVS_SUCCESS
|
|
* FVS_INVALID_FONTFILE
|
|
* FVS_FILE_OPEN_ERR
|
|
* FVS_FILE_BUILD_ERR
|
|
* FVS_INVALID_ARG
|
|
* FVS_FILE_IO_ERR
|
|
* FVS_BAD_VERSION
|
|
* FVS_FILE_EXISTS
|
|
* FVS_INSUFFICIENT_BUF
|
|
*
|
|
\**************************************************************************/
|
|
|
|
|
|
short STDCALL CheckType1AInternal (
|
|
char *pszKeyFile,
|
|
DWORD cjDesc,
|
|
char *pszDesc,
|
|
DWORD cjPFM,
|
|
char *pszPFM,
|
|
DWORD cjPFB,
|
|
char *pszPFB,
|
|
BOOL *pbCreatedPFM,
|
|
char *pszFontPath
|
|
|
|
)
|
|
{
|
|
DWORD cjKey;
|
|
|
|
*pbCreatedPFM = FALSE; // initialization is essential.
|
|
|
|
cjKey = strlen(pszKeyFile) + 1;
|
|
|
|
if (cjKey < 5) // 5 = strlen(".pfm") + 1;
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_UNK);
|
|
|
|
if (!_strcmpi(&pszKeyFile[cjKey - 5], ".PFM"))
|
|
{
|
|
// copy out pfm string when asked to do so:
|
|
|
|
if (pszPFM && (cjKey < cjPFM))
|
|
{
|
|
if (cjKey < cjPFM)
|
|
strcpy(pszPFM, pszKeyFile);
|
|
else
|
|
return FVS_MAKE_CODE(FVS_INSUFFICIENT_BUF, FVS_FILE_UNK);
|
|
}
|
|
|
|
return CheckPfmA(
|
|
pszKeyFile,
|
|
cjDesc,
|
|
pszDesc,
|
|
cjPFB,
|
|
pszPFB
|
|
);
|
|
}
|
|
else if (!_strcmpi(&pszKeyFile[cjKey - 5], ".INF"))
|
|
{
|
|
return CheckInfA (
|
|
pszKeyFile,
|
|
cjDesc,
|
|
pszDesc,
|
|
cjPFM,
|
|
pszPFM,
|
|
cjPFB,
|
|
pszPFB,
|
|
pbCreatedPFM,
|
|
pszFontPath
|
|
);
|
|
}
|
|
else
|
|
{
|
|
// this font is not our friend
|
|
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_UNK);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* CheckType1WithStatusA, try / except wrapper
|
|
*
|
|
* Effects:
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
* 14-Jun-1994 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
*
|
|
* Returns: 16-bit encoded value indicating error and type of file where
|
|
* error occurred. (see fvscodes.h) for definitions.
|
|
* The following table lists the "status" portion of the codes
|
|
* returned.
|
|
*
|
|
* FVS_SUCCESS
|
|
* FVS_INVALID_FONTFILE
|
|
* FVS_FILE_OPEN_ERR
|
|
* FVS_FILE_BUILD_ERR
|
|
* FVS_INVALID_ARG
|
|
* FVS_FILE_IO_ERR
|
|
* FVS_BAD_VERSION
|
|
* FVS_FILE_EXISTS
|
|
* FVS_INSUFFICIENT_BUF
|
|
* FVS_EXCEPTION
|
|
*
|
|
\**************************************************************************/
|
|
|
|
short STDCALL CheckType1WithStatusA (
|
|
char *pszKeyFile,
|
|
DWORD cjDesc,
|
|
char *pszDesc,
|
|
DWORD cjPFM,
|
|
char *pszPFM,
|
|
DWORD cjPFB,
|
|
char *pszPFB,
|
|
BOOL *pbCreatedPFM,
|
|
char *pszFontPath
|
|
)
|
|
{
|
|
short status;
|
|
try
|
|
{
|
|
status = CheckType1AInternal (
|
|
pszKeyFile,
|
|
cjDesc,
|
|
pszDesc,
|
|
cjPFM,
|
|
pszPFM,
|
|
cjPFB,
|
|
pszPFB,
|
|
pbCreatedPFM,
|
|
pszFontPath);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
status = FVS_MAKE_CODE(FVS_EXCEPTION, FVS_FILE_UNK);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* CheckType1A, try / except wrapper
|
|
*
|
|
* Effects:
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
* 14-Jun-1994 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL STDCALL CheckType1A (
|
|
char *pszKeyFile,
|
|
DWORD cjDesc,
|
|
char *pszDesc,
|
|
DWORD cjPFM,
|
|
char *pszPFM,
|
|
DWORD cjPFB,
|
|
char *pszPFB,
|
|
BOOL *pbCreatedPFM,
|
|
char *pszFontPath
|
|
)
|
|
{
|
|
short status = CheckType1WithStatusA(pszKeyFile,
|
|
cjDesc,
|
|
pszDesc,
|
|
cjPFM,
|
|
pszPFM,
|
|
cjPFB,
|
|
pszPFB,
|
|
pbCreatedPFM,
|
|
pszFontPath);
|
|
|
|
return (FVS_STATUS(status) == FVS_SUCCESS);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* FindPfb, given pfm file, see if pfb file exists in the same dir or in the
|
|
* parent directory of the pfm file
|
|
*
|
|
* History:
|
|
* 14-Jun-1994 -by- Bodin Dresevic [BodinD]
|
|
* Wrote it.
|
|
*
|
|
* Returns: 16-bit encoded value indicating error and type of file where
|
|
* error occurred. (see fvscodes.h) for definitions.
|
|
* The following table lists the "status" portion of the codes
|
|
* returned.
|
|
*
|
|
* FVS_SUCCESS
|
|
* FVS_INVALID_FONTFILE
|
|
* FVS_FILE_OPEN_ERR
|
|
*
|
|
\**************************************************************************/
|
|
|
|
|
|
short STDCALL FindPfb (
|
|
char *pszPFM,
|
|
char *achPFB
|
|
)
|
|
{
|
|
DWORD cjKey;
|
|
char *pszParent = NULL; // points to the where parent dir of the inf file is
|
|
char *pszBare = NULL; // "bare" .inf name, initialization essential
|
|
|
|
// example:
|
|
// if pszPFM -> "c:\psfonts\pfm\foo_____.pfm"
|
|
// then pszParent -> "pfm\foo_____.pfm"
|
|
|
|
cjKey = strlen(pszPFM) + 1;
|
|
|
|
if (cjKey < 5) // 5 = strlen(".pfm") + 1;
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_PFM);
|
|
|
|
// go on to check if .pfb file exists:
|
|
// We will first check .pfb file exists in the same dir as .pfm
|
|
|
|
strcpy(achPFB, pszPFM);
|
|
strcpy(&achPFB[cjKey - 5],".PFB");
|
|
|
|
if (!bFileExists(achPFB))
|
|
{
|
|
// we did not find the .pfb file in the same dir as .pfm
|
|
// Now check the parent directory of the .pfm file
|
|
|
|
pszBare = &pszPFM[cjKey - 5];
|
|
for ( ; pszBare > pszPFM; pszBare--)
|
|
{
|
|
if ((*pszBare == '\\') || (*pszBare == ':'))
|
|
{
|
|
pszBare++; // found it
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check if full path to .pfm was passed in or a bare
|
|
// name itself was passed in to look for .pfm file in the current dir
|
|
|
|
if ((pszBare > pszPFM) && (pszBare[-1] == '\\'))
|
|
{
|
|
// skip '\\' and search backwards for another '\\':
|
|
|
|
for (pszParent = &pszBare[-2]; pszParent > pszPFM; pszParent--)
|
|
{
|
|
if ((*pszParent == '\\') || (*pszParent == ':'))
|
|
{
|
|
pszParent++; // found it
|
|
break;
|
|
}
|
|
}
|
|
|
|
// create .pfb file name in the .pfm parent directory:
|
|
|
|
strcpy(&achPFB[pszParent - pszPFM], pszBare);
|
|
strcpy(&achPFB[strlen(achPFB) - 4], ".PFB");
|
|
|
|
}
|
|
else if (pszBare == pszPFM)
|
|
{
|
|
// bare name was passed in, to check for the inf file in the "." dir:
|
|
|
|
strcpy(achPFB, "..\\");
|
|
strcpy(&achPFB[3], pszBare); // 3 == strlen("..\\")
|
|
strcpy(&achPFB[strlen(achPFB) - 4], ".PFB");
|
|
}
|
|
else
|
|
{
|
|
return FVS_MAKE_CODE(FVS_INVALID_FONTFILE, FVS_FILE_PFM); // We should never get here.
|
|
}
|
|
|
|
// check again if we can find the file, if not fail.
|
|
|
|
if (!bFileExists(achPFB))
|
|
{
|
|
return FVS_MAKE_CODE(FVS_FILE_OPEN_ERR, FVS_FILE_PFB);
|
|
}
|
|
}
|
|
|
|
// now we have paths to .pfb file in the buffer provided by the caller.
|
|
|
|
return FVS_MAKE_CODE(FVS_SUCCESS, FVS_FILE_UNK);
|
|
}
|