Commit 91857a6c authored by Ian Pilcher's avatar Ian Pilcher Committed by Alexandre Julliard

Misc. error checking in PostScript driver.

parent ce7f12c4
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#include "winnt.h" /* HEAP_ZERO_MEMORY */ #include <limits.h> /* INT_MIN */
#include <float.h> /* FLT_MAX */
#include "winnt.h" /* HEAP_ZERO_MEMORY */
#include "psdrv.h" #include "psdrv.h"
#include "options.h" #include "options.h"
#include "debugtools.h" #include "debugtools.h"
...@@ -22,6 +24,58 @@ DEFAULT_DEBUG_CHANNEL(psdrv); ...@@ -22,6 +24,58 @@ DEFAULT_DEBUG_CHANNEL(psdrv);
/* ptr to fonts for which we have afm files */ /* ptr to fonts for which we have afm files */
FONTFAMILY *PSDRV_AFMFontList = NULL; FONTFAMILY *PSDRV_AFMFontList = NULL;
/*******************************************************************************
* CheckMetrics
*
* Check an AFMMETRICS structure to make sure all elements have been properly
* filled in.
*
*/
static const AFMMETRICS badMetrics =
{
INT_MIN, /* C */
FLT_MAX, /* WX */
NULL, /* N */
{ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX }, /* B */
NULL /* L */
};
inline static BOOL CheckMetrics(const AFMMETRICS *metrics)
{
if ( metrics->C == badMetrics.C ||
metrics->WX == badMetrics.WX ||
metrics->N == badMetrics.N ||
metrics->B.llx == badMetrics.B.llx ||
metrics->B.lly == badMetrics.B.lly ||
metrics->B.urx == badMetrics.B.urx ||
metrics->B.ury == badMetrics.B.ury )
return FALSE;
return TRUE;
}
/*******************************************************************************
* FreeAFM
*
* Free an AFM structure and any subsidiary objects that have been allocated
*
*/
static void FreeAFM(AFM *afm)
{
if (afm->FontName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FontName);
if (afm->FullName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FullName);
if (afm->FamilyName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FamilyName);
if (afm->EncodingScheme != NULL)
HeapFree(PSDRV_Heap, 0, afm->EncodingScheme);
if (afm->Metrics != NULL)
HeapFree(PSDRV_Heap, 0, afm->Metrics);
HeapFree(PSDRV_Heap, 0, afm);
}
/*********************************************************** /***********************************************************
* *
...@@ -32,21 +86,28 @@ FONTFAMILY *PSDRV_AFMFontList = NULL; ...@@ -32,21 +86,28 @@ FONTFAMILY *PSDRV_AFMFontList = NULL;
* Actually only collects the widths of numbered chars and puts then in * Actually only collects the widths of numbered chars and puts then in
* afm->CharWidths. * afm->CharWidths.
*/ */
static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp) static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
{ {
unsigned char line[256], valbuf[256]; unsigned char line[256], valbuf[256];
unsigned char *cp, *item, *value, *curpos, *endpos; unsigned char *cp, *item, *value, *curpos, *endpos;
int i; int i;
AFMMETRICS *metric; AFMMETRICS *metric;
afm->Metrics = metric = HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, afm->Metrics = metric = HeapAlloc( PSDRV_Heap, 0,
afm->NumofMetrics * sizeof(AFMMETRICS) ); afm->NumofMetrics * sizeof(AFMMETRICS) );
if (metric == NULL)
return FALSE;
for(i = 0; i < afm->NumofMetrics; i++, metric++) { for(i = 0; i < afm->NumofMetrics; i++, metric++) {
*metric = badMetrics;
do { do {
if(!fgets(line, sizeof(line), fp)) { if(!fgets(line, sizeof(line), fp)) {
ERR("Unexpected EOF\n"); ERR("Unexpected EOF\n");
return; HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
return FALSE;
} }
cp = line + strlen(line); cp = line + strlen(line);
do { do {
...@@ -61,11 +122,21 @@ static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp) ...@@ -61,11 +122,21 @@ static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
while(isspace(*item)) while(isspace(*item))
item++; item++;
value = strpbrk(item, " \t"); value = strpbrk(item, " \t");
if (!value) { ERR("No whitespace found.\n");return;} if (!value) {
ERR("No whitespace found.\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
return FALSE;
}
while(isspace(*value)) while(isspace(*value))
value++; value++;
cp = endpos = strchr(value, ';'); cp = endpos = strchr(value, ';');
if (!cp) { ERR("missing ;, failed. [%s]\n", line); return; } if (!cp) {
ERR("missing ;, failed. [%s]\n", line);
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
return FALSE;
}
while(isspace(*--cp)) while(isspace(*--cp))
; ;
memcpy(valbuf, value, cp - value + 1); memcpy(valbuf, value, cp - value + 1);
...@@ -104,13 +175,20 @@ static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp) ...@@ -104,13 +175,20 @@ static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
curpos = endpos + 1; curpos = endpos + 1;
} }
if (CheckMetrics(metric) == FALSE) {
ERR("Error parsing character metrics\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
return FALSE;
}
TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n", TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n",
metric->N->sz, metric->WX, metric->B.llx, metric->B.lly, metric->N->sz, metric->WX, metric->B.llx, metric->B.lly,
metric->B.urx, metric->B.ury); metric->B.urx, metric->B.ury);
} }
return; return TRUE;
} }
/*********************************************************** /***********************************************************
...@@ -123,6 +201,7 @@ static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp) ...@@ -123,6 +201,7 @@ static void PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
* *
* This is not complete (we don't handle kerning yet) and not efficient * This is not complete (we don't handle kerning yet) and not efficient
*/ */
static AFM *PSDRV_AFMParse(char const *file) static AFM *PSDRV_AFMParse(char const *file)
{ {
FILE *fp; FILE *fp;
...@@ -178,16 +257,31 @@ static AFM *PSDRV_AFMParse(char const *file) ...@@ -178,16 +257,31 @@ static AFM *PSDRV_AFMParse(char const *file)
if(!strncmp("FontName", buf, 8)) { if(!strncmp("FontName", buf, 8)) {
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, value); afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FontName == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
if(!strncmp("FullName", buf, 8)) { if(!strncmp("FullName", buf, 8)) {
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, value); afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FullName == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
if(!strncmp("FamilyName", buf, 10)) { if(!strncmp("FamilyName", buf, 10)) {
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, value); afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FamilyName == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
...@@ -264,12 +358,21 @@ static AFM *PSDRV_AFMParse(char const *file) ...@@ -264,12 +358,21 @@ static AFM *PSDRV_AFMParse(char const *file)
if(!strncmp("StartCharMetrics", buf, 16)) { if(!strncmp("StartCharMetrics", buf, 16)) {
sscanf(value, "%d", &(afm->NumofMetrics) ); sscanf(value, "%d", &(afm->NumofMetrics) );
PSDRV_AFMGetCharMetrics(afm, fp); if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
if(!strncmp("EncodingScheme", buf, 14)) { if(!strncmp("EncodingScheme", buf, 14)) {
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, value); afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->EncodingScheme == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
...@@ -284,11 +387,21 @@ static AFM *PSDRV_AFMParse(char const *file) ...@@ -284,11 +387,21 @@ static AFM *PSDRV_AFMParse(char const *file)
if(afm->FontName == NULL) { if(afm->FontName == NULL) {
WARN("%s contains no FontName.\n", file); WARN("%s contains no FontName.\n", file);
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, "nofont"); afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, "nofont");
if (afm->FontName == NULL) {
FreeAFM(afm);
return NULL;
}
} }
if(afm->FullName == NULL) if(afm->FullName == NULL)
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName); afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
if(afm->FamilyName == NULL) if(afm->FamilyName == NULL)
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName); afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
if (afm->FullName == NULL || afm->FamilyName == NULL) {
FreeAFM(afm);
return NULL;
}
if(afm->Ascender == 0.0) if(afm->Ascender == 0.0)
afm->Ascender = afm->FontBBox.ury; afm->Ascender = afm->FontBBox.ury;
if(afm->Descender == 0.0) if(afm->Descender == 0.0)
...@@ -351,7 +464,7 @@ AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name) ...@@ -351,7 +464,7 @@ AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
* Adds an afm to the list whose head is pointed to by head. Creates new * Adds an afm to the list whose head is pointed to by head. Creates new
* family node if necessary and always creates a new AFMLISTENTRY. * family node if necessary and always creates a new AFMLISTENTRY.
*/ */
void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm) BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
{ {
FONTFAMILY *family = *head; FONTFAMILY *family = *head;
FONTFAMILY **insert = head; FONTFAMILY **insert = head;
...@@ -359,6 +472,9 @@ void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm) ...@@ -359,6 +472,9 @@ void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
newafmle = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY, newafmle = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY,
sizeof(*newafmle)); sizeof(*newafmle));
if (newafmle == NULL)
return FALSE;
newafmle->afm = afm; newafmle->afm = afm;
while(family) { while(family) {
...@@ -371,11 +487,20 @@ void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm) ...@@ -371,11 +487,20 @@ void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
if(!family) { if(!family) {
family = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY, family = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY,
sizeof(*family)); sizeof(*family));
if (family == NULL) {
HeapFree(PSDRV_Heap, 0, newafmle);
return FALSE;
}
*insert = family; *insert = family;
family->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, family->FamilyName = HEAP_strdupA(PSDRV_Heap, 0,
afm->FamilyName); afm->FamilyName);
if (family->FamilyName == NULL) {
HeapFree(PSDRV_Heap, 0, family);
HeapFree(PSDRV_Heap, 0, newafmle);
return FALSE;
}
family->afmlist = newafmle; family->afmlist = newafmle;
return; return TRUE;
} }
tmpafmle = family->afmlist; tmpafmle = family->afmlist;
...@@ -384,7 +509,7 @@ void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm) ...@@ -384,7 +509,7 @@ void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
tmpafmle->next = newafmle; tmpafmle->next = newafmle;
return; return TRUE;
} }
/********************************************************** /**********************************************************
...@@ -446,11 +571,13 @@ static void PSDRV_DumpFontList(void) ...@@ -446,11 +571,13 @@ static void PSDRV_DumpFontList(void)
* *
* PSDRV_GetFontMetrics * PSDRV_GetFontMetrics
* *
* Only exported function in this file. Parses all afm files listed in * Parses all afm files listed in [afmfiles] and [afmdirs] of wine.conf
* [afmfiles] and [afmdirs] of wine.conf . *
* If this function fails, PSDRV_Init will destroy PSDRV_Heap, so don't worry
* about freeing all the memory that's been allocated.
*/ */
static void PSDRV_ReadAFMDir(const char* afmdir) { static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
DIR *dir; DIR *dir;
AFM *afm; AFM *afm;
...@@ -461,7 +588,12 @@ static void PSDRV_ReadAFMDir(const char* afmdir) { ...@@ -461,7 +588,12 @@ static void PSDRV_ReadAFMDir(const char* afmdir) {
if (strstr(dent->d_name,".afm")) { if (strstr(dent->d_name,".afm")) {
char *afmfn; char *afmfn;
afmfn=(char*)HeapAlloc(GetProcessHeap(),0,strlen(afmdir)+strlen(dent->d_name)+2); afmfn=(char*)HeapAlloc(PSDRV_Heap,0,
strlen(afmdir)+strlen(dent->d_name)+2);
if (afmfn == NULL) {
closedir(dir);
return FALSE;
}
strcpy(afmfn,afmdir); strcpy(afmfn,afmdir);
strcat(afmfn,"/"); strcat(afmfn,"/");
strcat(afmfn,dent->d_name); strcat(afmfn,dent->d_name);
...@@ -472,13 +604,25 @@ static void PSDRV_ReadAFMDir(const char* afmdir) { ...@@ -472,13 +604,25 @@ static void PSDRV_ReadAFMDir(const char* afmdir) {
!strcmp(afm->EncodingScheme,"AdobeStandardEncoding")) { !strcmp(afm->EncodingScheme,"AdobeStandardEncoding")) {
PSDRV_ReencodeCharWidths(afm); PSDRV_ReencodeCharWidths(afm);
} }
PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm); if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
closedir(dir);
FreeAFM(afm);
return FALSE;
}
}
else {
WARN("Error parsing %s\n", afmfn);
} }
HeapFree(GetProcessHeap(),0,afmfn); HeapFree(PSDRV_Heap,0,afmfn);
} }
} }
closedir(dir); closedir(dir);
} }
else {
WARN("Error opening %s\n", afmdir);
}
return TRUE;
} }
BOOL PSDRV_GetFontMetrics(void) BOOL PSDRV_GetFontMetrics(void)
...@@ -490,22 +634,29 @@ BOOL PSDRV_GetFontMetrics(void) ...@@ -490,22 +634,29 @@ BOOL PSDRV_GetFontMetrics(void)
if (PSDRV_GlyphListInit() != 0) if (PSDRV_GlyphListInit() != 0)
return FALSE; return FALSE;
while (PROFILE_EnumWineIniString( "afmfiles", idx++, key, sizeof(key), value, sizeof(value))) while (PROFILE_EnumWineIniString( "afmfiles", idx++, key, sizeof(key),
value, sizeof(value)))
{ {
AFM* afm = PSDRV_AFMParse(value); AFM* afm = PSDRV_AFMParse(value);
if (afm)
{ if (afm) {
if(afm->EncodingScheme && if(afm->EncodingScheme &&
!strcmp(afm->EncodingScheme, "AdobeStandardEncoding")) { !strcmp(afm->EncodingScheme, "AdobeStandardEncoding")) {
PSDRV_ReencodeCharWidths(afm); PSDRV_ReencodeCharWidths(afm);
} }
PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm); if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
return FALSE;
}
} }
else {
WARN("Error parsing %s\n", value);
}
} }
for (idx = 0; PROFILE_EnumWineIniString ("afmdirs", idx, key, sizeof (key), for (idx = 0; PROFILE_EnumWineIniString ("afmdirs", idx, key, sizeof (key),
value, sizeof (value)); ++idx) value, sizeof (value)); ++idx)
PSDRV_ReadAFMDir (value); if (PSDRV_ReadAFMDir (value) == FALSE)
return FALSE;
PSDRV_DumpGlyphList(); PSDRV_DumpGlyphList();
PSDRV_DumpFontList(); PSDRV_DumpFontList();
......
...@@ -219,7 +219,6 @@ static PSDRV_DEVMODEA DefaultDevmode = ...@@ -219,7 +219,6 @@ static PSDRV_DEVMODEA DefaultDevmode =
/* dummy */ 0 /* dummy */ 0
}, },
{ /* dmDrvPrivate */ { /* dmDrvPrivate */
/* ppdfilename */ "default.ppd",
/* numInstalledOptions */ 0 /* numInstalledOptions */ 0
} }
}; };
...@@ -467,27 +466,43 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) ...@@ -467,27 +466,43 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
AFM *afm; AFM *afm;
HANDLE hPrinter; HANDLE hPrinter;
const char *ppd = NULL; const char *ppd = NULL;
char ppdFileName[256];
TRACE("'%s'\n", name); TRACE("'%s'\n", name);
/*
* If this loop completes, last will point to the 'next' element of the
* final PRINTERINFO in the list
*/
for( ; pi; last = &pi->next, pi = pi->next) for( ; pi; last = &pi->next, pi = pi->next)
if(!strcmp(pi->FriendlyName, name)) if(!strcmp(pi->FriendlyName, name))
return pi; return pi;
pi = *last = HeapAlloc( PSDRV_Heap, 0, sizeof(*pi) ); pi = *last = HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(*pi) );
if (pi == NULL)
return NULL;
pi->FriendlyName = HEAP_strdupA( PSDRV_Heap, 0, name ); pi->FriendlyName = HEAP_strdupA( PSDRV_Heap, 0, name );
if (pi->FriendlyName == NULL)
goto fail;
/* Use Get|SetPrinterDataExA instead? */
res = DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type, res = DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type,
NULL, 0, &needed ); NULL, 0, &needed );
if(res == ERROR_INVALID_PRINTER_NAME || needed != sizeof(DefaultDevmode)) { if(res == ERROR_INVALID_PRINTER_NAME || needed != sizeof(DefaultDevmode)) {
pi->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) ); pi->Devmode = HeapAlloc( PSDRV_Heap, 0, sizeof(DefaultDevmode) );
if (pi->Devmode == NULL)
goto cleanup;
memcpy(pi->Devmode, &DefaultDevmode, sizeof(DefaultDevmode) ); memcpy(pi->Devmode, &DefaultDevmode, sizeof(DefaultDevmode) );
strcpy(pi->Devmode->dmPublic.dmDeviceName,name); strcpy(pi->Devmode->dmPublic.dmDeviceName,name);
DrvSetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, DrvSetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE,
REG_BINARY, (LPBYTE)&DefaultDevmode, sizeof(DefaultDevmode) ); REG_BINARY, (LPBYTE)&DefaultDevmode, sizeof(DefaultDevmode) );
/* need to do something here AddPrinter?? */ /* need to do something here AddPrinter?? */
} else { }
else {
pi->Devmode = HeapAlloc( PSDRV_Heap, 0, needed ); pi->Devmode = HeapAlloc( PSDRV_Heap, 0, needed );
DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type, DrvGetPrinterData16((LPSTR)name, (LPSTR)INT_PD_DEFAULT_DEVMODE, &type,
(LPBYTE)pi->Devmode, needed, &needed); (LPBYTE)pi->Devmode, needed, &needed);
...@@ -497,29 +512,48 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) ...@@ -497,29 +512,48 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
ERR ("OpenPrinterA failed with code %li\n", GetLastError ()); ERR ("OpenPrinterA failed with code %li\n", GetLastError ());
goto cleanup; goto cleanup;
} }
pi->Devmode->dmDrvPrivate.ppdFileName[0]='\0';
ppdFileName[0]='\0';
#ifdef HAVE_CUPS #ifdef HAVE_CUPS
{ {
ppd = cupsGetPPD(name); ppd = cupsGetPPD(name);
if (ppd) { if (ppd) {
strcpy(pi->Devmode->dmDrvPrivate.ppdFileName,ppd); strncpy(ppdFileName, ppd, sizeof(ppdFileName));
res = ERROR_SUCCESS; res = ERROR_SUCCESS;
/* we should unlink() that file later */ /* we should unlink() that file later */
} else { }
else {
ERR("Did not find ppd for %s\n",name); ERR("Did not find ppd for %s\n",name);
} }
} }
#endif #endif
if (!pi->Devmode->dmDrvPrivate.ppdFileName[0]) {
res = GetPrinterDataA (hPrinter, "PPD File", NULL, if (!ppdFileName[0]) {
pi->Devmode->dmDrvPrivate.ppdFileName, 256, &needed); res = GetPrinterDataA (hPrinter, "PPD File", NULL, ppdFileName,
sizeof(ppdFileName), &needed);
} }
if (res != ERROR_SUCCESS) { if (res != ERROR_SUCCESS) {
ERR ("Error %li getting PPD file name for printer '%s'\n", res, name); ERR ("Error %li getting PPD file name for printer '%s'\n", res, name);
goto closeprinter; goto closeprinter;
} }
ppdFileName[sizeof(ppdFileName) - 1] = '\0';
pi->ppd = PSDRV_ParsePPD(ppdFileName);
if(!pi->ppd) {
MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n",
ppdFileName);
goto closeprinter;
}
/*
* This is a hack. The default paper size should be read in as part of
* the Devmode structure, but Wine doesn't currently provide a convenient
* way to configure printers.
*/
res = GetPrinterDataA (hPrinter, "Paper Size", NULL, (LPBYTE) &dwPaperSize, res = GetPrinterDataA (hPrinter, "Paper Size", NULL, (LPBYTE) &dwPaperSize,
sizeof (DWORD), &needed); sizeof (DWORD), &needed);
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
...@@ -533,10 +567,10 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) ...@@ -533,10 +567,10 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", NULL, res = EnumPrinterDataExA (hPrinter, "PrinterDriverData\\FontSubTable", NULL,
0, &needed, &pi->FontSubTableSize); 0, &needed, &pi->FontSubTableSize);
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND) {
TRACE ("No 'FontSubTable' for printer '%s'\n", name); TRACE ("No 'FontSubTable' for printer '%s'\n", name);
else if (res == ERROR_MORE_DATA) }
{ else if (res == ERROR_MORE_DATA) {
pi->FontSubTable = HeapAlloc (PSDRV_Heap, 0, needed); pi->FontSubTable = HeapAlloc (PSDRV_Heap, 0, needed);
if (pi->FontSubTable == NULL) { if (pi->FontSubTable == NULL) {
ERR ("Failed to allocate %li bytes from heap\n", needed); ERR ("Failed to allocate %li bytes from heap\n", needed);
...@@ -550,9 +584,10 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) ...@@ -550,9 +584,10 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
ERR ("EnumPrinterDataExA returned %li\n", res); ERR ("EnumPrinterDataExA returned %li\n", res);
goto closeprinter; goto closeprinter;
} }
} else { }
FIXME ("EnumPrinterDataExA returned %li\n", res); else {
/* ignore error */ ERR("EnumPrinterDataExA returned %li\n", res);
goto closeprinter;
} }
if (ClosePrinter (hPrinter) == 0) { if (ClosePrinter (hPrinter) == 0) {
...@@ -560,22 +595,21 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) ...@@ -560,22 +595,21 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
goto cleanup; goto cleanup;
} }
pi->ppd = PSDRV_ParsePPD(pi->Devmode->dmDrvPrivate.ppdFileName);
if(!pi->ppd) {
MESSAGE("Couldn't find PPD file '%s', expect a crash now!\n",
pi->Devmode->dmDrvPrivate.ppdFileName);
goto cleanup;
}
pi->next = NULL; pi->next = NULL;
pi->Fonts = NULL; pi->Fonts = NULL;
for(font = pi->ppd->InstalledFonts; font; font = font->next) { for(font = pi->ppd->InstalledFonts; font; font = font->next) {
afm = PSDRV_FindAFMinList(PSDRV_AFMFontList, font->Name); afm = PSDRV_FindAFMinList(PSDRV_AFMFontList, font->Name);
if(!afm) if(!afm) {
TRACE( "Couldn't find AFM file for installed printer font '%s' - ignoring\n", font->Name); TRACE( "Couldn't find AFM file for installed printer font '%s' - "
else "ignoring\n", font->Name);
PSDRV_AddAFMtoList(&pi->Fonts, afm); }
else {
if (PSDRV_AddAFMtoList(&pi->Fonts, afm) == FALSE) {
PSDRV_FreeAFMList(pi->Fonts);
goto cleanup;
}
}
} }
if (ppd) unlink(ppd); if (ppd) unlink(ppd);
...@@ -584,9 +618,13 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name) ...@@ -584,9 +618,13 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
closeprinter: closeprinter:
ClosePrinter(hPrinter); ClosePrinter(hPrinter);
cleanup: cleanup:
HeapFree (PSDRV_Heap, 0, pi->FontSubTable); if (pi->FontSubTable)
HeapFree(PSDRV_Heap, 0, pi->FriendlyName); HeapFree(PSDRV_Heap, 0, pi->FontSubTable);
HeapFree(PSDRV_Heap, 0, pi->Devmode); if (pi->FriendlyName)
HeapFree(PSDRV_Heap, 0, pi->FriendlyName);
if (pi->Devmode)
HeapFree(PSDRV_Heap, 0, pi->Devmode);
fail:
HeapFree(PSDRV_Heap, 0, pi); HeapFree(PSDRV_Heap, 0, pi);
if (ppd) unlink(ppd); if (ppd) unlink(ppd);
*last = NULL; *last = NULL;
......
...@@ -170,7 +170,6 @@ typedef struct { ...@@ -170,7 +170,6 @@ typedef struct {
int dummy; int dummy;
} dmDocPrivate; } dmDocPrivate;
struct _tagdrvprivate { struct _tagdrvprivate {
char ppdFileName[256]; /* Hack */
UINT numInstalledOptions; /* Options at end of struct */ UINT numInstalledOptions; /* Options at end of struct */
} dmDrvPrivate; } dmDrvPrivate;
...@@ -274,7 +273,7 @@ extern BOOL PSDRV_GetFontMetrics(void); ...@@ -274,7 +273,7 @@ extern BOOL PSDRV_GetFontMetrics(void);
extern PPD *PSDRV_ParsePPD(char *fname); extern PPD *PSDRV_ParsePPD(char *fname);
extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name); extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name);
extern AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name); extern AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name);
extern void PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm); extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm);
extern void PSDRV_FreeAFMList( FONTFAMILY *head ); extern void PSDRV_FreeAFMList( FONTFAMILY *head );
extern BOOL WINAPI PSDRV_Init(HINSTANCE hinst, DWORD reason, LPVOID reserved); extern BOOL WINAPI PSDRV_Init(HINSTANCE hinst, DWORD reason, LPVOID reserved);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment