linamh/app-emulation/wine/files/0004-dib-engine-implement-most-engi.patch

9089 lines
314 KiB
Diff
Raw Normal View History

DIB Engine: implement most engine functions
From: Massimo Del Fedele <max@veneto.com>
---
dlls/winedib.drv/Makefile.in | 12
dlls/winedib.drv/bitblt.c | 525 ++++++++++++++--
dlls/winedib.drv/bitmap.c | 49 +-
dlls/winedib.drv/clipping.c | 6
dlls/winedib.drv/convert.c | 309 +++++++++
dlls/winedib.drv/dc.c | 280 ++++++++-
dlls/winedib.drv/dib.c | 24 -
dlls/winedib.drv/dibdrv.h | 292 +++++++++
dlls/winedib.drv/dibdrv_gdi32.h | 168 +++++
dlls/winedib.drv/dibdrv_main.c | 11
dlls/winedib.drv/dibdrvbitmap.c | 650 ++++++++++++++++++++
dlls/winedib.drv/driver.c | 254 ++++++++
dlls/winedib.drv/font.c | 116 +++-
dlls/winedib.drv/freetype.c | 136 ++++
dlls/winedib.drv/freetype.h | 186 ++++++
dlls/winedib.drv/graphics.c | 264 +++++---
dlls/winedib.drv/opengl.c | 32 -
dlls/winedib.drv/palette.c | 51 +-
dlls/winedib.drv/pen_brush.c | 492 ++++++++++++++-
dlls/winedib.drv/primitives.c | 274 ++++++++
dlls/winedib.drv/primitives_bitblt.c | 1075 +++++++++++++++++++++++++++++++++
dlls/winedib.drv/primitives_color.c | 142 ++++
dlls/winedib.drv/primitives_convert.c | 559 +++++++++++++++++
dlls/winedib.drv/primitives_font.c | 310 ++++++++++
dlls/winedib.drv/primitives_line.c | 434 +++++++++++++
dlls/winedib.drv/primitives_pixel.c | 244 +++++++
dlls/winedib.drv/primitives_rop2.c | 112 +++
dlls/winedib.drv/primitives_rop3.c | 786 ++++++++++++++++++++++++
dlls/winedib.drv/text.c | 179 +++++
dlls/winedib.drv/video.c | 8
30 files changed, 7706 insertions(+), 274 deletions(-)
create mode 100644 dlls/winedib.drv/convert.c
create mode 100644 dlls/winedib.drv/dibdrv_gdi32.h
create mode 100644 dlls/winedib.drv/dibdrvbitmap.c
create mode 100644 dlls/winedib.drv/driver.c
create mode 100644 dlls/winedib.drv/freetype.c
create mode 100644 dlls/winedib.drv/freetype.h
create mode 100644 dlls/winedib.drv/primitives.c
create mode 100644 dlls/winedib.drv/primitives_bitblt.c
create mode 100644 dlls/winedib.drv/primitives_color.c
create mode 100644 dlls/winedib.drv/primitives_convert.c
create mode 100644 dlls/winedib.drv/primitives_font.c
create mode 100644 dlls/winedib.drv/primitives_line.c
create mode 100644 dlls/winedib.drv/primitives_pixel.c
create mode 100644 dlls/winedib.drv/primitives_rop2.c
create mode 100644 dlls/winedib.drv/primitives_rop3.c
diff --git a/dlls/winedib.drv/Makefile.in b/dlls/winedib.drv/Makefile.in
index 66ad14f..722785e 100644
--- a/dlls/winedib.drv/Makefile.in
+++ b/dlls/winedib.drv/Makefile.in
@@ -11,15 +11,27 @@ C_SRCS = \
bitblt.c \
bitmap.c \
clipping.c \
+ convert.c \
dc.c \
dib.c \
dibdrv_main.c \
+ dibdrvbitmap.c \
driver.c \
font.c \
+ freetype.c \
graphics.c \
opengl.c \
palette.c \
pen_brush.c \
+ primitives.c \
+ primitives_bitblt.c \
+ primitives_color.c \
+ primitives_convert.c \
+ primitives_font.c \
+ primitives_line.c \
+ primitives_pixel.c \
+ primitives_rop2.c \
+ primitives_rop3.c \
text.c \
video.c
diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c
index 022f223..20cdcaa 100644
--- a/dlls/winedib.drv/bitblt.c
+++ b/dlls/winedib.drv/bitblt.c
@@ -25,6 +25,117 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+static inline void intSwap(int *a, int *b)
+{
+ int tmp;
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+/* clips a source and destination areas to their respective clip rectangles
+ returning both source and dest modified; result is TRUE if clipping
+ leads to a non null rectangle, FALSE otherwise */
+static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*dstClip)
+{
+ int xs1, ys1, xs2, ys2;
+ int xsc1, ysc1, xsc2, ysc2;
+ int xd1, yd1, xd2, yd2;
+ int xdc1, ydc1, xdc2, ydc2;
+ int w, h, dx, dy;
+
+ /* extract sizes */
+ w = sz->cx; h = sz->cy;
+
+ /* if sizes null or negative, just return false */
+ if(w <= 0 || h <= 0)
+ return FALSE;
+
+ /* extract dest area data */
+ xd1 = pd->x;
+ yd1 = pd->y;
+ xd2 = xd1 + w;
+ yd2 = yd1 + h;
+
+ /* extract source data */
+ xs1 = ps->x;
+ ys1 = ps->y;
+ xs2 = xs1 + w;
+ ys2 = ys1 + h;
+
+ /* if source clip area is not null, do first clipping on it */
+ if(srcClip)
+ {
+ /* extract source clipping area */
+ xsc1 = srcClip->left;
+ 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);
+
+ /* clip on source clipping start point */
+ if(xs1 < xsc1) { dx = xsc1 - xs1; w -= dx; xd1 += dx; xs1 = xsc1; }
+ if(ys1 < ysc1) { dy = ysc1 - ys1; h -= dy; yd1 += dy; ys1 = ysc1; }
+
+ /* 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 */
+ xdc1 = dstClip->left;
+ 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);
+
+ /* clip on dest clipping start point */
+ if(xd1 < xdc1) { dx = xdc1 - xd1; w -= dx; xs1 += dx; xd1 = xdc1; }
+ if(yd1 < ydc1) { dy = ydc1 - yd1; h -= dy; ys1 += dy; yd1 = ydc1; }
+
+ /* clip on dest clipping end point */
+ if(xd2 > xdc2) { dx = xd2 - xdc2; w -= dx; xs2 -= dx; xd2 = xdc2; }
+ if(yd2 > ydc2) { dy = yd2 - ydc2; h -= dy; ys2 -= dy; yd2 = ydc2; }
+
+ /* if already zero area, return false */
+ if(w <= 0 || h <= 0)
+ return FALSE;
+ }
+
+ /* sets clipped/translated points and sizes and returns TRUE */
+ ps->x = xs1; ps->y = ys1;
+ pd->x = xd1; pd->y = yd1;
+ sz->cx = w; sz->cy = h;
+
+ return TRUE;
+
+}
+
+
+/* clips a source and destination areas to their respective clip rectangles
+ returning both source and dest modified; result is TRUE if clipping
+ leads to a non null rectangle, FALSE otherwise */
+static BOOL StretchBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *szSrc, SIZE *szDst, RECT*srcClip, RECT*dstClip)
+{
+ ONCE(FIXME("TO DO\n"));
+
+ return TRUE;
+
+}
+
/***********************************************************************
* DIBDRV_AlphaBlend
*/
@@ -34,16 +145,17 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
{
BOOL res;
- TRACE("physDevDst:%p, xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p, xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n",
- physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, 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) : "",
+ xDst, yDst, widthDst, heightDst,
+ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
+ xSrc, ySrc, widthSrc, heightSrc));
if(physDevDst->hasDIB && physDevSrc->hasDIB)
{
/* DIB section selected in both source and dest DC, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc,
- blendfn);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else if(!physDevDst->hasDIB && !physDevSrc->hasDIB)
{
@@ -63,10 +175,8 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width
else /* if(physDevDst->hasDIB) */
{
/* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc,
- blendfn);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
return res;
}
@@ -80,35 +190,171 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
{
BOOL res;
- TRACE("physDevDst:%p, xDst:%d, yDst:%d, width:%d, height:%d, physDevSrc:%p, xSrc:%d, ySrc:%d, rop:%08x\n",
- physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop);
+ /* clip blit area */
+ POINT pd = {xDst, yDst};
+ POINT ps = {xSrc, ySrc};
+ SIZE sz = {width, height};
- if(physDevDst->hasDIB && physDevSrc->hasDIB)
- {
- /* DIB section selected in both source and dest DC, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
- physDevSrc->X11PhysDev, xSrc, ySrc, rop);
- }
- else if(!physDevDst->hasDIB && !physDevSrc->hasDIB)
- {
- /* DDB selected in noth source and dest DC, use X11 driver */
- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
- physDevSrc->X11PhysDev, xSrc, ySrc, rop);
- }
- else if(physDevSrc->hasDIB)
+ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, width:%d, height:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, rop:%08x\n",
+ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "",
+ xDst, yDst, width, height,
+ physDevSrc, physDevSrc ? (physDevSrc->hasDIB ? "DIB-" : "DDB"): "---", physDevSrc && physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
+ xSrc, ySrc, rop));
+
+ if(physDevDst->hasDIB)
{
- /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
- physDevSrc->X11PhysDev, xSrc, ySrc, rop);
+ /* DIB section selected in dest DC, use DIB Engine */
+
+ /* clip blit area */
+ RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height};
+
+ if(!physDevSrc || physDevSrc->hasDIB)
+ {
+ /* clip blit area */
+ if(physDevSrc)
+ {
+ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
+ res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, &dstClip);
+ }
+ else
+ 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;
+
+ /* source is null or has a DIB, no need to convert anyting */
+ res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop);
+ }
+ else
+ {
+ /* source is a DDB, must convert it to DIB */
+
+ /* don't clip on source */
+ 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;
+
+ /* we must differentiate from 2 cases :
+ 1) source DC is a memory DC
+ 2) source DC is a device DC */
+ if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
+ {
+ /* memory DC */
+ HBITMAP dib, ddb;
+
+ ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
+ if(!ddb)
+ {
+ ERR("Couldn't select out DDB from source HDC\n");
+ res = 0;
+ goto noBlt1;
+ }
+ dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, ySrc, height);
+ if(!dib)
+ {
+ ERR("Failed converting source DDB to DIB\n");
+ SelectObject(physDevSrc->hdc, ddb);
+ res = 0;
+ goto noBlt1;
+ }
+ SelectObject(physDevSrc->hdc, dib);
+ res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height,
+ physDevSrc, xSrc, 0, rop);
+ SelectObject(physDevSrc->hdc, ddb);
+ DeleteObject(dib);
+ noBlt1:
+ ;
+ }
+ else
+ {
+ /* device DC */
+ HBITMAP dib, stock;
+ HDC memHdc;
+
+ dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, xSrc, ySrc, width, height);
+ if(!dib)
+ {
+ ERR("Failed converting source DDB tp DIB for device DC\n");
+ res = 0;
+ goto noBlt2;
+ }
+ memHdc = CreateCompatibleDC(physDevDst->hdc);
+ if(!memHdc)
+ {
+ ERR("Failed creating temporary memory DC\n");
+ DeleteObject(dib);
+ res = 0;
+ goto noBlt2;
+ }
+ stock = SelectObject(memHdc, dib);
+ if(!stock)
+ {
+ ERR("Failed selecting converted DIB into temporary memory DC\n");
+ DeleteObject(dib);
+ DeleteDC(memHdc);
+ res = 0;
+ goto noBlt2;
+ }
+ res = BitBlt(physDevDst->hdc, xDst, yDst, width, height, memHdc, 0, 0, rop);
+
+ SelectObject(memHdc, stock);
+ DeleteObject(dib);
+ DeleteDC(memHdc);
+ noBlt2:
+ ;
+ }
+ }
}
- else /* if(physDevDst->hasDIB) */
+ else /* dest is a DDB */
{
- /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
- physDevSrc->X11PhysDev, xSrc, ySrc, rop);
+ /* DDB selected on dest DC, use X11 Driver */
+ if(!physDevSrc || !physDevSrc->hasDIB)
+ {
+ /* source is null or has also a DDB, no need to convert anything */
+ res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
+ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, rop);
+ }
+ else
+ {
+ /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
+ HBITMAP dib, ddb;
+
+ /* clip blit area */
+ if(physDevSrc)
+ {
+ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
+ res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0);
+ }
+ else
+ res = TRUE;
+ if(!res)
+ goto noBlt3;
+ xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y;
+
+ dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
+ if(!dib)
+ {
+ ERR("Couldn't select out DIB from source HDC\n");
+ res = 0;
+ goto noBlt3;
+ }
+ ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, ySrc, height);
+ if(!ddb)
+ {
+ ERR("Failed converting source DIB to DDB\n");
+ SelectObject(physDevSrc->hdc, dib);
+ res = 0;
+ goto noBlt3;
+ }
+ SelectObject(physDevSrc->hdc, ddb);
+ res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height,
+ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, 0, rop);
+ SelectObject(physDevSrc->hdc, dib);
+ DeleteObject(ddb);
+noBlt3:
+ ;
+ }
}
return res;
}
@@ -123,35 +369,186 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
{
BOOL res;
- TRACE("physDevDst:%p, xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p, xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d, rop:%8x\n",
- physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop);
+ /* clip blit area */
+ POINT pd = {xDst, yDst};
+ POINT ps = {xSrc, ySrc};
+ SIZE szDst = {widthDst, heightDst};
+ SIZE szSrc = {widthSrc, heightSrc};
- if(physDevDst->hasDIB && physDevSrc->hasDIB)
- {
- /* DIB section selected in both source and dest DC, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc,
- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop);
- }
- else if(!physDevDst->hasDIB && !physDevSrc->hasDIB)
- {
- /* DDB selected in noth source and dest DC, use X11 driver */
- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc,
- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop);
- }
- else if(physDevSrc->hasDIB)
+ /* if source and dest sizes match, just call BitBlt(), it's faster */
+ if(!physDevSrc || (widthDst == widthSrc && heightDst == heightSrc))
+ return DIBDRV_BitBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, rop);
+
+ 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, rop:%08x\n",
+ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "",
+ xDst, yDst, widthDst, heightDst,
+ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "",
+ xSrc, ySrc, widthSrc, heightSrc, rop));
+
+ if(physDevDst->hasDIB)
{
- /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc,
- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop);
+ /* DIB section selected in dest DC, use DIB Engine */
+
+ /* clip blit area */
+ RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height};
+
+ if(!physDevSrc || physDevSrc->hasDIB)
+ {
+ /* clip blit area */
+ if(physDevSrc)
+ {
+ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
+ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip);
+ }
+ else
+ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip);
+ if(!res)
+ goto noBlt2;
+ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
+ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
+
+ /* source is null or has a DIB, no need to convert anyting */
+ res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop);
+ }
+ else
+ {
+ /* source is a DDB, must convert it to DIB */
+
+ /* don't clip on source */
+ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip);
+ if(!res)
+ goto noBlt2;
+ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
+ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
+
+ /* we must differentiate from 2 cases :
+ 1) source DC is a memory DC
+ 2) source DC is a device DC */
+ if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
+ {
+ /* memory DC */
+ HBITMAP dib, ddb;
+
+ ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
+ if(!ddb)
+ {
+ ERR("Couldn't select out DDB from source HDC\n");
+ res = 0;
+ goto noBlt1;
+ }
+ dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, ySrc, heightSrc);
+ if(!dib)
+ {
+ ERR("Failed converting source DDB to DIB\n");
+ SelectObject(physDevSrc->hdc, ddb);
+ res = 0;
+ goto noBlt1;
+ }
+ SelectObject(physDevSrc->hdc, dib);
+ res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst,
+ physDevSrc, xSrc, 0, widthSrc, heightSrc, rop);
+ SelectObject(physDevSrc->hdc, ddb);
+ DeleteObject(dib);
+ noBlt1:
+ ;
+ }
+ else
+ {
+ /* device DC */
+ HBITMAP dib, stock;
+ HDC memHdc;
+
+ dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, xSrc, ySrc, widthSrc, heightSrc);
+ if(!dib)
+ {
+ ERR("Failed converting source DDB tp DIB for device DC\n");
+ res = 0;
+ goto noBlt2;
+ }
+ memHdc = CreateCompatibleDC(physDevDst->hdc);
+ if(!memHdc)
+ {
+ ERR("Failed creating temporary memory DC\n");
+ DeleteObject(dib);
+ res = 0;
+ goto noBlt2;
+ }
+ stock = SelectObject(memHdc, dib);
+ if(!stock)
+ {
+ ERR("Failed selecting converted DIB into temporary memory DC\n");
+ DeleteObject(dib);
+ DeleteDC(memHdc);
+ res = 0;
+ goto noBlt2;
+ }
+ res = StretchBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, memHdc, 0, 0, widthSrc, widthDst, rop);
+
+ SelectObject(memHdc, stock);
+ DeleteObject(dib);
+ DeleteDC(memHdc);
+ noBlt2:
+ ;
+ }
+ }
}
- else /* if(physDevDst->hasDIB) */
+ else /* dest is a DDB */
{
- /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc,
- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop);
+ /* DDB selected on dest DC, use X11 Driver */
+ if(!physDevSrc || !physDevSrc->hasDIB)
+ {
+ /* source is null or has also a DDB, no need to convert anything */
+ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
+ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, widthSrc, heightSrc, rop);
+ }
+ else
+ {
+ /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */
+ HBITMAP dib, ddb;
+
+ /* clip blit area */
+ if(physDevSrc)
+ {
+ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height};
+ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0);
+ }
+ else
+ res = TRUE;
+ if(!res)
+ goto noBlt3;
+ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy;
+ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy;
+
+ dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP));
+ if(!dib)
+ {
+ ERR("Couldn't select out DIB from source HDC\n");
+ res = 0;
+ goto noBlt3;
+ }
+ ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, ySrc, heightSrc);
+ if(!ddb)
+ {
+ ERR("Failed converting source DIB to DDB\n");
+ SelectObject(physDevSrc->hdc, dib);
+ res = 0;
+ goto noBlt3;
+ }
+ if(!SelectObject(physDevSrc->hdc, ddb))
+ {
+ ERR("Failed to select converted DDB into source HDC\n");
+ SelectObject(physDevSrc->hdc, dib);
+ DeleteObject(ddb);
+ res = 0;
+ goto noBlt3;
+ }
+ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst,
+ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, 0, widthSrc, heightSrc, rop);
+ SelectObject(physDevSrc->hdc, dib);
+ DeleteObject(ddb);
+noBlt3:
+ ;
+ }
}
return res;
}
@@ -162,14 +559,14 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
BOOL DIBDRV_PatBlt( DIBDRVPHYSDEV *physDev, INT left, INT top, INT width, INT height, DWORD rop )
{
BOOL res;
-
- TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop);
+
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, left, top, width, height, rop);
+ ONCE(FIXME("TEMPORARY - use BitBlt by now\n"));
+ res = DIBDRV_BitBlt(physDev, left, top, width, height, NULL, 0, 0, rop);
}
else
{
diff --git a/dlls/winedib.drv/bitmap.c b/dlls/winedib.drv/bitmap.c
index df7c03a..f3d3b9c 100644
--- a/dlls/winedib.drv/bitmap.c
+++ b/dlls/winedib.drv/bitmap.c
@@ -34,12 +34,12 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap )
DIBSECTION dibSection;
HBITMAP res;
- TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap);
-
/* try to get the DIBSECTION data from the bitmap */
if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP))
{
/* not a DIB section, sets it on physDev and use X11 behaviour */
+
+ MAYBE(TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap));
physDev->hasDIB = FALSE;
res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap);
if(res)
@@ -48,11 +48,30 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap )
else
{
/* it's a DIB section, sets it on physDev and use DIB Engine behaviour */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- physDev->hasDIB = TRUE;
- res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap);
- if(res)
+
+ MAYBE(TRACE("physDev:%p, hbitmap:%p, physBitmap=%p\n", physDev, hbitmap, &physDev->physBitmap));
+
+ /* frees any previously physical bitmap */
+ _DIBDRVBITMAP_Free(&physDev->physBitmap);
+
+ /* WARNING : the color table can't be grabbed here, since it's still
+ not initialized. It'll be grabbed on RealizeDefaultPalette(),
+ which is presumably the first call made after palette initialization.
+ So, by now we just set up palette size and leave NULL the palette pointer */
+ if(_DIBDRVBITMAP_InitFromBMIH(&physDev->physBitmap, &dibSection.dsBmih, dibSection.dsBitfields, NULL, dibSection.dsBm.bmBits))
+ {
+ /* stores the active bitmap */
+ res = physDev->hbitmap;
physDev->hbitmap = hbitmap;
+
+ /* remember there's a DIB selected in */
+ physDev->hasDIB = TRUE;
+ }
+ else
+ {
+ ERR("Failed to initialize physical bitmap\n");
+ res = 0;
+ }
}
return res;
@@ -66,7 +85,7 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits
DIBSECTION dibSection;
BOOL res;
- TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits);
+ MAYBE(TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits));
/* try to get the DIBSECTION data from the bitmap */
if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP))
@@ -76,9 +95,9 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits
}
else
{
- /* it's a DIB section, use DIB Engine behaviour */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pCreateBitmap(physDev->X11PhysDev, hbitmap, bmBits);
+ /* it's a DIB section, use DIB Engine behaviour - should not happen, but.... */
+ ONCE(FIXME("CreateBitmap() called for a DIB section - shouldn't happen\n"));
+ res = TRUE;
}
return res;
}
@@ -91,7 +110,7 @@ BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap )
DIBSECTION dibSection;
BOOL res;
- TRACE("hbitmap:%p\n", hbitmap);
+ MAYBE(TRACE("hbitmap:%p\n", hbitmap));
/* try to get the DIBSECTION data from the bitmap */
if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP))
@@ -102,8 +121,8 @@ BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap )
else
{
/* it's a DIB section, use DIB Engine behaviour */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
return res;
}
@@ -115,7 +134,7 @@ LONG DIBDRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count )
{
LONG res;
- TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count);
+ MAYBE(TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count));
/* GetBitmapBits is only valid for DDBs, so use X11 driver */
res = _DIBDRV_GetDisplayDriver()->pGetBitmapBits(hbitmap, buffer, count);
@@ -130,7 +149,7 @@ LONG DIBDRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count )
{
LONG res;
- TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count);
+ MAYBE(TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count));
/* SetBitmapBits is only valid for DDBs, so use X11 driver */
res = _DIBDRV_GetDisplayDriver()->pSetBitmapBits(hbitmap, bits, count);
diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c
index 1ddbb1b..81dec25 100644
--- a/dlls/winedib.drv/clipping.c
+++ b/dlls/winedib.drv/clipping.c
@@ -25,18 +25,18 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
/***********************************************************************
* DIBDRV_SetDeviceClipping
*/
void DIBDRV_SetDeviceClipping( DIBDRVPHYSDEV *physDev, HRGN vis_rgn, HRGN clip_rgn )
{
- TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn);
+ MAYBE(TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn);
+ ONCE(FIXME("STUB\n"));
}
else
{
diff --git a/dlls/winedib.drv/convert.c b/dlls/winedib.drv/convert.c
new file mode 100644
index 0000000..dc18e14
--- /dev/null
+++ b/dlls/winedib.drv/convert.c
@@ -0,0 +1,309 @@
+/*
+ * DIB Engine conversion routines
+ * Converts DDB <--> DIB
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+#include "winuser.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/***********************************************************************
+ * Creates DDB that is compatible with source hdc.
+ * hdc is the HDC on where the DIB MUST be selected in
+ * srcBmp is the source DIB
+ * startScan and scanLines specify the portion of DIB to convert
+ * in order to avoid unneeded conversion of large DIBs on blitting
+ *
+ * NOTE : the srcBmp DIB MUST NOT be selected in any DC */
+HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines )
+{
+ DIBSECTION ds;
+ BITMAPINFO *bmi;
+ HBITMAP hBmp = NULL;
+
+ int dibWidth, dibHeight;
+ BOOL topDown;
+ void *bits;
+ int stride;
+ UINT colorUsed;
+ int bitFields;
+ HDC tmpHdc;
+ HBITMAP tmpBmp;
+ int res;
+
+ /* gets DIBSECTION data from source DIB */
+ if(GetObjectW(srcBmp, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION))
+ {
+ ERR("Couldn't get DIBSECTION data\n");
+ return 0;
+ }
+
+ /* gets DIB info */
+ dibWidth = ds.dsBmih.biWidth;
+ dibHeight = ds.dsBmih.biHeight;
+ bits = ds.dsBm.bmBits;
+ stride = ((dibWidth * ds.dsBmih.biBitCount +31) &~31) / 8;
+
+ /* adjust bits to point at needed starting stripe */
+ if(dibHeight < 0)
+ {
+ /* top-down DIB */
+ topDown = TRUE;
+ dibHeight = -dibHeight;
+ bits = (BYTE *)bits + startScan * stride;
+ }
+ else
+ {
+ topDown = FALSE;
+ bits = (BYTE *)bits + (dibHeight - startScan - scanLines) * stride;
+ }
+
+ /* if requested part is out of source bitmap, returns 0 */
+ if(startScan >= dibHeight)
+ return 0;
+ if(startScan + scanLines >= dibHeight)
+ scanLines = dibHeight - startScan;
+
+ /* 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)
+ bitFields = 3;
+ }
+ else
+ {
+ colorUsed = ds.dsBmih.biClrUsed;
+ if(!colorUsed)
+ colorUsed = 1 << ds.dsBmih.biBitCount;
+ }
+
+ /* builds the needed BITMAPINFOHEADER */
+ bmi = HeapAlloc( GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER)+
+ sizeof(RGBQUAD)*colorUsed + sizeof(DWORD) * bitFields );
+ if (!bmi)
+ {
+ ERR("HeapAlloc failed\n");
+ return 0;
+ }
+
+ /* copy the header part */
+ memcpy( &bmi->bmiHeader, &ds.dsBmih, sizeof(BITMAPINFOHEADER) );
+
+ /* gets the color table part, if any */
+ if(colorUsed)
+ {
+ /* create a temporary DC, GetDIBColorTable() requests that
+ the DIB is selected in a DC.... */
+ if(!(tmpHdc = CreateCompatibleDC(hdc)))
+ {
+ ERR("Couldn't create the temporary HDC\n");
+ HeapFree(GetProcessHeap(), 0, bmi);
+ return 0;
+ }
+ /* selects the DIB into the temporary DC */
+ if( !(tmpBmp = SelectObject(tmpHdc, srcBmp)))
+ {
+ ERR("Couldn't select source DIB into temporary DC\n");
+ DeleteDC(tmpHdc);
+ HeapFree(GetProcessHeap(), 0, bmi);
+ return 0;
+ }
+ GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors);
+ SelectObject(tmpHdc, tmpBmp);
+ DeleteDC(tmpHdc);
+ }
+
+ /* fill the bitfields part, if any */
+ if(bitFields)
+ memcpy(bmi->bmiColors, ds.dsBitfields, 3 * sizeof(DWORD));
+
+ /* adjust dib size for SetDIBits, as it needs it to reverse top-down dibs
+ it must be set to the number of scanLines to transfer */
+ bmi->bmiHeader.biHeight = topDown ? -scanLines : scanLines;
+
+ /* creates destination compatible bitmap */
+ tmpHdc = GetDC(NULL);
+ hBmp = CreateCompatibleBitmap(tmpHdc, dibWidth, scanLines);
+ ReleaseDC(NULL, tmpHdc);
+ if(!hBmp)
+ {
+ ERR("CreateCompatibleBitmap failed\n");
+ HeapFree( GetProcessHeap(), 0, bmi );
+ return 0;
+ }
+
+ /* copies the requested scan lines from DIB to DDB */
+ /* FIXME : still no support for RLE packed DIBs */
+ res = SetDIBits( hdc, hBmp, 0, scanLines, bits, bmi, DIB_RGB_COLORS );
+ HeapFree( GetProcessHeap(), 0, bmi );
+ if(!res)
+ {
+ ERR("SetDIBits failed\n");
+ DeleteObject( hBmp );
+ return 0;
+ }
+ return hBmp;
+}
+
+/***********************************************************************
+ * Creates DIB that is compatible with the target hdc.
+ * startScan and scanLines specify the portion of DDB to convert
+ * in order to avoid unneeded conversion of large DDBs on blitting
+ *
+ * NOTE : the srcBmp DDB MUST NOT be selected in any DC */
+HBITMAP _DIBDRV_ConvertDDBtoDIB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines )
+{
+ HBITMAP hBmp = NULL;
+ BITMAP bitmap;
+ BITMAPINFO *bi;
+ void *bits = NULL;
+
+ if (!GetObjectW( srcBmp, sizeof(bitmap), &bitmap ))
+ {
+ ERR("Couldn't retrieve source bitmap\n");
+ return 0;
+ }
+
+ if(startScan + scanLines >= bitmap.bmHeight)
+ scanLines = bitmap.bmHeight - startScan;
+
+ bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) /* + 256 * sizeof(RGBQUAD) */);
+ if (!bi)
+ {
+ ERR("HeapAlloc failed\n");
+ return 0;
+ }
+
+ bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi->bmiHeader.biWidth = bitmap.bmWidth;
+ bi->bmiHeader.biHeight = scanLines;
+ bi->bmiHeader.biPlanes = bitmap.bmPlanes;
+ bi->bmiHeader.biBitCount = 32; /* bitmap.bmBitsPixel; */
+ bi->bmiHeader.biCompression = BI_RGB;
+ bi->bmiHeader.biSizeImage = 0;
+
+ /* Get the color table or the color masks */
+ /* NO NEED -- WE'RE REQUESTING A 32 bit DIB */
+#if 0
+ if (!GetDIBits(hdc, srcBmp, startScan, scanLines, NULL, bi, DIB_RGB_COLORS))
+ {
+ ERR("Couldn't get the color table/masks\n");
+ HeapFree( GetProcessHeap(), 0, bi );
+ return 0;
+ }
+#endif
+
+ /* Create bitmap and fill in bits */
+ hBmp = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+ if(!hBmp)
+ {
+ ERR("Failed to create DIB section\n");
+ HeapFree( GetProcessHeap(), 0, bi );
+ return 0;
+ }
+ if (bits)
+ {
+ if(!GetDIBits(hdc, srcBmp, startScan, scanLines, bits, bi, DIB_RGB_COLORS))
+ {
+ ERR("GetDIBits failed\n");
+ DeleteObject( hBmp );
+ HeapFree( GetProcessHeap(), 0, bi );
+ return 0;
+ }
+ }
+ else
+ {
+ ERR("CreateDibSection couldn't allocate DIB bits\n");
+ DeleteObject( hBmp );
+ HeapFree( GetProcessHeap(), 0, bi );
+ return 0;
+ }
+ HeapFree( GetProcessHeap(), 0, bi );
+ return hBmp;
+}
+
+/***********************************************************************
+ * BITBLT_ConvertDevDDBtoDIB
+ *
+ * Creates DIB that is compatible with the target hdc for a device (non memory) source DC */
+HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, int width, int height )
+{
+ HBITMAP bmp, dib;
+ HDC memHDC = NULL;
+
+ /* at first, we create a compatible DC and a bitmap with needed sizes */
+ memHDC = CreateCompatibleDC(hdcSrc);
+ if(!memHDC)
+ {
+ ERR("CreateCompatibleDC failed\n");
+ return 0;
+ }
+ bmp = CreateCompatibleBitmap(hdcSrc, width, height);
+ if(!bmp)
+ {
+ ERR("CreateCompatibleBitmap failed\n");
+ DeleteDC(memHDC);
+ return 0;
+ }
+
+ /* select the newly created DDB into the temporary DC */
+ bmp = SelectObject(memHDC, bmp);
+ if(!bmp)
+ {
+ ERR("Failed selecting DDB into temporary DC\n");
+ DeleteObject(bmp);
+ DeleteDC(memHDC);
+ return 0;
+ }
+
+ /* next, we blit pixels from device to the compatible bitmap */
+ if(!BitBlt(memHDC, 0, 0, width, height, hdcSrc, xSrc, ySrc, SRCCOPY))
+ {
+ ERR("BitBlt failed\n");
+ DeleteObject(bmp);
+ DeleteDC(memHDC);
+ return 0;
+ }
+
+ /* select out the DDB from the temporary DC */
+ bmp = SelectObject(memHDC, bmp);
+ DeleteDC(memHDC);
+ if(!bmp)
+ {
+ ERR("Failed selecting DDB out temporary DC\n");
+ DeleteObject(bmp);
+ return 0;
+ }
+
+ /*now we can convert the bitmap to a DIB */
+ dib = _DIBDRV_ConvertDDBtoDIB( hdcDst, bmp, 0, height );
+ if(!dib)
+ FIXME("ConvertDDBtoDIB failed\n");
+
+ /* free resources and return the created dib */
+ DeleteObject(bmp);
+ return dib;
+}
diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c
index c8e3b91..6184677 100644
--- a/dlls/winedib.drv/dc.c
+++ b/dlls/winedib.drv/dc.c
@@ -25,6 +25,100 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* some screen caps */
+static unsigned int screen_width;
+static unsigned int screen_height;
+static unsigned int screen_bpp;
+static unsigned int screen_depth;
+static RECT virtual_screen_rect;
+
+/* a few dynamic device caps */
+static int log_pixels_x; /* pixels per logical inch in x direction */
+static int log_pixels_y; /* pixels per logical inch in y direction */
+static int horz_size; /* horz. size of screen in millimeters */
+static int vert_size; /* vert. size of screen in millimeters */
+static int palette_size;
+static int device_init_done;
+
+/* NOTE :
+ Removing TC_RA_ABLE avoids bitmapped fonts, so FT_Face is always non-NULL
+ Adding TC_VA_ABLE forces to use gdi fonts always, so we can get an FT_Face
+*/
+unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
+ TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER |
+ TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE /* | TC_RA_ABLE */ | TC_VA_ABLE);
+ /* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */
+
+
+static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
+static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
+
+/******************************************************************************
+ * get_dpi
+ *
+ * get the dpi from the registry
+ */
+static DWORD get_dpi( void )
+{
+ DWORD dpi = 96;
+ HKEY hkey;
+
+ if (RegOpenKeyW(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS)
+ {
+ DWORD type, size, new_dpi;
+
+ size = sizeof(new_dpi);
+ if(RegQueryValueExW(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS)
+ {
+ if(type == REG_DWORD && new_dpi != 0)
+ dpi = new_dpi;
+ }
+ RegCloseKey(hkey);
+ }
+ return dpi;
+}
+
+/**********************************************************************
+ * device_init
+ *
+ * Perform initializations needed upon creation of the first device.
+ */
+static void device_init(void)
+{
+ Display *display;
+ Screen *screen;
+
+ /* opens default X11 Display */
+ if( (display = XOpenDisplay(NULL)) == NULL)
+ return;
+
+ /* gets default screen */
+ screen = XDefaultScreenOfDisplay(display);
+
+ /* gets screen sizes */
+ screen_width = XWidthOfScreen(screen);
+ screen_height = XHeightOfScreen(screen);
+
+ /* not sure about these ones... */
+ screen_bpp = XDefaultDepthOfScreen(screen);
+ screen_depth = XPlanesOfScreen(screen);
+ virtual_screen_rect.left = 0;
+ virtual_screen_rect.top = 0;
+ virtual_screen_rect.right = screen_width;
+ virtual_screen_rect.bottom = screen_height;
+
+ /* dummy ? */
+ palette_size = 0;
+
+ /* Initialize device caps */
+ log_pixels_x = log_pixels_y = get_dpi();
+ horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
+ vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
+
+ device_init_done = TRUE;
+}
+
/**********************************************************************
* DIBDRV_CreateDC
*/
@@ -34,8 +128,8 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev
DIBDRVPHYSDEV *physDev;
PHYSDEV X11PhysDev;
- TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n",
- hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData);
+ MAYBE(TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n",
+ hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData));
/* allocates physical device */
physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBDRVPHYSDEV) );
@@ -52,12 +146,53 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev
/* sets X11 Device pointer in DIB Engine device */
physDev->X11PhysDev = X11PhysDev;
+ /* stores the HDC */
+ physDev->hdc = hdc;
+
+ /* initializes device data (for GetDeviceCaps() )
+ on first DC creation */
+ if (!device_init_done)
+ device_init();
+
/* stock bitmap selected on DC creation */
physDev->hbitmap = GetStockObject(DEFAULT_BITMAP);
/* no DIB selected into DC on creation */
physDev->hasDIB = FALSE;
+ /* clear physical bitmap */
+ _DIBDRVBITMAP_Clear(&physDev->physBitmap);
+
+ /* clears pen and brush */
+ physDev->rop2 = R2_COPYPEN;
+
+ physDev->backgroundColor = 0;
+ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor);
+
+ physDev->penColor = 0;
+ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
+
+ physDev->brushColor = 0;
+ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor);
+ physDev->brushAnds = NULL;
+ physDev->brushXors = NULL;
+
+ physDev->brushStyle = BS_NULL;
+
+ physDev->isBrushBitmap = FALSE;
+ _DIBDRVBITMAP_Clear(&physDev->brushBitmap);
+ _DIBDRVBITMAP_Clear(&physDev->brushBmpCache);
+
+ /* text color */
+ physDev->textColor = 0;
+ physDev->textBackground = 0;
+
+ /* text color table for antialiased fonts */
+ memset(physDev->textColorTable, 0, 256);
+
+ /* freetype face associated to current DC HFONT */
+ physDev->face = NULL;
+
/* sets the result value and returns */
*pdev = physDev;
@@ -71,16 +206,31 @@ BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev )
{
BOOL res;
- TRACE("physDev:%p\n", physDev);
+ MAYBE(TRACE("physDev:%p\n", physDev));
/* frees X11 device */
res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev);
physDev->X11PhysDev = NULL;
+ /* frees physical bitmap */
+ _DIBDRVBITMAP_Free(&physDev->physBitmap);
+
+ /* frees brush bitmap */
+ _DIBDRVBITMAP_Free(&physDev->brushBitmap);
+ _DIBDRVBITMAP_Free(&physDev->brushBmpCache);
+
+ /* free brush ands and xors */
+ if(physDev->brushAnds)
+ {
+ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
+ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
+ }
+ physDev->brushAnds = NULL;
+ physDev->brushXors = NULL;
+
/* frees DIB Engine device */
HeapFree(GetProcessHeap(), 0, physDev);
- ONCE(FIXME("stub\n"));
return res;
}
@@ -92,8 +242,8 @@ INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID
{
INT res;
- TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n",
- physDev, escape, in_count, in_data, out_count, out_data);
+ MAYBE(TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n",
+ physDev, escape, in_count, in_data, out_count, out_data));
if(physDev->hasDIB)
{
@@ -116,13 +266,125 @@ INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap )
{
INT res;
- TRACE("physDev:%p, cap:%d\n", physDev, cap);
+ MAYBE(TRACE("physDev:%p, cap:%d\n", physDev, cap));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap);
+ switch(cap)
+ {
+ case DRIVERVERSION:
+ res = 0x300;
+ break;
+ case TECHNOLOGY:
+ res = DT_RASDISPLAY;
+ break;
+ case HORZSIZE:
+ res = horz_size;
+ break;
+ case VERTSIZE:
+ res = vert_size;
+ break;
+ case HORZRES:
+ res = screen_width;
+ break;
+ case VERTRES:
+ res = screen_height;
+ break;
+ case DESKTOPHORZRES:
+ res = virtual_screen_rect.right - virtual_screen_rect.left;
+ break;
+ case DESKTOPVERTRES:
+ res = virtual_screen_rect.bottom - virtual_screen_rect.top;
+ break;
+ case BITSPIXEL:
+ res = screen_bpp;
+ break;
+ case PLANES:
+ res = 1;
+ break;
+ case NUMBRUSHES:
+ res = -1;
+ break;
+ case NUMPENS:
+ res = -1;
+ break;
+ case NUMMARKERS:
+ res = 0;
+ break;
+ case NUMFONTS:
+ res = 0;
+ break;
+ case NUMCOLORS:
+ /* MSDN: Number of entries in the device's color table, if the device has
+ * a color depth of no more than 8 bits per pixel.For devices with greater
+ * color depths, -1 is returned. */
+ res = (screen_depth > 8) ? -1 : (1 << screen_depth);
+ break;
+ case CURVECAPS:
+ res = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+ CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+ break;
+ case LINECAPS:
+ res = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+ LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+ break;
+ case POLYGONALCAPS:
+ res = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+ PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+ break;
+ case TEXTCAPS:
+ res = text_caps;
+ break;
+ case CLIPCAPS:
+ res = CP_REGION;
+ break;
+ case RASTERCAPS:
+ res = (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
+ RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
+ (palette_size ? RC_PALETTE : 0));
+ break;
+ case SHADEBLENDCAPS:
+ res = (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA);
+ case ASPECTX:
+ case ASPECTY:
+ res = 36;
+ break;
+ case ASPECTXY:
+ res = 51;
+ break;
+ case LOGPIXELSX:
+ res = log_pixels_x;
+ break;
+ case LOGPIXELSY:
+ res = log_pixels_y;
+ break;
+ case CAPS1:
+ FIXME("(%p): CAPS1 is unimplemented, will return 0\n", physDev->hdc );
+ /* please see wingdi.h for the possible bit-flag values that need
+ to be returned. */
+ res = 0;
+ break;
+ case SIZEPALETTE:
+ res = palette_size;
+ break;
+ case NUMRESERVED:
+ case COLORRES:
+ case PHYSICALWIDTH:
+ case PHYSICALHEIGHT:
+ case PHYSICALOFFSETX:
+ case PHYSICALOFFSETY:
+ case SCALINGFACTORX:
+ case SCALINGFACTORY:
+ case VREFRESH:
+ case BLTALIGNMENT:
+ res = 0;
+ break;
+ default:
+ FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
+ res = 0;
+ break;
+ }
}
else
{
diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c
index 28330fa..b72c34a 100644
--- a/dlls/winedib.drv/dib.c
+++ b/dlls/winedib.drv/dib.c
@@ -33,11 +33,11 @@ HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap,
{
HBITMAP res;
- TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage);
+ MAYBE(TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage));
/* createDIBSection is only DIB-related, so we just use the engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pCreateDIBSection(physDev->X11PhysDev, hbitmap, bmi, usage);
+ ONCE(FIXME("STUB\n"));
+ res = hbitmap;
return res;
}
@@ -50,8 +50,8 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
{
INT res;
- TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n",
- physDev, hbitmap, startscan, lines, bits, bmi, coloruse);
+ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n",
+ physDev, hbitmap, startscan, lines, bits, bmi, coloruse));
/* 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);
@@ -67,11 +67,11 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count,
{
UINT res;
- TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors);
+ 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 */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetDIBColorTable(physDev->X11PhysDev, start, count, colors);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
return res;
}
@@ -84,8 +84,8 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan,
{
INT res;
- TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n",
- physDev, hbitmap, startscan, lines, bits, info, coloruse);
+ 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);
@@ -103,8 +103,8 @@ INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWOR
{
INT res;
- 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);
+ 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,
diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h
index 8a2e139..773941e 100644
--- a/dlls/winedib.drv/dibdrv.h
+++ b/dlls/winedib.drv/dibdrv.h
@@ -35,10 +35,15 @@
#include "winreg.h"
#include "wine/winbase16.h" /* GlobalLock16 */
+#include "freetype.h"
+
/* data structures needed to access opaque pointers
* defined in gdi32.h */
#include "dibdrv_gdi32.h"
+/* enable this if you want debugging (i.e. TRACEs) output */
+#define DIBDRV_ENABLE_MAYBE
+
/* provide a way to make debugging output appear
only once. Usage example:
ONCE(FIXME("Some message\n")); */
@@ -52,25 +57,197 @@
} \
}
+/* provide a way to make debugging output appear
+ only if enabled here. Can speed up stuffs
+ avoiding long traces.Usage example:
+ MAYBE(TRACE("Some message\n")); */
+#ifdef DIBDRV_ENABLE_MAYBE
+#define MAYBE(x) x
+#else
+#define MAYBE(x)
+#endif
+
+
/* extra stock object: default 1x1 bitmap for memory DCs
grabbed from gdi_private.h */
#define DEFAULT_BITMAP (STOCK_LAST+1)
+struct _DIBDRVBITMAP;
+struct _DIBDRVPHYSDEV;
+typedef struct _DIBDRV_PRIMITIVE_FUNCS
+{
+ /* color to pixel data conversion */
+ DWORD (* ColorToPixel) (const struct _DIBDRVBITMAP *bmp, COLORREF color);
+
+ /* pixel primitives */
+ void* (* GetPixelPointer) (const struct _DIBDRVBITMAP *bmp, int x, int y);
+ void (* SetPixel) ( struct _DIBDRVBITMAP *bmp, int x, int y, DWORD and, DWORD xor);
+ DWORD (* GetPixel) (const struct _DIBDRVBITMAP *bmp, int x, int y);
+
+ /* line drawing primitives */
+ void (* SolidHLine) ( struct _DIBDRVBITMAP *bmp, int x1, int x2, int y, DWORD and, DWORD xor);
+ void (* PatternHLine) ( struct _DIBDRVBITMAP *bmp, int x1, int x2, int y, const void *and, const void *xor, DWORD offset, DWORD count);
+ void (* SolidVLine) ( struct _DIBDRVBITMAP *bmp, int x, int y1, int y2, DWORD and, DWORD xor);
+
+ /* bitmap conversion helpers */
+ BOOL (* GetLine) (const struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf);
+ BOOL (* PutLine) ( struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf);
+
+ /* BitBlt primitives */
+ BOOL (* BitBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int width, int height,
+ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, DWORD rop );
+ BOOL (* StretchBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst,
+ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, DWORD rop );
+
+ /* font drawing helper */
+ void (* FreetypeBlit) ( struct _DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp);
+
+} DIBDRV_PRIMITIVE_FUNCS;
+
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4;
+extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1;
+
+/* DIB bitmaps formats */
+typedef enum _DIBFORMAT
+{
+ DIBFMT_UNKNOWN = 0,
+ DIBFMT_DIB1 = 1,
+ DIBFMT_DIB4 = 2,
+ DIBFMT_DIB4_RLE = 3,
+ DIBFMT_DIB8 = 4,
+ DIBFMT_DIB8_RLE = 5,
+ DIBFMT_DIB16_RGB = 6,
+ DIBFMT_DIB16_BITFIELDS = 7,
+ DIBFMT_DIB24 = 8,
+ DIBFMT_DIB32_RGB = 9,
+ DIBFMT_DIB32_BITFIELDS = 10
+} DIBFORMAT;
+
+/* DIB driver's generic bitmap structure */
+typedef struct _DIBDRVBITMAP
+{
+ /* bitmap format of dib */
+ DIBFORMAT format;
+
+ /* pointer to top left corner of bitmap */
+ void *bits;
+
+ /* flags indicating if bits array is owned
+ by the bitmap */
+ BOOL ownsBits;
+
+ /* bitmap dimensions */
+ int width;
+ int height;
+
+ /* bitmap stride (== width in bytes) of a bitmap line */
+ /* negative for a bottom-up bitmap */
+ int stride;
+
+ /* number of bits/pixel in bitmap */
+ int bitCount;
+
+ /* calculated numbers for bitfields */
+
+ /* bitfields masks */
+ DWORD redMask, greenMask, blueMask;
+ /* shifting required within a COLORREF's BYTE */
+ int redShift, greenShift, blueShift;
+ /* size of the fields */
+ int redLen, greenLen, blueLen;
+
+ /* color table and its size */
+ RGBQUAD *colorTable;
+ DWORD colorTableSize;
+
+ /* flag indicating that color table has been grabbed */
+ BOOL colorTableGrabbed;
+
+ /* primitive function pointers */
+ DIBDRV_PRIMITIVE_FUNCS *funcs;
+
+} DIBDRVBITMAP;
+
+/* dash patterns */
+typedef struct _DASHPATTERN
+{
+ DWORD count;
+ DWORD dashes[6];
+
+} DASHPATTERN;
+
/* DIB driver physical device */
typedef struct _DIBDRVPHYSDEV
{
/* X11 driver physical device */
PHYSDEV X11PhysDev;
+ /* HDC associated with physDev */
+ HDC hdc;
+
/* is a DIB selected into DC ? */
BOOL hasDIB;
/* currently selected HBITMAP */
HBITMAP hbitmap;
+
+ /* physical bitmap */
+ DIBDRVBITMAP physBitmap;
/* active ROP2 */
INT rop2;
+ /* background color and active ROP2 precalculated
+ AND and XOR values for it */
+ COLORREF backgroundColor;
+ DWORD backgroundAnd, backgroundXor;
+
+ /* pen color and active ROP2 precalculated
+ AND and XOR values for it */
+ COLORREF penColorref;
+ DWORD penColor;
+ DWORD penAnd, penXor;
+ const DASHPATTERN *penPattern;
+ DWORD curDash, leftInDash;
+ enum MARKSPACE { mark, space } markSpace;
+
+ /* pen drawing functions */
+ void (* penHLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y);
+ void (* penVLine) (struct _DIBDRVPHYSDEV *physDev, int x, int y1, int y2);
+ void (* penLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2);
+ void (* brushHLine)(struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y);
+
+ /* brush color and active ROP2 precalculated
+ AND and XOR values for it */
+ COLORREF brushColorref;
+ DWORD brushColor;
+ DWORD brushAnd, brushXor;
+ DWORD *brushAnds, *brushXors;
+
+ /* brush style */
+ UINT brushStyle;
+
+ /* brush bitmap, if needed, and its converted/resized cache copy */
+ BOOL isBrushBitmap;
+ DIBDRVBITMAP brushBitmap;
+ DIBDRVBITMAP brushBmpCache;
+
+ /* text color */
+ COLORREF textColor;
+ COLORREF textBackground;
+
+ /* text color table for antialiased fonts */
+ COLORREF textColorTable[256];
+
+ /* freetype face associated to current DC HFONT */
+ FT_Face face;
+
} DIBDRVPHYSDEV;
@@ -90,4 +267,117 @@ void _DIBDRV_FreeDisplayDriver(void);
Gets a pointer to display drives'function table */
inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void);
-#endif /* __WINE_DIBDRV_H */
+/* *********************************************************************
+ * ROP2 AND OTHER DRAWING RELATED FUNCTIONS
+ * ********************************************************************/
+
+void _DIBDRV_CalcAndXorMasks(INT rop, DWORD color, DWORD *and, DWORD *xor);
+
+inline void _DIBDRV_rop32(DWORD *ptr, DWORD and, DWORD xor);
+inline void _DIBDRV_rop16(WORD *ptr, WORD and, WORD xor);
+inline void _DIBDRV_rop8(BYTE *ptr, BYTE and, BYTE xor);
+
+void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev);
+
+/* *********************************************************************
+ * ROP2 FUNCTIONS
+ * ********************************************************************/
+
+/* the ROP3 operations
+ this is a BIG case block; beware that some
+ commons ROP3 operations will be optimized
+ from inside blt routines */
+DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop);
+
+/* *********************************************************************
+ * PHYSICAL BITMAP FUNCTIONS
+ * ********************************************************************/
+
+/* gets human-readable dib format name */
+const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp);
+
+/* initializes dib from a bitmap :
+ dib dib being initialized
+ bi source BITMAPINFOHEADER with required DIB format info
+ bit_fields color masks
+ color_table color table, if any
+ bits pointer to image data array
+ NOTE : DIBDRVBITMAP doesn't owns bits, but do own color table */
+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);
+
+/* initializes a DIBRDVBITMAP copying it from a source one
+ Parameters :
+ dib destination DIBDRVBITMAP
+ src source DIBDRVBITMAP
+ copy TRUE->copy source pixel array FALSE->link to source pixel array */
+BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy);
+
+/* creates a DIBRDVBITMAP copying format info from a source one
+ Parameters :
+ dib destination DIBDRVBITMAP
+ src source DIBDRVBITMAP
+ widht, height sizes of newly created bitmap */
+BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height);
+
+/* Clears a DIBDRVBITMAP structure data
+ WARNING : doesn't free anything */
+void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp);
+
+/* Frees a DIBDRVBITMAP structure data */
+void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp);
+
+/* checks whether the format of 2 DIBs are identical
+ it checks the pixel bit count and the color table size
+ and content, if needed */
+BOOL _DIBDRVBITMAP_FormatMatch(const DIBDRVBITMAP *d1, const DIBDRVBITMAP *d2);
+
+/* convert a given dib into another format given by 'format' parameter */
+BOOL _DIBDRVBITMAP_Convert(DIBDRVBITMAP *dst, const DIBDRVBITMAP *src, const DIBDRVBITMAP *format);
+
+/* creates a solid-filled DIB of given color and format
+ DIB format is given by 'format' parameter */
+BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int width, int height, DWORD Color);
+
+/* expands horizontally a bitmap to reach a minimum size,
+ keeping its width as a multiple of a base width
+ Used to widen brushes in order to optimize blitting */
+BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth);
+
+/* *********************************************************************
+ * DIB <--> DDB CONVERSION ROUTINES
+ * ********************************************************************/
+
+/***********************************************************************
+ * Creates DDB that is compatible with source hdc.
+ * hdc is the HDC on where the DIB MUST be selected in
+ * srcBmp is the source DIB
+ * startScan and scanLines specify the portion of DIB to convert
+ * in order to avoid unneeded conversion of large DIBs on blitting
+ *
+ * NOTE : the srcBmp DIB MUST NOT be selected in any DC */
+HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines );
+
+/***********************************************************************
+ * Creates DIB that is compatible with the target hdc.
+ * startScan and scanLines specify the portion of DDB to convert
+ * in order to avoid unneeded conversion of large DDBs on blitting
+ *
+ * NOTE : the srcBmp DDB MUST NOT be selected in any DC */
+HBITMAP _DIBDRV_ConvertDDBtoDIB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines );
+
+/***********************************************************************
+ * Creates DIB that is compatible with the target hdc for a device (non memory) source DC */
+HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, int width, int height );
+
+/* *********************************************************************
+ * QUERY FUNCTIONS
+ * ********************************************************************/
+
+/***********************************************************************
+ * DIBDRV_GetDeviceCaps */
+INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap );
+
+#endif
diff --git a/dlls/winedib.drv/dibdrv_gdi32.h b/dlls/winedib.drv/dibdrv_gdi32.h
new file mode 100644
index 0000000..8e4eb05
--- /dev/null
+++ b/dlls/winedib.drv/dibdrv_gdi32.h
@@ -0,0 +1,168 @@
+/*
+ * GDI structures - grabbed from dlls/gdi32/gdi_private.h
+ * Those are needed to access some opaque gdi32 pointers
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_DIBDRV_GDI32_H
+#define __WINE_DIBDRV_GDI32_H
+
+
+/* driver function pointers - used here to forward calls to X11 driver when needed */
+typedef struct { int opaque; } *PHYSDEV; /* PHYSDEV is an opaque pointer */
+typedef struct tagDC_FUNCS
+{
+ INT (CDECL *pAbortDoc)(PHYSDEV);
+ BOOL (CDECL *pAbortPath)(PHYSDEV);
+ BOOL (CDECL *pAlphaBlend)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,BLENDFUNCTION);
+ BOOL (CDECL *pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT);
+ BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
+ BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
+ BOOL (CDECL *pBeginPath)(PHYSDEV);
+ BOOL (CDECL *pBitBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,DWORD);
+ INT (CDECL *pChoosePixelFormat)(PHYSDEV,const PIXELFORMATDESCRIPTOR *);
+ BOOL (CDECL *pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
+ BOOL (CDECL *pCloseFigure)(PHYSDEV);
+ BOOL (CDECL *pCreateBitmap)(PHYSDEV,HBITMAP,LPVOID);
+ BOOL (CDECL *pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
+ HBITMAP (CDECL *pCreateDIBSection)(PHYSDEV,HBITMAP,const BITMAPINFO *,UINT);
+ BOOL (CDECL *pDeleteBitmap)(HBITMAP);
+ BOOL (CDECL *pDeleteDC)(PHYSDEV);
+ BOOL (CDECL *pDeleteObject)(PHYSDEV,HGDIOBJ);
+ INT (CDECL *pDescribePixelFormat)(PHYSDEV,INT,UINT,PIXELFORMATDESCRIPTOR *);
+ DWORD (CDECL *pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
+ BOOL (CDECL *pEllipse)(PHYSDEV,INT,INT,INT,INT);
+ INT (CDECL *pEndDoc)(PHYSDEV);
+ INT (CDECL *pEndPage)(PHYSDEV);
+ BOOL (CDECL *pEndPath)(PHYSDEV);
+ BOOL (CDECL *pEnumDeviceFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM);
+ INT (CDECL *pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT);
+ INT (CDECL *pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD);
+ INT (CDECL *pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID);
+ BOOL (CDECL *pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT);
+ INT (CDECL *pExtSelectClipRgn)(PHYSDEV,HRGN,INT);
+ BOOL (CDECL *pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*);
+ BOOL (CDECL *pFillPath)(PHYSDEV);
+ BOOL (CDECL *pFillRgn)(PHYSDEV,HRGN,HBRUSH);
+ BOOL (CDECL *pFlattenPath)(PHYSDEV);
+ BOOL (CDECL *pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
+ BOOL (CDECL *pGdiComment)(PHYSDEV,UINT,CONST BYTE*);
+ LONG (CDECL *pGetBitmapBits)(HBITMAP,void*,LONG);
+ BOOL (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
+ BOOL (CDECL *pGetDCOrgEx)(PHYSDEV,LPPOINT);
+ UINT (CDECL *pGetDIBColorTable)(PHYSDEV,UINT,UINT,RGBQUAD*);
+ INT (CDECL *pGetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
+ INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT);
+ BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID);
+ BOOL (CDECL *pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR);
+ COLORREF (CDECL *pGetNearestColor)(PHYSDEV,COLORREF);
+ COLORREF (CDECL *pGetPixel)(PHYSDEV,INT,INT);
+ INT (CDECL *pGetPixelFormat)(PHYSDEV);
+ UINT (CDECL *pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY);
+ BOOL (CDECL *pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,INT,LPINT,LPINT,LPSIZE);
+ BOOL (CDECL *CDECL pGetTextMetrics)(PHYSDEV,TEXTMETRICW*);
+ INT (CDECL *pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT);
+ BOOL (CDECL *pInvertRgn)(PHYSDEV,HRGN);
+ BOOL (CDECL *pLineTo)(PHYSDEV,INT,INT);
+ BOOL (CDECL *pModifyWorldTransform)(PHYSDEV,const XFORM*,INT);
+ BOOL (CDECL *pMoveTo)(PHYSDEV,INT,INT);
+ INT (CDECL *pOffsetClipRgn)(PHYSDEV,INT,INT);
+ INT (CDECL *pOffsetViewportOrg)(PHYSDEV,INT,INT);
+ INT (CDECL *pOffsetWindowOrg)(PHYSDEV,INT,INT);
+ BOOL (CDECL *pPaintRgn)(PHYSDEV,HRGN);
+ BOOL (CDECL *pPatBlt)(PHYSDEV,INT,INT,INT,INT,DWORD);
+ BOOL (CDECL *pPie)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
+ BOOL (CDECL *pPolyBezier)(PHYSDEV,const POINT*,DWORD);
+ BOOL (CDECL *pPolyBezierTo)(PHYSDEV,const POINT*,DWORD);
+ BOOL (CDECL *pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD);
+ BOOL (CDECL *pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT);
+ BOOL (CDECL *pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD);
+ BOOL (CDECL *pPolygon)(PHYSDEV,const POINT*,INT);
+ BOOL (CDECL *pPolyline)(PHYSDEV,const POINT*,INT);
+ BOOL (CDECL *pPolylineTo)(PHYSDEV,const POINT*,INT);
+ UINT (CDECL *pRealizeDefaultPalette)(PHYSDEV);
+ UINT (CDECL *pRealizePalette)(PHYSDEV,HPALETTE,BOOL);
+ BOOL (CDECL *pRectangle)(PHYSDEV,INT,INT,INT,INT);
+ HDC (CDECL *pResetDC)(PHYSDEV,const DEVMODEW*);
+ BOOL (CDECL *pRestoreDC)(PHYSDEV,INT);
+ BOOL (CDECL *pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT);
+ INT (CDECL *pSaveDC)(PHYSDEV);
+ INT (CDECL *pScaleViewportExt)(PHYSDEV,INT,INT,INT,INT);
+ INT (CDECL *pScaleWindowExt)(PHYSDEV,INT,INT,INT,INT);
+ HBITMAP (CDECL *pSelectBitmap)(PHYSDEV,HBITMAP);
+ HBRUSH (CDECL *pSelectBrush)(PHYSDEV,HBRUSH);
+ BOOL (CDECL *pSelectClipPath)(PHYSDEV,INT);
+ HFONT (CDECL *pSelectFont)(PHYSDEV,HFONT,HANDLE);
+ HPALETTE (CDECL *pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
+ HPEN (CDECL *pSelectPen)(PHYSDEV,HPEN);
+ INT (CDECL *pSetArcDirection)(PHYSDEV,INT);
+ LONG (CDECL *pSetBitmapBits)(HBITMAP,const void*,LONG);
+ COLORREF (CDECL *pSetBkColor)(PHYSDEV,COLORREF);
+ INT (CDECL *pSetBkMode)(PHYSDEV,INT);
+ COLORREF (CDECL *pSetDCBrushColor)(PHYSDEV, COLORREF);
+ DWORD (CDECL *pSetDCOrg)(PHYSDEV,INT,INT);
+ COLORREF (CDECL *pSetDCPenColor)(PHYSDEV, COLORREF);
+ UINT (CDECL *pSetDIBColorTable)(PHYSDEV,UINT,UINT,const RGBQUAD*);
+ INT (CDECL *pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT);
+ INT (CDECL *pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID,
+ const BITMAPINFO*,UINT);
+ VOID (CDECL *pSetDeviceClipping)(PHYSDEV,HRGN,HRGN);
+ BOOL (CDECL *pSetDeviceGammaRamp)(PHYSDEV,LPVOID);
+ INT (CDECL *pSetMapMode)(PHYSDEV,INT);
+ DWORD (CDECL *pSetMapperFlags)(PHYSDEV,DWORD);
+ COLORREF (CDECL *pSetPixel)(PHYSDEV,INT,INT,COLORREF);
+ BOOL (CDECL *pSetPixelFormat)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
+ INT (CDECL *pSetPolyFillMode)(PHYSDEV,INT);
+ INT (CDECL *pSetROP2)(PHYSDEV,INT);
+ INT (CDECL *pSetRelAbs)(PHYSDEV,INT);
+ INT (CDECL *pSetStretchBltMode)(PHYSDEV,INT);
+ UINT (CDECL *pSetTextAlign)(PHYSDEV,UINT);
+ INT (CDECL *pSetTextCharacterExtra)(PHYSDEV,INT);
+ DWORD (CDECL *pSetTextColor)(PHYSDEV,DWORD);
+ INT (CDECL *pSetTextJustification)(PHYSDEV,INT,INT);
+ INT (CDECL *pSetViewportExt)(PHYSDEV,INT,INT);
+ INT (CDECL *pSetViewportOrg)(PHYSDEV,INT,INT);
+ INT (CDECL *pSetWindowExt)(PHYSDEV,INT,INT);
+ INT (CDECL *pSetWindowOrg)(PHYSDEV,INT,INT);
+ BOOL (CDECL *pSetWorldTransform)(PHYSDEV,const XFORM*);
+ INT (CDECL *pStartDoc)(PHYSDEV,const DOCINFOW*);
+ INT (CDECL *pStartPage)(PHYSDEV);
+ BOOL (CDECL *pStretchBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,DWORD);
+ INT (CDECL *pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void *,
+ const BITMAPINFO*,UINT,DWORD);
+ BOOL (CDECL *pStrokeAndFillPath)(PHYSDEV);
+ BOOL (CDECL *pStrokePath)(PHYSDEV);
+ BOOL (CDECL *pSwapBuffers)(PHYSDEV);
+ BOOL (CDECL *pUnrealizePalette)(HPALETTE);
+ BOOL (CDECL *pWidenPath)(PHYSDEV);
+
+ /* OpenGL32 */
+ BOOL (CDECL *pwglCopyContext)(HGLRC, HGLRC, UINT);
+ HGLRC (CDECL *pwglCreateContext)(PHYSDEV);
+ BOOL (CDECL *pwglDeleteContext)(HGLRC);
+ PROC (CDECL *pwglGetProcAddress)(LPCSTR);
+ HDC (CDECL *pwglGetPbufferDCARB)(PHYSDEV, void*);
+ BOOL (CDECL *pwglMakeCurrent)(PHYSDEV, HGLRC);
+ BOOL (CDECL *pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC);
+ BOOL (CDECL *pwglSetPixelFormatWINE)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *);
+ BOOL (CDECL *pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2);
+ BOOL (CDECL *pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD);
+ BOOL (CDECL *pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD);
+} DC_FUNCTIONS;
+
+#endif
diff --git a/dlls/winedib.drv/dibdrv_main.c b/dlls/winedib.drv/dibdrv_main.c
index 28429d2..e436440 100644
--- a/dlls/winedib.drv/dibdrv_main.c
+++ b/dlls/winedib.drv/dibdrv_main.c
@@ -35,15 +35,26 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
switch(reason)
{
case DLL_PROCESS_ATTACH:
+
/* Loads display driver */
_DIBDRV_LoadDisplayDriver();
+
+ /* initializes freetype library */
+ if(!_DIBDRV_FreeType_Init())
+ ERR("Couldn't initialize freetype library.\n");
+
break;
case DLL_THREAD_DETACH:
/* do thread detach */
break;
case DLL_PROCESS_DETACH:
+
+ /* terminates freetype library */
+ _DIBDRV_FreeType_Terminate();
+
/* unloads display driver */
_DIBDRV_FreeDisplayDriver();
+
break;
}
return ret;
diff --git a/dlls/winedib.drv/dibdrvbitmap.c b/dlls/winedib.drv/dibdrvbitmap.c
new file mode 100644
index 0000000..2c8c367
--- /dev/null
+++ b/dlls/winedib.drv/dibdrvbitmap.c
@@ -0,0 +1,650 @@
+/*
+ * DIB Engine DIBDRVBITMAP handling
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* gets human-readable dib format name */
+const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp)
+{
+ if(!bmp)
+ {
+ ERR("Null bitmap\n");
+ return "NULL BITMAP DETECTED";
+ }
+ switch(bmp->format)
+ {
+ case DIBFMT_DIB1:
+ return "DIBFMT_DIB1";
+ case DIBFMT_DIB4:
+ return "DIBFMT_DIB4";
+ case DIBFMT_DIB4_RLE:
+ return "DIBFMT_DIB4_RLE";
+ case DIBFMT_DIB8:
+ return "DIBFMT_DIB8";
+ case DIBFMT_DIB8_RLE:
+ return "DIBFMT_DIB8_RLE";
+ case DIBFMT_DIB16_RGB:
+ return "DIBFMT_DIB_RGB";
+ case DIBFMT_DIB16_BITFIELDS:
+ return "DIBFMT_DIB16_BITFIELDS";
+ case DIBFMT_DIB24:
+ return "DIBFMT_DIB24";
+ case DIBFMT_DIB32_RGB:
+ return "DIBFMT_DIB32_RGB";
+ case DIBFMT_DIB32_BITFIELDS:
+ return "DIBFMT_DIB32_BITFIELDS";
+ case DIBFMT_UNKNOWN:
+ default:
+ return "DIBFMT_UNKNOWN";
+ }
+}
+
+/* calculates shift and length given a bit mask */
+static void CalcShiftAndLen(DWORD mask, int *shift, int *len)
+{
+ int s, l;
+
+ /* FIXME----*/
+ if(mask == 0)
+ {
+ FIXME("color mask == 0 -- problem on init_dib\n");
+ *shift = 0;
+ *len = 0;
+ return;
+ }
+
+ /* calculates bit shift
+ (number of 0's on right of bit field */
+ s = 0;
+ while ((mask & 1) == 0)
+ {
+ mask >>= 1;
+ s++;
+ }
+
+ /* calculates bitfield length
+ (number of 1's in bit field */
+ l = 0;
+ while ((mask & 1) == 1)
+ {
+ mask >>= 1;
+ l++;
+ }
+ *shift = s;
+ *len = l;
+}
+
+/* initializes bit fields from bit masks */
+static void InitBitFields(DIBDRVBITMAP *dib, const DWORD *bit_fields)
+{
+ dib->redMask = bit_fields[0];
+ dib->greenMask = bit_fields[1];
+ dib->blueMask = bit_fields[2];
+ CalcShiftAndLen(dib->redMask, &dib->redShift, &dib->redLen);
+ CalcShiftAndLen(dib->greenMask, &dib->greenShift, &dib->greenLen);
+ CalcShiftAndLen(dib->blueMask, &dib->blueShift, &dib->blueLen);
+}
+
+/* initializes dib from a bitmap :
+ dib dib being initialized
+ bi source BITMAPINFOHEADER with required DIB format info
+ bit_fields color masks
+ colorTable color table, if any
+ bits pointer to image data array
+ NOTE : DIBDRVBITMAP doesn't owns bits, but do own color table
+*/
+BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields,
+ const RGBQUAD *colorTable, void *bits)
+{
+ MAYBE(TRACE("dib=%p, bi=%p, bit_fields=%p, colorTable=%p, bits=%p\n", dib, bi, bit_fields, colorTable, bits));
+
+ /* initializes DIB dimensions and color depth */
+ dib->bitCount = bi->biBitCount;
+ dib->width = bi->biWidth;
+ dib->height = bi->biHeight;
+ dib->stride = ((dib->width * dib->bitCount + 31) >> 3) & ~3;
+
+ /* initializes image data pointer */
+ dib->bits = bits;
+ dib->ownsBits = FALSE;
+
+ /* initializes color table */
+ dib->colorTableSize = 0;
+ dib->colorTable = NULL;
+ dib->colorTableGrabbed = FALSE;
+
+ /* checks whether dib is top-down or bottom-up one */
+ if(dib->height < 0)
+ {
+ /* top-down dib */
+ dib->height = -dib->height;
+ }
+ else
+ {
+ /* bottom-up dib */
+ /* data->bits always points to the top-left corner and the stride is -ve */
+ dib->bits = (BYTE*)dib->bits + (dib->height - 1) * dib->stride;
+ dib->stride = -dib->stride;
+ }
+
+ /* gets and stores bitmap format */
+ switch(dib->bitCount)
+ {
+ case 24:
+ dib->format = DIBFMT_DIB24;
+ dib->funcs = &DIBDRV_funcs_DIB24;
+ break;
+
+ case 32:
+
+ if(bi->biCompression == BI_RGB)
+ {
+ dib->format = DIBFMT_DIB32_RGB;
+ dib->funcs = &DIBDRV_funcs_DIB32_RGB;
+ }
+ else
+ {
+ InitBitFields(dib, bit_fields);
+ dib->format = DIBFMT_DIB32_BITFIELDS;
+ dib->funcs = &DIBDRV_funcs_DIB32_BITFIELDS;
+ }
+ break;
+
+ case 16:
+ if(bi->biCompression == BI_RGB)
+ {
+ dib->format = DIBFMT_DIB16_RGB;
+ dib->funcs = &DIBDRV_funcs_DIB16_RGB;
+ }
+ else
+ {
+ InitBitFields(dib, bit_fields);
+ dib->format = DIBFMT_DIB16_BITFIELDS;
+ dib->funcs = &DIBDRV_funcs_DIB16_BITFIELDS;
+ }
+ break;
+
+ case 8:
+ dib->format = DIBFMT_DIB8;
+ dib->funcs = &DIBDRV_funcs_DIB8;
+ dib->colorTableSize = 256;
+ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed;
+ break;
+
+ case 4:
+ dib->format = DIBFMT_DIB4;
+ dib->funcs = &DIBDRV_funcs_DIB4;
+ dib->colorTableSize = 16;
+ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed;
+ break;
+
+ case 1:
+ dib->format = DIBFMT_DIB1;
+ dib->funcs = &DIBDRV_funcs_DIB1;
+ dib->colorTableSize = 2;
+ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed;
+ break;
+
+ default:
+ dib->format = DIBFMT_UNKNOWN;
+ dib->funcs = NULL;
+ FIXME("bpp %d not supported\n", dib->bitCount);
+ return FALSE;
+ }
+ MAYBE(TRACE("DIB FORMAT : %s\n", _DIBDRVBITMAP_GetFormatName(dib)));
+
+ /* allocates color table and copy it from source, *if* source is
+ not null */
+ if(dib->colorTableSize && colorTable)
+ {
+ if(!(dib->colorTable = HeapAlloc(GetProcessHeap(), 0,
+ dib->colorTableSize * sizeof(dib->colorTable[0]))
+ ))
+ {
+ ERR("HeapAlloc failed\n");
+ return FALSE;
+ }
+ memcpy(dib->colorTable, colorTable,
+ dib->colorTableSize * sizeof(dib->colorTable[0]));
+ dib->colorTableGrabbed = TRUE;
+ }
+ else if(!dib->colorTableSize)
+ /* no color table on more than 8 bits/pixel */
+ dib->colorTableGrabbed = TRUE;
+
+ MAYBE(TRACE("END\n"));
+ return TRUE;
+}
+
+BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi)
+{
+ static const DWORD bit_fields_DIB32_RGB[3] = {0xff0000, 0x00ff00, 0x0000ff};
+ static const DWORD bit_fields_DIB16_RGB[3] = {0x7c00, 0x03e0, 0x001f};
+ BITMAPINFOHEADER *bi = (BITMAPINFOHEADER *)bmi;
+ const DWORD *masks = NULL;
+ RGBQUAD *colorTable = NULL;
+ BYTE *ptr = (BYTE*)bmi + bi->biSize;
+ int num_colors = bi->biClrUsed;
+ BOOL res;
+
+ MAYBE(TRACE("dib=%p, bmi=%p\n", dib, bmi));
+
+ if(bi->biCompression == BI_BITFIELDS)
+ {
+ masks = (DWORD *)ptr;
+ ptr += 3 * sizeof(DWORD);
+ }
+ else if(bi->biBitCount == 32)
+ masks = bit_fields_DIB32_RGB;
+ else if(bi->biBitCount == 16)
+ masks = bit_fields_DIB16_RGB;
+
+ if(!num_colors && bi->biBitCount <= 8)
+ num_colors = 1 << bi->biBitCount;
+ if(num_colors)
+ colorTable = (RGBQUAD*)ptr;
+ ptr += num_colors * sizeof(*colorTable);
+
+ res = _DIBDRVBITMAP_InitFromBMIH(dib, bi, masks, colorTable, ptr);
+ MAYBE(TRACE("END\n"));
+ return res;
+}
+
+/* initializes a DIBRDVBITMAP copying it from a source one
+ Parameters :
+ dib destination DIBDRVBITMAP
+ src source DIBDRVBITMAP
+ copy TRUE->copy source pixel array FALSE->link to source pixel array
+*/
+BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy)
+{
+ MAYBE(TRACE("dib=%p, src=%p, copy=%d\n", dib, src, copy));
+
+ dib->format = src->format;
+ dib->width = src->width;
+ dib->height = src->height;
+ dib->stride = src->stride;
+ dib->bitCount = src->bitCount;
+
+ dib->redMask = src->redMask;
+ dib->greenMask = src->greenMask;
+ dib->blueMask = src->blueMask;
+ dib->redShift = src->redShift;
+ dib->greenShift = src->greenShift;
+ dib->blueShift = src->blueShift;
+ dib->redLen = src->redLen;
+ dib->greenLen = src->greenLen;
+ dib->blueLen = src->blueLen;
+
+ dib->funcs = src->funcs;
+
+ if(copy)
+ {
+ int size = dib->height*abs(dib->stride);
+ if(!(dib->bits = HeapAlloc(GetProcessHeap(), 0, size)))
+ {
+ ERR("Failed to allocate bits buffer\n");
+ return FALSE;
+ }
+ dib->ownsBits = TRUE;
+
+ /* check for bottom-up DIB */
+ if(dib->stride < 0)
+ {
+ /* copy the bitmap array */
+ memcpy(dib->bits, (BYTE *)src->bits + (src->height - 1) * src->stride, size);
+
+ dib->bits = (BYTE *)dib->bits - (dib->height-1) * dib->stride;
+ }
+ else
+ {
+ /* copy the bitmap array */
+ memcpy(dib->bits, src->bits, size);
+ }
+ }
+ else
+ {
+ dib->bits = src->bits;
+ dib->ownsBits = FALSE;
+ }
+
+ if(src->colorTable)
+ {
+ dib->colorTable = HeapAlloc(GetProcessHeap(), 0, src->colorTableSize * sizeof(src->colorTable[0]));
+ memcpy(dib->colorTable, src->colorTable, src->colorTableSize * sizeof(src->colorTable[0]));
+ }
+ else
+ dib->colorTable = NULL;
+ dib->colorTableSize = src->colorTableSize;
+ dib->colorTableGrabbed = TRUE;
+ MAYBE(TRACE("END\n"));
+ return TRUE;
+}
+
+/* creates a DIBRDVBITMAP copying format info from a source one
+ Parameters :
+ dib destination DIBDRVBITMAP
+ src source DIBDRVBITMAP
+ widht, height sizes of newly created bitmap
+*/
+BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height)
+{
+ MAYBE(TRACE("dib=%p, src=%p, width=%d, height=%d\n", dib, src, width, height));
+
+ /* grab color and format info from source DIB */
+ if(!_DIBDRVBITMAP_InitFromDibdrvbitmap(dib, src, FALSE))
+ {
+ ERR("Failed grabbing source dib format\n");
+ return FALSE;
+ }
+
+ /* sets up new DIB dimensions */
+ dib->width = width;
+ dib->height = height;
+
+ /* calculates new stride basing of new width */
+ dib->stride = ((width * dib->bitCount +31) &~31) / 8;
+ if(src->stride < 0)
+ dib->stride = -dib->stride;
+
+ /* allocates bits for newly created DIB */
+ if(!(dib->bits = HeapAlloc(GetProcessHeap(), 0, height*abs(dib->stride))))
+ {
+ ERR("Failed to allocate bits buffer\n");
+ return FALSE;
+ }
+ /* check for bottom-up DIB */
+ if(dib->stride < 0)
+ dib->bits = (BYTE *)dib->bits - (dib->height-1) * dib->stride;
+ dib->ownsBits = TRUE;
+
+ MAYBE(TRACE("END\n"));
+ return TRUE;
+ }
+
+/* Clears a DIBDRVBITMAP structure data
+ WARNING : doesn't free anything */
+void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp)
+{
+ MAYBE(TRACE("bmp=%p\n", bmp));
+
+ bmp->bits = NULL;
+ bmp->ownsBits = FALSE;
+ bmp->colorTable = NULL;
+ bmp->colorTableSize = 0;
+ bmp->colorTableGrabbed = FALSE;
+
+ MAYBE(TRACE("END\n"));
+}
+
+/* Frees a DIBDRVBITMAP structure data */
+void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp)
+{
+ MAYBE(TRACE("bmp=%p\n", bmp));
+
+ /* frees bits, if needed */
+ if(bmp->bits && bmp->ownsBits)
+ {
+ /* on bottom-up dibs, bits doesn't point to starting
+ of buffer.... bad design choice */
+ if(bmp->stride < 0)
+ bmp->bits = (BYTE *)bmp->bits + bmp->stride * (bmp->height -1);
+ HeapFree(GetProcessHeap(), 0, bmp->bits);
+ }
+ bmp->ownsBits = FALSE;
+ bmp->bits = NULL;
+
+ /* frees color table */
+ if(bmp->colorTable)
+ HeapFree(GetProcessHeap(), 0, bmp->colorTable);
+ bmp->colorTable = NULL;
+ bmp->colorTableSize = 0;
+ bmp->colorTableGrabbed = FALSE;
+
+ MAYBE(TRACE("END\n"));
+}
+
+
+/* checks whether the format of 2 DIBs are identical
+ it checks the pixel bit count and the color table size
+ and content, if needed */
+BOOL _DIBDRVBITMAP_FormatMatch(const DIBDRVBITMAP *d1, const DIBDRVBITMAP *d2)
+{
+ /* checks at first the format (bit count and color masks) */
+ if(d1->format != d2->format)
+ return FALSE;
+
+ /* formats matches, now checks color tables if needed */
+ switch(d1->format)
+ {
+ case DIBFMT_DIB32_RGB :
+ case DIBFMT_DIB32_BITFIELDS :
+ case DIBFMT_DIB24 :
+ case DIBFMT_DIB16_RGB :
+ case DIBFMT_DIB16_BITFIELDS :
+ return TRUE;
+
+ case DIBFMT_DIB1 :
+ case DIBFMT_DIB4 :
+ /*case DIBFMT_DIB4_RLE :*/
+ case DIBFMT_DIB8 :
+ /*case DIBFMT_DIB8_RLE :*/
+ if(d1->colorTableSize != d2->colorTableSize)
+ return FALSE;
+ return !memcmp(d1->colorTable, d2->colorTable, d1->colorTableSize * sizeof(d1->colorTable[0]));
+
+ default:
+ ERR("Unexpected depth %d\n", d1->bitCount);
+ return FALSE;
+ }
+}
+
+/* convert a given dib into another format given by 'format' parameter */
+BOOL _DIBDRVBITMAP_Convert(DIBDRVBITMAP *dst, const DIBDRVBITMAP *src, const DIBDRVBITMAP *format)
+{
+ int width, height;
+ int iLine;
+ void *buf;
+ BOOL res;
+
+ MAYBE(TRACE("dst=%p, src=%p, format=%p\n", dst, src, format));
+
+ /* free, if needed, destination bitmap */
+ _DIBDRVBITMAP_Free(dst);
+
+ /* if format and source bitmaps format match,
+ just copy source on destination */
+ if(_DIBDRVBITMAP_FormatMatch(src, format))
+ {
+ res = _DIBDRVBITMAP_InitFromDibdrvbitmap(dst, src, TRUE);
+ MAYBE(TRACE("END - Identical formats\n"));
+ return res;
+ }
+
+ /* formats don't match, we create the dest bitmap with same format as format's one
+ but with source's one dimensions */
+ width = src->width;
+ height = src->height;
+ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(dst, format, width, height))
+ {
+ ERR("Couldn't create destination bmp\n");
+ return FALSE;
+ }
+
+ /* we now copy/convert from source to dest */
+ if(!(buf = HeapAlloc(GetProcessHeap(), 0, width * 4)))
+ {
+ ERR("HeapAlloc failed\n");
+ return FALSE;
+ }
+
+ for(iLine = 0; iLine < height; iLine++)
+ {
+ src->funcs->GetLine(src, iLine, 0, width, buf);
+ dst->funcs->PutLine(dst, iLine, 0, width, buf);
+ }
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ MAYBE(TRACE("END - different formats\n"));
+ return TRUE;
+}
+
+/* creates a solid-filled DIB of given color and format
+ DIB format is given by 'format' parameter */
+BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int width, int height, DWORD Color)
+{
+ DWORD *buf, *bufPnt;
+ int i;
+
+ MAYBE(TRACE("bmp=%p, format=%p, width=%d, height=%d, Color=%08x\n", bmp, format, width, height, Color));
+
+ /* swaps color bytes....*/
+ Color = RGB((Color >> 8) & 0xff, (Color >> 16) &0xff, Color &0xff);
+
+ /* creates the destination bitmap */
+ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(bmp, format, width, height))
+ {
+ ERR("Couldn't create destination bmp\n");
+ return FALSE;
+ }
+
+ /* creates a temporary line filled with given color */
+ if(!(buf = HeapAlloc(GetProcessHeap(), 0, width * 4)))
+ {
+ ERR("HeapAlloc failed\n");
+ return FALSE;
+ }
+
+ for(i = 0, bufPnt = buf; i < width; i++)
+ *bufPnt++ = Color;
+
+ /* fills the bitmap */
+ for(i = 0; i < height; i++)
+ bmp->funcs->PutLine(bmp, i, 0, width, buf);
+
+ /* frees temporaty line */
+ HeapFree(GetProcessHeap(), 0, buf);
+
+ MAYBE(TRACE("END\n"));
+ return TRUE;
+}
+
+/* expands horizontally a bitmap to reach a minimum size,
+ keeping its width as a multiple of a base width
+ Used to widen brushes in order to optimize blitting */
+BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth)
+{
+ BYTE *srcBuf, *dstBuf;
+ int chunkSize;
+ int iLine, iCol;
+ DIBDRVBITMAP tmpDib;
+ void *bits;
+ BOOL ownsBits;
+
+ MAYBE(TRACE("dib=%p, baseWidth=%d, minWidth=%d\n", dib, baseWidth, minWidth));
+
+ /* if dst dib already wide enough, just do nothing */
+ if(dib->width >= minWidth)
+ {
+ MAYBE(TRACE("END - No need to expand\n"));
+ return TRUE;
+ }
+
+ /* source DIB can't be NULL */
+ if(!dib->bits)
+ {
+ ERR("Empty source DIB detected\n");
+ return FALSE;
+ }
+
+ /* round up minWidth to be a multiple of source width */
+ minWidth += (baseWidth - (minWidth % baseWidth));
+
+ /* creates a temporary destination bitmap with required sizes */
+ _DIBDRVBITMAP_Clear(&tmpDib);
+ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(&tmpDib, dib, minWidth, dib->height))
+ {
+ ERR("Couldn't create the temporary DIB for brush cache\n");
+ return FALSE;
+ }
+
+ /* if format uses almost 1 byte/pixel, fast copy path */
+ if(dib->bitCount >= 8)
+ {
+ chunkSize = dib->width * dib->bitCount / 8;
+ for(iLine = 0; iLine < dib->height; iLine++)
+ {
+ srcBuf = (BYTE *)dib->bits + iLine * dib->stride;
+ dstBuf = (BYTE *)tmpDib.bits + iLine * tmpDib.stride;
+ for(iCol = 0; iCol < tmpDib.width; iCol += dib->width)
+ {
+ memcpy(dstBuf, srcBuf, chunkSize);
+ dstBuf += chunkSize;
+ }
+ }
+ }
+ /* otherwise slow path -- could be optimized */
+ else
+ {
+ chunkSize = dib->width * 4;
+ /* allocates a line buffer */
+ if(!(srcBuf = HeapAlloc(GetProcessHeap(), 0, tmpDib.width * 4)))
+ {
+ ERR("HeapAlloc failed\n");
+ return FALSE;
+ }
+
+ FIXME("dib:format=%s, funcs=%p, bits=%p, width=%d, height=%d, stride=%d\n",
+ _DIBDRVBITMAP_GetFormatName(dib), dib->funcs, dib->bits, dib->width, dib->height, dib->stride);
+ for(iLine = 0; iLine < dib->height; iLine++)
+ {
+ /* fills the line buffer repeating source's line data */
+ dib->funcs->GetLine(dib, iLine, 0, dib->width, srcBuf);
+ dstBuf = srcBuf + chunkSize;
+ for(iCol = dib->width; iCol < tmpDib.width; iCol += dib->width)
+ {
+ memcpy(dstBuf, srcBuf, chunkSize);
+ dstBuf += chunkSize;
+ }
+ /* stores the line on destination bmp */
+ tmpDib.funcs->PutLine(&tmpDib, iLine, 0, tmpDib.width, srcBuf);
+ }
+ HeapFree(GetProcessHeap(), 0, srcBuf);
+ }
+
+ /* swaps temp DIB and source one */
+ bits = dib->bits;
+ ownsBits = dib->ownsBits;
+ dib->bits = tmpDib.bits;
+ dib->ownsBits = tmpDib.ownsBits;
+ tmpDib.bits = bits;
+ tmpDib.ownsBits = ownsBits;
+
+ /* frees the temporary DIB */
+ _DIBDRVBITMAP_Free(&tmpDib);
+
+ MAYBE(TRACE("END\n"));
+ return TRUE;
+}
diff --git a/dlls/winedib.drv/driver.c b/dlls/winedib.drv/driver.c
new file mode 100644
index 0000000..46fa7a1
--- /dev/null
+++ b/dlls/winedib.drv/driver.c
@@ -0,0 +1,254 @@
+/*
+ * Access to display driver
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+#include <stdio.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* CreateDriver
+ * Allocate and fill the function pointer structure for a given module. */
+static DC_FUNCTIONS *CreateDriver( HMODULE module )
+{
+ DC_FUNCTIONS *funcs;
+
+ if (!(funcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*funcs))))
+ return NULL;
+
+ /* fill the function table */
+ if (module)
+ {
+#define GET_FUNC(name) funcs->p##name = (void*)GetProcAddress( module, #name )
+ GET_FUNC(AbortDoc);
+ GET_FUNC(AbortPath);
+ GET_FUNC(AlphaBlend);
+ GET_FUNC(AngleArc);
+ GET_FUNC(Arc);
+ GET_FUNC(ArcTo);
+ GET_FUNC(BeginPath);
+ GET_FUNC(BitBlt);
+ GET_FUNC(ChoosePixelFormat);
+ GET_FUNC(Chord);
+ GET_FUNC(CloseFigure);
+ GET_FUNC(CreateBitmap);
+ GET_FUNC(CreateDC);
+ GET_FUNC(CreateDIBSection);
+ GET_FUNC(DeleteBitmap);
+ GET_FUNC(DeleteDC);
+ GET_FUNC(DescribePixelFormat);
+ GET_FUNC(DeviceCapabilities);
+ GET_FUNC(Ellipse);
+ GET_FUNC(EndDoc);
+ GET_FUNC(EndPage);
+ GET_FUNC(EndPath);
+ GET_FUNC(EnumDeviceFonts);
+ GET_FUNC(ExcludeClipRect);
+ GET_FUNC(ExtDeviceMode);
+ GET_FUNC(ExtEscape);
+ GET_FUNC(ExtFloodFill);
+ GET_FUNC(ExtSelectClipRgn);
+ GET_FUNC(ExtTextOut);
+ GET_FUNC(FillPath);
+ GET_FUNC(FillRgn);
+ GET_FUNC(FlattenPath);
+ GET_FUNC(FrameRgn);
+ GET_FUNC(GdiComment);
+ GET_FUNC(GetBitmapBits);
+ GET_FUNC(GetCharWidth);
+ GET_FUNC(GetDCOrgEx);
+ GET_FUNC(GetDIBColorTable);
+ GET_FUNC(GetDIBits);
+ GET_FUNC(GetDeviceCaps);
+ GET_FUNC(GetDeviceGammaRamp);
+ GET_FUNC(GetICMProfile);
+ GET_FUNC(GetNearestColor);
+ GET_FUNC(GetPixel);
+ GET_FUNC(GetPixelFormat);
+ GET_FUNC(GetSystemPaletteEntries);
+ GET_FUNC(GetTextExtentExPoint);
+ GET_FUNC(GetTextMetrics);
+ GET_FUNC(IntersectClipRect);
+ GET_FUNC(InvertRgn);
+ GET_FUNC(LineTo);
+ GET_FUNC(MoveTo);
+ GET_FUNC(ModifyWorldTransform);
+ GET_FUNC(OffsetClipRgn);
+ GET_FUNC(OffsetViewportOrg);
+ GET_FUNC(OffsetWindowOrg);
+ GET_FUNC(PaintRgn);
+ GET_FUNC(PatBlt);
+ GET_FUNC(Pie);
+ GET_FUNC(PolyBezier);
+ GET_FUNC(PolyBezierTo);
+ GET_FUNC(PolyDraw);
+ GET_FUNC(PolyPolygon);
+ GET_FUNC(PolyPolyline);
+ GET_FUNC(Polygon);
+ GET_FUNC(Polyline);
+ GET_FUNC(PolylineTo);
+ GET_FUNC(RealizeDefaultPalette);
+ GET_FUNC(RealizePalette);
+ GET_FUNC(Rectangle);
+ GET_FUNC(ResetDC);
+ GET_FUNC(RestoreDC);
+ GET_FUNC(RoundRect);
+ GET_FUNC(SaveDC);
+ GET_FUNC(ScaleViewportExt);
+ GET_FUNC(ScaleWindowExt);
+ GET_FUNC(SelectBitmap);
+ GET_FUNC(SelectBrush);
+ GET_FUNC(SelectClipPath);
+ GET_FUNC(SelectFont);
+ GET_FUNC(SelectPalette);
+ GET_FUNC(SelectPen);
+ GET_FUNC(SetArcDirection);
+ GET_FUNC(SetBitmapBits);
+ GET_FUNC(SetBkColor);
+ GET_FUNC(SetBkMode);
+ GET_FUNC(SetDCBrushColor);
+ GET_FUNC(SetDCOrg);
+ GET_FUNC(SetDCPenColor);
+ GET_FUNC(SetDIBColorTable);
+ GET_FUNC(SetDIBits);
+ GET_FUNC(SetDIBitsToDevice);
+ GET_FUNC(SetDeviceClipping);
+ GET_FUNC(SetDeviceGammaRamp);
+ GET_FUNC(SetMapMode);
+ GET_FUNC(SetMapperFlags);
+ GET_FUNC(SetPixel);
+ GET_FUNC(SetPixelFormat);
+ GET_FUNC(SetPolyFillMode);
+ GET_FUNC(SetROP2);
+ GET_FUNC(SetRelAbs);
+ GET_FUNC(SetStretchBltMode);
+ GET_FUNC(SetTextAlign);
+ GET_FUNC(SetTextCharacterExtra);
+ GET_FUNC(SetTextColor);
+ GET_FUNC(SetTextJustification);
+ GET_FUNC(SetViewportExt);
+ GET_FUNC(SetViewportOrg);
+ GET_FUNC(SetWindowExt);
+ GET_FUNC(SetWindowOrg);
+ GET_FUNC(SetWorldTransform);
+ GET_FUNC(StartDoc);
+ GET_FUNC(StartPage);
+ GET_FUNC(StretchBlt);
+ GET_FUNC(StretchDIBits);
+ GET_FUNC(StrokeAndFillPath);
+ GET_FUNC(StrokePath);
+ GET_FUNC(SwapBuffers);
+ GET_FUNC(UnrealizePalette);
+ GET_FUNC(WidenPath);
+
+ /* OpenGL32 */
+ GET_FUNC(wglCreateContext);
+ GET_FUNC(wglDeleteContext);
+ GET_FUNC(wglGetProcAddress);
+ GET_FUNC(wglGetPbufferDCARB);
+ GET_FUNC(wglMakeContextCurrentARB);
+ GET_FUNC(wglMakeCurrent);
+ GET_FUNC(wglSetPixelFormatWINE);
+ GET_FUNC(wglShareLists);
+ GET_FUNC(wglUseFontBitmapsA);
+ GET_FUNC(wglUseFontBitmapsW);
+#undef GET_FUNC
+ }
+ else
+ memset( funcs, 0, sizeof(*funcs) );
+
+ /* add it to the list */
+ return funcs;
+}
+
+
+/* LoadDisplayDriver
+ * Loads display driver - partially grabbed from gdi32 */
+static DC_FUNCTIONS *X11DrvFuncs = NULL;
+static HMODULE X11DrvModule = 0;
+DC_FUNCTIONS *_DIBDRV_LoadDisplayDriver(void)
+{
+ char buffer[MAX_PATH], libname[32], *name, *next;
+ HMODULE module = 0;
+ HKEY hkey;
+
+ if (X11DrvFuncs) /* already loaded */
+ return X11DrvFuncs;
+
+ strcpy( buffer, "x11" ); /* default value */
+ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
+ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey ))
+ {
+ DWORD type, count = sizeof(buffer);
+ RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count );
+ RegCloseKey( hkey );
+ }
+
+ name = buffer;
+ while (name)
+ {
+ next = strchr( name, ',' );
+ if (next)
+ *next++ = 0;
+
+ snprintf( libname, sizeof(libname), "wine%s.drv", name );
+ if ((module = LoadLibraryA( libname )) != 0)
+ break;
+ name = next;
+ }
+
+ if (!(X11DrvFuncs = CreateDriver(module)))
+ {
+ ERR( "Could not create graphics driver '%s'\n", buffer );
+ FreeLibrary( module );
+ ExitProcess(1);
+ }
+
+ X11DrvModule = module;
+ return X11DrvFuncs;
+}
+
+/* FreeDisplayDriver
+ Frees resources allocated by Display driver */
+void _DIBDRV_FreeDisplayDriver(void)
+{
+ /* frees function table */
+ if(X11DrvFuncs)
+ {
+ HeapFree(GetProcessHeap(), 0, X11DrvFuncs);
+ X11DrvFuncs = 0;
+ }
+ /* and unload the module */
+ if(X11DrvModule)
+ {
+ FreeLibrary(X11DrvModule);
+ X11DrvModule = 0;
+ }
+}
+
+/* GetDisplayDriver
+ Gets a pointer to display drives'function table */
+inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void)
+{
+ return X11DrvFuncs;
+
+}
diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c
index 675145f..215b27d 100644
--- a/dlls/winedib.drv/font.c
+++ b/dlls/winedib.drv/font.c
@@ -32,14 +32,40 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color )
{
COLORREF res;
+ INT r, g, b;
+ INT i;
- TRACE("physDev:%p, color:%08x\n", physDev, color);
+ MAYBE(TRACE("physDev:%p, color:%08x\n", physDev, color));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetTextColor(physDev->X11PhysDev, color);
+
+ /* do nothing if color is the same as actual one */
+ if(color == physDev->textColor)
+ return color;
+
+ /* stores old color */
+ res = physDev->textColor;
+
+ /* fills the text color table used on antialiased font display */
+ if(physDev->physBitmap.funcs)
+ {
+ r = GetRValue(color);
+ g = GetGValue(color);
+ b = GetBValue(color);
+ for(i = 0; i < 256; i++)
+ {
+ physDev->textColorTable[i] = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, RGB(
+ MulDiv(r, i, 256),
+ MulDiv(g, i, 256),
+ MulDiv(b, i, 256)
+ ));
+ }
+ }
+
+ /* returns previous text color */
+ return res;
}
else
{
@@ -52,17 +78,75 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color )
/***********************************************************************
* DIBDRV_SelectFont
*/
-HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, HANDLE gdiFont )
+HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, GdiFont *gdiFont )
{
HFONT res;
+ FT_Int i;
+ FT_Error error;
+ FT_CharMap charmap = NULL;
+ LOGFONTW lf;
- TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont);
+ MAYBE(TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSelectFont(physDev->X11PhysDev, hfont, gdiFont);
+
+ /* gets font information */
+ GetObjectW(hfont, sizeof(lf), &lf);
+ MAYBE(TRACE("Font is : '%s'\n", debugstr_w(lf.lfFaceName)));
+
+ /* FIXME: just handles gdifont, don't know if it needs to handle hfont too
+ BTW, still don't know how to get FT_Face from non-gdi font here
+ */
+ if(!gdiFont)
+ {
+ FIXME("No gdi font - unhandled by now.\n");
+ return hfont;
+ }
+
+ physDev->face = gdiFont->ft_face;
+ if(!physDev->face)
+ {
+ FIXME("Error, null Ft_Face\n");
+ return hfont;
+ }
+
+ /* setup the correct charmap.... maybe */
+ for (i = 0; i < physDev->face->num_charmaps; ++i)
+ {
+ if (physDev->face->charmaps[i]->platform_id != TT_PLATFORM_MICROSOFT)
+ continue;
+
+ if (physDev->face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS)
+ {
+ charmap = physDev->face->charmaps[i];
+ break;
+ }
+
+ if (charmap == NULL)
+ {
+ WARN("Selected fallout charmap #%d\n", i);
+ charmap = physDev->face->charmaps[i];
+ }
+ }
+ if (charmap == NULL)
+ {
+ WARN("No Windows character map found\n");
+ charmap = physDev->face->charmaps[0];
+ return 0;
+ }
+
+ error = pFT_Set_Charmap(physDev->face, charmap);
+ if (error != FT_Err_Ok)
+ {
+ ERR("%s returned %i\n", "FT_Set_Charmap", error);
+ return 0;
+ }
+
+ /* we use GDI fonts, so just return false */
+ return 0;
+
}
else
{
@@ -80,13 +164,13 @@ BOOL DIBDRV_EnumDeviceFonts( DIBDRVPHYSDEV *physDev, LPLOGFONTW plf,
{
BOOL res;
- TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp);
+ MAYBE(TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pEnumDeviceFonts(physDev->X11PhysDev, plf, proc, lp);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
}
else
{
@@ -103,13 +187,13 @@ BOOL DIBDRV_GetTextMetrics( DIBDRVPHYSDEV *physDev, TEXTMETRICW *metrics )
{
BOOL res;
- TRACE("physDev:%p, metrics:%p\n", physDev, metrics);
+ MAYBE(TRACE("physDev:%p, metrics:%p\n", physDev, metrics));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetTextMetrics(physDev->X11PhysDev, metrics);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
}
else
{
@@ -127,13 +211,13 @@ BOOL DIBDRV_GetCharWidth( DIBDRVPHYSDEV *physDev, UINT firstChar, UINT lastChar,
{
BOOL res;
- TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer);
+ MAYBE(TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetCharWidth(physDev->X11PhysDev, firstChar, lastChar, buffer);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
}
else
{
diff --git a/dlls/winedib.drv/freetype.c b/dlls/winedib.drv/freetype.c
new file mode 100644
index 0000000..111a18b
--- /dev/null
+++ b/dlls/winedib.drv/freetype.c
@@ -0,0 +1,136 @@
+/*
+ * Truetype font functions
+ *
+ * Copyright 2008 Massimo Del Fedele
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+#define MAKE_FUNCPTR(f) typeof(f) * p##f = NULL;
+MAKE_FUNCPTR(FT_Done_Face)
+MAKE_FUNCPTR(FT_Done_FreeType)
+MAKE_FUNCPTR(FT_Get_Char_Index)
+MAKE_FUNCPTR(FT_Get_Glyph_Name)
+MAKE_FUNCPTR(FT_Get_Sfnt_Name)
+MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count)
+MAKE_FUNCPTR(FT_Get_Sfnt_Table)
+MAKE_FUNCPTR(FT_Init_FreeType)
+MAKE_FUNCPTR(FT_Load_Glyph)
+MAKE_FUNCPTR(FT_Load_Char)
+MAKE_FUNCPTR(FT_Get_Glyph)
+MAKE_FUNCPTR(FT_Glyph_Copy)
+MAKE_FUNCPTR(FT_Glyph_To_Bitmap)
+MAKE_FUNCPTR(FT_Done_Glyph)
+MAKE_FUNCPTR(FT_New_Face)
+MAKE_FUNCPTR(FT_Set_Charmap)
+MAKE_FUNCPTR(FT_Set_Char_Size)
+MAKE_FUNCPTR(FT_Set_Pixel_Sizes)
+MAKE_FUNCPTR(FT_Get_First_Char)
+MAKE_FUNCPTR(FT_Render_Glyph)
+MAKE_FUNCPTR(FT_Glyph_Transform)
+#undef MAKE_FUNCPTR
+
+/* freetype initialization flag */
+static BOOL FreeType_Initialized = FALSE;
+
+/* freetype dll handle */
+static void *ft_handle = NULL;
+
+/* freetype library handle */
+FT_Library DIBDRV_ftLibrary = NULL;
+
+/* initialize freetype library */
+BOOL _DIBDRV_FreeType_Init(void)
+{
+ FT_Int error;
+
+ ft_handle = wine_dlopen(SONAME_LIBFREETYPE, RTLD_NOW, NULL, 0);
+ if(!ft_handle)
+ {
+ WINE_MESSAGE(
+ "Wine cannot find the FreeType font library. To enable Wine to\n"
+ "use TrueType fonts please install a version of FreeType greater than\n"
+ "or equal to 2.0.5.\n"
+ "http://www.freetype.org\n");
+ return FALSE;
+ }
+
+#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
+ LOAD_FUNCPTR(FT_Done_Face)
+ LOAD_FUNCPTR(FT_Done_FreeType)
+ LOAD_FUNCPTR(FT_Get_Char_Index)
+ LOAD_FUNCPTR(FT_Get_Glyph_Name)
+ LOAD_FUNCPTR(FT_Get_Sfnt_Name)
+ LOAD_FUNCPTR(FT_Get_Sfnt_Name_Count)
+ LOAD_FUNCPTR(FT_Get_Sfnt_Table)
+ LOAD_FUNCPTR(FT_Init_FreeType)
+ LOAD_FUNCPTR(FT_Load_Glyph)
+ LOAD_FUNCPTR(FT_Load_Char)
+ LOAD_FUNCPTR(FT_Get_Glyph)
+ LOAD_FUNCPTR(FT_Glyph_Copy)
+ LOAD_FUNCPTR(FT_Glyph_To_Bitmap)
+ LOAD_FUNCPTR(FT_Done_Glyph)
+ LOAD_FUNCPTR(FT_New_Face)
+ LOAD_FUNCPTR(FT_Set_Charmap)
+ LOAD_FUNCPTR(FT_Set_Char_Size)
+ LOAD_FUNCPTR(FT_Set_Pixel_Sizes)
+ LOAD_FUNCPTR(FT_Get_First_Char)
+ LOAD_FUNCPTR(FT_Render_Glyph)
+ LOAD_FUNCPTR(FT_Glyph_Transform)
+#undef LOAD_FUNCPTR
+
+ error = pFT_Init_FreeType(&DIBDRV_ftLibrary);
+ if (error != FT_Err_Ok)
+ {
+ ERR("%s returned %i\n", "FT_Init_FreeType", error);
+ wine_dlclose(ft_handle, NULL, 0);
+ return FALSE;
+ }
+
+ /* marks library as initialized */
+ FreeType_Initialized = TRUE;
+
+ return TRUE;
+
+sym_not_found:
+ WINE_MESSAGE(
+ "Wine cannot find certain functions that it needs inside the FreeType\n"
+ "font library. To enable Wine to use TrueType fonts please upgrade\n"
+ "FreeType to at least version 2.0.5.\n"
+ "http://www.freetype.org\n");
+ wine_dlclose(ft_handle, NULL, 0);
+ ft_handle = NULL;
+ return FALSE;
+}
+
+/* terminates freetype library */
+void _DIBDRV_FreeType_Terminate(void)
+{
+ if(!FreeType_Initialized)
+ return;
+
+ /* terminates and unload freetype library */
+ pFT_Done_FreeType(DIBDRV_ftLibrary);
+ wine_dlclose(ft_handle, NULL, 0);
+ ft_handle = NULL;
+ FreeType_Initialized = FALSE;
+
+}
diff --git a/dlls/winedib.drv/freetype.h b/dlls/winedib.drv/freetype.h
new file mode 100644
index 0000000..93619ff
--- /dev/null
+++ b/dlls/winedib.drv/freetype.h
@@ -0,0 +1,186 @@
+/*
+ * Truetype font functions
+ *
+ * Copyright 2008 Massimo Del Fedele
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef __WINE_DIBDRV_FREETYPE_H
+#define __WINE_DIBDRV__FREETYPE_H
+
+/* freetype library for font support */
+#ifdef HAVE_FREETYPE
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_IDS_H
+
+/* freetype library handle */
+extern FT_Library DIBDRV_ftLibrary;
+
+/******************************************************************************************/
+/* FREETYPE STUFFS */
+/* grabbed from winex11.drv/freetype.c */
+/******************************************************************************************/
+
+/* This is basically a copy of FT_Bitmap_Size with an extra element added */
+typedef struct {
+ FT_Short height;
+ FT_Short width;
+ FT_Pos size;
+ FT_Pos x_ppem;
+ FT_Pos y_ppem;
+ FT_Short internal_leading;
+} Bitmap_Size;
+
+/* FT_Bitmap_Size gained 3 new elements between FreeType 2.1.4 and 2.1.5
+ So to let this compile on older versions of FreeType we'll define the
+ new structure here. */
+typedef struct {
+ FT_Short height, width;
+ FT_Pos size, x_ppem, y_ppem;
+} My_FT_Bitmap_Size;
+
+struct enum_data
+{
+ ENUMLOGFONTEXW elf;
+ NEWTEXTMETRICEXW ntm;
+ DWORD type;
+};
+
+typedef struct tagFace {
+ struct list entry;
+ WCHAR *StyleName;
+ char *file;
+ void *font_data_ptr;
+ DWORD font_data_size;
+ FT_Long face_index;
+ FONTSIGNATURE fs;
+ FONTSIGNATURE fs_links;
+ DWORD ntmFlags;
+ FT_Fixed font_version;
+ BOOL scalable;
+ Bitmap_Size size; /* set if face is a bitmap */
+ BOOL external; /* TRUE if we should manually add this font to the registry */
+ struct tagFamily *family;
+ /* Cached data for Enum */
+ struct enum_data *cached_enum_data;
+} Face;
+
+typedef struct tagFamily {
+ struct list entry;
+ const WCHAR *FamilyName;
+ struct list faces;
+} Family;
+
+typedef struct {
+ GLYPHMETRICS gm;
+ INT adv; /* These three hold to widths of the unrotated chars */
+ INT lsb;
+ INT bbx;
+ BOOL init;
+} GM;
+
+typedef struct {
+ FLOAT eM11, eM12;
+ FLOAT eM21, eM22;
+} FMAT2;
+
+typedef struct {
+ DWORD hash;
+ LOGFONTW lf;
+ FMAT2 matrix;
+ BOOL can_use_bitmap;
+} FONT_DESC;
+
+typedef struct tagHFONTLIST {
+ struct list entry;
+ HFONT hfont;
+} HFONTLIST;
+
+typedef struct {
+ struct list entry;
+ Face *face;
+ struct tagGdiFont *font;
+} CHILD_FONT;
+
+typedef struct tagGdiFont {
+ struct list entry;
+ GM **gm;
+ DWORD gmsize;
+ struct list hfontlist;
+ OUTLINETEXTMETRICW *potm;
+ DWORD total_kern_pairs;
+ KERNINGPAIR *kern_pairs;
+ struct list child_fonts;
+
+ /* the following members can be accessed without locking, they are never modified after creation */
+ FT_Face ft_face;
+ struct font_mapping *mapping;
+ LPWSTR name;
+ int charset;
+ int codepage;
+ BOOL fake_italic;
+ BOOL fake_bold;
+ BYTE underline;
+ BYTE strikeout;
+ INT orientation;
+ FONT_DESC font_desc;
+ LONG aveWidth, ppem;
+ double scale_y;
+ SHORT yMax;
+ SHORT yMin;
+ DWORD ntmFlags;
+ FONTSIGNATURE fs;
+ struct tagGdiFont *base_font;
+ VOID *GSUB_Table;
+ DWORD cache_num;
+} GdiFont;
+
+/* initialize freetype library */
+BOOL _DIBDRV_FreeType_Init(void);
+
+/* terminates freetype library */
+void _DIBDRV_FreeType_Terminate(void);
+
+#define MAKE_FUNCPTR(f) extern typeof(f) * p##f;
+MAKE_FUNCPTR(FT_Done_Face)
+MAKE_FUNCPTR(FT_Done_FreeType)
+MAKE_FUNCPTR(FT_Get_Char_Index)
+MAKE_FUNCPTR(FT_Get_Glyph_Name)
+MAKE_FUNCPTR(FT_Get_Sfnt_Name)
+MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count)
+MAKE_FUNCPTR(FT_Get_Sfnt_Table)
+MAKE_FUNCPTR(FT_Init_FreeType)
+MAKE_FUNCPTR(FT_Load_Glyph)
+MAKE_FUNCPTR(FT_Load_Char)
+MAKE_FUNCPTR(FT_Get_Glyph)
+MAKE_FUNCPTR(FT_Glyph_Copy)
+MAKE_FUNCPTR(FT_Glyph_To_Bitmap)
+MAKE_FUNCPTR(FT_Done_Glyph)
+MAKE_FUNCPTR(FT_New_Face)
+MAKE_FUNCPTR(FT_Set_Charmap)
+MAKE_FUNCPTR(FT_Set_Char_Size)
+MAKE_FUNCPTR(FT_Set_Pixel_Sizes)
+MAKE_FUNCPTR(FT_Get_First_Char)
+MAKE_FUNCPTR(FT_Render_Glyph)
+MAKE_FUNCPTR(FT_Glyph_Transform)
+#undef MAKE_FUNCPTR
+
+#endif /* HAVE_FREETYPE */
+
+#endif
diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c
index b74c08e..8dda082 100644
--- a/dlls/winedib.drv/graphics.c
+++ b/dlls/winedib.drv/graphics.c
@@ -25,23 +25,33 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+static inline void OrderInt(int *i1, int *i2)
+{
+ if(*i1 > *i2)
+ {
+ int tmp;
+ tmp = *i1;
+ *i1 = *i2;
+ *i2 = tmp;
+ }
+}
+
/***********************************************************************
* DIBDRV_Arc
*/
-BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom,
- INT xstart, INT ystart, INT xend, INT yend )
+BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
+ int xstart, int ystart, int xend, int yend )
{
BOOL res;
- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
- physDev, left, top, right, bottom, xstart, ystart, xend, yend);
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
+ physDev, left, top, right, bottom, xstart, ystart, xend, yend));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, left, top, right, bottom,
- xstart, ystart, xend, yend);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -55,20 +65,19 @@ BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT botto
/***********************************************************************
* DIBDRV_Chord
*/
-BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom,
- INT xstart, INT ystart, INT xend, INT yend )
+BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
+ int xstart, int ystart, int xend, int yend )
{
BOOL res;
- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
- physDev, left, top, right, bottom, xstart, ystart, xend, yend);
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
+ physDev, left, top, right, bottom, xstart, ystart, xend, yend));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, left, top, right, bottom,
- xstart, ystart, xend, yend);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -82,18 +91,18 @@ BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bot
/***********************************************************************
* DIBDRV_Ellipse
*/
-BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom )
+BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom )
{
BOOL res;
- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
- physDev, left, top, right, bottom);
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
+ physDev, left, top, right, bottom));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, left, top, right, bottom);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -106,19 +115,19 @@ BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT b
/**********************************************************************
* DIBDRV_ExtFloodFill
*/
-BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color,
+BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color,
UINT fillType )
{
BOOL res;
- TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n",
- physDev, x, y, color, fillType);
+ MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n",
+ physDev, x, y, color, fillType));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, x, y, color, fillType);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -135,13 +144,13 @@ BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp )
{
BOOL res;
- TRACE("physDev:%p, lpp:%p\n", physDev, lpp);
+ MAYBE(TRACE("physDev:%p, lpp:%p\n", physDev, lpp));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, lpp);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -154,17 +163,15 @@ BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp )
/***********************************************************************
* DIBDRV_GetPixel
*/
-COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y )
+COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y )
{
COLORREF res;
- TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y);
+ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, x, y);
+ res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y);
}
else
{
@@ -177,17 +184,26 @@ COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y )
/***********************************************************************
* DIBDRV_LineTo
*/
-BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y )
+BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, int x, int y )
{
BOOL res;
+ POINT curPos;
- TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y);
+ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, x, y);
+ GetCurrentPositionEx(physDev->hdc, &curPos);
+
+ _DIBDRV_ResetDashOrigin(physDev);
+
+ if(curPos.y == y)
+ physDev->penHLine(physDev, curPos.x, x, y);
+ else if(curPos.x == x)
+ physDev->penVLine(physDev, x, curPos.y, y);
+ else
+ physDev->penLine(physDev, curPos.x, curPos.y, x, y);
+ res = TRUE;
}
else
{
@@ -200,17 +216,43 @@ BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y )
/***********************************************************************
* DIBDRV_PaintRgn
*/
+BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom);
BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn )
{
- BOOL res;
+ BOOL res = FALSE;
+ int i;
+ RECT *rect;
+ RGNDATA *data;
+ int size;
- TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn);
+ MAYBE(TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, hrgn);
+ /* gets needed region data size */
+ if(!(size = GetRegionData(hrgn, 0, NULL)))
+ goto fin;
+
+ /* allocates buffer and gets actual region data */
+ if(!(data = HeapAlloc(GetProcessHeap(), 0, size)))
+ goto fin;
+ if(!GetRegionData(hrgn, size, data))
+ {
+ HeapFree(GetProcessHeap(), 0, data);
+ goto fin;
+ }
+
+ /* paints the filled rectangles */
+ rect = (RECT *)data->Buffer;
+ for(i = 0; i < data->rdh.nCount; i++)
+ {
+ DIBDRV_Rectangle( physDev, rect->left, rect->top, rect->right, rect->bottom);
+ rect++;
+ }
+ HeapFree( GetProcessHeap(), 0, data );
+ res = TRUE;
+fin:
+ ;
}
else
{
@@ -223,20 +265,19 @@ BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn )
/***********************************************************************
* DIBDRV_Pie
*/
-BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom,
- INT xstart, INT ystart, INT xend, INT yend )
+BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
+ int xstart, int ystart, int xend, int yend )
{
BOOL res;
- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
- physDev, left, top, right, bottom, xstart, ystart, xend, yend);
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
+ physDev, left, top, right, bottom, xstart, ystart, xend, yend));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, left, top, right, bottom,
- xstart, ystart, xend, yend);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -250,17 +291,17 @@ BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT botto
/**********************************************************************
* DIBDRV_Polygon
*/
-BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count )
+BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, int count )
{
BOOL res;
- TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count);
+ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, pt, count);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -273,17 +314,17 @@ BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count )
/**********************************************************************
* DIBDRV_Polyline
*/
-BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count )
+BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, int count )
{
BOOL res;
- TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count);
+ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, pt, count);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -296,17 +337,17 @@ BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count )
/**********************************************************************
* DIBDRV_PolyPolygon
*/
-BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const INT* counts, UINT polygons)
+BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const int* counts, UINT polygons)
{
BOOL res;
- TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons);
+ MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, pt, counts, polygons);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -324,13 +365,13 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD*
{
BOOL res;
- TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines);
+ MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, pt, counts, polylines);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -343,23 +384,65 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD*
/***********************************************************************
* DIBDRV_Rectangle
*/
-BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom)
+BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
{
- BOOL res;
+ BOOL res = TRUE;
+ int i;
+ DIBDRVBITMAP *bmp = &physDev->physBitmap;
- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
- physDev, left, top, right, bottom);
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev, x1, y1, x2, y2));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, left, top, right, bottom);
+ OrderInt(&x1, &x2);
+ OrderInt(&y1, &y2);
+
+ /* temporary fix.... should be done by clipping */
+ if(x1 < 0) x1 = 0;
+ if(x2 < 0) x2 = 0;
+ if(y1 < 0) y1 = 0;
+ if(y2 < 0) y2 = 0;
+ if(x1 >= bmp->width) x1 = bmp->width - 1;
+ if(y1 >= bmp->height) y1 = bmp->height - 1;
+ if(x2 > bmp->width) x2 = bmp->width;
+ if(y2 > bmp->height) y2 = bmp->height ;
+ if(x1 >= x2 || y1 >= y2)
+ goto fin;
+
+ _DIBDRV_ResetDashOrigin(physDev);
+
+ /* particular case where the rectangle
+ degenerates to a line or a point */
+ if(x1 >= x2 - 1)
+ {
+ physDev->penVLine(physDev, x1, y1, y2);
+ goto fin;
+ }
+ else if (y1 >= y2 -1)
+ {
+ physDev->penHLine(physDev, x1, x2, y1);
+ goto fin;
+ }
+
+ /* Draw the perimeter */
+ physDev->penHLine(physDev, x1 , x2 , y1 );
+ physDev->penHLine(physDev, x1 , x2 , y2 - 1);
+ physDev->penVLine(physDev, x1 , y1 + 1, y2 - 1);
+ physDev->penVLine(physDev, x2 - 1, y1 + 1, y2 - 1);
+
+ /* fill the inside */
+ if(x2 >= x1 + 2)
+ for (i = y1 + 1; i < y2 - 1; i++)
+ physDev->brushHLine(physDev, x1 + 1, x2 - 1, i);
+
+ res = TRUE;
+fin:
+ ;
}
else
{
/* DDB selected in, use X11 driver */
- res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, left, top, right, bottom);
+ res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, x1, y1, x2, y2);
}
return res;
}
@@ -367,20 +450,19 @@ BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT
/***********************************************************************
* DIBDRV_RoundRect
*/
-BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right,
- INT bottom, INT ell_width, INT ell_height )
+BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, int left, int top, int right,
+ int bottom, int ell_width, int ell_height )
{
BOOL res;
- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n",
- physDev, left, top, right, bottom, ell_width, ell_height);
+ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n",
+ physDev, left, top, right, bottom, ell_width, ell_height));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, left, top, right, bottom,
- ell_width, ell_height);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
@@ -394,17 +476,23 @@ BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right,
/***********************************************************************
* DIBDRV_SetPixel
*/
-COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color )
+COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color )
{
COLORREF res;
+ DWORD and, xor;
- TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color);
+ MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, x, y, color);
+ /* gets previous pixel */
+ res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y);
+
+ /* calculates AND and XOR from color */
+ _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), color, &and, &xor);
+
+ /* sets the pixel */
+ physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, and, xor);
}
else
{
@@ -417,17 +505,17 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color )
/***********************************************************************
* DIBDRV_SetDCOrg
*/
-DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, INT x, INT y )
+DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, int x, int y )
{
DWORD res;
- TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y);
+ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, x, y);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
}
else
{
diff --git a/dlls/winedib.drv/opengl.c b/dlls/winedib.drv/opengl.c
index e8ec96c..f7855f6 100644
--- a/dlls/winedib.drv/opengl.c
+++ b/dlls/winedib.drv/opengl.c
@@ -32,7 +32,7 @@ int DIBDRV_ChoosePixelFormat( DIBDRVPHYSDEV *physDev,
{
int res;
- TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd);
+ MAYBE(TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd));
if(physDev->hasDIB)
{
@@ -55,7 +55,7 @@ int DIBDRV_DescribePixelFormat( DIBDRVPHYSDEV *physDev,
{
int res;
- TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd);
+ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd));
if(physDev->hasDIB)
{
@@ -75,7 +75,7 @@ int DIBDRV_GetPixelFormat( DIBDRVPHYSDEV *physDev)
{
int res;
- TRACE("physDev:%p\n", physDev);
+ MAYBE(TRACE("physDev:%p\n", physDev));
if(physDev->hasDIB)
{
@@ -97,7 +97,7 @@ BOOL DIBDRV_SetPixelFormat( DIBDRVPHYSDEV *physDev,
{
BOOL res;
- TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd);
+ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd));
if(physDev->hasDIB)
{
@@ -117,7 +117,7 @@ BOOL DIBDRV_SwapBuffers( DIBDRVPHYSDEV *physDev )
{
BOOL res;
- TRACE("physDev:%p\n", physDev);
+ MAYBE(TRACE("physDev:%p\n", physDev));
if(physDev->hasDIB)
{
@@ -142,7 +142,7 @@ BOOL CDECL DIBDRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
BOOL res;
- TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask);
+ MAYBE(TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask));
ONCE(FIXME("stub\n"));
res = _DIBDRV_GetDisplayDriver()->pwglCopyContext(hglrcSrc, hglrcDst, mask);
@@ -159,7 +159,7 @@ HGLRC CDECL DIBDRV_wglCreateContext(DIBDRVPHYSDEV *physDev)
{
HGLRC res;
- TRACE("physDev:%p\n", physDev);
+ MAYBE(TRACE("physDev:%p\n", physDev));
if(physDev->hasDIB)
{
@@ -184,7 +184,7 @@ BOOL CDECL DIBDRV_wglDeleteContext(HGLRC hglrc)
{
BOOL res;
- TRACE("hglrc:%p\n", hglrc);
+ MAYBE(TRACE("hglrc:%p\n", hglrc));
ONCE(FIXME("stub\n"));
res = _DIBDRV_GetDisplayDriver()->pwglDeleteContext(hglrc);
@@ -200,7 +200,7 @@ PROC CDECL DIBDRV_wglGetProcAddress(LPCSTR lpszProc)
{
PROC res;
- TRACE("lpszProc:%p\n", lpszProc);
+ MAYBE(TRACE("lpszProc:%p\n", lpszProc));
ONCE(FIXME("stub\n"));
res = _DIBDRV_GetDisplayDriver()->pwglGetProcAddress(lpszProc);
@@ -220,7 +220,7 @@ HDC CDECL DIBDRV_wglGetPbufferDCARB(DIBDRVPHYSDEV *physDev, HPBUFFERARB hPbuffer
{
HDC res;
- TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer);
+ MAYBE(TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer));
if(physDev->hasDIB)
{
@@ -245,7 +245,7 @@ BOOL CDECL DIBDRV_wglMakeContextCurrentARB(DIBDRVPHYSDEV* pDrawDev, DIBDRVPHYSDE
{
BOOL res;
- TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc);
+ MAYBE(TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc));
if(pDrawDev->hasDIB && pReadDev->hasDIB)
{
@@ -282,7 +282,7 @@ BOOL CDECL DIBDRV_wglMakeCurrent(DIBDRVPHYSDEV *physDev, HGLRC hglrc)
{
BOOL res;
- TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc);
+ MAYBE(TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc));
if(physDev->hasDIB)
{
@@ -308,7 +308,7 @@ BOOL CDECL DIBDRV_wglSetPixelFormatWINE(DIBDRVPHYSDEV *physDev, int iPixelFormat
{
BOOL res;
- TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd);
+ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd));
if(physDev->hasDIB)
{
@@ -333,7 +333,7 @@ BOOL CDECL DIBDRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
{
BOOL res;
- TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2);
+ MAYBE(TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2));
ONCE(FIXME("stub\n"));
res = _DIBDRV_GetDisplayDriver()->pwglShareLists(hglrc1, hglrc2);
@@ -350,7 +350,7 @@ BOOL CDECL DIBDRV_wglUseFontBitmapsA(DIBDRVPHYSDEV *physDev, DWORD first, DWORD
{
BOOL res;
- TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase);
+ MAYBE(TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase));
if(physDev->hasDIB)
{
@@ -375,7 +375,7 @@ BOOL CDECL DIBDRV_wglUseFontBitmapsW(DIBDRVPHYSDEV *physDev, DWORD first, DWORD
{
BOOL res;
- TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase);
+ MAYBE(TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase));
if(physDev->hasDIB)
{
diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c
index 9daf47d..148a6d5 100644
--- a/dlls/winedib.drv/palette.c
+++ b/dlls/winedib.drv/palette.c
@@ -32,7 +32,7 @@ UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary
{
UINT res;
- TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE"));
+ MAYBE(TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE")));
/* we should in any case call X11 function, as UnrealizePalette() doesn't
* take a physDev parameter */
@@ -54,7 +54,7 @@ BOOL DIBDRV_UnrealizePalette( HPALETTE hpal )
{
BOOL res;
- TRACE("hpal:%p\n", hpal);
+ MAYBE(TRACE("hpal:%p\n", hpal));
/* we should in any case call X11 function, as UnrealizePalette() doesn't
* take a physDev parameter */
@@ -74,13 +74,13 @@ UINT DIBDRV_GetSystemPaletteEntries( DIBDRVPHYSDEV *physDev, UINT start, UINT co
{
UINT res;
- TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries);
+ MAYBE(TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetSystemPaletteEntries(physDev->X11PhysDev, start, count, entries);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
}
else
{
@@ -97,13 +97,13 @@ COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color )
{
COLORREF res;
- TRACE("physDev:%p, color:%x\n", physDev, color);
+ MAYBE(TRACE("physDev:%p, color:%x\n", physDev, color));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetNearestColor(physDev->X11PhysDev, color);
+ ONCE(FIXME("STUB\n"));
+ res = 0;
}
else
{
@@ -119,14 +119,36 @@ COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color )
UINT DIBDRV_RealizeDefaultPalette( DIBDRVPHYSDEV *physDev )
{
UINT res;
+#ifdef DIBDRV_ENABLE_MAYBE
+ int i;
+ RGBQUAD *q;
+#endif
- TRACE("physDev:%p\n", physDev);
+ MAYBE(TRACE("physDev:%p\n", physDev));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev);
+ ONCE(FIXME("STUB\n"));
+ /* HACK - we can't get the dib color table during SelectBitmap since it hasn't
+ been initialized yet. This is called from DC_InitDC so it's a convenient place
+ to grab the color table. */
+ MAYBE(TRACE("Color table size = %d, Color table = %p\n", physDev->physBitmap.colorTableSize, physDev->physBitmap.colorTable));
+ if(!physDev->physBitmap.colorTableGrabbed)
+ {
+ MAYBE(TRACE("Grabbing palette\n"));
+ physDev->physBitmap.colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(physDev->physBitmap.colorTable[0]) * physDev->physBitmap.colorTableSize);
+ GetDIBColorTable(physDev->hdc, 0, physDev->physBitmap.colorTableSize, physDev->physBitmap.colorTable);
+#ifdef DIBDRV_ENABLE_MAYBE
+ for(i = 0; i < physDev->physBitmap.colorTableSize; i++)
+ {
+ q = physDev->physBitmap.colorTable + i;
+ TRACE(" %03d : R%03d G%03d B%03d\n", i, q->rgbRed, q->rgbGreen, q->rgbBlue);
+ }
+#endif
+ physDev->physBitmap.colorTableGrabbed = TRUE;
+ }
+ res = 0;
}
else
{
@@ -140,13 +162,14 @@ BOOL DIBDRV_GetICMProfile(DIBDRVPHYSDEV *physDev, LPDWORD lpcbName, LPWSTR lpszF
{
BOOL res;
- TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename);
+ MAYBE(TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetICMProfile(physDev->X11PhysDev, lpcbName, lpszFilename);
+ ONCE(FIXME("STUB\n"));
+
+ res = 0;
}
else
{
diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c
index bde2f23..31c9cd2 100644
--- a/dlls/winedib.drv/pen_brush.c
+++ b/dlls/winedib.drv/pen_brush.c
@@ -26,20 +26,317 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+static const DASHPATTERN dashPatterns[4] =
+{
+ {2, {18, 6}},
+ {2, {3, 3}},
+ {4, {9, 6, 3, 6}},
+ {6, {9, 3, 3, 3, 3, 3}}
+};
+
+static inline void OrderEndPoints(int *s, int *e)
+{
+ if(*s > *e)
+ {
+ int tmp;
+ tmp = *s + 1;
+ *s = *e + 1;
+ *e = tmp;
+ }
+}
+
+static void SolidPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
+{
+ OrderEndPoints(&x1, &x2);
+ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x1, x2, y, physDev->penAnd, physDev->penXor);
+}
+
+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);
+}
+
+static void WINAPI SolidPenLineCallback(int x, int y, LPARAM lparam)
+{
+ DIBDRVPHYSDEV *physDev = (DIBDRVPHYSDEV *)lparam;
+
+ physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, physDev->penAnd, physDev->penXor);
+ return;
+}
+
+void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
+{
+ LineDDA(x1, y1, x2, y2, SolidPenLineCallback, (LPARAM)physDev);
+}
+
+static inline void GetDashColors(DIBDRVPHYSDEV *physDev, DWORD *and, DWORD *xor)
+{
+ if(physDev->markSpace == mark)
+ {
+ *and = physDev->penAnd;
+ *xor = physDev->penXor;
+ }
+ else if(GetBkMode(physDev->hdc) == OPAQUE)
+ {
+ *and = physDev->backgroundAnd;
+ *xor = physDev->backgroundXor;
+ }
+ else
+ {
+ *and = 0xffffffff;
+ *xor = 0;
+ }
+}
+
+static inline void NextDash(DIBDRVPHYSDEV *physDev)
+{
+ if(physDev->leftInDash != 0)
+ return;
+
+ physDev->curDash++;
+ if(physDev->curDash == physDev->penPattern->count)
+ physDev->curDash = 0;
+ physDev->leftInDash = physDev->penPattern->dashes[physDev->curDash];
+ if(physDev->markSpace == mark)
+ physDev->markSpace = space;
+ else
+ physDev->markSpace = mark;
+}
+
+static void DashedPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
+{
+ int x = x1;
+ DWORD and, xor;
+ DWORD dashLen;
+
+ if(x1 <= x2)
+ {
+ while(x != x2)
+ {
+ GetDashColors(physDev, &and, &xor);
+
+ dashLen = physDev->leftInDash;
+ if(x + dashLen > x2)
+ dashLen = x2 - x;
+
+ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x, x + dashLen, y, and, xor);
+ x += dashLen;
+
+ physDev->leftInDash -= dashLen;
+ NextDash(physDev);
+ }
+ }
+ else
+ {
+ while(x != x2)
+ {
+ GetDashColors(physDev, &and, &xor);
+
+ dashLen = physDev->leftInDash;
+ if(x - (int)dashLen < x2)
+ dashLen = x - x2;
+
+ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x - dashLen + 1, x + 1, y, and, xor);
+ x -= dashLen;
+
+ physDev->leftInDash -= dashLen;
+ NextDash(physDev);
+ }
+ }
+}
+
+static void DashedPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2)
+{
+ int y = y1;
+ DWORD and, xor;
+ DWORD dashLen;
+
+ if(y1 <= y2)
+ {
+ while(y != y2)
+ {
+ GetDashColors(physDev, &and, &xor);
+
+ dashLen = physDev->leftInDash;
+ if(y + dashLen > y2)
+ dashLen = y2 - y;
+
+ physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y, y + dashLen, and, xor);
+ y += dashLen;
+
+ physDev->leftInDash -= dashLen;
+ NextDash(physDev);
+ }
+ }
+ else
+ {
+ while(y != y2)
+ {
+ GetDashColors(physDev, &and, &xor);
+
+ dashLen = physDev->leftInDash;
+ if(y - (int)dashLen < y2)
+ dashLen = y - y2;
+
+ physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y - dashLen + 1, y + 1, and, xor);
+ y -= dashLen;
+
+ physDev->leftInDash -= dashLen;
+ NextDash(physDev);
+ }
+ }
+}
+
+static void WINAPI DashedPenLineCallback(int x, int y, LPARAM lparam)
+{
+ DIBDRVPHYSDEV *physDev = (DIBDRVPHYSDEV *)lparam;
+ DWORD and, xor;
+
+ GetDashColors(physDev, &and, &xor);
+
+ physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, and, xor);
+
+ physDev->leftInDash--;
+ NextDash(physDev);
+
+ return;
+}
+
+static void DashedPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
+{
+ LineDDA(x1, y1, x2, y2, DashedPenLineCallback, (LPARAM)physDev);
+}
+
+void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev)
+{
+ physDev->curDash = 0;
+ if(physDev->penPattern)
+ physDev->leftInDash = physDev->penPattern->dashes[0];
+ physDev->markSpace = mark;
+}
+
+
+/* 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 *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;
+}
+
+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;
+}
+
+static void SolidBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
+{
+ OrderEndPoints(&x1, &x2);
+ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x1, x2, y, physDev->brushAnd, physDev->brushXor);
+}
+
+
+static void GenerateMasks(DIBDRVPHYSDEV *physDev, DIBDRVBITMAP *bmp, DWORD **and, DWORD **xor)
+{
+ int rop = GetROP2(physDev->hdc);
+ DWORD *color_ptr, *and_ptr, *xor_ptr;
+ DWORD size = bmp->height * abs(bmp->stride);
+
+ *and = HeapAlloc(GetProcessHeap(), 0, size);
+ *xor = HeapAlloc(GetProcessHeap(), 0, size);
+
+ color_ptr = bmp->bits;
+ and_ptr = *and;
+ xor_ptr = *xor;
+
+ while(size)
+ {
+ _DIBDRV_CalcAndXorMasks(rop, *color_ptr++, and_ptr++, xor_ptr++);
+ size -= 4;
+ }
+}
+
+static void PatternBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y)
+{
+ DWORD *and, *xor, brushY = y % physDev->brushBitmap.height;
+
+ if(!physDev->brushAnds)
+ GenerateMasks(physDev, &physDev->brushBitmap, &physDev->brushAnds, &physDev->brushXors);
+
+ OrderEndPoints(&x1, &x2);
+ and = (DWORD *)((char *)physDev->brushAnds + brushY * physDev->brushBitmap.stride);
+ xor = (DWORD *)((char *)physDev->brushXors + brushY * physDev->brushBitmap.stride);
+
+ physDev->physBitmap.funcs->PatternHLine(&physDev->physBitmap, x1, x2, y, and, xor, physDev->brushBitmap.width, x1 % physDev->brushBitmap.width);
+}
+
/***********************************************************************
* DIBDRV_SelectPen
*/
HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen )
{
HPEN res;
+ LOGPEN logpen;
- TRACE("physDev:%p, hpen:%p\n", physDev, hpen);
+ MAYBE(TRACE("physDev:%p, hpen:%p\n", physDev, hpen));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSelectPen(physDev->X11PhysDev, 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);
+
+ _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), physDev->penColor, &physDev->penAnd, &physDev->penXor);
+
+ switch(logpen.lopnStyle)
+ {
+ default:
+ ONCE(FIXME("Unhandled pen style %d\n", logpen.lopnStyle));
+ /* fall through */
+ case PS_SOLID:
+ physDev->penHLine = SolidPenHLine;
+ physDev->penVLine = SolidPenVline;
+ physDev->penLine = SolidPenLine;
+ physDev->penPattern = NULL;
+ break;
+
+ case PS_DASH:
+ case PS_DOT:
+ case PS_DASHDOT:
+ case PS_DASHDOTDOT:
+ physDev->penHLine = DashedPenHLine;
+ physDev->penVLine = DashedPenVLine;
+ physDev->penLine = DashedPenLine;
+ physDev->penPattern = &dashPatterns[logpen.lopnStyle - PS_DASH];
+ _DIBDRV_ResetDashOrigin(physDev);
+ break;
+ }
+ res = hpen;
}
else
{
@@ -56,13 +353,13 @@ COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor )
{
COLORREF res;
- TRACE("physDev:%p, crColor:%x\n", physDev, crColor);
+ MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev, crColor));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev->X11PhysDev, crColor);
+ ONCE(FIXME("STUB\n"));
+ res = crColor;
}
else
{
@@ -77,19 +374,151 @@ COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor )
*/
HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush )
{
- HBRUSH res;
+ HBRUSH res = hbrush;
+ LOGBRUSH logbrush;
+
- TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush);
+ MAYBE(TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush);
+ GetObjectW(hbrush, sizeof(logbrush), &logbrush);
+
+ /* frees any currently selected DIB brush and cache */
+ _DIBDRVBITMAP_Free(&physDev->brushBitmap);
+ _DIBDRVBITMAP_Free(&physDev->brushBmpCache);
+ if(physDev->brushAnds)
+ {
+ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
+ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
+ }
+ physDev->brushAnds = NULL;
+ physDev->brushXors = NULL;
+
+ switch (logbrush.lbStyle)
+ {
+ default:
+ FIXME("Unhandled brush style %d\n", logbrush.lbStyle);
+ physDev->brushColorref = 0;
+ goto solid;
+
+ case BS_SOLID:
+ physDev->brushColorref = 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);
+
+ _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->brushColor,
+ &physDev->brushAnd, &physDev->brushXor);
+
+ /* set the physDev brush style */
+ physDev->brushStyle = BS_SOLID;
+ physDev->isBrushBitmap = FALSE;
+
+ break;
+
+ case BS_DIBPATTERN8X8:
+ case BS_DIBPATTERN:
+ {
+ DIBDRVBITMAP src;
+ BITMAPINFO *bmi;
+
+ FIXME("DIB Pattern\n");
+
+ /* if no DIB selected in, fallback to null brush */
+ if(!physDev->physBitmap.bits)
+ {
+ physDev->brushColorref = 0;
+ goto solid;
+ }
+
+ /* gets brush DIB's pointer */
+ bmi = GlobalLock16(logbrush.lbHatch);
+
+ /* initializes a temporary DIB with brush's one */
+ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&src, bmi))
+ {
+ ERR("Failed to initialize brush DIB\n");
+ res = 0;
+ goto err;
+ }
+
+ /* converts brush bitmap to match currently selected one's format */
+ if(!_DIBDRVBITMAP_Convert(&physDev->brushBitmap, &src, &physDev->physBitmap))
+ {
+ ERR("Failed to convert brush DIB\n");
+ _DIBDRVBITMAP_Free(&src);
+ res = 0;
+ goto err;
+ }
+
+ /* frees temporary DIB's data */
+ _DIBDRVBITMAP_Free(&src);
+
+ /* use DIB pattern for brush lines */
+ physDev->brushHLine = PatternBrushHLine;
+
+ err:
+ /* frees brush's DIB pointer */
+ GlobalUnlock16(logbrush.lbHatch);
+
+ break;
+ }
+ case BS_DIBPATTERNPT:
+ FIXME("BS_DIBPATTERNPT not supported\n");
+ physDev->brushColorref = 0;
+ goto solid;
+
+ case BS_HATCHED:
+ FIXME("BS_HATCHED not supported\n");
+ physDev->brushColorref = 0;
+ goto solid;
+
+ case BS_NULL:
+ {
+ MAYBE(TRACE("NULL Pattern\n"));
+ physDev->brushColorref = 0;
+ goto solid;
+ }
+
+ case BS_PATTERN:
+ case BS_PATTERN8X8:
+ FIXME("BS_PATTERN not supported\n");
+ physDev->brushColorref = 0;
+ goto solid;
+ }
+
+ MAYBE(TRACE("END\n"));
+ return hbrush;
}
else
{
/* DDB selected in, use X11 driver */
+
+ /* we must check if a DIB pattern is requested */
+ GetObjectW(hbrush, sizeof(logbrush), &logbrush);
+ switch (logbrush.lbStyle)
+ {
+ case BS_DIBPATTERN8X8:
+ case BS_DIBPATTERN:
+ case BS_DIBPATTERNPT:
+ FIXME("A DIB pattern was requested for a DDB bitmap\n");
+ break;
+
+ case BS_SOLID:
+ case BS_HATCHED:
+ case BS_NULL:
+ case BS_PATTERN:
+ case BS_PATTERN8X8:
+ default:
+ break;
+ }
res = _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush);
}
return res;
@@ -102,13 +531,13 @@ COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor )
{
COLORREF res;
- TRACE("physDev:%p, crColor:%x\n", physDev, crColor);
+ MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev, crColor));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev->X11PhysDev, crColor);
+ ONCE(FIXME("STUB\n"));
+ res = crColor;
}
else
{
@@ -121,14 +550,29 @@ COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor )
/***********************************************************************
* SetROP2
*/
-INT DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, INT rop )
+int DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, int rop )
{
- INT prevRop;
+ int prevRop;
- TRACE("physDev:%p, rop:%x\n", physDev, rop);
+ MAYBE(TRACE("physDev:%p, rop:%x\n", physDev, rop));
prevRop = physDev->rop2;
physDev->rop2 = rop;
+
+ if(prevRop != rop)
+ {
+ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor);
+ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor);
+ _DIBDRV_CalcAndXorMasks(rop, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor);
+ if(physDev->brushAnds)
+ {
+ HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
+ HeapFree(GetProcessHeap(), 0, physDev->brushXors);
+ }
+ physDev->brushAnds = NULL;
+ physDev->brushXors = NULL;
+ }
+
return prevRop;
/* note : X11 Driver don't have SetROP2() function exported */
}
@@ -140,13 +584,17 @@ COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color )
{
COLORREF res;
- TRACE("physDev:%p, color:%x\n", physDev, color);
+ MAYBE(TRACE("physDev:%p, color:%x\n", physDev, color));
if(physDev->hasDIB)
{
- /* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev->X11PhysDev, color);
+ physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color);
+
+ if(physDev->physBitmap.bitCount == 1)
+ FixupFgColors1(physDev);
+ _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor);
+
+ res = TRUE;
}
else
{
diff --git a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c
new file mode 100644
index 0000000..cbad239
--- /dev/null
+++ b/dlls/winedib.drv/primitives.c
@@ -0,0 +1,274 @@
+/*
+ * DIB Engine Primitives function pointers
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* ------------------------------------------------------------*/
+/* COLOR FUNCTIONS */
+DWORD _DIBDRV_ColorToPixel32_RGB (const DIBDRVBITMAP *dib, COLORREF color);
+DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color);
+DWORD _DIBDRV_ColorToPixel24 (const DIBDRVBITMAP *dib, COLORREF color);
+DWORD _DIBDRV_ColorToPixel16_RGB (const DIBDRVBITMAP *dib, COLORREF color);
+DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color);
+DWORD _DIBDRV_ColorToPixelColortable (const DIBDRVBITMAP *dib, COLORREF color);
+
+/* ------------------------------------------------------------*/
+/* PIXEL POINTER READING */
+void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y);
+void *_DIBDRV_GetPixelPointer24(const DIBDRVBITMAP *dib, int x, int y);
+void *_DIBDRV_GetPixelPointer16(const DIBDRVBITMAP *dib, int x, int y);
+void *_DIBDRV_GetPixelPointer8 (const DIBDRVBITMAP *dib, int x, int y);
+void *_DIBDRV_GetPixelPointer4 (const DIBDRVBITMAP *dib, int x, int y);
+void *_DIBDRV_GetPixelPointer1 (const DIBDRVBITMAP *dib, int x, int y);
+
+/* ------------------------------------------------------------*/
+/* PIXEL WRITING */
+void _DIBDRV_SetPixel32(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
+void _DIBDRV_SetPixel24(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
+void _DIBDRV_SetPixel16(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
+void _DIBDRV_SetPixel8 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
+void _DIBDRV_SetPixel4 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor);
+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 _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y);
+DWORD _DIBDRV_GetPixel24 (const DIBDRVBITMAP *dib, int x, int y);
+DWORD _DIBDRV_GetPixel16_RGB (const DIBDRVBITMAP *dib, int x, int y);
+DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y);
+DWORD _DIBDRV_GetPixel8 (const DIBDRVBITMAP *dib, int x, int y);
+DWORD _DIBDRV_GetPixel4 (const DIBDRVBITMAP *dib, int x, int y);
+DWORD _DIBDRV_GetPixel1 (const DIBDRVBITMAP *dib, int x, int y);
+
+/* ------------------------------------------------------------*/
+/* HORIZONTAL SOLID LINES */
+void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
+void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
+void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
+void _DIBDRV_SolidHLine8 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
+void _DIBDRV_SolidHLine4 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
+void _DIBDRV_SolidHLine1 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor);
+
+/* ------------------------------------------------------------*/
+/* HORIZONTAL PATTERN LINES */
+void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
+void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
+void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
+void _DIBDRV_PatternHLine8 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
+void _DIBDRV_PatternHLine4 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
+void _DIBDRV_PatternHLine1 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset);
+
+/* ------------------------------------------------------------*/
+/* VERTICAL LINES */
+void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
+void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
+void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
+void _DIBDRV_SolidVLine8 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
+void _DIBDRV_SolidVLine4 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
+void _DIBDRV_SolidVLine1 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor);
+
+/* ----------------------------------------------------------------*/
+/* CONVERT PRIMITIVES */
+/* converts (part of) line of any DIB format from/to DIB32_RGB one */
+BOOL _DIBDRV_GetLine32_RGB (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine24 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine16_RGB (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine8 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine4 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_GetLine1 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+
+BOOL _DIBDRV_PutLine32_RGB (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine32_BITFIELDS(DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine24 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine16_RGB (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine16_BITFIELDS(DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine8 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine4 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+BOOL _DIBDRV_PutLine1 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf);
+
+/* ------------------------------------------------------------*/
+/* BLITTING PRIMITIVES */
+BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, DWORD rop);
+BOOL _DIBDRV_BitBlt_32(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, DWORD rop);
+BOOL _DIBDRV_BitBlt_24(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, DWORD rop);
+BOOL _DIBDRV_BitBlt_16(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, DWORD rop);
+BOOL _DIBDRV_BitBlt_8(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, DWORD rop);
+
+BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop);
+
+/* ------------------------------------------------------------*/
+/* FREETYPE FONT BITMAP BLITTING */
+void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_32_RGB (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_24 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_16_RGB (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_8 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_4 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+void _DIBDRV_freetype_blit_1 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp);
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB =
+{
+ _DIBDRV_ColorToPixel32_RGB,
+ _DIBDRV_GetPixelPointer32,
+ _DIBDRV_SetPixel32,
+ _DIBDRV_GetPixel32_RGB,
+ _DIBDRV_SolidHLine32,
+ _DIBDRV_PatternHLine32,
+ _DIBDRV_SolidVLine32,
+ _DIBDRV_GetLine32_RGB,
+ _DIBDRV_PutLine32_RGB,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_32_RGB
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS =
+{
+ _DIBDRV_ColorToPixel32_BITFIELDS,
+ _DIBDRV_GetPixelPointer32,
+ _DIBDRV_SetPixel32,
+ _DIBDRV_GetPixel32_BITFIELDS,
+ _DIBDRV_SolidHLine32,
+ _DIBDRV_PatternHLine32,
+ _DIBDRV_SolidVLine32,
+ _DIBDRV_GetLine32_BITFIELDS,
+ _DIBDRV_PutLine32_BITFIELDS,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_32_BITFIELDS
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24 =
+{
+ _DIBDRV_ColorToPixel24,
+ _DIBDRV_GetPixelPointer24,
+ _DIBDRV_SetPixel24,
+ _DIBDRV_GetPixel24,
+ _DIBDRV_SolidHLine24,
+ _DIBDRV_PatternHLine24,
+ _DIBDRV_SolidVLine24,
+ _DIBDRV_GetLine24,
+ _DIBDRV_PutLine24,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_24
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB =
+{
+ _DIBDRV_ColorToPixel16_RGB,
+ _DIBDRV_GetPixelPointer16,
+ _DIBDRV_SetPixel16,
+ _DIBDRV_GetPixel16_RGB,
+ _DIBDRV_SolidHLine16,
+ _DIBDRV_PatternHLine16,
+ _DIBDRV_SolidVLine16,
+ _DIBDRV_GetLine16_RGB,
+ _DIBDRV_PutLine16_RGB,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_16_RGB
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS =
+{
+ _DIBDRV_ColorToPixel16_BITFIELDS,
+ _DIBDRV_GetPixelPointer16,
+ _DIBDRV_SetPixel16,
+ _DIBDRV_GetPixel16_BITFIELDS,
+ _DIBDRV_SolidHLine16,
+ _DIBDRV_PatternHLine16,
+ _DIBDRV_SolidVLine16,
+ _DIBDRV_GetLine16_BITFIELDS,
+ _DIBDRV_PutLine16_BITFIELDS,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_16_BITFIELDS
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8 =
+{
+ _DIBDRV_ColorToPixelColortable,
+ _DIBDRV_GetPixelPointer8,
+ _DIBDRV_SetPixel8,
+ _DIBDRV_GetPixel8,
+ _DIBDRV_SolidHLine8,
+ _DIBDRV_PatternHLine8,
+ _DIBDRV_SolidVLine8,
+ _DIBDRV_GetLine8,
+ _DIBDRV_PutLine8,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_8
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4 =
+{
+ _DIBDRV_ColorToPixelColortable,
+ _DIBDRV_GetPixelPointer4,
+ _DIBDRV_SetPixel4,
+ _DIBDRV_GetPixel4,
+ _DIBDRV_SolidHLine4,
+ _DIBDRV_PatternHLine4,
+ _DIBDRV_SolidVLine4,
+ _DIBDRV_GetLine4,
+ _DIBDRV_PutLine4,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_4
+};
+
+DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1 =
+{
+ _DIBDRV_ColorToPixelColortable,
+ _DIBDRV_GetPixelPointer1,
+ _DIBDRV_SetPixel1,
+ _DIBDRV_GetPixel1,
+ _DIBDRV_SolidHLine1,
+ _DIBDRV_PatternHLine1,
+ _DIBDRV_SolidVLine1,
+ _DIBDRV_GetLine1,
+ _DIBDRV_PutLine1,
+ _DIBDRV_BitBlt_generic,
+ _DIBDRV_StretchBlt_generic,
+ _DIBDRV_freetype_blit_1
+};
diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c
new file mode 100644
index 0000000..da48352
--- /dev/null
+++ b/dlls/winedib.drv/primitives_bitblt.c
@@ -0,0 +1,1075 @@
+/*
+ * DIB Engine BitBlt Primitives
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* shrinks a line -- srcWidth >= dstWidth */
+static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
+{
+ int srcPos, dstPos;
+ int delta;
+
+ srcPos = 0;
+ dstPos = 0;
+ delta = 0;
+ while(dstPos < dstWidth)
+ {
+ *dst++ = *src;
+ while(delta < srcWidth)
+ {
+ srcPos++;
+ src++;
+ delta += dstWidth;
+ }
+ delta -= srcWidth;
+ dstPos++;
+ }
+}
+
+/* expands a line -- srcWidth <= dstWidth */
+static void ExpandLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
+{
+ int srcPos;
+ int delta;
+
+ srcPos = 0;
+ delta = 0;
+ while(srcPos < srcWidth)
+ {
+ while(delta < dstWidth)
+ {
+ *dst++ = *src;
+ delta += srcWidth;
+ }
+ delta -= dstWidth;
+ src++;
+ srcPos++;
+ }
+}
+
+/* stretch a line */
+static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth)
+{
+ if(srcWidth > dstWidth)
+ ShrinkLine(dst, dstWidth, src, srcWidth);
+ else if(srcWidth < dstWidth)
+ ExpandLine(dst, dstWidth, src, srcWidth);
+ else
+ memcpy(dst, src, 4 * srcWidth);
+}
+
+/* ------------------------------------------------------------*/
+/* BLITTING PRIMITIVES */
+BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, DWORD rop)
+{
+ int ys, yd;
+ int i;
+ DWORD *dwBuf;
+ DIBDRVBITMAP *dstBmp, *patBmp;
+ const DIBDRVBITMAP *srcBmp;
+ DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
+ BOOL usePat, useSrc, useDst;
+ DWORD patColor;
+ BOOL res = FALSE;
+
+ /* 32 bit RGB source and destination buffer, if needed */
+ DWORD *sBuf = 0, *dBuf = 0, *pBuf = 0;
+
+ /* get elements usage */
+ usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
+ useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
+ useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
+
+ /* gets source, dest and pattern bitmaps, if available */
+ if(usePat && physDevDst->isBrushBitmap)
+ patBmp = &physDevDst->brushBmpCache;
+ else
+ patBmp = NULL;
+
+ if(useSrc)
+ srcBmp = &physDevSrc->physBitmap;
+ else
+ srcBmp = NULL;
+ dstBmp = &physDevDst->physBitmap;
+
+ /* gets pattern color, in case it's needed */
+ if(usePat)
+ patColor = physDevDst->brushColor;
+ else
+ patColor = 0;
+
+ /* allocate 32 bit RGB destination buffer */
+ if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+
+ MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n",
+ dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height,
+ srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop));
+
+ /* some simple ROPs optimizations */
+ switch(rop)
+ {
+ case BLACKNESS:
+ MAYBE(TRACE("BLACKNESS\n"));
+ memset(dBuf, 0x00, width * 4);
+ for(yd = yDst; yd < yDst+height; yd++)
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ break;
+
+ case WHITENESS:
+ MAYBE(TRACE("WHITENESS\n"));
+ for(dwBuf = dBuf, i = width; i; i--)
+ *dwBuf++ = 0x00ffffff;
+ for(yd = yDst; yd < yDst+height; yd++)
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ break;
+
+ case SRCCOPY:
+ MAYBE(TRACE("SRCCOPY\n"));
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ break;
+
+ /* fallback for generic ROP operation */
+ default:
+ rop >>= 16;
+ if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n"));
+ if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf);
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBuf;
+ wPatPnt = pBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(useSrc && useDst)
+ {
+ if(usePat)
+ MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n"));
+ else
+ MAYBE(TRACE("BitBlt use: src+dst\n"));
+ if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf);
+ dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(useSrc && usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n"));
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
+ wDstPnt = sBuf;
+ wSrcPnt = sBuf;
+ wPatPnt = pBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(useSrc)
+ {
+ if(usePat)
+ MAYBE(TRACE("BitBlt use: src+pat - solid brush\n"));
+ else
+ MAYBE(TRACE("BitBlt use: src\n"));
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf);
+ wDstPnt = sBuf;
+ wSrcPnt = sBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(useDst && usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n"));
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
+ wDstPnt = sBuf;
+ wPatPnt = pBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(useDst)
+ {
+ if(usePat)
+ MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n"));
+ else
+ MAYBE(TRACE("BitBlt use: dst\n"));
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf);
+ wDstPnt = sBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("BitBlt use: pat -- pattern brush\n"));
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4)))
+ goto error;
+ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++)
+ {
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf);
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else if(usePat)
+ {
+ MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
+ MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
+ MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height));
+ for(yd = yDst; yd < yDst+height; yd++)
+ {
+ wDstPnt = dBuf;
+ for(i = width; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf);
+ }
+ }
+ else
+ ERR("What happened ?????? \n");
+ break;
+ } /* switch */
+ res = TRUE;
+error:
+ if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf );
+ if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
+ if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
+ return res;
+}
+
+/* ------------------------------------------------------------*/
+/* STRETCHING PRIMITIVES */
+BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst,
+ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc,
+ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop)
+{
+ int ys, yd;
+ int i, delta;
+ DWORD *dwBuf;
+ DIBDRVBITMAP *dstBmp, *patBmp;
+ const DIBDRVBITMAP *srcBmp;
+ DWORD *wDstPnt, *wSrcPnt, *wPatPnt;
+ BOOL usePat, useSrc, useDst;
+ DWORD patColor;
+ BOOL res = FALSE;
+
+ /* 32 bit RGB source and destination buffer, if needed */
+ DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0;
+
+ /* get elements usage */
+ usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000));
+ useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000));
+ useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000));
+
+ /* gets source, dest and pattern bitmaps, if available */
+ if(usePat && physDevDst->isBrushBitmap)
+ patBmp = &physDevDst->brushBmpCache;
+ else
+ patBmp = NULL;
+
+ if(useSrc)
+ srcBmp = &physDevSrc->physBitmap;
+ else
+ srcBmp = NULL;
+ dstBmp = &physDevDst->physBitmap;
+
+ /* gets pattern color, in case it's needed */
+ if(usePat)
+ patColor = physDevDst->brushColor;
+ else
+ patColor = 0;
+
+ /* allocate 32 bit RGB destination buffer */
+ if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+
+ MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, , widthSrc:%d, heightSrc:%drop:%8x\n",
+ dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst,
+ srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop));
+
+ /* some simple ROPs optimizations */
+ switch(rop)
+ {
+ case BLACKNESS:
+ MAYBE(TRACE("BLACKNESS\n"));
+ memset(dBuf, 0x00, widthDst * 4);
+ for(yd = yDst; yd < yDst+heightDst; yd++)
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ break;
+
+ case WHITENESS:
+ MAYBE(TRACE("WHITENESS\n"));
+ for(dwBuf = dBuf, i = widthDst; i; i--)
+ *dwBuf++ = 0x00ffffff;
+ for(yd = yDst; yd < yDst+heightDst; yd++)
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ break;
+
+ case SRCCOPY:
+ MAYBE(TRACE("SRCCOPY\n"));
+ sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4);
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
+ while(delta < heightDst)
+ {
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
+ StretchLine(dBuf, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ break;
+
+ /* fallback for generic ROP operation */
+ default:
+ rop >>= 16;
+ if(useSrc && useDst && usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n"));
+ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
+ goto error;
+ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(useSrc && useDst)
+ {
+ if(usePat)
+ MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n"));
+ else
+ MAYBE(TRACE("StretchBlt use: src+dst\n"));
+ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
+ goto error;
+ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(useSrc && usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n"));
+ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
+ goto error;
+ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(useSrc)
+ {
+ if(usePat)
+ MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n"));
+ else
+ MAYBE(TRACE("StretchBlt use: src\n"));
+ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4)))
+ goto error;
+ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig);
+ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc);
+ wDstPnt = dBuf;
+ wSrcPnt = sBufStr;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(useDst && usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n"));
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(useDst)
+ {
+ if(usePat)
+ MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n"));
+ else
+ MAYBE(TRACE("StretchBlt use: dst\n"));
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ wDstPnt = dBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf);
+ wDstPnt = dBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(usePat && physDevDst->isBrushBitmap)
+ {
+ MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n"));
+ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4)))
+ goto error;
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf);
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf);
+ wDstPnt = dBuf;
+ wPatPnt = pBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else if(usePat)
+ {
+ MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor));
+ MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp)));
+ MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst));
+ if(heightSrc > heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(yd < heightDst)
+ {
+ wDstPnt = dBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ while(delta < heightSrc)
+ {
+ ys++;
+ delta += heightDst;
+ }
+ delta -= heightSrc;
+ yd++;
+ }
+ }
+ else if(heightSrc < heightDst)
+ {
+ ys = 0;
+ yd = 0;
+ delta = 0;
+ while(ys < heightSrc)
+ {
+ while(delta < heightDst)
+ {
+ wDstPnt = dBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf);
+ yd++;
+ delta += heightSrc;
+ }
+ delta -= heightDst;
+ ys++;
+ }
+ }
+ else
+ {
+ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++)
+ {
+ wDstPnt = dBuf;
+ for(i = widthDst; i > 0 ; i--)
+ {
+ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop);
+ wDstPnt++;
+ }
+ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf);
+ }
+ }
+ }
+ else
+ ERR("What happened ?????? \n");
+ break;
+ } /* switch */
+ res = TRUE;
+error:
+ if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig );
+ if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr );
+ if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf );
+ if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf );
+ return res;
+}
diff --git a/dlls/winedib.drv/primitives_color.c b/dlls/winedib.drv/primitives_color.c
new file mode 100644
index 0000000..3ccc2e0
--- /dev/null
+++ b/dlls/winedib.drv/primitives_color.c
@@ -0,0 +1,142 @@
+/*
+ * DIB Engine color Primitives
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* ------------------------------------------------------------*/
+/* BITFIELD HELPERS */
+static inline DWORD PutField32(DWORD field, int shift, int len)
+{
+ shift = shift - (8 - len);
+ if (len <= 8)
+ field &= (((1 << len) - 1) << (8 - len));
+ if (shift < 0)
+ field >>= -shift;
+ else
+ field <<= shift;
+ return field;
+}
+
+static inline WORD PutField16(WORD field, int shift, int len)
+{
+ shift = shift - (8 - len);
+ if (len <= 8)
+ field &= (((1 << len) - 1) << (8 - len));
+ if (shift < 0)
+ field >>= -shift;
+ else
+ field <<= shift;
+ return field;
+}
+
+/* ------------------------------------------------------------*/
+/* COLOR FUNCTIONS */
+DWORD _DIBDRV_ColorToPixel32_RGB(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
+}
+
+DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ DWORD r,g,b;
+
+ r = GetRValue(color);
+ g = GetGValue(color);
+ b = GetBValue(color);
+
+ return PutField32(r, dib->redShift, dib->redLen) |
+ PutField32(g, dib->greenShift, dib->greenLen) |
+ PutField32(b, dib->blueShift, dib->blueLen);
+}
+
+DWORD _DIBDRV_ColorToPixel24(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) );
+}
+
+DWORD _DIBDRV_ColorToPixel16_RGB(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ return ( ((color >> 19) & 0x001f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) );
+}
+
+DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ DWORD r,g,b;
+
+ r = GetRValue(color);
+ g = GetGValue(color);
+ b = GetBValue(color);
+
+ return PutField16(r, dib->redShift, dib->redLen) |
+ PutField16(g, dib->greenShift, dib->greenLen) |
+ PutField16(b, dib->blueShift, dib->blueLen);
+}
+
+DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color)
+{
+ int i, best_index = 0;
+ DWORD r, g, b;
+ 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;
+ diff = (r - cur->rgbRed) * (r - cur->rgbRed)
+ + (g - cur->rgbGreen) * (g - cur->rgbGreen)
+ + (b - cur->rgbBlue) * (b - cur->rgbBlue);
+
+ if(diff == 0)
+ {
+ best_index = i;
+ break;
+ }
+
+ if(diff < best_diff)
+ {
+ best_diff = diff;
+ best_index = i;
+ }
+ }
+ return best_index;
+}
diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c
new file mode 100644
index 0000000..800e3fd
--- /dev/null
+++ b/dlls/winedib.drv/primitives_convert.c
@@ -0,0 +1,559 @@
+/*
+ * DIB Engine conversions Primitives
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+static inline COLORREF SwapColors(DWORD c)
+{
+ return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16);
+
+}
+
+/* ----------------------------------------------------------------*/
+/* CONVERT PRIMITIVES */
+/* converts (part of) line of any DIB format from/to DIB32_RGB one */
+BOOL _DIBDRV_GetLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ DWORD *src;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ dwBuf -= startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
+ for(; width; width--)
+ *dwBuf++ = *src++;
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ BYTE *bBuf = (BYTE *)buf;
+ DWORD *src;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ bBuf -= 4 * startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ 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;
+ src++;
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine24(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ BYTE *bBuf = (BYTE *)buf;
+ BYTE *src;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ bBuf -= 4 * startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ src = ((BYTE *)bmp->bits + line * bmp->stride + 3 * startx);
+ for(; width ; width--)
+ {
+ *bBuf++ = *src++;
+ *bBuf++ = *src++;
+ *bBuf++ = *src++;
+ *bBuf++ = 0x0;
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ WORD *src;
+ DWORD b;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ dwBuf -= startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ src = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
+ for(; width ; width--)
+ {
+ b = *src++;
+ /* 0RRR|RRGG|GGGB|BBBB */
+ *dwBuf++ = ((b & 0x1f) << 3) | ((b & 0x3e0) << 6) | ((b & 0x7c00) << 9);
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ WORD *src;
+ DWORD b;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ dwBuf -= startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ src = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * 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 ));
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine8(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *src;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ dwBuf -= startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ src = ((BYTE *)bmp->bits + line * bmp->stride + startx);
+ for(; width ; width--)
+ *dwBuf++ = *((DWORD *)bmp->colorTable + *src++);
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *src;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ dwBuf -= startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+ if(!bmp->colorTable)
+ {
+ ERR("Called with uninitialized color table\n");
+ return FALSE;
+ }
+#endif
+
+ src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 1));
+ /* if startx is odd, get first nibble */
+ if(startx & 0x01)
+ {
+ *dwBuf++ = *((DWORD *)bmp->colorTable + (*src++ & 0x0f));
+ width--;
+ }
+
+ /* then gets all full image bytes */
+ for( ; width > 1 ; width -= 2)
+ {
+ *dwBuf++ = *((DWORD *)bmp->colorTable + ((*src >> 4) & 0x0f));
+ *dwBuf++ = *((DWORD *)bmp->colorTable + (*src++ & 0x0f));
+ }
+
+ /* last nibble, if any */
+ if(width)
+ *dwBuf++ = *((DWORD *)bmp->colorTable + ((*src >> 4) & 0x0f));
+ return TRUE;
+}
+
+BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *src;
+ BYTE b;
+ char i;
+ DWORD pixOn = *((DWORD *)bmp->colorTable + 1);
+ DWORD pixOff = *(DWORD *)bmp->colorTable;
+
+#ifdef DIBDRV_CHECK_RANGES
+ /* range check */
+ if(line < 0 || line >= bmp->height)
+ return FALSE;
+ if(startx < 0)
+ {
+ width += startx;
+ dwBuf -= startx;
+ startx = 0;
+ }
+ if(startx + width > bmp->width)
+ width = bmp->width - startx;
+ if(width <= 0)
+ return FALSE;
+#endif
+
+ src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3));
+ /* get first partial byte, if any */
+ startx = (8 - (startx & 0x03)) & 0x03;
+ width -= startx;
+ if(startx)
+ {
+ b = *src++ << (8 - startx);
+ while(startx--)
+ {
+ if(b & 0x80)
+ *dwBuf++ = pixOn;
+ else
+ *dwBuf++ = pixOff;
+ b <<= 1;
+ }
+ }
+
+ /* then gets full next bytes */
+ for( ; width > 7 ; width -= 8)
+ {
+ b = *src++;
+ for(i = 0 ; i < 8 ; i++)
+ {
+ if(b & 0x80)
+ *dwBuf++ = pixOn;
+ else
+ *dwBuf++ = pixOff;
+ b <<= 1;
+ }
+ }
+
+ /* last partial byte, if any */
+ if(width)
+ {
+ b = *src;
+ while(width--)
+ {
+ if(b & 0x80)
+ *dwBuf++ = pixOn;
+ else
+ *dwBuf++ = pixOff;
+ b <<= 1;
+ }
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
+ for(; width; width--)
+ *dst++ = *dwBuf++;
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx);
+ DWORD c;
+ for(; width; width--)
+ {
+ c = *dwBuf++;
+ *dst++ =
+ ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) |
+ ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) |
+ ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask);
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine24(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + 3 * startx);
+ DWORD c;
+ for(; width; width--)
+ {
+ c = *dwBuf++;
+ *dst++ = c & 0x000000ff;
+ *dst++ = (c & 0x0000ff00) >> 8;
+ *dst++ = (c & 0x00ff0000) >> 16;
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
+ DWORD c;
+ for(; width; width--)
+ {
+ c = *dwBuf++;
+ *dst++ =
+ ((c & 0x000000f8) >> 3) |
+ ((c & 0x0000f800) >> 6) |
+ ((c & 0x00f80000) >> 9);
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx);
+ DWORD c;
+ for(; width; width--)
+ {
+ c = *dwBuf++;
+ *dst++ =
+ ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) |
+ ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) |
+ ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask);
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine8(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + startx);
+ DWORD c;
+ DWORD last_color = 0xffffffff;
+ int last_index = -1;
+
+ for(; width; width--)
+ {
+ c = *dwBuf++;
+
+ /* slight optimization, as images often have many
+ consecutive pixels with same color */
+ if(last_index == -1 || c != last_color)
+ {
+ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
+ last_color = c;
+ }
+ *dst++ = last_index;
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 1));
+ DWORD c;
+ DWORD last_color = 0xffffffff;
+ int last_index = -1;
+
+ /* if startx is odd, put first nibble */
+ if(startx & 0x01)
+ {
+ c = *dwBuf++;
+
+ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
+ last_color = c;
+ *dst = (*dst & 0xf0) | last_index;
+ dst++;
+ width--;
+ }
+
+ /* then gets all full image bytes */
+ for( ; width > 1 ; width -= 2)
+ {
+ c = *dwBuf++;
+
+ /* slight optimization, as images often have many
+ consecutive pixels with same color */
+ if(last_index == -1 || c != last_color)
+ {
+ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
+ last_color = c;
+ }
+ *dst = last_index << 4;
+
+ c = *dwBuf++;
+
+ /* slight optimization, as images often have many
+ consecutive pixels with same color */
+ if(last_index == -1 || c != last_color)
+ {
+ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
+ last_color = c;
+ }
+ *dst++ |= last_index;
+ }
+
+ /* last nibble, if any */
+ if(width)
+ {
+ c = *dwBuf;
+
+ /* slight optimization, as images often have many
+ consecutive pixels with same color */
+ if(last_index == -1 || c != last_color)
+ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c));
+ *dst = (*dst & 0x0f) | (last_index << 4);
+ }
+ return TRUE;
+}
+
+BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf)
+{
+ DWORD *dwBuf = (DWORD *)buf;
+ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3));
+ BYTE b, mask;
+ char i;
+ DWORD c;
+
+ /* get foreground color */
+ DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff;
+
+ /* put first partial byte, if any */
+ startx &= 0x03;
+ mask = 0x80 >> startx;
+ startx = (8 - startx) & 0x03;
+ if(startx)
+ {
+ width -= startx;
+ b = *dst;
+ while(startx--)
+ {
+ c = *dwBuf++ & 0x00ffffff;
+ if(c == 0x00ffffff || c == fore)
+ b |= mask;
+ else
+ b &= !mask;
+ mask >>= 1;
+ }
+ *dst++ = b;
+ }
+
+ /* then puts full next bytes */
+ for( ; width > 7 ; width -= 8)
+ {
+ b = 0;
+ mask = 0x80;
+ for(i = 0 ; i < 8 ; i++)
+ {
+ c = *dwBuf++ & 0x00ffffff;
+ if(c == 0x00ffffff || c == fore)
+ b |= mask;
+ mask >>= 1;
+ }
+ *dst++ = b;
+ }
+
+ /* last partial byte, if any */
+ if(width)
+ {
+ b = *dst;
+ mask = 0x80;
+ while(width--)
+ {
+ c = *dwBuf++ & 0x00ffffff;
+ if(c == 0x00ffffff || c == fore)
+ b |= mask;
+ else
+ b &= !mask;
+ mask >>= 1;
+ }
+ *dst = b;
+ }
+ return TRUE;
+}
diff --git a/dlls/winedib.drv/primitives_font.c b/dlls/winedib.drv/primitives_font.c
new file mode 100644
index 0000000..dd1d64b
--- /dev/null
+++ b/dlls/winedib.drv/primitives_font.c
@@ -0,0 +1,310 @@
+/*
+ * DIB Engine Font Primitives
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* ------------------------------------------------------------*/
+/* FREETYPE FONT BITMAP BLITTING */
+void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+ DWORD *ptr;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ ptr = (DWORD *)((BYTE *)dib->bits + (dibY * dib->stride) + x * 4);
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ *ptr = c;
+ }
+ buf++;
+ ptr++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
+
+void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp)
+{
+ /* FIXME : MUST BE OPTIMIZED !!! */
+
+ DIBDRVBITMAP *dib = &physDev->physBitmap;
+ int bmpX, bmpY;
+ BYTE *buf;
+ int dibX, dibY;
+ int DIBX, DIBY;
+ DWORD c;
+
+ /* gets DIB limits */
+ DIBX = dib->width;
+ DIBY = dib->height;
+
+ /* loop for every pixel in bitmap */
+ buf = bmp->buffer;
+ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++)
+ {
+ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++)
+ {
+ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf)
+ {
+ c = physDev->textColorTable[*buf];
+ dib->funcs->SetPixel(dib, dibX, dibY, 0, c);
+ }
+ buf++;
+ }
+ }
+}
diff --git a/dlls/winedib.drv/primitives_line.c b/dlls/winedib.drv/primitives_line.c
new file mode 100644
index 0000000..af41e2d
--- /dev/null
+++ b/dlls/winedib.drv/primitives_line.c
@@ -0,0 +1,434 @@
+/*
+ * DIB Engine line Primitives
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* ------------------------------------------------------------*/
+/* HORIZONTAL LINES */
+void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
+{
+ DWORD *ptr;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ for(i = start; i < end; i++)
+ _DIBDRV_rop32(ptr++, and, xor);
+}
+
+void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+ BYTE and_bytes[3], xor_bytes[3];
+
+ and_bytes[0] = and & 0xff;
+ and_bytes[1] = (and >> 8) & 0xff;
+ and_bytes[2] = (and >> 16) & 0xff;
+ xor_bytes[0] = xor & 0xff;
+ xor_bytes[1] = (xor >> 8) & 0xff;
+ xor_bytes[2] = (xor >> 16) & 0xff;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr++, and_bytes[0], xor_bytes[0]);
+ _DIBDRV_rop8(ptr++, and_bytes[1], xor_bytes[1]);
+ _DIBDRV_rop8(ptr++, and_bytes[2], xor_bytes[2]);
+ }
+}
+
+void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
+{
+ WORD *ptr;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ for(i = start; i < end; i++)
+ _DIBDRV_rop16(ptr++, and, xor);
+}
+
+void _DIBDRV_SolidHLine8(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ for(i = start; i < end; i++)
+ _DIBDRV_rop8(ptr++, and, xor);
+}
+
+void _DIBDRV_SolidHLine4(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+ BYTE byte_and, byte_xor;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+ byte_and = (and & 0xf) | ((and << 4) & 0xf0);
+ byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
+
+ if(start & 1) /* upper nibble untouched */
+ _DIBDRV_rop8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
+
+ for(i = (start + 1) / 2; i < end / 2; i++)
+ _DIBDRV_rop8(ptr++, byte_and, byte_xor);
+
+ if(end & 1) /* lower nibble untouched */
+ _DIBDRV_rop8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
+}
+
+void _DIBDRV_SolidHLine1(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+ BYTE byte_and = 0, byte_xor = 0, mask;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ if(and & 1) byte_and = 0xff;
+ if(xor & 1) byte_xor = 0xff;
+
+ if((start & ~7) == (end & ~7)) /* special case run inside one byte */
+ {
+ mask = ((1L << ((end & 7) - (start & 7))) - 1) << (8 - (end & 7));
+ _DIBDRV_rop8(ptr, byte_and | ~mask, byte_xor & mask);
+ return;
+ }
+
+ if(start & 7)
+ {
+ mask = (1 << (8 - (start & 7))) - 1;
+ _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask);
+ }
+
+ for(i = (start + 7) / 8; i < end / 8; i++)
+ _DIBDRV_rop8(ptr++, byte_and, byte_xor);
+
+ if(end & 7)
+ {
+ mask = ~((1 << (8 - (end & 7))) - 1);
+ _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask);
+ }
+}
+
+void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
+{
+ DWORD *ptr;
+ const DWORD *and_ptr = and, *xor_ptr = xor;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ and_ptr += offset;
+ xor_ptr += offset;
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop32(ptr++, *and_ptr++, *xor_ptr++);
+ if(++offset == count)
+ {
+ offset = 0;
+ and_ptr = and;
+ xor_ptr = xor;
+ }
+ }
+}
+
+void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
+{
+ BYTE *ptr;
+ const BYTE *and_ptr = and, *xor_ptr = xor;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ and_ptr += offset * 3;
+ xor_ptr += offset * 3;
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
+ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
+ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
+ if(++offset == count)
+ {
+ offset = 0;
+ and_ptr = and;
+ xor_ptr = xor;
+ }
+ }
+}
+
+void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
+{
+ WORD *ptr;
+ const WORD *and_ptr = and, *xor_ptr = xor;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ and_ptr += offset;
+ xor_ptr += offset;
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop16(ptr++, *and_ptr++, *xor_ptr++);
+ if(++offset == count)
+ {
+ offset = 0;
+ and_ptr = and;
+ xor_ptr = xor;
+ }
+ }
+}
+
+void _DIBDRV_PatternHLine8(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
+{
+ BYTE *ptr;
+ const BYTE *and_ptr = and, *xor_ptr = xor;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ and_ptr += offset;
+ xor_ptr += offset;
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
+ if(++offset == count)
+ {
+ offset = 0;
+ and_ptr = and;
+ xor_ptr = xor;
+ }
+ }
+}
+
+void _DIBDRV_PatternHLine4(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
+{
+ BYTE *ptr;
+ const BYTE *and_ptr = and, *xor_ptr = xor;
+ int i;
+ BYTE byte_and, byte_xor;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ and_ptr += offset / 2;
+ xor_ptr += offset / 2;
+
+ for(i = start; i < end; i++)
+ {
+ if(offset & 1)
+ {
+ byte_and = *and_ptr++ & 0x0f;
+ byte_xor = *xor_ptr++ & 0x0f;
+ }
+ else
+ {
+ byte_and = (*and_ptr & 0xf0) >> 4;
+ byte_xor = (*xor_ptr & 0xf0) >> 4;
+ }
+
+ if(i & 1)
+ byte_and |= 0xf0;
+ else
+ {
+ byte_and = (byte_and << 4) | 0x0f;
+ byte_xor <<= 4;
+ }
+
+ _DIBDRV_rop8(ptr, byte_and, byte_xor);
+
+ if(i & 1) ptr++;
+
+ if(++offset == count)
+ {
+ offset = 0;
+ and_ptr = and;
+ xor_ptr = xor;
+ }
+ }
+}
+
+void _DIBDRV_PatternHLine1(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
+{
+ BYTE *ptr;
+ const BYTE *and_ptr = and, *xor_ptr = xor;
+ int i;
+ BYTE byte_and, byte_xor, dst_mask, brush_mask;
+
+ ptr = dib->funcs->GetPixelPointer(dib, start, row);
+
+ and_ptr += offset / 8;
+ xor_ptr += offset / 8;
+
+ for(i = start; i < end; i++)
+ {
+ dst_mask = 1 << (7 - (i & 7));
+ brush_mask = 1 << (7 - (offset & 7));
+
+ byte_and = (*and_ptr & brush_mask) ? 0xff : 0;
+ byte_xor = (*xor_ptr & brush_mask) ? 0xff : 0;
+
+ byte_and |= ~dst_mask;
+ byte_xor &= dst_mask;
+
+ _DIBDRV_rop8(ptr, byte_and, byte_xor);
+
+ if((i & 7) == 7) ptr++;
+ if(++offset == count)
+ {
+ offset = 0;
+ and_ptr = and;
+ xor_ptr = xor;
+ }
+ else if((offset & 7) == 7)
+ {
+ and_ptr++;
+ xor_ptr++;
+ }
+ }
+}
+
+/* ------------------------------------------------------------*/
+/* VERTICAL LINES */
+void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, col, start);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop32((DWORD*)ptr, and, xor);
+ ptr += dib->stride;
+ }
+}
+
+void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+ BYTE and_bytes[3], xor_bytes[3];
+
+ and_bytes[0] = and & 0xff;
+ and_bytes[1] = (and >> 8) & 0xff;
+ and_bytes[2] = (and >> 16) & 0xff;
+ xor_bytes[0] = xor & 0xff;
+ xor_bytes[1] = (xor >> 8) & 0xff;
+ xor_bytes[2] = (xor >> 16) & 0xff;
+
+ ptr = dib->funcs->GetPixelPointer(dib, col, start);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr, and_bytes[0], xor_bytes[0]);
+ _DIBDRV_rop8(ptr + 1, and_bytes[1], xor_bytes[1]);
+ _DIBDRV_rop8(ptr + 2, and_bytes[2], xor_bytes[2]);
+ ptr += dib->stride;
+ }
+}
+
+void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, col, start);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop16((WORD*)ptr, and, xor);
+ ptr += dib->stride;
+ }
+}
+
+void _DIBDRV_SolidVLine8(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+
+ ptr = dib->funcs->GetPixelPointer(dib, col, start);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr, and, xor);
+ ptr += dib->stride;
+ }
+}
+
+void _DIBDRV_SolidVLine4(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+ BYTE byte_and, byte_xor;
+
+ if(col & 1) /* upper nibble untouched */
+ {
+ byte_and = (and & 0xf) | 0xf0;
+ byte_xor = (xor & 0xf);
+ }
+ else
+ {
+ byte_and = ((and << 4) & 0xf0) | 0x0f;
+ byte_xor = ((xor << 4) & 0xf0);
+ }
+
+ ptr = dib->funcs->GetPixelPointer(dib, col, start);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr, byte_and, byte_xor);
+ ptr += dib->stride;
+ }
+}
+
+void _DIBDRV_SolidVLine1(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ int i;
+ BYTE byte_and = 0, byte_xor = 0, mask;
+
+ if(and & 1) byte_and = 0xff;
+ if(xor & 1) byte_xor = 0xff;
+
+ mask = 1 << (7 - (col & 7));
+
+ byte_and |= ~mask;
+ byte_xor &= mask;
+
+ ptr = dib->funcs->GetPixelPointer(dib, col, start);
+
+ for(i = start; i < end; i++)
+ {
+ _DIBDRV_rop8(ptr, byte_and, byte_xor);
+ ptr += dib->stride;
+ }
+}
diff --git a/dlls/winedib.drv/primitives_pixel.c b/dlls/winedib.drv/primitives_pixel.c
new file mode 100644
index 0000000..ca68cf1
--- /dev/null
+++ b/dlls/winedib.drv/primitives_pixel.c
@@ -0,0 +1,244 @@
+/*
+ * DIB Engine pixel Primitives
+ *
+ * Copyright 2009 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+
+/* ------------------------------------------------------------*/
+/* BITFIELD HELPERS */
+static 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)
+{
+ BYTE *ptr = dib->bits;
+
+ ptr += (y * dib->stride);
+
+ ptr += x * 4;
+ return ptr;
+}
+
+void *_DIBDRV_GetPixelPointer24(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->bits;
+
+ ptr += (y * dib->stride);
+
+ ptr += x * 3;
+ return ptr;
+}
+
+void *_DIBDRV_GetPixelPointer16(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->bits;
+
+ ptr += (y * dib->stride);
+
+ ptr += x * 2;
+ return ptr;
+}
+
+void *_DIBDRV_GetPixelPointer8(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->bits;
+
+ ptr += (y * dib->stride);
+
+ ptr += x;
+ return ptr;
+}
+
+void *_DIBDRV_GetPixelPointer4(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->bits;
+
+ ptr += (y * dib->stride);
+
+ ptr += x / 2;
+ return ptr;
+}
+
+void *_DIBDRV_GetPixelPointer1(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->bits;
+
+ ptr += (y * dib->stride);
+
+ ptr += x / 8;
+ return ptr;
+}
+
+/* ------------------------------------------------------------*/
+/* PIXEL WRITING */
+void _DIBDRV_SetPixel32(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
+{
+ DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
+ _DIBDRV_rop32(ptr, and, xor);
+}
+
+void _DIBDRV_SetPixel24(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
+{
+ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
+ _DIBDRV_rop8(ptr, and & 0xff, xor & 0xff);
+ _DIBDRV_rop8(ptr + 1, (and >> 8) & 0xff, (xor >> 8) & 0xff);
+ _DIBDRV_rop8(ptr + 2, (and >> 16) & 0xff, (xor >> 16) & 0xff);
+}
+
+void _DIBDRV_SetPixel16(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
+{
+ WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y);
+ _DIBDRV_rop16(ptr, and, xor);
+}
+
+void _DIBDRV_SetPixel8(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
+{
+ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
+ _DIBDRV_rop8(ptr, and, xor);
+}
+
+void _DIBDRV_SetPixel4(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
+{
+ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y);
+ BYTE byte_and, byte_xor;
+
+ if(x & 1) /* upper nibble untouched */
+ {
+ byte_and = (and & 0xf) | 0xf0;
+ byte_xor = (xor & 0xf);
+ }
+ else
+ {
+ byte_and = ((and << 4) & 0xf0) | 0x0f;
+ byte_xor = ((xor << 4) & 0xf0);
+ }
+
+ _DIBDRV_rop8(ptr, byte_and, byte_xor);
+}
+
+void _DIBDRV_SetPixel1(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor)
+{
+ BYTE *ptr;
+ BYTE byte_and = 0, byte_xor = 0, mask;
+
+ if(and & 1) byte_and = 0xff;
+ if(xor & 1) byte_xor = 0xff;
+
+ mask = 1 << (7 - (x & 7));
+
+ byte_and |= ~mask;
+ byte_xor &= mask;
+
+ ptr = dib->funcs->GetPixelPointer(dib, x, y);
+
+ _DIBDRV_rop8(ptr, byte_and, byte_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 _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 |
+ GetField32(*ptr, dib->greenShift, dib->greenLen) << 8 |
+ GetField32(*ptr, dib->blueShift, dib->blueLen);
+}
+
+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];
+}
+
+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);
+}
+
+DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y)
+{
+ WORD *ptr = 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);
+}
+
+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;
+}
+
+DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y), pix;
+ RGBQUAD *color;
+
+ if(x & 1)
+ pix = *ptr & 0x0f;
+ else
+ pix = *ptr >> 4;
+
+ color = dib->colorTable + pix;
+ return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue;
+}
+
+DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y)
+{
+ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y), pix;
+ RGBQUAD *color;
+
+ pix = *ptr;
+
+ pix >>= (7 - (x & 7));
+ pix &= 1;
+
+ color = dib->colorTable + pix;
+ return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue;
+}
diff --git a/dlls/winedib.drv/primitives_rop2.c b/dlls/winedib.drv/primitives_rop2.c
new file mode 100644
index 0000000..b23e919
--- /dev/null
+++ b/dlls/winedib.drv/primitives_rop2.c
@@ -0,0 +1,112 @@
+/*
+ * DIB Engine ROP2 Primitives
+ *
+ * Copyright 2008 Huw Davies
+ * Copyright 2008 Massimo Del Fedele
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* ------------------------------------------------------------*/
+/* BASIC ROP HELPER */
+/*
+ *
+ * Decompose the 16 ROP2s into an expression of the form
+ *
+ * D = (D & A) ^ X
+ *
+ * Where A and X depend only on P (and so can be precomputed).
+ *
+ * A X
+ *
+ * R2_BLACK 0 0 0
+ * R2_NOTMERGEPEN ~(D | P) ~P ~P
+ * R2_MASKNOTPEN ~P & D ~P 0
+ * R2_NOTCOPYPEN ~P 0 ~P
+ * R2_MASKPENNOT P & ~D P P
+ * R2_NOT ~D 1 1
+ * R2_XORPEN P ^ D 1 P
+ * R2_NOTMASKPEN ~(P & D) P 1
+ * R2_MASKPEN P & D P 0
+ * R2_NOTXORPEN ~(P ^ D) 1 ~P
+ * R2_NOP D 1 0
+ * R2_MERGENOTPEN ~P | D P ~P
+ * R2_COPYPEN P 0 P
+ * R2_MERGEPENNOT P | ~D ~P 1
+ * R2_MERGEPEN P | D ~P P
+ * R2_WHITE 1 0 1
+ *
+ */
+
+/* A = (P & A1) | (~P & A2) */
+#define ZERO {0, 0}
+#define ONE {0xffffffff, 0xffffffff}
+#define P {0xffffffff, 0}
+#define NOT_P {0, 0xffffffff}
+
+static const DWORD rop2_and_array[16][2] =
+{
+ ZERO, NOT_P, NOT_P, ZERO,
+ P, ONE, ONE, P,
+ P, ONE, ONE, P,
+ ZERO, NOT_P, NOT_P, ZERO
+};
+
+/* X = (P & X1) | (~P & X2) */
+static const DWORD rop2_xor_array[16][2] =
+{
+ ZERO, NOT_P, ZERO, NOT_P,
+ P, ONE, P, ONE,
+ ZERO, NOT_P, ZERO, NOT_P,
+ P, ONE, P, ONE
+};
+
+#undef NOT_P
+#undef P
+#undef ONE
+#undef ZERO
+
+void _DIBDRV_CalcAndXorMasks(INT rop, DWORD color, DWORD *and, DWORD *xor)
+{
+ /* NB The ROP2 codes start at one and the arrays are zero-based */
+ rop = (rop - 1) & 0x0f;
+ *and = (color & rop2_and_array[rop][0]) | ((~color) & rop2_and_array[rop][1]);
+ *xor = (color & rop2_xor_array[rop][0]) | ((~color) & rop2_xor_array[rop][1]);
+}
+
+/* ------------------------------------------------------------*/
+/* ROP PIXEL FUNCTIONS */
+
+inline void _DIBDRV_rop32(DWORD *ptr, DWORD and, DWORD xor)
+{
+ *ptr = (*ptr & and) ^ xor;
+}
+
+inline void _DIBDRV_rop16(WORD *ptr, WORD and, WORD xor)
+{
+ *ptr = (*ptr & and) ^ xor;
+}
+
+inline void _DIBDRV_rop8(BYTE *ptr, BYTE and, BYTE xor)
+{
+ *ptr = (*ptr & and) ^ xor;
+}
diff --git a/dlls/winedib.drv/primitives_rop3.c b/dlls/winedib.drv/primitives_rop3.c
new file mode 100644
index 0000000..398258b
--- /dev/null
+++ b/dlls/winedib.drv/primitives_rop3.c
@@ -0,0 +1,786 @@
+#include "config.h"
+#include "wine/port.h"
+
+#include "dibdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+
+/* the ROP3 operations
+ this is a BIG case block; beware that some
+ commons ROP3 operations will be optimized
+ from inside blt routines */
+DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop)
+{
+ switch(rop)
+ {
+ case 0x00: /* 0 BLACKNESS */
+ return 0;
+
+ case 0x01: /* DPSoon */
+ return (~(p | s | d)) & 0x00ffffff;
+
+ case 0x02: /* DPSona */
+ return (d & ~(p | s)) & 0x00ffffff;
+
+ case 0x03: /* PSon */
+ return (~(p | s)) & 0x00ffffff;
+
+ case 0x04: /* SDPona */
+ return (s & ~(d | p)) & 0x00ffffff;
+
+ case 0x05: /* DPon */
+ return (~(d | p)) & 0x00ffffff;
+
+ case 0x06: /* PDSxnon */
+ return (~(p | ~(d ^ s))) & 0x00ffffff;
+
+ case 0x07: /* PDSaon */
+ return (~((d & s) | p) ) & 0x00ffffff;
+
+ case 0x08: /* SDPnaa */
+ return (d & ~p & s) & 0x00ffffff;
+
+ case 0x09: /* PDSxon */
+ return (~((d ^ s) | p)) & 0x00ffffff;
+
+ case 0x0A: /* DPna */
+ return (~p & d) & 0x00ffffff;
+
+ case 0x0B: /* PSDnaon */
+ return (~((~d & s) | p)) & 0x00ffffff;
+
+ case 0x0C: /* SPna */
+ return (~p & s) & 0x00ffffff;
+
+ case 0x0D: /* PDSnaon */
+ return (~((~s & d) | p)) & 0x00ffffff;
+
+ case 0x0E: /* PDSonon */
+ return (~(~(d | s) | p)) & 0x00ffffff;
+
+ case 0x0F: /* Pn */
+ return (~p) & 0x00ffffff;
+
+ case 0x10: /* PDSona */
+ return (~(d | s) & p) & 0x00ffffff;
+
+ case 0x11: /* DSon NOTSRCERASE */
+ return (~(d | s)) & 0x00ffffff;
+
+ case 0x12: /* SDPxnon */
+ return (~(~(d ^ p) | s)) & 0x00ffffff;
+
+ case 0x13: /* SDPaon */
+ return (~((d & p) | s)) & 0x00ffffff;
+
+ case 0x14: /* DPSxnon */
+ return (~(~(p ^ s) | d)) & 0x00ffffff;
+
+ case 0x15: /* DPSaon */
+ return (~((p & s) | d)) & 0x00ffffff;
+
+ case 0x16: /* PSDPSanaxx */
+ return (((~(p & s) & d) ^ s) ^ p) & 0x00ffffff;
+
+ case 0x17: /* SSPxDSxaxn */
+ return (~(((d ^ s) & (s ^ p)) ^ s)) & 0x00ffffff;
+
+ case 0x18: /* SPxPDxa */
+ return ((s ^ p) & (p ^ d)) & 0x00ffffff;
+
+ case 0x19: /* SDPSanaxn */
+ return (~((~(p & s) & d) ^ s)) & 0x00ffffff;
+
+ case 0x1A: /* PDSPaox */
+ return (((s & p) | d) ^ p) & 0x00ffffff;
+
+ case 0x1B: /* SDPSxaxn */
+ return (~(((p ^ s) & d) ^ s)) & 0x00ffffff;
+
+ case 0x1C: /* PSDPaox */
+ return (((d & p) | s) ^ p) & 0x00ffffff;
+
+ case 0x1D: /* DSPDxaxn */
+ return (~(((p ^ d) & s) ^ d)) & 0x00ffffff;
+
+ case 0x1E: /* PDSox */
+ return ((d | s) ^ p) & 0x00ffffff;
+
+ case 0x1F: /* PDSoan */
+ return (~((d | s) & p)) & 0x00ffffff;
+
+ case 0x20: /* DPSnaa */
+ return (p & ~s & d) & 0x00ffffff;
+
+ case 0x21: /* SDPxon */
+ return (~((d ^ p) | s)) & 0x00ffffff;
+
+ case 0x22: /* DSna */
+ return (d & ~s) & 0x00ffffff;
+
+ case 0x23: /* SPDnaon */
+ return (~((p & ~d) | s)) & 0x00ffffff;
+
+ case 0x24: /* SPxDSxa */
+ return ((s ^ p) & (d ^ s)) & 0x00ffffff;
+
+ case 0x25: /* PDSPanaxn */
+ return (~((~(s & p) & d) ^ p)) & 0x00ffffff;
+
+ case 0x26: /* SDPSaox */
+ return (((p & s) | d) ^ s) & 0x00ffffff;
+
+ case 0x27: /* SDPSxnox */
+ return ((~(p ^ s) | d) ^ s) & 0x00ffffff;
+
+ case 0x28: /* DPSxa */
+ return ((p ^ s) & d) & 0x00ffffff;
+
+ case 0x29: /* PSDPSaoxxn */
+ return (~((((p & s) | d) ^ s) ^ p)) & 0x00ffffff;
+
+ case 0x2A: /* DPSana */
+ return (~(p & s) & d) & 0x00ffffff;
+
+ case 0x2B: /* SSPxPDxaxn */
+ return (~(((s ^ p) & (p ^ d)) ^ s)) & 0x00ffffff;
+
+ case 0x2C: /* SPDSoax */
+ return (((d | s) & p) ^ s) & 0x00ffffff;
+
+ case 0x2D: /* PSDnox */
+ return ((s | ~d) ^ p) & 0x00ffffff;
+
+ case 0x2E: /* PSDPxox */
+ return (((d ^ p) | s) ^ p) & 0x00ffffff;
+
+ case 0x2F: /* PSDnoan */
+ return (~((s | ~d) & p)) & 0x00ffffff;
+
+ case 0x30: /* PSna */
+ return (p & ~s) & 0x00ffffff;
+
+ case 0x31: /* SDPnaon */
+ return (~((d & ~p) | s)) & 0x00ffffff;
+
+ case 0x32: /* SDPSoox */
+ return ((p | s | d) ^ s) & 0x00ffffff;
+
+ case 0x33: /* Sn NOTSRCCOPY */
+ return (~s) & 0x00ffffff;
+
+ case 0x34: /* SPDSaox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x35: /* SPDSxnox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x36: /* SDPox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x37: /* SDPoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x38: /* PSDPoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x39: /* SPDnox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x3A: /* SPDSxox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x3B: /* SPDnoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x3C: /* PSx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x3D: /* SPDSonox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x3E: /* SPDSnaox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x3F: /* PSan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x40: /* PSDnaa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x41: /* DPSxon */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x42: /* SDxPDxa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x43: /* SPDSanaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x44: /* SDna SRCERASE */
+ return (s & ~d) & 0x00ffffff;
+
+ case 0x45: /* DPSnaon */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x46: /* DSPDaox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x47: /* PSDPxaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x48: /* SDPxa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x49: /* PDSPDaoxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x4A: /* DPSDoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x4B: /* PDSnox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x4C: /* SDPana */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x4D: /* SSPxDSxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x4E: /* PDSPxox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x4F: /* PDSnoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x50: /* PDna */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x51: /* DSPnaon */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x52: /* DPSDaox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x53: /* SPDSxaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x54: /* DPSonon */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x55: /* Dn DSTINVERT */
+ return (~d) & 0x00ffffff;
+
+ case 0x56: /* DPSox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x57: /* DPSoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x58: /* PDSPoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x59: /* DPSnox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x5A: /* DPx PATINVERT */
+ return (d ^ p) & 0x00ffffff;
+
+ case 0x5B: /* DPSDonox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x5C: /* DPSDxox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x5D: /* DPSnoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x5E: /* DPSDnaox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x5F: /* DPan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x60: /* PDSxa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x61: /* DSPDSaoxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x62: /* DSPDoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x63: /* SDPnox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x64: /* SDPSoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x65: /* DSPnox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x66: /* DSx SRCINVERT */
+ return (d ^ s) & 0x00ffffff;
+
+ case 0x67: /* SDPSonox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x68: /* DSPDSonoxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x69: /* PDSxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x6A: /* DPSax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x6B: /* PSDPSoaxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x6C: /* SDPax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x6D: /* PDSPDoaxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x6E: /* SDPSnoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x6F: /* PDSxnan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x70: /* PDSana */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x71: /* SSDxPDxaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x72: /* SDPSxox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x73: /* SDPnoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x74: /* DSPDxox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x75: /* DSPnoan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x76: /* SDPSnaox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x77: /* DSan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x78: /* PDSax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x79: /* DSPDSoaxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x7A: /* DPSDnoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x7B: /* SDPxnan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x7C: /* SPDSnoax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x7D: /* DPSxnan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x7E: /* SPxDSxo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x7F: /* DPSaan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x80: /* DPSaa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x81: /* SPxDSxon */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x82: /* DPSxna */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x83: /* SPDSnoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x84: /* SDPxna */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x85: /* PDSPnoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x86: /* DSPDSoaxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x87: /* PDSaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x88: /* DSa SRCAND */
+ return (d & s) & 0x00ffffff;
+
+ case 0x89: /* SDPSnaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x8A: /* DSPnoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x8B: /* DSPDxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x8C: /* SDPnoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x8D: /* SDPSxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x8E: /* SSDxPDxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x8F: /* PDSanan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x90: /* PDSxna */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x91: /* SDPSnoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x92: /* DPSDPoaxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x93: /* SPDaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x94: /* PSDPSoaxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x95: /* DPSaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x96: /* DPSxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x97: /* PSDPSonoxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x98: /* SDPSonoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x99: /* DSxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x9A: /* DPSnax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x9B: /* SDPSoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x9C: /* SPDnax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x9D: /* DSPDoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x9E: /* DSPDSaoxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0x9F: /* PDSxan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA0: /* DPa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA1: /* PDSPnaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA2: /* DPSnoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA3: /* DPSDxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA4: /* PDSPonoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA5: /* PDxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA6: /* DSPnax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA7: /* PDSPoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA8: /* DPSoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xA9: /* DPSoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xAA: /* D */
+ return (d) & 0x00ffffff;
+
+ case 0xAB: /* DPSono */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xAC: /* SPDSxax */
+ return (s ^ (p & (d ^ s))) & 0x00ffffff;
+
+ case 0xAD: /* DPSDaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xAE: /* DSPnao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xAF: /* DPno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB0: /* PDSnoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB1: /* PDSPxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB2: /* SSPxDSxox */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB3: /* SDPanan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB4: /* PSDnax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB5: /* DPSDoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB6: /* DPSDPaoxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB7: /* SDPxan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB8: /* PSDPxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xB9: /* DSPDaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xBA: /* DPSnao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xBB: /* DSno MERGEPAINT */
+ return (d | ~s) & 0x00ffffff;
+
+ case 0xBC: /* SPDSanax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xBD: /* SDxPDxan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xBE: /* DPSxo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xBF: /* DPSano */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC0: /* PSa MERGECOPY */
+ return (p & s) & 0x00ffffff;
+
+ case 0xC1: /* SPDSnaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC2: /* SPDSonoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC3: /* PSxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC4: /* SPDnoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC5: /* SPDSxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC6: /* SDPnax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC7: /* PSDPoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC8: /* SDPoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xC9: /* SPDoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xCA: /* DPSDxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xCB: /* SPDSaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ default:
+ case 0xCC: /* S SRCCOPY */
+ return (s) & 0x00ffffff;
+
+ case 0xCD: /* SDPono */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xCE: /* SDPnao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xCF: /* SPno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD0: /* PSDnoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD1: /* PSDPxoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD2: /* PDSnax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD3: /* SPDSoaxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD4: /* SSPxPDxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD5: /* DPSanan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD6: /* PSDPSaoxx */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD7: /* DPSxan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD8: /* PDSPxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xD9: /* SDPSaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xDA: /* DPSDanax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xDB: /* SPxDSxan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xDC: /* SPDnao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xDD: /* SDno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xDE: /* SDPxo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xDF: /* SDPano */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE0: /* PDSoa */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE1: /* PDSoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE2: /* DSPDxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE3: /* PSDPaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE4: /* SDPSxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE5: /* PDSPaoxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE6: /* SDPSanax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE7: /* SPxPDxan */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE8: /* SSPxDSxax */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xE9: /* DSPDSanaxxn */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xEA: /* DPSao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xEB: /* DPSxno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xEC: /* SDPao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xED: /* SDPxno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xEE: /* DSo SRCPAINT */
+ return (d | s) & 0x00ffffff;
+
+ case 0xEF: /* SDPnoo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF0: /* P PATCOPY */
+ return (p) & 0x00ffffff;
+
+ case 0xF1: /* PDSono */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF2: /* PDSnao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF3: /* PSno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF4: /* PSDnao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF5: /* PDno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF6: /* PDSxo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF7: /* PDSano */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF8: /* PDSao */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xF9: /* PDSxno */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xFA: /* DPo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xFB: /* DPSnoo PATPAINT */
+ return (p | ~s | d) & 0x00ffffff;
+
+ case 0xFC: /* PSo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xFD: /* PSDnoo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xFE: /* DPSoo */
+ return (0x123456) & 0x00ffffff;
+
+ case 0xFF: /* 1 WHITENESS */
+ return 0x00ffffff;
+
+ } /* switch */
+}
diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c
index 0176011..e2cea0c 100644
--- a/dlls/winedib.drv/text.c
+++ b/dlls/winedib.drv/text.c
@@ -25,6 +25,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
+/* converts font sizes from Word space to Device space */
+static void FontSizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h)
+{
+ POINT pts[2];
+ pts[0].x = 0;
+ pts[0].y = 0;
+ pts[1].x = abs(*w);
+ pts[1].y = abs(*h);
+ LPtoDP(physDev->hdc, pts, 2);
+ *w = pts[1].x - pts[0].x;
+ *h = pts[1].y - pts[0].y;
+}
+
/***********************************************************************
* DIBDRV_ExtTextOut
*/
@@ -32,17 +45,163 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags,
const RECT *lprect, LPCWSTR wstr, UINT count,
const INT *lpDx )
{
+ /* FIXME : TODO many, many stuffs... just trivial text support by now */
+
BOOL res;
+ FT_Face face;
+ FT_UInt glyph_index;
+ INT n;
+ INT error;
+ LOGFONTW lf;
+ int w, h;
+ LPCWSTR wstrPnt;
+
+ FT_Glyph glyph;
+ FT_BitmapGlyph bitmap;
+ double cosEsc, sinEsc;
+ FT_Matrix matrix;
+ FT_Vector start;
+ int dx, dy;
- TRACE("physDev:%p, x:%d, y:%d, flags:%x, lprect:%p, wstr:%s, count:%d, lpDx:%p\n",
- physDev, x, y, flags, lprect, debugstr_w(wstr), count, lpDx);
+
+ MAYBE(TRACE("physDev:%p, x:%d, y:%d, flags:%x, lprect:%p, wstr:%s, count:%d, lpDx:%p\n",
+ physDev, x, y, flags, lprect, debugstr_w(wstr), count, lpDx));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect,
- wstr, count, lpDx);
+
+ face = physDev->face;
+ if(!face)
+ {
+ ERR("FreeType face is null\n");
+ res = FALSE;
+ goto fin;
+ }
+
+ /* outputs the string in case it is given by glyph indexes
+ make locating it in logs much easier */
+ if(TRACE_ON(dibdrv) && flags & ETO_GLYPH_INDEX)
+ {
+ WCHAR a = 'A';
+ WCHAR *str = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*(count+1));
+ int delta = a - pFT_Get_Char_Index( face, a);
+ int i;
+ memcpy(str, wstr, sizeof(WCHAR)*count);
+ for(i = 0; str[i] && i < count; i++)
+ str[i] += delta;
+ TRACE("String: '%s'\n", debugstr_w(str));
+ HeapFree(GetProcessHeap(), 0, str);
+ }
+
+ /* gets font data, etc */
+ GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
+
+ /* convert sizes to device space */
+ w = lf.lfWidth; h = lf.lfHeight;
+ FontSizes_ws2ds(physDev, &w, &h);
+
+ /* if opaque, paint the font background */
+/*
+ if(flags | ETO_OPAQUE)
+ {
+ int iLine;
+ for(iLine = lprect->top; iLine < lprect->bottom; iLine++)
+ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap,
+ lprect->left, lprect->right-1, iLine, 0, physDev->backgroundColor);
+ }
+*/
+ /* sets character pixel size */
+ error = pFT_Set_Pixel_Sizes(
+ face,
+ MulDiv(w, 96, DIBDRV_GetDeviceCaps(physDev, LOGPIXELSX)),
+ MulDiv(h, 96, DIBDRV_GetDeviceCaps(physDev, LOGPIXELSY))
+ );
+ if(error)
+ ERR("Couldn't set char size to (%d,%d)\n", lf.lfWidth, lf.lfHeight);
+
+ /* transformation matrix and vector */
+ start.x = 0;
+ start.y = 0;
+ if(lf.lfEscapement != 0)
+ {
+ cosEsc = cos(lf.lfEscapement * M_PI / 1800);
+ sinEsc = sin(lf.lfEscapement * M_PI / 1800);
+ }
+ else
+ {
+ cosEsc = 1;
+ sinEsc = 0;
+ }
+ matrix.xx = (FT_Fixed)( cosEsc * 0x10000L );
+ matrix.xy = (FT_Fixed)(-sinEsc * 0x10000L );
+ matrix.yx = (FT_Fixed)( sinEsc * 0x10000L );
+ matrix.yy = (FT_Fixed)( cosEsc * 0x10000L );
+
+ /* outputs characters one by one */
+ wstrPnt = wstr;
+ for ( n = 0; n < count; n++ )
+ {
+ /* retrieve glyph index from character code */
+ if(flags & ETO_GLYPH_INDEX)
+ glyph_index = *wstrPnt++;
+ else
+ glyph_index = pFT_Get_Char_Index( face, *wstrPnt++);
+
+ /* load glyph image into the slot (erase previous one) */
+ error = pFT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT );
+ if(error)
+ {
+ ERR("Couldn't load glyph at index %d\n", glyph_index);
+ /* ignore errors */
+ continue;
+ }
+ error = pFT_Get_Glyph(face->glyph, &glyph);
+ if ( error )
+ {
+ FIXME("Couldn't get glyph\n");
+ continue;
+ }
+
+ /* apply transformation to glyph */
+ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ pFT_Glyph_Transform(glyph, &matrix, &start );
+
+ /* gets advance BEFORE transforming... */
+ dx = glyph->advance.x;
+ dy = glyph->advance.y;
+
+ /* convert to an anti-aliased bitmap, if needed */
+ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
+ {
+ error = pFT_Glyph_To_Bitmap(
+ &glyph,
+ FT_RENDER_MODE_NORMAL,
+ 0, /* no additional translation */
+ 1 /* destroy copy in "image" */
+ );
+
+ /* ignore errors */
+ if ( error )
+ {
+ FIXME("Couldn't render glyph\n");
+ pFT_Done_Glyph(glyph);
+ continue;
+ }
+ }
+
+ /* now, draw to our target surface */
+ bitmap = (FT_BitmapGlyph)glyph;
+ physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmap->left, y-bitmap->top, &bitmap->bitmap);
+
+ /* increment pen position */
+ x += dx>>16;
+ y -= dy>>16;
+
+ pFT_Done_Glyph(glyph);
+
+ res = TRUE;
+ }
}
else
{
@@ -50,6 +209,7 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags,
res = _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect,
wstr, count, lpDx);
}
+fin:
return res;
}
@@ -61,15 +221,14 @@ BOOL DIBDRV_GetTextExtentExPoint( DIBDRVPHYSDEV *physDev, LPCWSTR str, INT count
{
BOOL res;
- TRACE("physDev:%p, str:%s, count:%d, maxExt:%d, lpnFit:%p, alpDx:%p, size:%p\n",
- physDev, debugstr_w(str), count, maxExt, lpnFit, alpDx, size);
+ MAYBE(TRACE("physDev:%p, str:%s, count:%d, maxExt:%d, lpnFit:%p, alpDx:%p, size:%p\n",
+ physDev, debugstr_w(str), count, maxExt, lpnFit, alpDx, size));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pGetTextExtentExPoint(physDev->X11PhysDev, str, count, maxExt,
- lpnFit, alpDx, size);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{
diff --git a/dlls/winedib.drv/video.c b/dlls/winedib.drv/video.c
index 730e62a..9892d69 100644
--- a/dlls/winedib.drv/video.c
+++ b/dlls/winedib.drv/video.c
@@ -32,7 +32,7 @@ BOOL DIBDRV_GetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp )
{
BOOL res;
- TRACE("physDev:%p, ramp:%p\n", physDev, ramp);
+ MAYBE(TRACE("physDev:%p, ramp:%p\n", physDev, ramp));
if(physDev->hasDIB)
{
@@ -55,13 +55,13 @@ BOOL DIBDRV_SetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp )
{
BOOL res;
- TRACE("physDev:%p, ramp:%p\n", physDev, ramp);
+ MAYBE(TRACE("physDev:%p, ramp:%p\n", physDev, ramp));
if(physDev->hasDIB)
{
/* DIB section selected in, use DIB Engine */
- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
- res = _DIBDRV_GetDisplayDriver()->pSetDeviceGammaRamp(physDev->X11PhysDev, ramp);
+ ONCE(FIXME("STUB\n"));
+ res = TRUE;
}
else
{