From 44a79c4925f11cce18bc483d997771d0e8f87401 Mon Sep 17 00:00:00 2001 From: Huw D M Davies Date: Tue, 23 Mar 1999 13:46:04 +0000 Subject: [PATCH] Added StretchDIBits for the PostScript driver. --- graphics/psdrv/bitmap.c | 203 ++++++++++++++++++++++++++++++++++++++-- graphics/psdrv/ps.c | 163 ++++++++++++++++++++++++++++++++ include/psdrv.h | 12 ++- 3 files changed, 368 insertions(+), 10 deletions(-) diff --git a/graphics/psdrv/bitmap.c b/graphics/psdrv/bitmap.c index 6cf8e1f9301..450d72a1f67 100644 --- a/graphics/psdrv/bitmap.c +++ b/graphics/psdrv/bitmap.c @@ -8,22 +8,209 @@ #include "gdi.h" #include "psdrv.h" #include "debug.h" +#include "bitmap.h" +#include "winbase.h" + + +/*************************************************************************** + * 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(psdrv, "Not implemented yet\n"); + return FALSE; + break; + } + + PSDRV_WriteImageDict(dc, info->bmiHeader.biBitCount, xDst, yDst, + widthDst, heightDst, widthSrc, heightSrc); + 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 ) + INT heightDst, INT xSrc, INT ySrc, + INT widthSrc, INT heightSrc, const void *bits, + const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) { - TRACE(psdrv, "(%d,%d %dx%d) -> (%d,%d %dx%d) on %08x. %d colour bits\n", - xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst, - dc->hSelf, info->bmiHeader.biBitCount); + DWORD fullSrcWidth; + INT widthbytes, fullSrcHeight; + WORD bpp, compression; + const char *ptr; + INT line; + + TRACE(psdrv, "%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(psdrv, "full size=%ldx%d bpp=%d compression=%d\n", fullSrcWidth, + fullSrcHeight, bpp, compression); - FIXME(psdrv, "stub\n"); - return FALSE; + if(compression != BI_RGB) { + FIXME(psdrv, "Compression not supported\n"); + return FALSE; + } + + + 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(psdrv, "This won't work...\n"); + for(line = 0; line < heightSrc; line++, ptr += widthbytes) + PSDRV_WriteBytes(dc, ptr + xSrc/8, widthSrc/8); + PSDRV_WriteGRestore(dc); + 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(psdrv, "This won't work...\n"); + for(line = 0; line < heightSrc; line++, ptr += widthbytes) + PSDRV_WriteBytes(dc, ptr + xSrc/2, widthSrc/2); + PSDRV_WriteGRestore(dc); + 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); + PSDRV_WriteGRestore(dc); + 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); + PSDRV_WriteGRestore(dc); + 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); + PSDRV_WriteGRestore(dc); + 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); + PSDRV_WriteGRestore(dc); + break; + + default: + FIXME(psdrv, "Unsupported depth\n"); + return FALSE; + + } + + return TRUE; } + + + + + + diff --git a/graphics/psdrv/ps.c b/graphics/psdrv/ps.c index b8d9ba27c92..3b1bd802c61 100644 --- a/graphics/psdrv/ps.c +++ b/graphics/psdrv/ps.c @@ -690,4 +690,167 @@ BOOL PSDRV_WriteRotate(DC *dc, float ang) return PSDRV_WriteSpool(dc, buf, strlen(buf)); } +BOOL PSDRV_WriteIndexColorSpaceBegin(DC *dc, int size) +{ + char buf[256]; + sprintf(buf, "[/Indexed /DeviceRGB %d\n<\n", size); + return PSDRV_WriteSpool(dc, buf, strlen(buf)); +} +BOOL PSDRV_WriteIndexColorSpaceEnd(DC *dc) +{ + char buf[] = ">\n] setcolorspace\n"; + return PSDRV_WriteSpool(dc, buf, sizeof(buf) - 1); +} + +BOOL PSDRV_WriteRGB(DC *dc, COLORREF *map, int number) +{ + char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1), *ptr; + int i; + + ptr = buf; + for(i = 0; i < number; i++) { + sprintf(ptr, "%02x%02x%02x%c", (int)GetRValue(map[i]), + (int)GetGValue(map[i]), (int)GetBValue(map[i]), + ((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' '); + ptr += 7; + } + PSDRV_WriteSpool(dc, buf, number * 7); + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} + + +BOOL PSDRV_WriteImageDict(DC *dc, WORD depth, INT xDst, INT yDst, + INT widthDst, INT heightDst, INT widthSrc, + INT heightSrc) +{ + char start[] = "%d %d translate\n%d %d scale\n<<\n" + " /ImageType 1\n /Width %d\n /Height %d\n /BitsPerComponent %d\n" + " /ImageMatrix [%d 0 0 %d 0 %d]\n"; + + char decode1[] = " /Decode [0 %d]\n"; + char decode3[] = " /Decode [0 1 0 1 0 1]\n"; + + char end[] = " /DataSource currentfile /ASCIIHexDecode filter\n>> image\n"; + + char *buf = HeapAlloc(PSDRV_Heap, 0, 1000); + + sprintf(buf, start, xDst, yDst, widthDst, heightDst, widthSrc, heightSrc, + (depth < 8) ? depth : 8, widthSrc, -heightSrc, heightSrc); + + PSDRV_WriteSpool(dc, buf, strlen(buf)); + + switch(depth) { + case 8: + sprintf(buf, decode1, 255); + break; + + case 4: + sprintf(buf, decode1, 15); + break; + + case 1: + sprintf(buf, decode1, 1); + break; + + default: + strcpy(buf, decode3); + break; + } + + PSDRV_WriteSpool(dc, buf, strlen(buf)); + + PSDRV_WriteSpool(dc, end, sizeof(end) - 1); + + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} + +BOOL PSDRV_WriteBytes(DC *dc, const BYTE *bytes, int number) +{ + char *buf = HeapAlloc(PSDRV_Heap, 0, number * 3 + 1); + char *ptr; + int i; + + ptr = buf; + + for(i = 0; i < number; i++) { + sprintf(ptr, "%02x%c", bytes[i], + ((i & 0xf) == 0xf) || (i == number - 1) ? '\n' : ' '); + ptr += 3; + } + PSDRV_WriteSpool(dc, buf, number * 3); + + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} + +BOOL PSDRV_WriteDIBits16(DC *dc, const WORD *words, int number) +{ + char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1); + char *ptr; + int i; + + ptr = buf; + + for(i = 0; i < number; i++) { + int r, g, b; + + /* We want 0x0 -- 0x1f to map to 0x0 -- 0xff */ + + r = words[i] >> 10 & 0x1f; + r = r << 3 | r >> 2; + g = words[i] >> 5 & 0x1f; + g = g << 3 | g >> 2; + b = words[i] & 0x1f; + b = b << 3 | b >> 2; + sprintf(ptr, "%02x%02x%02x%c", r, g, b, + ((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' '); + ptr += 7; + } + PSDRV_WriteSpool(dc, buf, number * 7); + + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} + +BOOL PSDRV_WriteDIBits24(DC *dc, const BYTE *bits, int number) +{ + char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1); + char *ptr; + int i; + + ptr = buf; + + for(i = 0; i < number; i++) { + sprintf(ptr, "%02x%02x%02x%c", bits[i * 3 + 2], bits[i * 3 + 1], + bits[i * 3], + ((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' '); + ptr += 7; + } + PSDRV_WriteSpool(dc, buf, number * 7); + + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} + +BOOL PSDRV_WriteDIBits32(DC *dc, const BYTE *bits, int number) +{ + char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1); + char *ptr; + int i; + + ptr = buf; + + for(i = 0; i < number; i++) { + sprintf(ptr, "%02x%02x%02x%c", bits[i * 4 + 2], bits[i * 4 + 1], + bits[i * 4], + ((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' '); + ptr += 7; + } + PSDRV_WriteSpool(dc, buf, number * 7); + + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} diff --git a/include/psdrv.h b/include/psdrv.h index 3aa5946fc8e..3f27316b10f 100644 --- a/include/psdrv.h +++ b/include/psdrv.h @@ -282,8 +282,16 @@ extern BOOL PSDRV_WriteClip(DC *dc); extern BOOL PSDRV_WriteEOClip(DC *dc); extern BOOL PSDRV_WriteHatch(DC *dc); extern BOOL PSDRV_WriteRotate(DC *dc, float ang); - - +extern BOOL PSDRV_WriteIndexColorSpaceBegin(DC *dc, int size); +extern BOOL PSDRV_WriteIndexColorSpaceEnd(DC *dc); +extern BOOL PSDRV_WriteRGB(DC *dc, COLORREF *map, int number); +extern BOOL PSDRV_WriteImageDict(DC *dc, WORD depth, INT xDst, INT yDst, + INT widthDst, INT heightDst, INT widthSrc, + INT heightSrc); +extern BOOL PSDRV_WriteBytes(DC *dc, const BYTE *bytes, int number); +extern BOOL PSDRV_WriteDIBits16(DC *dc, const WORD *words, int number); +extern BOOL PSDRV_WriteDIBits24(DC *dc, const BYTE *bits, int number); +extern BOOL PSDRV_WriteDIBits32(DC *dc, const BYTE *bits, int number);