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

#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);  /* End-of-Data for /HexASCIIDecodeFilter */
    PSDRV_WriteGRestore(dc);
    return TRUE;
}






