blob: 1b44f14445aa9f6391d51ca1b8bbf9e1bac78d46 [file] [log] [blame]
/*
* 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 the DIB bits aren't byte aligned at the start of
* a line - 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 || widthSrc & 7)
FIXME("This won't work...\n");
for(line = 0; line < heightSrc; line++, ptr += widthbytes)
PSDRV_WriteBytes(dc, ptr + xSrc/8, widthSrc/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 || widthSrc & 1)
FIXME("This won't work...\n");
for(line = 0; line < heightSrc; line++, ptr += widthbytes)
PSDRV_WriteBytes(dc, ptr + xSrc/2, widthSrc/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;
}