linamh/app-emulation/wine/files/0009-dib-engine-fixes-against-wine-.patch
2009-08-01 09:30:00 +00:00

1696 lines
65 KiB
Diff

DIB Engine: fixes against wine tests
From: Massimo Del Fedele <max@veneto.com>
---
dlls/winedib.drv/bitblt.c | 68 +++---
dlls/winedib.drv/convert.c | 16 +
dlls/winedib.drv/dc.c | 32 +--
dlls/winedib.drv/dib.c | 405 ++++++++++++++++++++++++++++++++-
dlls/winedib.drv/dibdrv.h | 27 ++
dlls/winedib.drv/dibdrvbitmap.c | 124 ++++++++++
dlls/winedib.drv/graphics.c | 10 +
dlls/winedib.drv/palette.c | 63 +++++
dlls/winedib.drv/pen_brush.c | 95 ++++++--
dlls/winedib.drv/primitives_bitblt.c | 18 +
dlls/winedib.drv/primitives_color.c | 71 ++++--
dlls/winedib.drv/primitives_convert.c | 66 ++++-
dlls/winedib.drv/primitives_pixel.c | 44 ++--
13 files changed, 883 insertions(+), 156 deletions(-)
diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c
index db66142..97feefd 100644
--- a/dlls/winedib.drv/bitblt.c
+++ b/dlls/winedib.drv/bitblt.c
@@ -82,7 +82,7 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*
ys1 = ps->y;
xs2 = xs1 + w;
ys2 = ys1 + h;
-
+
/* if source clip area is not null, do first clipping on it */
if(srcClip)
{
@@ -91,7 +91,7 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*
ysc1 = srcClip->top;
xsc2 = srcClip->right;
ysc2 = srcClip->bottom;
-
+
/* order clip area rectangle points */
if(xsc1 > xsc2) intSwap(&xsc1, &xsc2);
if(ysc1 > ysc2) intSwap(&ysc1, &ysc2);
@@ -103,13 +103,12 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*
/* clip on source clipping end point */
if(xs2 > xsc2) { dx = xs2 - xsc2; w -= dx; xd2 -= dx; xs2 = xsc2; }
if(ys2 > ysc2) { dy = ys2 - ysc2; h -= dy; yd2 -= dy; ys2 = ysc2; }
-
+
/* if already zero area, return false */
if(w <= 0 || h <= 0)
return FALSE;
}
/* now do clipping on destination area */
-
if(dstClip)
{
/* extract destination clipping area */
@@ -117,7 +116,7 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*
ydc1 = dstClip->top;
xdc2 = dstClip->right;
ydc2 = dstClip->bottom;
-
+
/* order clip area rectangle points */
if(xdc1 > xdc2) intSwap(&xdc1, &xdc2);
if(ydc1 > ydc2) intSwap(&ydc1, &ydc2);
@@ -267,6 +266,13 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
_DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst);
_DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc);
_DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc);
+
+ /* from tests, it seems that negative coords on phys space are not allowed */
+ if(xDst < 0 || yDst < 0 || xSrc < 0 || ySrc < 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
/* first clip on physical DC sizes */
setPoint(&pd, xDst, yDst);
@@ -282,7 +288,7 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
else
res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip);
if(!res)
- return FALSE;
+ return TRUE;
xDst = pd.x; yDst = pd.y;
xSrc = ps.x; ySrc = ps.y;
widthDst = szDst.cx; heightDst = szDst.cy;
@@ -317,9 +323,7 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
BOOL res;
POINT pd = {xDst, yDst};
- POINT ps = {xSrc, ySrc};
SIZE szDst = {widthDst, heightDst};
- SIZE szSrc = {widthSrc, heightSrc};
MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n",
physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "",
@@ -327,10 +331,12 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
xSrc, ySrc, widthSrc, heightSrc));
- /* if sizes are null or negative, returns false */
- if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0)
+ /* if sizes are null or negative, or source positions are negatives, returns false */
+ if(widthSrc <= 0 || heightSrc <= 0 ||
+ widthDst <= 0 || heightDst <= 0)
{
res = FALSE;
+ SetLastError(ERROR_INVALID_PARAMETER);
goto fin;
}
@@ -360,18 +366,25 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
/* DDB selected on dest DC -- must double-convert */
HBITMAP tmpDIB, stock;
HDC tmpDC;
- RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
MAYBE(TRACE("Blending DIB->DDB\n"));
- /* clip blit area */
- res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0);
- if(!res)
+ /* we should anyways convert dest to physical coordinates here before processing
+ in order to check its consistency -- source coords will be converted/clipped later
+ As we do a conversion to a temporary DIB for destination, we don't care about it */
+ _DIBDRV_Position_ws2ds(physDevDst, &pd.x, &pd.y);
+ _DIBDRV_Sizes_ws2ds(physDevDst, &szDst.cx, &szDst.cy);
+
+ /* test shows that negatives origins are not allowed */
+ if(pd.x < 0 || pd.y < 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ res = FALSE;
goto fin;
- xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
- xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
+ }
/* converts dest DDB onto a temporary DIB -- just the needed part */
- tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst);
+ /* WARNING -- that one could fail if rectangle on dest id out of range */
+ tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, pd.x, pd.y, szDst.cx, szDst.cy);
if(!tmpDIB)
{
ERR("Couldn't convert dest DDB to DIB\n");
@@ -399,7 +412,7 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
}
/* blends source DIB onto temp DIB and re-blits onto dest DC */
- res = GdiAlphaBlend(tmpDC, 0, 0, widthDst, heightDst, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
+ res = GdiAlphaBlend(tmpDC, 0, 0, szDst.cx, szDst.cy, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn);
if(!res)
MAYBE(TRACE("AlphaBlend failed\n"));
else
@@ -438,6 +451,7 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
setPoint(&ps, xSrc, ySrc);
setSize(&sz, width, height);
setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height);
+
if(physDevSrc)
{
setRect(&srcClip, 0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height);
@@ -446,13 +460,13 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
else
res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip);
if(!res)
- return FALSE;
+ return TRUE;
xDst = pd.x; yDst = pd.y;
xSrc = ps.x; ySrc = ps.y;
width = sz.cx; height = sz.cy;
/* then, do blitting for each dest clip area (no clipping on source) */
- res = FALSE;
+ res = TRUE;
for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++)
{
RECT *r = physDevDst->regionRects + iRec;
@@ -462,8 +476,8 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
setSize(&sz, width, height);
if(!BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip))
continue;
- if(physDevDst->physBitmap.funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop))
- res = TRUE;
+ if(!physDevDst->physBitmap.funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop))
+ res = FALSE;
}
return res;
}
@@ -503,8 +517,8 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
/* source is a DDB, must convert it to DIB */
/* don't clip on source */
- res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip);
- if(!res)
+ res = !BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip);
+ if(res)
goto noBlt2;
xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y;
@@ -596,11 +610,11 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
if(physDevSrc)
{
RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
- res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0);
+ res = !BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0);
}
else
- res = TRUE;
- if(!res)
+ res = FALSE;
+ if(res)
goto noBlt3;
xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y;
diff --git a/dlls/winedib.drv/convert.c b/dlls/winedib.drv/convert.c
index dc18e14..2f20ac1 100644
--- a/dlls/winedib.drv/convert.c
+++ b/dlls/winedib.drv/convert.c
@@ -51,7 +51,7 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca
HDC tmpHdc;
HBITMAP tmpBmp;
int res;
-
+
/* gets DIBSECTION data from source DIB */
if(GetObjectW(srcBmp, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION))
{
@@ -87,13 +87,10 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca
/* gets the size of DIB palette and bitfields, if any */
bitFields = 0;
- if(ds.dsBmih.biBitCount > 8)
- {
- colorUsed = 0;
- if(ds.dsBmih.biCompression == BI_BITFIELDS)
+ colorUsed = 0;
+ if(ds.dsBmih.biCompression == BI_BITFIELDS)
bitFields = 3;
- }
- else
+ else if(ds.dsBmih.biBitCount <= 8)
{
colorUsed = ds.dsBmih.biClrUsed;
if(!colorUsed)
@@ -131,9 +128,11 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca
HeapFree(GetProcessHeap(), 0, bmi);
return 0;
}
- GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors);
+ if(!GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors))
+ ERR("GetDIBColorTable failed\n");
SelectObject(tmpHdc, tmpBmp);
DeleteDC(tmpHdc);
+
}
/* fill the bitfields part, if any */
@@ -165,6 +164,7 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca
DeleteObject( hBmp );
return 0;
}
+
return hBmp;
}
diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c
index 9ffceee..f5324b0 100644
--- a/dlls/winedib.drv/dc.c
+++ b/dlls/winedib.drv/dc.c
@@ -80,6 +80,10 @@ static DWORD get_dpi( void )
return dpi;
}
+/* dummy function for pen/brush drawing primitives initializations */
+static void dummy4(DIBDRVPHYSDEV *physDev, int a, int b, int c) {} ;
+static void dummy5(DIBDRVPHYSDEV *physDev, int a, int b, int c, int d) {} ;
+
/**********************************************************************
* device_init
*
@@ -120,10 +124,6 @@ static void device_init(void)
device_init_done = TRUE;
}
-/* dummy null function for pen and brush */
-static void dummy3(DIBDRVPHYSDEV *p, int a, int b, int c) {}
-static void dummy4(DIBDRVPHYSDEV *p, int a, int b, int c, int d) {}
-
/**********************************************************************
* DIBDRV_CreateDC
*/
@@ -180,22 +180,24 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev
physDev->backgroundColor = 0;
_DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor);
+ /* stock pen */
+ physDev->penStyle = PS_NULL;
physDev->penColor = 0;
+ physDev->penColorref = 0;
_DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
-
- physDev->penStyle = PS_NULL;
- physDev->penHLine = dummy3;
- physDev->penVLine = dummy3;
- physDev->penLine = dummy4;
+ physDev->penHLine = dummy4;
+ physDev->penVLine = dummy4;
+ physDev->penLine = dummy5;
physDev->penPattern = NULL;
- physDev->brushColor = 0;
- _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor);
+ /* stock brush */
+ physDev->brushStyle = BS_NULL;
+ physDev->brushColor = 0x0;
+ physDev->brushColorref = 0x0;
+ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0x0, &physDev->brushAnd, &physDev->brushXor);
physDev->brushAnds = NULL;
physDev->brushXors = NULL;
-
- physDev->brushStyle = BS_NULL;
- physDev->brushHLine = dummy3;
+ physDev->brushHLine = dummy4;
physDev->isBrushBitmap = FALSE;
_DIBDRVBITMAP_Clear(&physDev->brushBitmap);
@@ -215,7 +217,7 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev
/* sets the result value and returns */
*pdev = physDev;
-
+
return TRUE;
}
diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c
index 653148d..41fb158 100644
--- a/dlls/winedib.drv/dib.c
+++ b/dlls/winedib.drv/dib.c
@@ -25,6 +25,43 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+/* Default 1 BPP palette */
+static DWORD pal1[] =
+{
+ 0x000000,
+ 0xffffff
+};
+
+/* Default 4 BPP palette */
+static DWORD pal4[] =
+{
+ 0x000000,0x800000,0x008000,0x808000,
+ 0x000080,0x800080,0x008080,0x808080,
+ 0xc0c0c0,0xff0000,0x00ff00,0xffff00,
+ 0x0000ff,0xff00ff,0x00ffff,0xffffff
+};
+
+/* Default 8 BPP palette */
+static DWORD pal8[] =
+{
+ 0x000000,0x800000,0x008000,0x808000,0x000080,0x800080,0x008080,0xc0c0c0,0xc0dcc0,0xa6caf0,0x000000,0x000033,0x000066,0x000099,0x0000cc,0x0000ff,
+ 0x003300,0x003333,0x003366,0x003399,0x0033cc,0x0033ff,0x006600,0x006633,0x006666,0x006699,0x0066cc,0x0066ff,0x009900,0x009933,0x009966,0x009999,
+ 0x0099cc,0x0099ff,0x00cc00,0x00cc33,0x00cc66,0x00cc99,0x00cccc,0x00ccff,0x00ff00,0x00ff33,0x00ff66,0x00ff99,0x00ffcc,0x00ffff,0x330000,0x330033,
+ 0x330066,0x330099,0x3300cc,0x3300ff,0x333300,0x333333,0x333366,0x333399,0x3333cc,0x3333ff,0x336600,0x336633,0x336666,0x336699,0x3366cc,0x3366ff,
+ 0x339900,0x339933,0x339966,0x339999,0x3399cc,0x3399ff,0x33cc00,0x33cc33,0x33cc66,0x33cc99,0x33cccc,0x33ccff,0x33ff00,0x33ff33,0x33ff66,0x33ff99,
+ 0x33ffcc,0x33ffff,0x660000,0x660033,0x660066,0x660099,0x6600cc,0x6600ff,0x663300,0x663333,0x663366,0x663399,0x6633cc,0x6633ff,0x666600,0x666633,
+ 0x666666,0x666699,0x6666cc,0x6666ff,0x669900,0x669933,0x669966,0x669999,0x6699cc,0x6699ff,0x66cc00,0x66cc33,0x66cc66,0x66cc99,0x66cccc,0x66ccff,
+ 0x66ff00,0x66ff33,0x66ff66,0x66ff99,0x66ffcc,0x66ffff,0x990000,0x990033,0x990066,0x990099,0x9900cc,0x9900ff,0x993300,0x993333,0x993366,0x993399,
+ 0x9933cc,0x9933ff,0x996600,0x996633,0x996666,0x996699,0x9966cc,0x9966ff,0x999900,0x999933,0x999966,0x999999,0x9999cc,0x9999ff,0x99cc00,0x99cc33,
+ 0x99cc66,0x99cc99,0x99cccc,0x99ccff,0x99ff00,0x99ff33,0x99ff66,0x99ff99,0x99ffcc,0x99ffff,0xcc0000,0xcc0033,0xcc0066,0xcc0099,0xcc00cc,0xcc00ff,
+ 0xcc3300,0xcc3333,0xcc3366,0xcc3399,0xcc33cc,0xcc33ff,0xcc6600,0xcc6633,0xcc6666,0xcc6699,0xcc66cc,0xcc66ff,0xcc9900,0xcc9933,0xcc9966,0xcc9999,
+ 0xcc99cc,0xcc99ff,0xcccc00,0xcccc33,0xcccc66,0xcccc99,0xcccccc,0xccccff,0xccff00,0xccff33,0xccff66,0xccff99,0xccffcc,0xccffff,0xff0000,0xff0033,
+ 0xff0066,0xff0099,0xff00cc,0xff00ff,0xff3300,0xff3333,0xff3366,0xff3399,0xff33cc,0xff33ff,0xff6600,0xff6633,0xff6666,0xff6699,0xff66cc,0xff66ff,
+ 0xff9900,0xff9933,0xff9966,0xff9999,0xff99cc,0xff99ff,0xffcc00,0xffcc33,0xffcc66,0xffcc99,0xffcccc,0xffccff,0xffff00,0xffff33,0xffff66,0xffff99,
+ 0xffffcc,0xffffff,0x050500,0x050501,0x050502,0x050503,0x050504,0x050505,0xe8e8e8,0xe9e9e9,0xeaeaea,0xebebeb,0xececec,0xededed,0xeeeeee,0xefefef,
+ 0xf0f0f0,0xf1f1f1,0xf2f2f2,0xf3f3f3,0xf4f4f4,0xf5f5f5,0xfffbf0,0xa0a0a4,0x808080,0xf00000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00ffff,0xffffff
+};
+
/***********************************************************************
* DIBDRV_CreateDIBSection
*/
@@ -46,15 +83,206 @@ HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap,
* DIBDRV_GetDIBits
*/
INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
- UINT lines, LPCVOID bits, const BITMAPINFO *bmi, UINT coloruse )
+ UINT lines, LPVOID bits, BITMAPINFO *info, UINT coloruse )
{
INT res;
-
- MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n",
- physDev, hbitmap, startscan, lines, bits, bmi, coloruse));
+ DIBSECTION ds;
+ DIBDRVBITMAP sBmp, dBmp;
+ DWORD *buf;
+ int iLine;
+ int size;
+ BOOL justInfo, justInfoHeader;
+ int requestedBpp;
+ RGBQUAD *colorTable;
+ int colorTableSize;
+ BITMAPINFO *sourceInfo;
- /* GetDIBits reads bits from a DDB, so we should use the X11 driver */
- res = _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, bmi, coloruse);
+ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n",
+ physDev, hbitmap, startscan, lines, bits, info, coloruse));
+ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION))
+ {
+ /* GetDIBits reads bits from a DIB, so we should use the engine driver */
+
+ /* for the moment, we don't support startscan != 0 */
+ if(startscan != 0)
+ {
+ FIXME("startscan != 0 still not supported\n");
+ return 0;
+ }
+
+ /* sanity check */
+ size = info->bmiHeader.biSize;
+ if(size != sizeof(BITMAPINFOHEADER) && size != sizeof(BITMAPCOREHEADER))
+ {
+ ERR("Unknown header size %d\n", size);
+ return 0;
+ }
+
+ /* get requested BPP */
+ requestedBpp = info->bmiHeader.biBitCount;
+
+ /* check wetrher we wants just the BITMAPINFO data */
+ justInfo = (bits == NULL);
+
+ /* check wether we wants just to get BITMAPINFOHEADER data */
+ justInfoHeader = (requestedBpp == 0);
+
+ if(!justInfo && justInfoHeader)
+ {
+ ERR("Bad requested BPP\n");
+ return 0;
+ }
+
+ /* copy / set missing DIB info */
+ if(justInfo)
+ {
+ info->bmiHeader.biWidth = ds.dsBmih.biWidth;
+ info->bmiHeader.biHeight = ds.dsBmih.biHeight;
+ }
+ info->bmiHeader.biPlanes = 1;
+ if(justInfoHeader)
+ info->bmiHeader.biBitCount = ds.dsBmih.biBitCount;
+ if(size == sizeof(BITMAPINFOHEADER))
+ {
+ if(justInfoHeader)
+ {
+ info->bmiHeader.biCompression = ds.dsBmih.biCompression;
+ info->bmiHeader.biXPelsPerMeter = ds.dsBmih.biXPelsPerMeter;
+ info->bmiHeader.biYPelsPerMeter = ds.dsBmih.biYPelsPerMeter;
+ info->bmiHeader.biClrUsed = ds.dsBmih.biClrUsed;
+ info->bmiHeader.biClrImportant = ds.dsBmih.biClrImportant;
+ }
+ info->bmiHeader.biSizeImage = ds.dsBmih.biSizeImage;
+ }
+
+ /* width and height *must* match source's ones */
+ if(info->bmiHeader.biWidth != ds.dsBmih.biWidth ||
+ abs(info->bmiHeader.biHeight) != abs(ds.dsBmih.biHeight))
+ {
+ ERR("Size of requested bitmap data don't match source's ones\n");
+ return 0;
+ }
+
+ /* if we just wants the BITMAPINFOHEADER data, we're done */
+ if(justInfoHeader || (justInfo && ds.dsBmih.biBitCount > 8))
+ return abs(info->bmiHeader.biHeight);
+
+ /* we now have to get source data -- we need it for palette, for example */
+ colorTableSize = 0;
+ if(ds.dsBmih.biBitCount <= 8)
+ colorTableSize = (1 << ds.dsBmih.biBitCount);
+ else if(ds.dsBmih.biCompression == BI_BITFIELDS)
+ colorTableSize = 3;
+ sourceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + colorTableSize * sizeof(RGBQUAD));
+ if(!sourceInfo)
+ {
+ ERR("HeapAlloc failed\n");
+ return 0;
+ }
+ memcpy(sourceInfo, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
+ if(ds.dsBmih.biBitCount <= 8)
+ {
+ /* grab palette - well, we should. No way to do it by now....
+ we should add a list HBITMAP <--> DIBDRVBITMAP and fiddle to many
+ , many parts of the engine. Not worth the effort by now.
+ So, we just synthesize the table */
+ switch(requestedBpp)
+ {
+ case 1:
+ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal1, 2*sizeof(DWORD));
+ break;
+
+ case 4:
+ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal4, 16*sizeof(DWORD));
+ break;
+
+ case 8:
+ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal8, 256*sizeof(DWORD));
+ break;
+
+ default:
+ ERR("Unknown requested bith depth %d\n", requestedBpp);
+ _DIBDRVBITMAP_Free(&sBmp);
+ return 0;
+ }
+ }
+ else if(ds.dsBmih.biCompression == BI_BITFIELDS)
+ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), ds.dsBitfields, 3 * sizeof(RGBQUAD));
+ _DIBDRVBITMAP_Clear(&sBmp);
+ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, sourceInfo))
+ {
+ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n");
+ HeapFree(GetProcessHeap(), 0, sourceInfo);
+ return 0;
+ }
+ _DIBDRVBITMAP_Set_Bits(&sBmp, ds.dsBm.bmBits, FALSE);
+ HeapFree(GetProcessHeap(), 0, sourceInfo);
+
+ /* now grab / synthesize the color table if needed */
+ if(requestedBpp <= 8)
+ {
+ colorTable = (RGBQUAD *)((BYTE *)info + size);
+ if(requestedBpp == ds.dsBmih.biBitCount)
+ {
+ /* same source and dest format - copy color tables */
+ memcpy(colorTable, sBmp.colorTable, colorTableSize);
+ }
+ else
+ {
+ /* different formats -- synthesize color table */
+ switch(requestedBpp)
+ {
+ case 1:
+ memcpy(colorTable, pal1, 2*sizeof(DWORD));
+ break;
+
+ case 4:
+ memcpy(colorTable, pal4, 16*sizeof(DWORD));
+ break;
+
+ case 8:
+ memcpy(colorTable, pal8, 256*sizeof(DWORD));
+ break;
+
+ default:
+ ERR("Unknown requested bith depth %d\n", requestedBpp);
+ _DIBDRVBITMAP_Free(&sBmp);
+ return 0;
+ }
+ }
+ }
+
+ /* if we just wanted DIB info, job is done */
+ if(justInfo)
+ {
+ _DIBDRVBITMAP_Free(&sBmp);
+ return abs(info->bmiHeader.biHeight);
+ }
+
+ /* Creates a DIBDRVBITMAP from dest dib */
+ _DIBDRVBITMAP_Clear(&dBmp);
+ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&dBmp, info))
+ {
+ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n");
+ _DIBDRVBITMAP_Free(&sBmp);
+ return 0;
+ }
+ _DIBDRVBITMAP_Set_Bits(&dBmp, bits, FALSE);
+
+ /* now we can do the bit conversion */
+ buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD));
+ for(iLine = 0; iLine < lines; iLine++)
+ {
+ sBmp.funcs->GetLine(&sBmp, iLine, 0, ds.dsBmih.biWidth, buf);
+ dBmp.funcs->PutLine(&dBmp, iLine, 0, ds.dsBmih.biWidth, buf);
+ }
+ _DIBDRVBITMAP_Free(&sBmp);
+ _DIBDRVBITMAP_Free(&dBmp);
+ return lines;
+ }
+ else
+ /* GetDIBits reads bits from a DDB, use X11 driver */
+ res = _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse);
return res;
}
@@ -66,7 +294,10 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
const RGBQUAD *colors )
{
DIBDRVBITMAP *dib = &physDev->physBitmap;
-
+#if 0
+ HBITMAP thisDIB;
+#endif
+
MAYBE(TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors));
/* SetDIBColorTable operates on a DIB, so we use the engine */
@@ -80,7 +311,7 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
/* if dib hasn't a color table, or has a small one, we must before
create/extend it */
- if(!(dib->colorTable))
+ if(!dib->colorTable)
{
dib->colorTableSize = (1 << dib->bitCount);
dib->colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(RGBQUAD) * dib->colorTableSize);
@@ -104,6 +335,13 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
memcpy(dib->colorTable + start, colors, sizeof(RGBQUAD) * count);
dib->colorTableGrabbed = TRUE;
+ /* hack to make GDI32 sense the DIB color table change
+ (fixes a couple of todos in bitmap test suite */
+#if 0
+ thisDIB = SelectObject(physDev->hdc, GetStockObject(OBJ_BITMAP));
+ SelectObject(physDev->hdc, thisDIB);
+#endif
+
return TRUE;
}
@@ -114,13 +352,59 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
{
INT res;
+ DIBSECTION ds;
+ DIBDRVBITMAP sBmp, dBmp;
+ DWORD *buf;
+ int iLine;
MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n",
physDev, hbitmap, startscan, lines, bits, info, coloruse));
- /* SetDIBits writes bits to a DDB, so we should use the X11 driver */
- res = _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse);
+ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION))
+ {
+ /* SetDIBits writes bits to a DIB, so we should use the engine driver */
+
+ /* for the moment, we don't support startscan != 0 */
+ if(startscan != 0)
+ {
+ FIXME("startscan != 0 still not supported\n");
+ return 0;
+ }
+
+ /* Creates a DIBDRVBITMAP from source dib */
+ _DIBDRVBITMAP_Clear(&sBmp);
+ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, info))
+ {
+ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n");
+ return 0;
+ }
+ _DIBDRVBITMAP_Set_Bits(&sBmp, (LPVOID)bits, FALSE);
+
+ /* same for destination dib */
+ if(!_DIBDRVBITMAP_InitFromHBITMAP(&dBmp, hbitmap, FALSE))
+ {
+ ERR("_DIBDRVBITMAP_InitFromHBITMAP failed\n");
+ _DIBDRVBITMAP_Free(&sBmp);
+ return 0;
+ }
+
+ /* now we can do the bit conversion */
+ buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD));
+ for(iLine = 0; iLine < lines; iLine++)
+ {
+ sBmp.funcs->GetLine(&sBmp, iLine, 0, ds.dsBmih.biWidth, buf);
+ dBmp.funcs->PutLine(&dBmp, iLine, 0, ds.dsBmih.biWidth, buf);
+ }
+ _DIBDRVBITMAP_Free(&sBmp);
+ _DIBDRVBITMAP_Free(&dBmp);
+ return lines;
+ }
+ else
+ {
+ /* SetDIBits writes bits to a DDB, so we should use the X11 driver */
+ res = _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse);
+ }
return res;
}
@@ -132,14 +416,105 @@ INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWOR
UINT startscan, UINT lines, LPCVOID bits,
const BITMAPINFO *info, UINT coloruse )
{
- INT res;
+ BITMAPINFO *bitmapInfo;
+ int bmInfoSize;
+ int dibHeight, dibWidth;
+ DIBDRVBITMAP sBmp;
+ int sLine, dLine, iLine;
+ void *buf;
MAYBE(TRACE("physDev:%p, xDest:%d, yDest:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n",
physDev, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse));
- /* SetDIBitsToDevice operates on a physical device, so we should use the X11 driver */
- res = _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc,
- startscan, lines, bits, info, coloruse);
+ if(physDev->hasDIB)
+ {
+ /* DIB section selected in, use DIB Engine */
+
+ /* inverts y on source -- FIXME: check if right with some tests, it seems so */
+ ySrc = abs(info->bmiHeader.biHeight) - ySrc - cy;
+
+ dibHeight = info->bmiHeader.biHeight;
+ dibWidth = info->bmiHeader.biWidth;
- return res;
+ /* sanity check and source clipping on physical sizes */
+ if(startscan >= abs(dibHeight))
+ return 0;
+ if(startscan + lines > abs(dibHeight))
+ lines = abs(dibHeight) - startscan;
+
+ /* adjust height because of startscan */
+ dibHeight += (dibHeight > 0 ? -startscan : startscan);
+
+ if(xSrc >= dibWidth)
+ return 0;
+ if(xSrc + cx > dibWidth)
+ cx = dibWidth - xSrc;
+ if(ySrc > abs(dibHeight))
+ return 0;
+ if(ySrc + cy > abs(dibHeight))
+ cy = abs(dibHeight) - ySrc;
+
+ ySrc -= startscan;
+ cy -= startscan;
+ if(cy <= 0)
+ return 0;
+ if(ySrc < 0)
+ {
+ yDest += ySrc;
+ cy += ySrc;
+ ySrc = 0;
+ }
+ if(cy <= 0)
+ return 0;
+
+ /* grab a copy of BITMAPINFO */
+ bmInfoSize = sizeof(BITMAPINFOHEADER);
+ if(info->bmiHeader.biCompression == BI_BITFIELDS)
+ bmInfoSize += 3 * sizeof(RGBQUAD);
+ else if (info->bmiHeader.biBitCount <= 8)
+ {
+ if(info->bmiHeader.biClrUsed)
+ bmInfoSize += info->bmiHeader.biClrUsed * sizeof(RGBQUAD);
+ else
+ bmInfoSize += (1 << info->bmiHeader.biBitCount) * sizeof(RGBQUAD);
+ }
+ if(!(bitmapInfo = HeapAlloc(GetProcessHeap(), 0, bmInfoSize)))
+ {
+ ERR("HeapAlloc failed\n");
+ return 0;
+ }
+ memcpy(bitmapInfo, info, bmInfoSize);
+ bitmapInfo->bmiHeader.biHeight = dibHeight;
+
+ /* create a DIBDRVBITMAP from BITMAPINFO data */
+ _DIBDRVBITMAP_Clear(&sBmp);
+ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, bitmapInfo))
+ {
+ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n");
+ HeapFree(GetProcessHeap, 0, bitmapInfo);
+ return 0;
+ }
+ HeapFree(GetProcessHeap(), 0, bitmapInfo);
+ _DIBDRVBITMAP_Set_Bits(&sBmp, (LPVOID)bits, FALSE);
+
+ /* transfer lines to dest bitmap */
+ if(!(buf = HeapAlloc(GetProcessHeap(), 0, cx * sizeof(RGBQUAD))))
+ {
+ ERR("HeapAlloc failed\n");
+ return 0;
+ }
+ for(sLine = ySrc, dLine = yDest, iLine = 0; iLine < cy; sLine++, dLine++, iLine++)
+ {
+ sBmp.funcs->GetLine(&sBmp, sLine, xSrc, cx, buf);
+ physDev->physBitmap.funcs->PutLine(&physDev->physBitmap, dLine, xDest, cx, buf);
+ }
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ return cy;
+ }
+ else
+ {
+ return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc,
+ startscan, lines, bits, info, coloruse);
+ }
}
diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h
index 66cc114..8243d4b 100644
--- a/dlls/winedib.drv/dibdrv.h
+++ b/dlls/winedib.drv/dibdrv.h
@@ -312,6 +312,11 @@ DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop);
/* gets human-readable dib format name */
const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp);
+/* sets/gets bits of a DIBDRVBITMAP taking in account if it's a top down
+ or a bottom-up DIB */
+void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns);
+void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP *dib);
+
/* initializes dib from a bitmap :
dib dib being initialized
bi source BITMAPINFOHEADER with required DIB format info
@@ -322,7 +327,7 @@ const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp);
BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
const RGBQUAD *color_table, void *bits);
-BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi);
+BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi);
/* initializes a DIBRDVBITMAP copying it from a source one
Parameters :
@@ -331,6 +336,13 @@ BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi);
copy TRUE->copy source pixel array FALSE->link to source pixel array */
BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy);
+/* initializes a DIBRDVBITMAP from a DIB HBITMAP
+ Parameters :
+ bmp destination DIBDRVBITMAP
+ hbmp source HBITMAP
+ copyPixels TRUE->copy source pixel array FALSE->link to source pixel array */
+BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL copyPixels);
+
/* creates a DIBRDVBITMAP copying format info from a source one
Parameters :
dib destination DIBDRVBITMAP
@@ -413,4 +425,17 @@ void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h);
/* converts a rectangle form Word space to Device space */
void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst);
+/* *********************************************************************
+ * COLOR UTILITIES
+ * ********************************************************************/
+
+/* maps a colorref to actual color */
+COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color);
+
+/* gets nearest color index in DIB palette of a given colorref */
+DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color);
+
+/* gets nearest color to DIB palette color */
+DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color);
+
#endif
diff --git a/dlls/winedib.drv/dibdrvbitmap.c b/dlls/winedib.drv/dibdrvbitmap.c
index 2c8c367..8e6b653 100644
--- a/dlls/winedib.drv/dibdrvbitmap.c
+++ b/dlls/winedib.drv/dibdrvbitmap.c
@@ -107,6 +107,41 @@ static void InitBitFields(DIBDRVBITMAP *dib, const DWORD *bit_fields)
CalcShiftAndLen(dib->blueMask, &dib->blueShift, &dib->blueLen);
}
+/* sets/gets bits of a DIBDRVBITMAP taking in account if it's a top down
+ or a bottom-up DIB */
+void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns)
+{
+ /* checks whether dib is top-down or bottom-up one */
+ if(dib->stride > 0)
+ {
+ /* top-down dib */
+ dib->bits = bits;
+ }
+ else
+ {
+ /* bottom-up dib */
+ /* data->bits always points to the top-left corner and the stride is -ve */
+ dib->bits = (BYTE*)bits - (dib->height - 1) * dib->stride;
+ }
+ dib->ownsBits = owns;
+}
+
+void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP * dib)
+{
+ /* checks whether dib is top-down or bottom-up one */
+ if(dib->stride > 0)
+ {
+ /* top-down dib */
+ return dib->bits;
+ }
+ else
+ {
+ /* bottom-up dib */
+ /* data->bits always points to the top-left corner and the stride is -ve */
+ return (BYTE*)dib->bits + (dib->height - 1) * dib->stride;
+ }
+}
+
/* initializes dib from a bitmap :
dib dib being initialized
bi source BITMAPINFOHEADER with required DIB format info
@@ -238,7 +273,7 @@ BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, c
return TRUE;
}
-BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi)
+BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi)
{
static const DWORD bit_fields_DIB32_RGB[3] = {0xff0000, 0x00ff00, 0x0000ff};
static const DWORD bit_fields_DIB16_RGB[3] = {0x7c00, 0x03e0, 0x001f};
@@ -343,6 +378,93 @@ BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *s
return TRUE;
}
+/* initializes a DIBRDVBITMAP from a DIB HBITMAP
+ Parameters :
+ bmp destination DIBDRVBITMAP
+ hbmp source HBITMAP
+ copyPixels TRUE->copy source pixel array FALSE->link to source pixel array */
+BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL copyPixels)
+{
+ BITMAPINFO *destInfo;
+ DIBSECTION ds;
+ int size;
+
+ MAYBE(TRACE("bmp=%p, hbmp=%p, copyPixels = %s\n", bmp, hbmp, copyPixels ? "TRUE" : "FALSE"));
+
+ /* be sure bitmap is empty */
+ _DIBDRVBITMAP_Clear(bmp);
+
+ /* gets source bitmap data */
+ if(!(size = GetObjectW(hbmp, sizeof(DIBSECTION), &ds)))
+ {
+ ERR("Failed getting bitmap object\n");
+ return FALSE;
+ }
+ if(size != sizeof(DIBSECTION))
+ {
+ ERR("Bitmap is not a DIB section\n");
+ return FALSE;
+ }
+
+ destInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+ if(!destInfo)
+ {
+ ERR("HeapAlloc failed\n");
+ return FALSE;
+ }
+
+ memcpy(destInfo, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
+ if(ds.dsBmih.biCompression == BI_BITFIELDS)
+ memcpy((BITMAPINFOHEADER *)destInfo + 1, ds.dsBitfields, 3 * sizeof(RGBQUAD));
+ else if(ds.dsBmih.biBitCount <= 8)
+ {
+ FIXME("Can't grab color table here.... syslvel lock\n");
+ return FALSE;
+#if 0
+ HDC refDC = CreateCompatibleDC(0);
+ if(!refDC)
+ {
+ ERR("CreateCompatibleDC() failed\n");
+ return FALSE;
+ }
+ if(!GetDIBits(refDC, hbmp, 0, 1, NULL, destInfo, DIB_RGB_COLORS))
+ {
+ DeleteDC(refDC);
+ HeapFree(GetProcessHeap(), 0, destInfo);
+ ERR("GetDIBits failed\n");
+ return FALSE;
+ }
+ DeleteDC(refDC);
+#endif
+ }
+ if(!_DIBDRVBITMAP_InitFromBitmapinfo(bmp, destInfo))
+ {
+ HeapFree(GetProcessHeap(), 0, destInfo);
+ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n");
+ return FALSE;
+ }
+ HeapFree(GetProcessHeap(), 0, destInfo);
+ if(copyPixels)
+ {
+ size = abs(bmp->stride) * bmp->height;
+ if(!(bmp->bits = HeapAlloc(GetProcessHeap(), 0, size)))
+ {
+ ERR("HeapAlloc failed\n");
+ _DIBDRVBITMAP_Free(bmp);
+ return FALSE;
+ }
+ memcpy(bmp->bits, ds.dsBm.bmBits, size);
+ bmp->ownsBits = TRUE;
+ }
+ else
+ bmp->bits = ds.dsBm.bmBits;
+ if(bmp->stride < 0)
+ bmp->bits = (BYTE*)bmp->bits - (bmp->height - 1) * bmp->stride;
+
+ return TRUE;
+}
+
+
/* creates a DIBRDVBITMAP copying format info from a source one
Parameters :
dib destination DIBDRVBITMAP
diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c
index af264d0..4aebe8e 100644
--- a/dlls/winedib.drv/graphics.c
+++ b/dlls/winedib.drv/graphics.c
@@ -132,7 +132,7 @@ static inline void SideIntersect(const POINT *p1, const POINT *p2, const RECT *r
break;
case TOP_SIDE: /* top */
inters->x = MulDiv(p2->x - p1->x, r->top - p1->y, p2->y - p1->y) + p1->x;
- inters->y = r->bottom;
+ inters->y = r->top;
break;
case RIGHT_SIDE: /* right */
inters->x = r->right - 1;
@@ -698,7 +698,7 @@ BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count )
{
/* gets polygon bounding box -- for ytop and ybottom */
PolygonBoundingBox(clipped, clippedCount, &bBox);
-
+
/* gets all ordered intersections of polygon with
current scanline */
for(ys = bBox.top; ys < bBox.bottom; ys++)
@@ -972,6 +972,12 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color )
if(physDev->hasDIB)
{
+ /* get real colorref */
+ color = _DIBDRV_MapColor(physDev, color);
+
+ /* map to pixel color / palette index */
+ color = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color);
+
_DIBDRV_Position_ws2ds(physDev, &x, &y);
/* gets previous pixel */
diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c
index a1aa648..87016da 100644
--- a/dlls/winedib.drv/palette.c
+++ b/dlls/winedib.drv/palette.c
@@ -25,6 +25,69 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+/* maps a colorref to actual color */
+COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color)
+{
+ WORD index;
+ RGBQUAD *palColor;
+ HPALETTE hPal;
+ PALETTEENTRY paletteEntry;
+
+ switch(color >> 24)
+ {
+ case 0x10 : /* DIBINDEX */
+ MAYBE(TRACE("DIBINDEX Color is %08x\n", color));
+ index = color & 0xffff;
+ if(index >= physDev->physBitmap.colorTableSize)
+ {
+ WARN("DIBINDEX color out of range\n");
+ return 0;
+ }
+ palColor = physDev->physBitmap.colorTable + index;
+ MAYBE(TRACE("Returning color %08x\n", RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue)));
+ return RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue);
+
+ case 0x01: /* PALETTEINDEX */
+ MAYBE(TRACE("PALETTEINDEX Color is %08x\n", color));
+ index = color & 0xffff;
+ if(!(hPal = GetCurrentObject(physDev->hdc, OBJ_PAL)))
+ {
+ ERR("Couldn't get palette\n");
+ return 0;
+ }
+ if (!GetPaletteEntries(hPal, index, 1, &paletteEntry))
+ {
+ WARN("PALETTEINDEX(%x) : index %d is out of bounds, assuming black\n", color, index);
+ return 0;
+ }
+ MAYBE(TRACE("Returning color %08x\n", RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue)));
+ return RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue);
+
+ case 0x02: /* PALETTERGB */
+ return _DIBDRV_GetNearestColor(&physDev->physBitmap, color & 0xffffff);
+
+ default:
+ /* RGB color -- we must process special case for monochrome bitmaps */
+ if(physDev->physBitmap.bitCount == 1)
+ {
+ RGBQUAD *back = physDev->physBitmap.colorTable;
+ RGBQUAD *fore = back+1;
+ if(fore->rgbRed * fore->rgbRed + fore->rgbGreen * fore->rgbGreen + fore->rgbBlue * fore->rgbBlue <
+ back->rgbRed * back->rgbRed + back->rgbGreen * back->rgbGreen + back->rgbBlue * back->rgbBlue)
+ {
+ fore = back;
+ back = fore + 1;
+ }
+ if ( ((color >> 16) & 0xff) + ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2)
+ return RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue);
+ else
+ return RGB(back->rgbRed, back->rgbGreen, back->rgbBlue);
+ }
+ else
+ return color;
+ }
+}
+
/***********************************************************************
* DIBDRV_RealizePalette
*/
diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c
index 7b15ece..c40bfaf 100644
--- a/dlls/winedib.drv/pen_brush.c
+++ b/dlls/winedib.drv/pen_brush.c
@@ -51,7 +51,7 @@ static void SolidPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x1, x2, y, physDev->penAnd, physDev->penXor);
}
-static void SolidPenVline(DIBDRVPHYSDEV *physDev, int x, int y1, int y2)
+static void SolidPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2)
{
OrderEndPoints(&y1, &y2);
physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y1, y2, physDev->penAnd, physDev->penXor);
@@ -65,7 +65,7 @@ static void WINAPI SolidPenLineCallback(int x, int y, LPARAM lparam)
return;
}
-void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
+static void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
{
LineDDA(x1, y1, x2, y2, SolidPenLineCallback, (LPARAM)physDev);
}
@@ -216,22 +216,29 @@ void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev)
physDev->markSpace = mark;
}
-
+#if 0
/* For 1bpp bitmaps, unless the selected foreground color exactly
matches foreground's colortable OR it's the WHITE color,
the background color is used -- tested on WinXP */
static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color)
{
+ RGBQUAD *back = physDev->physBitmap.colorTable;
RGBQUAD *fore = physDev->physBitmap.colorTable+1;
- if((color & 0x00ffffff) == 0x00ffffff ||
- (
- fore->rgbRed == GetRValue(color) &&
- fore->rgbGreen == GetGValue(color) &&
- fore->rgbBlue == GetBValue(color)
- ))
- return 1;
- return 0;
+ if(
+ fore->rgbRed == GetRValue(color) &&
+ fore->rgbGreen == GetGValue(color) &&
+ fore->rgbBlue == GetBValue(color))
+ return 1;
+ else if(
+ back->rgbRed == GetRValue(color) &&
+ back->rgbGreen == GetGValue(color) &&
+ back->rgbBlue == GetBValue(color))
+ return 0;
+ else if((color & 0x00ffffff) == 0x00ffffff)
+ return 1;
+ else
+ return 0;
}
static void FixupFgColors1(DIBDRVPHYSDEV *physDev)
@@ -248,6 +255,45 @@ static void FixupFgColors1(DIBDRVPHYSDEV *physDev)
physDev->brushAnds = NULL;
physDev->brushXors = NULL;
}
+#endif
+
+#if 0
+/* For 1bpp bitmaps, unless the selected foreground color exactly
+ matches one of the colors in the colortable, then the color that
+ isn't the bkgnd color is used. */
+static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color)
+{
+ RGBQUAD rgb;
+ int i;
+
+ rgb.rgbRed = GetRValue(color);
+ rgb.rgbGreen = GetGValue(color);
+ rgb.rgbBlue = GetBValue(color);
+
+ for(i = 0; i < physDev->physBitmap.colorTableSize; i++)
+ {
+ RGBQUAD *cur = physDev->physBitmap.colorTable + i;
+ if((rgb.rgbRed == cur->rgbRed) && (rgb.rgbGreen == cur->rgbGreen) && (rgb.rgbBlue == cur->rgbBlue))
+ return i;
+ }
+ return ~physDev->backgroundColor & 1;
+}
+
+static void FixupFgColors1(DIBDRVPHYSDEV *physDev)
+{
+ int rop = GetROP2(physDev->hdc);
+
+ physDev->penColor = AdjustFgColor(physDev, physDev->penColorref);
+ physDev->brushColor = AdjustFgColor(physDev, physDev->brushColorref);
+
+ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor);
+ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor);
+ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
+ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
+ physDev->brushAnds = NULL;
+ physDev->brushXors = NULL;
+}
+#endif
static void SolidBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
{
@@ -310,23 +356,21 @@ HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen )
{
GetObjectW(hpen, sizeof(logpen), &logpen);
- physDev->penColorref = logpen.lopnColor;
-
- if(physDev->physBitmap.bitCount == 1)
- FixupFgColors1(physDev);
- else
- physDev->penColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, logpen.lopnColor);
+ physDev->penColorref = _DIBDRV_MapColor(physDev, logpen.lopnColor);
+ physDev->penColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->penColorref);
_DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), physDev->penColor, &physDev->penAnd, &physDev->penXor);
+ physDev->penStyle = logpen.lopnStyle;
switch(logpen.lopnStyle)
{
default:
ONCE(FIXME("Unhandled pen style %d\n", logpen.lopnStyle));
+ physDev->penStyle = PS_SOLID;
/* fall through */
case PS_SOLID:
physDev->penHLine = SolidPenHLine;
- physDev->penVLine = SolidPenVline;
+ physDev->penVLine = SolidPenVLine;
physDev->penLine = SolidPenLine;
physDev->penPattern = NULL;
break;
@@ -415,16 +459,13 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush )
goto solid;
case BS_SOLID:
- physDev->brushColorref = logbrush.lbColor;
+ physDev->brushColorref = _DIBDRV_MapColor(physDev, logbrush.lbColor);
solid:
MAYBE(TRACE("SOLID Pattern -- color is %x\n", physDev->brushColorref));
physDev->brushStyle = BS_SOLID;
physDev->brushHLine = SolidBrushHLine;
- if(physDev->physBitmap.bitCount == 1)
- FixupFgColors1(physDev);
- else
- physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, logbrush.lbColor);
+ physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->brushColorref);
_DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->brushColor,
&physDev->brushAnd, &physDev->brushXor);
@@ -496,8 +537,9 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush )
{
MAYBE(TRACE("NULL Pattern\n"));
physDev->brushColorref = 0;
+ physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, 0);
physDev->brushHLine = NullBrushHLine;
- goto solid;
+ break;
}
case BS_PATTERN:
@@ -601,10 +643,9 @@ COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color )
if(physDev->hasDIB)
{
- physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color);
+ physDev->backgroundColor = _DIBDRV_MapColor(physDev, color);
+ physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->backgroundColor);
- if(physDev->physBitmap.bitCount == 1)
- FixupFgColors1(physDev);
_DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor);
res = TRUE;
diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c
index 7feeb49..27d573f 100644
--- a/dlls/winedib.drv/primitives_bitblt.c
+++ b/dlls/winedib.drv/primitives_bitblt.c
@@ -25,6 +25,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+static inline COLORREF SwapColors(DWORD c)
+{
+ return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16);
+
+}
+
/* shrinks a line -- srcWidth >= dstWidth */
static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
{
@@ -407,9 +413,11 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
srcBmp = NULL;
dstBmp = &physDevDst->physBitmap;
- /* gets pattern color, in case it's needed */
+ /* gets pattern color, in case it's needed
+ it's NOT the COLORREF value (colors are swapped
+ NOR the pixel value (it's applied to a 32 BPP BI_RGB */
if(usePat)
- patColor = physDevDst->brushColor;
+ patColor = SwapColors(physDevDst->brushColorref);
else
patColor = 0;
@@ -658,9 +666,11 @@ BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
srcBmp = NULL;
dstBmp = &physDevDst->physBitmap;
- /* gets pattern color, in case it's needed */
+ /* gets pattern color, in case it's needed
+ it's NOT the COLORREF value (colors are swapped
+ NOR the pixel value (it's applied to a 32 BPP BI_RGB */
if(usePat)
- patColor = physDevDst->brushColor;
+ patColor = SwapColors(physDevDst->brushColorref);
else
patColor = 0;
diff --git a/dlls/winedib.drv/primitives_color.c b/dlls/winedib.drv/primitives_color.c
index 3ccc2e0..6c42b44 100644
--- a/dlls/winedib.drv/primitives_color.c
+++ b/dlls/winedib.drv/primitives_color.c
@@ -94,31 +94,30 @@ DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
PutField16(b, dib->blueShift, dib->blueLen);
}
-DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color)
+/* gets nearest color to DIB palette color */
+DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ RGBQUAD *c;
+
+ if(dib->bitCount > 8)
+ return color;
+
+ c = dib->colorTable + _DIBDRV_GetNearestColorIndex(dib, color);
+ return RGB(c->rgbRed, c->rgbGreen, c->rgbBlue);
+
+}
+
+/* gets nearest color index in DIB palette of a given colorref */
+DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color)
{
- int i, best_index = 0;
DWORD r, g, b;
+ int i, best_index = 0;
DWORD diff, best_diff = 0xffffffff;
-
+
r = GetRValue(color);
g = GetGValue(color);
b = GetBValue(color);
- /* just in case it's being called without color table
- properly initialized */
- if(!dib->colorTableGrabbed)
- return 0;
-
- /* for monochrome bitmaps, color is background
- if not matching foreground */
- if(dib->colorTableSize == 2)
- {
- RGBQUAD *fore = dib->colorTable + 1;
- if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue)
- return 1;
- return 0;
- }
-
for(i = 0; i < dib->colorTableSize; i++)
{
RGBQUAD *cur = dib->colorTable + i;
@@ -140,3 +139,39 @@ DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color)
}
return best_index;
}
+
+DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ DWORD r, g, b;
+
+ r = GetRValue(color);
+ g = GetGValue(color);
+ b = GetBValue(color);
+
+ /* just in case it's being called without color table
+ properly initialized */
+ if(!dib->colorTableGrabbed)
+ return 0;
+
+ /* for monochrome bitmaps, color is :
+ foreground if matching foreground ctable
+ else background if matching background ctable
+ else foreground ix 0xffffff
+ else background */
+ if(dib->colorTableSize == 2)
+ {
+ RGBQUAD *back = dib->colorTable;
+ RGBQUAD *fore = dib->colorTable + 1;
+ if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue)
+ return 1;
+ else if(r == back->rgbRed && g == back->rgbGreen && b == back->rgbBlue)
+ return 0;
+ if((color & 0xffffff) == 0xffffff)
+ return 1;
+ else
+ return 0;
+ }
+
+ /* otherwise looks for nearest color in palette */
+ return _DIBDRV_GetNearestColorIndex(dib, color);
+}
diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c
index f8f87ce..24a5e77 100644
--- a/dlls/winedib.drv/primitives_convert.c
+++ b/dlls/winedib.drv/primitives_convert.c
@@ -31,6 +31,33 @@ static inline COLORREF SwapColors(DWORD c)
}
+static inline DWORD PlaceField32(BYTE c, int shift, int len)
+{
+ DWORD res = c;
+ if(len < 8)
+ res >>= (8 - len);
+ else
+ res <<= (len - 8);
+ return res << shift;
+}
+
+static inline WORD PlaceField16(BYTE c, int shift, int len)
+{
+ WORD res = c;
+ if(len < 8)
+ res >>= (8 - len);
+ else
+ res <<= (len - 8);
+ return res << shift;
+}
+
+static inline BYTE GetField32(DWORD dwColor, int shift, int len)
+{
+ dwColor = dwColor & (((1 << (len)) - 1) << shift);
+ dwColor = dwColor << (32 - (shift + len)) >> 24;
+ return dwColor;
+}
+
/* ----------------------------------------------------------------*/
/* CONVERT PRIMITIVES */
/* converts (part of) line of any DIB format from/to DIB32_RGB one */
@@ -63,7 +90,7 @@ BOOL _DIBDRV_GetLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int wi
BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
{
- BYTE *bBuf = (BYTE *)buf;
+ DWORD *dwBuf = (DWORD *)buf;
DWORD *src;
#ifdef DIBDRV_CHECK_RANGES
@@ -85,10 +112,10 @@ BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx,
src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
for(; width ; width--)
{
- *bBuf++ = (*src & bmp->blueMask ) >> bmp->blueShift;
- *bBuf++ = (*src & bmp->greenMask) >> bmp->greenShift;
- *bBuf++ = (*src & bmp->redMask ) >> bmp->redShift;
- *bBuf++ = 0x0;
+ *dwBuf++ =
+ GetField32(*src, bmp->redShift , bmp->redLen ) << 16 |
+ GetField32(*src, bmp->greenShift, bmp->greenLen) << 8 |
+ GetField32(*src, bmp->blueShift , bmp->blueLen );
src++;
}
return TRUE;
@@ -184,6 +211,7 @@ BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx,
for(; width ; width--)
{
b = *src++;
+
*dwBuf++ =((( b & bmp->blueMask) >> bmp->blueShift ) << ( 8 - bmp->blueLen )) |
(((b & bmp->greenMask) >> bmp->greenShift) << (16 - bmp->greenLen)) |
(((b & bmp->redMask ) >> bmp->redShift ) << (24 - bmp->redLen ));
@@ -350,14 +378,14 @@ BOOL _DIBDRV_PutLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx,
{
DWORD *dwBuf = (DWORD *)buf;
DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
- DWORD c;
+ RGBQUAD *c;
for(; width; width--)
{
- c = *dwBuf++;
+ c = (RGBQUAD *)dwBuf++;
*dst++ =
- ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) |
- ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) |
- ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask);
+ PlaceField32(c->rgbRed , bmp->redShift , bmp->redLen ) |
+ PlaceField32(c->rgbGreen, bmp->greenShift, bmp->greenLen) |
+ PlaceField32(c->rgbBlue , bmp->blueShift , bmp->blueLen );
}
return TRUE;
}
@@ -386,6 +414,7 @@ BOOL _DIBDRV_PutLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int wi
{
c = *dwBuf++;
*dst++ =
+ /* 0RRR|RRGG|GGGB|BBBB */
((c & 0x000000f8) >> 3) |
((c & 0x0000f800) >> 6) |
((c & 0x00f80000) >> 9);
@@ -506,8 +535,9 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
DWORD c;
/* get foreground color */
+ DWORD back = *(DWORD *)bmp->colorTable & 0x00ffffff;
DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff;
-
+
/* put first partial byte, if any */
startx &= 0x07;
mask = 0x80 >> startx;
@@ -519,7 +549,11 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
while(startx--)
{
c = *dwBuf++ & 0x00ffffff;
- if(c == 0x00ffffff || c == fore)
+ if(c == fore)
+ b |= mask;
+ else if(c == back)
+ b &= !mask;
+ else if(c == 0x00ffffff)
b |= mask;
else
b &= !mask;
@@ -536,7 +570,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
for(i = 0 ; i < 8 ; i++)
{
c = *dwBuf++ & 0x00ffffff;
- if(c == 0x00ffffff || c == fore)
+ if(c == fore || (c == 0x00ffffff && c != back))
b |= mask;
mask >>= 1;
}
@@ -551,7 +585,11 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width,
while(width--)
{
c = *dwBuf++ & 0x00ffffff;
- if(c == 0x00ffffff || c == fore)
+ if(c == fore)
+ b |= mask;
+ else if(c == back)
+ b &= !mask;
+ else if(c == 0x00ffffff)
b |= mask;
else
b &= !mask;
diff --git a/dlls/winedib.drv/primitives_pixel.c b/dlls/winedib.drv/primitives_pixel.c
index ca68cf1..78e68c7 100644
--- a/dlls/winedib.drv/primitives_pixel.c
+++ b/dlls/winedib.drv/primitives_pixel.c
@@ -25,24 +25,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
-
/* ------------------------------------------------------------*/
/* BITFIELD HELPERS */
-static DWORD GetField32 (DWORD pixel, int shift, int len)
+static inline DWORD GetField32 (DWORD pixel, int shift, int len)
{
pixel = pixel & (((1 << (len)) - 1) << shift);
pixel = pixel << (32 - (shift + len)) >> 24;
return pixel;
}
-static WORD GetField16 (WORD pixel, int shift, int len)
-{
- FIXME("TODO\n");
- return 0;
-}
-
-
-
/* ------------------------------------------------------------*/
/* PIXEL POINTER READING */
void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y)
@@ -174,45 +165,50 @@ void _DIBDRV_SetPixel1(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
/* PIXEL READING */
DWORD _DIBDRV_GetPixel32_RGB(const DIBDRVBITMAP *dib, int x, int y)
{
- DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
- return *ptr;
+ DWORD c = *(DWORD *)dib->funcs->GetPixelPointer(dib, x, y);
+ return
+ ((c & 0x000000ff) << 16) |
+ ((c & 0x0000ff00) ) |
+ ((c & 0x00ff0000) >> 16) |
+ ( c & 0xff000000 ); /* last one for alpha channel */
}
DWORD _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y)
{
DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
- return GetField32(*ptr, dib->redShift, dib->redLen) << 16 |
+ return GetField32(*ptr, dib->redShift, dib->redLen) |
GetField32(*ptr, dib->greenShift, dib->greenLen) << 8 |
- GetField32(*ptr, dib->blueShift, dib->blueLen);
+ GetField32(*ptr, dib->blueShift, dib->blueLen) << 16;
}
DWORD _DIBDRV_GetPixel24(const DIBDRVBITMAP *dib, int x, int y)
{
BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
- return (ptr[0] << 16) | (ptr[1] << 8) | ptr[2];
+ return ((WORD)ptr[0] << 16) | ((WORD)ptr[1] << 8) | (WORD)ptr[2];
}
DWORD _DIBDRV_GetPixel16_RGB(const DIBDRVBITMAP *dib, int x, int y)
{
- WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
- return ((*ptr & 0x7c00) << 9) | ((*ptr & 0x03e0) << 6) | ((*ptr & 0x001f) << 3);
+ WORD c = *(WORD *)dib->funcs->GetPixelPointer(dib, x, y);
+ /* 0RRR|RRGG|GGGB|BBBB */
+ return ((c & 0x7c00) >> 7) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 19);
}
DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y)
{
- WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
+ WORD c = *(WORD *)dib->funcs->GetPixelPointer(dib, x, y);
- return GetField16(*ptr, dib->redShift, dib->redLen) << 16 |
- GetField16(*ptr, dib->greenShift, dib->greenLen) << 8 |
- GetField16(*ptr, dib->blueShift, dib->blueLen);
+ return (((c & dib->blueMask ) >> dib->blueShift ) << (24 - dib->blueLen )) |
+ (((c & dib->greenMask) >> dib->greenShift) << (16 - dib->greenLen)) |
+ (((c & dib->redMask ) >> dib->redShift ) << ( 8 - dib->redLen ));
}
DWORD _DIBDRV_GetPixel8(const DIBDRVBITMAP *dib, int x, int y)
{
BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
RGBQUAD *color = dib->colorTable + *ptr;
- return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue;
+ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16);
}
DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y)
@@ -226,7 +222,7 @@ DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y)
pix = *ptr >> 4;
color = dib->colorTable + pix;
- return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue;
+ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16);
}
DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y)
@@ -240,5 +236,5 @@ DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y)
pix &= 1;
color = dib->colorTable + pix;
- return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue;
+ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16);
}