/*
 *	PostScript driver bitmap functions
 *
 * Copyright 1998  Huw D M Davies
 *
 */

#include "gdi.h"
#include "psdrv.h"
#include "debugtools.h"
#include "bitmap.h"
#include "winbase.h"

DEFAULT_DEBUG_CHANNEL(psdrv)


/***************************************************************************
 *                PSDRV_WriteImageHeader
 *
 * Helper for PSDRV_StretchDIBits
 *
 * BUGS
 *  Uses level 2 PostScript
 */

static BOOL PSDRV_WriteImageHeader(DC *dc, const BITMAPINFO *info, INT xDst,
				   INT yDst, INT widthDst, INT heightDst,
				   INT widthSrc, INT heightSrc)
{
    COLORREF map[256];
    int i;

    switch(info->bmiHeader.biBitCount) {
    case 8:
        PSDRV_WriteIndexColorSpaceBegin(dc, 255);
	for(i = 0; i < 256; i++) {
	    map[i] =  info->bmiColors[i].rgbRed |
	      info->bmiColors[i].rgbGreen << 8 |
	      info->bmiColors[i].rgbBlue << 16;
	}
	PSDRV_WriteRGB(dc, map, 256);
	PSDRV_WriteIndexColorSpaceEnd(dc);
	break;

    case 4:
        PSDRV_WriteIndexColorSpaceBegin(dc, 15);
	for(i = 0; i < 16; i++) {
	    map[i] =  info->bmiColors[i].rgbRed |
	      info->bmiColors[i].rgbGreen << 8 |
	      info->bmiColors[i].rgbBlue << 16;
	}
	PSDRV_WriteRGB(dc, map, 16);
	PSDRV_WriteIndexColorSpaceEnd(dc);
	break;

    case 1:
        PSDRV_WriteIndexColorSpaceBegin(dc, 1);
	for(i = 0; i < 2; i++) {
	    map[i] =  info->bmiColors[i].rgbRed |
	      info->bmiColors[i].rgbGreen << 8 |
	      info->bmiColors[i].rgbBlue << 16;
	}
	PSDRV_WriteRGB(dc, map, 2);
	PSDRV_WriteIndexColorSpaceEnd(dc);
	break;

    case 15:
    case 16:
    case 24:
    case 32:
      {
	PSCOLOR pscol;
	pscol.type = PSCOLOR_RGB;
	pscol.value.rgb.r = pscol.value.rgb.g = pscol.value.rgb.b = 0.0;
        PSDRV_WriteSetColor(dc, &pscol);
        break;
      }

    default:
        FIXME("Not implemented yet\n");
	return FALSE;
	break;
    }

    PSDRV_WriteImageDict(dc, info->bmiHeader.biBitCount, xDst, yDst,
			  widthDst, heightDst, widthSrc, heightSrc, NULL);
    return TRUE;
}


/***************************************************************************
 *
 *	PSDRV_StretchDIBits
 *
 * BUGS
 *  Doesn't work correctly if xSrc isn't byte aligned - this affects 1 and 4
 *  bit depths.
 *  Compression not implemented.
 */
INT PSDRV_StretchDIBits( DC *dc, INT xDst, INT yDst, INT widthDst,
			 INT heightDst, INT xSrc, INT ySrc,
			 INT widthSrc, INT heightSrc, const void *bits,
			 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{
    DWORD fullSrcWidth;
    INT widthbytes, fullSrcHeight;
    WORD bpp, compression;
    const char *ptr;
    INT line;

    TRACE("%08x (%d,%d %dx%d) -> (%d,%d %dx%d)\n", dc->hSelf,
	  xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst);

    DIB_GetBitmapInfo((const BITMAPINFOHEADER *)info, &fullSrcWidth,
		      &fullSrcHeight, &bpp, &compression);

    widthbytes = DIB_GetDIBWidthBytes(fullSrcWidth, bpp);

    TRACE("full size=%ldx%d bpp=%d compression=%d\n", fullSrcWidth,
	  fullSrcHeight, bpp, compression);


    if(compression != BI_RGB) {
        FIXME("Compression not supported\n");
	return FALSE;
    }

    xDst = XLPTODP(dc, xDst);
    yDst = YLPTODP(dc, yDst);
    widthDst = XLSTODS(dc, widthDst);
    heightDst = YLSTODS(dc, heightDst);

    switch(bpp) {

    case 1:
	PSDRV_WriteGSave(dc);
	PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst,
			       widthSrc, heightSrc);
	ptr = bits;
	ptr += (ySrc * widthbytes);
	if(xSrc & 7)
	    FIXME("This won't work...\n");
        for(line = 0; line < heightSrc; line++, ptr += widthbytes)
	    PSDRV_WriteBytes(dc, ptr + xSrc/8, (widthSrc+7)/8);
	break;

    case 4:
	PSDRV_WriteGSave(dc);
	PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst,
			       widthSrc, heightSrc);
	ptr = bits;
	ptr += (ySrc * widthbytes);
	if(xSrc & 1)
	    FIXME("This won't work...\n");
        for(line = 0; line < heightSrc; line++, ptr += widthbytes)
	    PSDRV_WriteBytes(dc, ptr + xSrc/2, (widthSrc+1)/2);
	break;

    case 8:
	PSDRV_WriteGSave(dc);
	PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst,
			       widthSrc, heightSrc);
	ptr = bits;
	ptr += (ySrc * widthbytes);
        for(line = 0; line < heightSrc; line++, ptr += widthbytes)
	    PSDRV_WriteBytes(dc, ptr + xSrc, widthSrc);
	break;

    case 15:
    case 16:
	PSDRV_WriteGSave(dc);
	PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst,
			       widthSrc, heightSrc);

	ptr = bits;
	ptr += (ySrc * widthbytes);
        for(line = 0; line < heightSrc; line++, ptr += widthbytes)
	    PSDRV_WriteDIBits16(dc, (WORD *)ptr + xSrc, widthSrc);
	break;

    case 24:
	PSDRV_WriteGSave(dc);
	PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst,
			       widthSrc, heightSrc);

	ptr = bits;
	ptr += (ySrc * widthbytes);
        for(line = 0; line < heightSrc; line++, ptr += widthbytes)
	    PSDRV_WriteDIBits24(dc, ptr + xSrc * 3, widthSrc);
	break;

    case 32:
	PSDRV_WriteGSave(dc);
	PSDRV_WriteImageHeader(dc, info, xDst, yDst, widthDst, heightDst,
			       widthSrc, heightSrc);

	ptr = bits;
	ptr += (ySrc * widthbytes);
        for(line = 0; line < heightSrc; line++, ptr += widthbytes)
	    PSDRV_WriteDIBits32(dc, ptr + xSrc * 3, widthSrc);
	break;

    default:
        FIXME("Unsupported depth\n");
	return FALSE;

    }
    PSDRV_WriteSpool(dc, "%\n", 2);  /* some versions of ghostscript seem to
					eat one too many chars after the image
					operator */
    PSDRV_WriteGRestore(dc);
    return TRUE;
}






