23245f3322
git-svn-id: https://svn.disconnected-by-peer.at/svn/linamh/trunk/linamh@1438 6952d904-891a-0410-993b-d76249ca496b
1696 lines
65 KiB
Diff
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);
|
|
}
|