/*
 *	PostScript output functions
 *
 *	Copyright 1998  Huw D M Davies
 *
 */

#include <ctype.h>
#include <string.h>
#include "windows.h"
#include "psdrv.h"
#include "print.h"
#include "debug.h"

static char psheader[] = /* title llx lly urx ury orientation */
"%%!PS-Adobe-3.0\n"
"%%%%Creator: Wine PostScript Driver\n"
"%%%%Title: %s\n"
"%%%%BoundingBox: %d %d %d %d\n"
"%%%%Pages: (atend)\n"
"%%%%Orientation: %s\n"
"%%%%EndComments\n";

static char psbeginprolog[] = 
"%%BeginProlog\n";

static char psendprolog[] =
"%%EndProlog\n";

static char psvectorstart[] =
"/ANSIEncoding [\n";

static char psvectorend[] =
"] def\n";

static char psprolog[] = /* output ANSIEncoding vector first */
"/reencodefont {\n"
"findfont\n"
"dup length dict begin\n"
"{1 index /FID ne {def} {pop pop} ifelse} forall\n"
"/Encoding ANSIEncoding def\n"
"currentdict\n"
"end\n"
"definefont pop\n"
"} bind def\n"
"/tmpmtrx matrix def\n";

static char psbeginsetup[] =
"%%BeginSetup\n";

static char psendsetup[] =
"%%EndSetup\n";

static char psbeginfeature[] = /* feature, value */
"mark {\n"
"%%%%BeginFeature: %s %s\n";

static char psendfeature[] =
"\n%%EndFeature\n"
"} stopped cleartomark\n";

static char psnewpage[] = /* name, number, xres, yres, xtrans, ytrans, rot */
"%%%%Page: %s %d\n"
"%%%%BeginPageSetup\n"
"/pgsave save def\n"
"72 %d div 72 %d div scale\n"
"%d %d translate\n"
"1 -1 scale\n"
"%d rotate\n"
"%%%%EndPageSetup\n";

static char psendpage[] =
"pgsave restore\n"
"showpage\n";

static char psfooter[] = /* pages */
"%%%%Trailer\n"
"%%%%Pages: %d\n"
"%%%%EOF\n";

static char psmoveto[] = /* x, y */
"%d %d moveto\n";

static char pslineto[] = /* x, y */
"%d %d lineto\n";

static char psstroke[] = 
"stroke\n";

static char psrectangle[] = /* x, y, width, height, -width */
"%d %d moveto\n"
"%d 0 rlineto\n"
"0 %d rlineto\n"
"%d 0 rlineto\n"
"closepath\n";

static char psshow[] = /* string */
"(%s) show\n";

static char pssetfont[] = /* fontname, xscale, yscale, ascent, escapement */
"/%s findfont\n"
"[%d 0 0 %d 0 0]\n"
"%d 10 div matrix rotate\n"
"matrix concatmatrix\n"
"makefont setfont\n";

static char pssetlinewidth[] = /* width */
"%d setlinewidth\n";

static char pssetdash[] = /* dash, offset */
"[%s] %d setdash\n";

static char pssetgray[] = /* gray */
"%.2f setgray\n";

static char pssetrgbcolor[] = /* r, g, b */
"%.2f %.2f %.2f setrgbcolor\n";

static char psellipse[] = /* x, y, a, b */
"tmpmtrx currentmatrix pop\n"
"%d %d translate\n"
"%d %d scale\n"
"0 0 1 0 360 arc\n"
"tmpmtrx setmatrix\n";

static char psgsave[] =
"gsave\n";

static char psgrestore[] =
"grestore\n";

static char psfill[] =
"fill\n";

char *PSDRV_ANSIVector[256] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"space",	"exclam",	"quotedbl",	"numbersign",
"dollar",	"percent",	"ampersand",	"quotesingle",
"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",
"grave",	"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",	NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		"quoteleft",	"quoteright",	NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		NULL,		NULL,		NULL,
NULL,		"exclamdown",	"cent",		"sterling",
"currency",	"yen",		"brokenbar",	"section",
"dieresis",	"copyright",	"ordfeminine",	"guillemotleft",
"logicalnot",	"hyphen",	"registered",	"macron",
"degree",	"plusminus",	"twosuperior",	"threesuperior",
"acute",	"mu",		"paragraph",	"periodcentered",
"cedilla",	"onesuperior",	"ordmasculine",	"guillemotright",
"onequarter",	"onehalf",	"threequarters","questiondown",
"Agrave",	"Aacute",	"Acircumflex",	"Atilde",
"Adieresis",	"Aring",	"AE",		"Ccedilla",
"Egrave",	"Eacute",	"Ecircumflex",	"Edieresis",
"Igrave",	"Iacute",	"Icircumflex",	"Idieresis",
"Eth",		"Ntilde",	"Ograve",	"Oacute",
"Ocircumflex",	"Otilde",	"Odieresis",	"multiply",
"Oslash",	"Ugrave",	"Uacute",	"Ucircumflex",
"Udieresis",	"Yacute",	"Thorn",	"germandbls",
"agrave",	"aacute",	"acircumflex",	"atilde",
"adieresis",	"aring",	"ae",		"ccedilla",
"egrave",	"eacute",	"ecircumflex",	"edieresis",
"igrave",	"iacute",	"icircumflex",	"idieresis",
"eth",		"ntilde",	"ograve",	"oacute",
"ocircumflex",	"otilde",	"odieresis",	"divide",
"oslash",	"ugrave",	"uacute",	"ucircumflex",
"udieresis",	"yacute",	"thorn",	"ydieresis"
};


char psreencodefont[] = /* newfontname basefontname*/
"/%s /%s reencodefont\n";


int PSDRV_WriteSpool(DC *dc, LPSTR lpData, WORD cch)
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;

    if(physDev->job.NeedPageHeader) {
	physDev->job.PageNo++;
        if( !PSDRV_WriteNewPage(dc) )
	    return FALSE;
	physDev->job.NeedPageHeader = FALSE;
    }
    return WriteSpool( physDev->job.hJob, lpData, cch );
}


INT32 PSDRV_WriteFeature(HANDLE16 hJob, char *feature, char *value,
			 char *invocation)
{

    char *buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psheader) +
			     strlen(feature) + strlen(value));


    sprintf(buf, psbeginfeature, feature, value);
    WriteSpool( hJob, buf, strlen(buf) );

    WriteSpool( hJob, invocation, strlen(invocation) );

    WriteSpool( hJob, psendfeature, strlen(psendfeature) );
    
    HeapFree( PSDRV_Heap, 0, buf );
    return 1;
}



INT32 PSDRV_WriteHeader( DC *dc, char *title, int len )
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char *buf, *titlebuf, *orient, vectbuf[256];
    INPUTSLOT *slot;
    PAGESIZE *page;
    int urx, ury, i, j;

    titlebuf = (char *)HeapAlloc( PSDRV_Heap, 0, len+1 );
    if(!titlebuf) {
        WARN(psdrv, "HeapAlloc failed\n");
        return 0;
    }
    memcpy(titlebuf, title, len);
    titlebuf[len] = '\0';

    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psheader) + len + 30);
    if(!buf) {
        WARN(psdrv, "HeapAlloc failed\n");
	HeapFree( PSDRV_Heap, 0, titlebuf );
        return 0;
    }

    if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) {
      /* BBox co-ords are in default user co-ord system so urx < ury even in
	 landscape mode */
	urx = (int) (dc->w.devCaps->vertSize * 72.0 / 25.4);
        ury = (int) (dc->w.devCaps->horzSize * 72.0 / 25.4);
	orient = "Landscape";
    } else {
        urx = (int) (dc->w.devCaps->horzSize * 72.0 / 25.4);
	ury = (int) (dc->w.devCaps->vertSize * 72.0 / 25.4);
	orient = "Portrait";
    }

    /* FIXME should do something better with BBox */

    sprintf(buf, psheader, title, 0, 0, urx, ury, orient);		

    if( WriteSpool( physDev->job.hJob, buf, strlen(buf) ) != 
	                                             strlen(buf) ) {
        WARN(psdrv, "WriteSpool error\n");
	HeapFree( PSDRV_Heap, 0, titlebuf );
	HeapFree( PSDRV_Heap, 0, buf );
	return 0;
    }
    HeapFree( PSDRV_Heap, 0, titlebuf );
    HeapFree( PSDRV_Heap, 0, buf );

    WriteSpool( physDev->job.hJob, psbeginprolog, strlen(psbeginprolog) );
    WriteSpool( physDev->job.hJob, psvectorstart, strlen(psvectorstart) );
    
    for(i = 0; i < 256; i += 8) {
        vectbuf[0] = '\0';
        for(j = 0; j < 8; j++) {
	    strcat(vectbuf, "/");
	    if(PSDRV_ANSIVector[i+j]) {
	        strcat(vectbuf, PSDRV_ANSIVector[i+j]);
		strcat(vectbuf, " ");
	    } else {
	        strcat(vectbuf, ".notdef ");
	    }
	}
	strcat(vectbuf, "\n");
	WriteSpool( physDev->job.hJob, vectbuf, strlen(vectbuf) );
    }

    WriteSpool( physDev->job.hJob, psvectorend, strlen(psvectorend) );
    WriteSpool( physDev->job.hJob, psprolog, strlen(psprolog) );
    WriteSpool( physDev->job.hJob, psendprolog, strlen(psendprolog) );


    WriteSpool( physDev->job.hJob, psbeginsetup, strlen(psbeginsetup) );

    for(slot = physDev->pi->ppd->InputSlots; slot; slot = slot->next) {
        if(slot->WinBin == physDev->Devmode->dmPublic.dmDefaultSource) {
	    if(slot->InvocationString) {
	        PSDRV_WriteFeature(physDev->job.hJob, "*InputSlot", slot->Name,
			     slot->InvocationString);
		break;
	    }
	}
    }

    for(page = physDev->pi->ppd->PageSizes; page; page = page->next) {
        if(page->WinPage == physDev->Devmode->dmPublic.dmPaperSize) {
	    if(page->InvocationString) {
	        PSDRV_WriteFeature(physDev->job.hJob, "*PageSize", page->Name,
			     page->InvocationString);
		break;
	    }
	}
    }

    WriteSpool( physDev->job.hJob, psendsetup, strlen(psendsetup) );


    return 1;
}


INT32 PSDRV_WriteFooter( DC *dc )
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char *buf;

    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psfooter) + 100 );
    if(!buf) {
        WARN(psdrv, "HeapAlloc failed\n");
        return 0;
    }

    sprintf(buf, psfooter, physDev->job.PageNo);

    if( WriteSpool( physDev->job.hJob, buf, strlen(buf) ) != 
	                                             strlen(buf) ) {
        WARN(psdrv, "WriteSpool error\n");
	HeapFree( PSDRV_Heap, 0, buf );
	return 0;
    }
    HeapFree( PSDRV_Heap, 0, buf );
    return 1;
}



INT32 PSDRV_WriteEndPage( DC *dc )
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;

    if( WriteSpool( physDev->job.hJob, psendpage, sizeof(psendpage)-1 ) != 
	                                             sizeof(psendpage)-1 ) {
        WARN(psdrv, "WriteSpool error\n");
	return 0;
    }
    return 1;
}




INT32 PSDRV_WriteNewPage( DC *dc )
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char *buf;
    char name[100];
    signed int xtrans, ytrans, rotation;

    sprintf(name, "%d", physDev->job.PageNo);

    buf = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psnewpage) + 200 );
    if(!buf) {
        WARN(psdrv, "HeapAlloc failed\n");
        return 0;
    }

    if(physDev->Devmode->dmPublic.dmOrientation == DMORIENT_LANDSCAPE) {
        if(physDev->pi->ppd->LandscapeOrientation == -90) {
	    xtrans = dc->w.devCaps->vertRes;
	    ytrans = dc->w.devCaps->horzRes;
	    rotation = 90;
	} else {
	    xtrans = ytrans = 0;
	    rotation = -90;
	}
    } else {
        xtrans = 0;
	ytrans = dc->w.devCaps->vertRes;
	rotation = 0;
    }

    sprintf(buf, psnewpage, name, physDev->job.PageNo,
	    dc->w.devCaps->logPixelsX, dc->w.devCaps->logPixelsY,
	    xtrans, ytrans, rotation);

    if( WriteSpool( physDev->job.hJob, buf, strlen(buf) ) != 
	                                             strlen(buf) ) {
        WARN(psdrv, "WriteSpool error\n");
	HeapFree( PSDRV_Heap, 0, buf );
	return 0;
    }
    HeapFree( PSDRV_Heap, 0, buf );
    return 1;
}


BOOL32 PSDRV_WriteMoveTo(DC *dc, INT32 x, INT32 y)
{
    char buf[100];

    sprintf(buf, psmoveto, x, y);
    return PSDRV_WriteSpool(dc, buf, strlen(buf));
}

BOOL32 PSDRV_WriteLineTo(DC *dc, INT32 x, INT32 y)
{
    char buf[100];

    sprintf(buf, pslineto, x, y);
    return PSDRV_WriteSpool(dc, buf, strlen(buf));
}


BOOL32 PSDRV_WriteStroke(DC *dc)
{
    return PSDRV_WriteSpool(dc, psstroke, sizeof(psstroke)-1);
}



BOOL32 PSDRV_WriteRectangle(DC *dc, INT32 x, INT32 y, INT32 width, 
			INT32 height)
{
    char buf[100];

    sprintf(buf, psrectangle, x, y, width, height, -width);
    return PSDRV_WriteSpool(dc, buf, strlen(buf));
}

BOOL32 PSDRV_WriteEllispe(DC *dc, INT32 x, INT32 y, INT32 a, INT32 b)
{
    char buf[256];

    sprintf(buf, psellipse, x, y, a, b);
    return PSDRV_WriteSpool(dc, buf, strlen(buf));
}

static char encodingext[] = "-ANSI";

BOOL32 PSDRV_WriteSetFont(DC *dc, BOOL32 UseANSI)
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char *buf, *newbuf;

    buf = (char *)HeapAlloc( PSDRV_Heap, 0,
	     sizeof(pssetfont) + strlen(physDev->font.afm->FontName) + 40);

    if(!buf) {
        WARN(psdrv, "HeapAlloc failed\n");
        return FALSE;
    }

    newbuf = (char *)HeapAlloc( PSDRV_Heap, 0,
	      strlen(physDev->font.afm->FontName) + sizeof(encodingext));

    if(!newbuf) {
        WARN(psdrv, "HeapAlloc failed\n");
	HeapFree(PSDRV_Heap, 0, buf);
        return FALSE;
    }

    if(UseANSI)
        sprintf(newbuf, "%s%s", physDev->font.afm->FontName, encodingext);
    else
        strcpy(newbuf, physDev->font.afm->FontName);

    sprintf(buf, pssetfont, newbuf, 
		physDev->font.size, -physDev->font.size,
	        -physDev->font.escapement);

    PSDRV_WriteSpool(dc, buf, strlen(buf));
    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}    

BOOL32 PSDRV_WriteSetColor(DC *dc, PSCOLOR *color)
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char buf[256];

    if(PSDRV_CmpColor(&physDev->inkColor, color))
        return TRUE;

    PSDRV_CopyColor(&physDev->inkColor, color);
    switch(color->type) {
    case PSCOLOR_RGB:
        sprintf(buf, pssetrgbcolor, color->value.rgb.r, color->value.rgb.g,
		color->value.rgb.b);
	return PSDRV_WriteSpool(dc, buf, strlen(buf));

    case PSCOLOR_GRAY:	
        sprintf(buf, pssetgray, color->value.gray.i);
	return PSDRV_WriteSpool(dc, buf, strlen(buf));
	
    default:
        ERR(psdrv, "Unkonwn colour type %d\n", color->type);
	break;
    }

    return FALSE;
}

BOOL32 PSDRV_WriteSetPen(DC *dc)
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char buf[256];

    sprintf(buf, pssetlinewidth, physDev->pen.width);
    PSDRV_WriteSpool(dc, buf, strlen(buf));

    if(physDev->pen.dash) {
        sprintf(buf, pssetdash, physDev->pen.dash, 0);
	PSDRV_WriteSpool(dc, buf, strlen(buf));
    }

    return TRUE;
}

BOOL32 PSDRV_WriteReencodeFont(DC *dc)
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    char *buf, *newbuf;
 
    buf = (char *)HeapAlloc( PSDRV_Heap, 0,
	     sizeof(psreencodefont) + 2 * strlen(physDev->font.afm->FontName) 
			     + sizeof(encodingext));

    if(!buf) {
        WARN(psdrv, "HeapAlloc failed\n");
        return FALSE;
    }

    newbuf = (char *)HeapAlloc( PSDRV_Heap, 0,
	      strlen(physDev->font.afm->FontName) + sizeof(encodingext));

    if(!newbuf) {
        WARN(psdrv, "HeapAlloc failed\n");
	HeapFree(PSDRV_Heap, 0, buf);
        return FALSE;
    }

    sprintf(newbuf, "%s%s", physDev->font.afm->FontName, encodingext);
    sprintf(buf, psreencodefont, newbuf, physDev->font.afm->FontName);

    PSDRV_WriteSpool(dc, buf, strlen(buf));

    HeapFree(PSDRV_Heap, 0, newbuf);
    HeapFree(PSDRV_Heap, 0, buf);
    return TRUE;
}    

BOOL32 PSDRV_WriteShow(DC *dc, char *str, INT32 count)
{
    char *buf, *buf1;
    INT32 buflen = count + 10, i, done;

    buf = (char *)HeapAlloc( PSDRV_Heap, 0, buflen );
    
    for(i = done = 0; i < count; i++) {
        if(!isprint(str[i])) {
	    if(done + 4 >= buflen)
	        buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
	    sprintf(buf + done, "\\%03o", (int)(unsigned char)str[i] );
	    done += 4;
	} else if(str[i] == '\\' || str[i] == '(' || str[i] == ')' ) {
	    if(done + 2 >= buflen)
	        buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
	    buf[done++] = '\\';
	    buf[done++] = str[i];
	} else {
	    if(done + 1 >= buflen)
	        buf = HeapReAlloc( PSDRV_Heap, 0, buf, buflen += 10 );
	    buf[done++] = str[i];
	}
    }
    buf[done] = '\0';

    buf1 = (char *)HeapAlloc( PSDRV_Heap, 0, sizeof(psshow) + done);

    sprintf(buf1, psshow, buf);

    PSDRV_WriteSpool(dc, buf1, strlen(buf1));
    HeapFree(PSDRV_Heap, 0, buf);
    HeapFree(PSDRV_Heap, 0, buf1);

    return TRUE;
}    

BOOL32 PSDRV_WriteFill(DC *dc)
{
    return PSDRV_WriteSpool(dc, psfill, sizeof(psfill)-1);
}

BOOL32 PSDRV_Writegsave(DC *dc)
{
    return PSDRV_WriteSpool(dc, psgsave, sizeof(psgsave)-1);
}

BOOL32 PSDRV_Writegrestore(DC *dc)
{
    return PSDRV_WriteSpool(dc, psgrestore, sizeof(psgrestore)-1);
}





