From 632391dbf42e67d296a405afb3958a7c4b99e066 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 20 Jul 2011 14:36:10 +0200 Subject: [PATCH] wineps: Add a couple of helper functions to simplify the StretchDIBits implementation. --- dlls/wineps.drv/bitmap.c | 146 +++++++++++++-------------------------- dlls/wineps.drv/ps.c | 33 +++++++-- dlls/wineps.drv/psdrv.h | 3 +- 3 files changed, 76 insertions(+), 106 deletions(-) diff --git a/dlls/wineps.drv/bitmap.c b/dlls/wineps.drv/bitmap.c index 681307db767..cb4ea3048be 100644 --- a/dlls/wineps.drv/bitmap.c +++ b/dlls/wineps.drv/bitmap.c @@ -94,44 +94,16 @@ static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, 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(dev, 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(dev, map, 256); - PSDRV_WriteIndexColorSpaceEnd(dev); - break; - - case 4: - PSDRV_WriteIndexColorSpaceBegin(dev, 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(dev, map, 16); - PSDRV_WriteIndexColorSpaceEnd(dev); - break; - + switch(info->bmiHeader.biBitCount) + { case 1: - PSDRV_WriteIndexColorSpaceBegin(dev, 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(dev, map, 2); + case 4: + case 8: + PSDRV_WriteIndexColorSpaceBegin(dev, (1 << info->bmiHeader.biBitCount) - 1); + PSDRV_WriteRGBQUAD(dev, info->bmiColors, 1 << info->bmiHeader.biBitCount); PSDRV_WriteIndexColorSpaceEnd(dev); break; - case 15: case 16: case 24: case 32: @@ -142,14 +114,10 @@ static BOOL PSDRV_WriteImageHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst PSDRV_WriteSetColor(dev, &pscol); break; } - - default: - FIXME("Not implemented yet\n"); - return FALSE; } PSDRV_WriteImage(dev, info->bmiHeader.biBitCount, xDst, yDst, - widthDst, heightDst, widthSrc, heightSrc, FALSE); + widthDst, heightDst, widthSrc, heightSrc, FALSE, info->bmiHeader.biHeight < 0); return TRUE; } @@ -170,24 +138,20 @@ static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT INT yDst, INT widthDst, INT heightDst, INT widthSrc, INT heightSrc) { - COLORREF map[2]; PSCOLOR bkgnd, foregnd; - int i; assert(info->bmiHeader.biBitCount == 1); - for(i = 0; i < 2; i++) { - map[i] = info->bmiColors[i].rgbRed | - info->bmiColors[i].rgbGreen << 8 | - info->bmiColors[i].rgbBlue << 16; - } - /* We'll write the mask with -ve polarity so that the foregnd color corresponds to a bit equal to 0 in the bitmap. */ - PSDRV_CreateColor(dev, &foregnd, map[0]); - PSDRV_CreateColor(dev, &bkgnd, map[1]); + PSDRV_CreateColor(dev, &foregnd, RGB(info->bmiColors[0].rgbRed, + info->bmiColors[0].rgbGreen, + info->bmiColors[0].rgbBlue) ); + PSDRV_CreateColor(dev, &bkgnd, RGB(info->bmiColors[1].rgbRed, + info->bmiColors[1].rgbGreen, + info->bmiColors[1].rgbBlue) ); PSDRV_WriteGSave(dev); PSDRV_WriteNewPath(dev); @@ -198,7 +162,7 @@ static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT PSDRV_WriteSetColor(dev, &foregnd); PSDRV_WriteImage(dev, 1, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc, TRUE); + widthSrc, heightSrc, TRUE, info->bmiHeader.biHeight < 0); return TRUE; } @@ -213,6 +177,34 @@ static inline DWORD max_ascii85_size(DWORD size) return (size + 3) / 4 * 5; } +/*************************************************************************** + * PSDRV_WriteImageBits + */ +static void PSDRV_WriteImageBits( PHYSDEV dev, const BITMAPINFO *info, INT xDst, INT yDst, + INT widthDst, INT heightDst, INT widthSrc, INT heightSrc, + void *bits, DWORD size ) +{ + BYTE *rle, *ascii85; + DWORD rle_len, ascii85_len; + + if (info->bmiHeader.biBitCount == 1) + /* Use imagemask rather than image */ + PSDRV_WriteImageMaskHeader(dev, info, xDst, yDst, widthDst, heightDst, + widthSrc, heightSrc); + else + PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst, + widthSrc, heightSrc); + + rle = HeapAlloc(GetProcessHeap(), 0, max_rle_size(size)); + rle_len = RLE_encode(bits, size, rle); + ascii85 = HeapAlloc(GetProcessHeap(), 0, max_ascii85_size(rle_len)); + ascii85_len = ASCII85_encode(rle, rle_len, ascii85); + HeapFree(GetProcessHeap(), 0, rle); + PSDRV_WriteData(dev, ascii85, ascii85_len); + PSDRV_WriteSpool(dev, "~>\n", 3); + HeapFree(GetProcessHeap(), 0, ascii85); +} + /*************************************************************************** * * PSDRV_StretchDIBits @@ -232,8 +224,8 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT line; POINT pt[2]; const BYTE *src_ptr; - BYTE *dst_ptr, *bitmap, *rle, *ascii85; - DWORD rle_len, ascii85_len, bitmap_size; + BYTE *dst_ptr, *bitmap; + DWORD bitmap_size; TRACE("%p (%d,%d %dx%d) -> (%d,%d %dx%d)\n", dev->hdc, xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst); @@ -241,7 +233,6 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, if (!get_bitmap_info( info, &fullSrcWidth, &fullSrcHeight, &bpp, &compression )) return FALSE; stride = get_dib_width_bytes(fullSrcWidth, bpp); - if(fullSrcHeight < 0) stride = -stride; /* top-down */ TRACE("full size=%dx%d bpp=%d compression=%d rop=%08x\n", fullSrcWidth, fullSrcHeight, bpp, compression, dwRop); @@ -265,14 +256,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, switch(bpp) { case 1: - PSDRV_SetClip(dev); - PSDRV_WriteGSave(dev); - - /* Use imagemask rather than image */ - PSDRV_WriteImageMaskHeader(dev, info, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc); src_ptr = bits; - if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride; src_ptr += (ySrc * stride); if(xSrc & 7) FIXME("This won't work...\n"); @@ -283,12 +267,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, break; case 4: - PSDRV_SetClip(dev); - PSDRV_WriteGSave(dev); - PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc); src_ptr = bits; - if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride; src_ptr += (ySrc * stride); if(xSrc & 1) FIXME("This won't work...\n"); @@ -299,12 +278,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, break; case 8: - PSDRV_SetClip(dev); - PSDRV_WriteGSave(dev); - PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc); src_ptr = bits; - if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride; src_ptr += (ySrc * stride); bitmap_size = heightSrc * widthSrc; dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size); @@ -312,16 +286,8 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, memcpy(dst_ptr, src_ptr + xSrc, widthSrc); break; - case 15: case 16: - PSDRV_SetClip(dev); - PSDRV_WriteGSave(dev); - PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc); - - src_ptr = bits; - if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride; src_ptr += (ySrc * stride); bitmap_size = heightSrc * widthSrc * 3; dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size); @@ -348,13 +314,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, break; case 24: - PSDRV_SetClip(dev); - PSDRV_WriteGSave(dev); - PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc); - src_ptr = bits; - if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride; src_ptr += (ySrc * stride); bitmap_size = heightSrc * widthSrc * 3; dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size); @@ -371,13 +331,7 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, break; case 32: - PSDRV_SetClip(dev); - PSDRV_WriteGSave(dev); - PSDRV_WriteImageHeader(dev, info, xDst, yDst, widthDst, heightDst, - widthSrc, heightSrc); - src_ptr = bits; - if(stride < 0) src_ptr += (fullSrcHeight + 1) * stride; src_ptr += (ySrc * stride); bitmap_size = heightSrc * widthSrc * 3; dst_ptr = bitmap = HeapAlloc(GetProcessHeap(), 0, bitmap_size); @@ -399,15 +353,11 @@ INT PSDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, } - rle = HeapAlloc(GetProcessHeap(), 0, max_rle_size(bitmap_size)); - rle_len = RLE_encode(bitmap, bitmap_size, rle); + PSDRV_SetClip(dev); + PSDRV_WriteGSave(dev); + PSDRV_WriteImageBits( dev, info, xDst, yDst, widthDst, heightDst, + widthSrc, heightSrc, bitmap, bitmap_size ); HeapFree(GetProcessHeap(), 0, bitmap); - ascii85 = HeapAlloc(GetProcessHeap(), 0, max_ascii85_size(rle_len)); - ascii85_len = ASCII85_encode(rle, rle_len, ascii85); - HeapFree(GetProcessHeap(), 0, rle); - PSDRV_WriteData(dev, ascii85, ascii85_len); - HeapFree(GetProcessHeap(), 0, ascii85); - PSDRV_WriteSpool(dev, "~>\n", 3); PSDRV_WriteGRestore(dev); PSDRV_ResetClip(dev); return abs(heightSrc); diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c index 7a935646b74..ab9d5707411 100644 --- a/dlls/wineps.drv/ps.c +++ b/dlls/wineps.drv/ps.c @@ -672,8 +672,23 @@ BOOL PSDRV_WriteRGB(PHYSDEV dev, COLORREF *map, int number) return TRUE; } +BOOL PSDRV_WriteRGBQUAD(PHYSDEV dev, const RGBQUAD *rgb, int number) +{ + char *buf = HeapAlloc(PSDRV_Heap, 0, number * 7 + 1), *ptr; + int i; + + ptr = buf; + for(i = 0; i < number; i++) + ptr += sprintf(ptr, "%02x%02x%02x%c", rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue, + ((i & 0x7) == 0x7) || (i == number - 1) ? '\n' : ' '); + + PSDRV_WriteSpool(dev, buf, ptr - buf); + HeapFree(PSDRV_Heap, 0, buf); + return TRUE; +} + static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth, - INT widthSrc, INT heightSrc, char *bits) + INT widthSrc, INT heightSrc, char *bits, BOOL top_down) { static const char start[] = "<<\n" " /ImageType 1\n /Width %d\n /Height %d\n /BitsPerComponent %d\n" @@ -687,8 +702,12 @@ static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth, char *buf = HeapAlloc(PSDRV_Heap, 0, 1000); - sprintf(buf, start, widthSrc, heightSrc, - (depth < 8) ? depth : 8, widthSrc, -heightSrc, heightSrc); + if (top_down) + sprintf(buf, start, widthSrc, heightSrc, + (depth < 8) ? depth : 8, widthSrc, heightSrc, 0); + else + sprintf(buf, start, widthSrc, heightSrc, + (depth < 8) ? depth : 8, widthSrc, -heightSrc, heightSrc); PSDRV_WriteSpool(dev, buf, strlen(buf)); @@ -725,7 +744,7 @@ static BOOL PSDRV_WriteImageDict(PHYSDEV dev, WORD depth, BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst, INT widthDst, INT heightDst, INT widthSrc, - INT heightSrc, BOOL mask) + INT heightSrc, BOOL mask, BOOL top_down) { static const char start[] = "%d %d translate\n%d %d scale\n"; static const char image[] = "image\n"; @@ -734,7 +753,7 @@ BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst, sprintf(buf, start, xDst, yDst, widthDst, heightDst); PSDRV_WriteSpool(dev, buf, strlen(buf)); - PSDRV_WriteImageDict(dev, depth, widthSrc, heightSrc, NULL); + PSDRV_WriteImageDict(dev, depth, widthSrc, heightSrc, NULL, top_down); if(mask) PSDRV_WriteSpool(dev, imagemask, sizeof(imagemask) - 1); else @@ -835,7 +854,7 @@ BOOL PSDRV_WritePatternDict(PHYSDEV dev, BITMAP *bm, BYTE *bits) } } PSDRV_WriteSpool(dev, mypat, sizeof(mypat) - 1); - PSDRV_WriteImageDict(dev, 1, 8, 8, buf); + PSDRV_WriteImageDict(dev, 1, 8, 8, buf, FALSE); PSDRV_WriteSpool(dev, "def\n", 4); PSDRV_WriteIndexColorSpaceBegin(dev, 1); @@ -892,7 +911,7 @@ BOOL PSDRV_WriteDIBPatternDict(PHYSDEV dev, BITMAPINFO *bmi, UINT usage) } } PSDRV_WriteSpool(dev, mypat, sizeof(mypat) - 1); - PSDRV_WriteImageDict(dev, 1, 8, 8, buf); + PSDRV_WriteImageDict(dev, 1, 8, 8, buf, FALSE); PSDRV_WriteSpool(dev, "def\n", 4); PSDRV_WriteIndexColorSpaceBegin(dev, 1); diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index b9b6a797407..d228023db2a 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -516,9 +516,10 @@ extern BOOL PSDRV_WriteRotate(PHYSDEV dev, float ang) DECLSPEC_HIDDEN; extern BOOL PSDRV_WriteIndexColorSpaceBegin(PHYSDEV dev, int size) DECLSPEC_HIDDEN; extern BOOL PSDRV_WriteIndexColorSpaceEnd(PHYSDEV dev) DECLSPEC_HIDDEN; extern BOOL PSDRV_WriteRGB(PHYSDEV dev, COLORREF *map, int number) DECLSPEC_HIDDEN; +extern BOOL PSDRV_WriteRGBQUAD(PHYSDEV dev, const RGBQUAD *rgb, int number) DECLSPEC_HIDDEN; extern BOOL PSDRV_WriteImage(PHYSDEV dev, WORD depth, INT xDst, INT yDst, INT widthDst, INT heightDst, INT widthSrc, - INT heightSrc, BOOL mask) DECLSPEC_HIDDEN; + INT heightSrc, BOOL mask, BOOL top_down) DECLSPEC_HIDDEN; extern BOOL PSDRV_WriteBytes(PHYSDEV dev, const BYTE *bytes, DWORD number) DECLSPEC_HIDDEN; extern BOOL PSDRV_WriteData(PHYSDEV dev, const BYTE *byte, DWORD number) DECLSPEC_HIDDEN; extern DWORD PSDRV_WriteSpool(PHYSDEV dev, LPCSTR lpData, DWORD cch) DECLSPEC_HIDDEN;