wineps: Add a couple of helper functions to simplify the StretchDIBits implementation.
This commit is contained in:
parent
116160f4ef
commit
632391dbf4
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue