217 lines
5.3 KiB
C
217 lines
5.3 KiB
C
/*
|
|
* 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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|