From 702b67c62807859bace52b5858dd8d0af3c4fc10 Mon Sep 17 00:00:00 2001 From: Massimo Del Fedele Date: Sun, 18 Jul 2010 12:26:10 +0200 Subject: [PATCH] DIB Engine: implement most engine functions --- 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 66ad14f329f..722785e67b9 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 022f2237b88..20cdcaa6cdd 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 df7c03a22d8..f3d3b9c2432 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 1ddbb1b4984..81dec252902 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 00000000000..dc18e14a47c --- /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 c8e3b91ad97..61846778022 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 28330faf320..b72c34afe66 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 8a2e139856a..773941ece8f 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 00000000000..8e4eb055b7e --- /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 28429d2f183..e4364409a14 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 00000000000..2c8c367a658 --- /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 00000000000..46fa7a149b2 --- /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 + +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 675145fbd29..215b27dff9a 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 00000000000..111a18b6980 --- /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 00000000000..93619ff93f0 --- /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 +#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 b74c08ef728..8dda082eac0 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 e8ec96cbedf..f7855f64b4e 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 9daf47dff97..148a6d5b605 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 bde2f232634..31c9cd28adf 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 00000000000..cbad239f674 --- /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 00000000000..da4835298ae --- /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 00000000000..3ccc2e0d914 --- /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 00000000000..800e3fd19b0 --- /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 00000000000..dd1d64b3fcb --- /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 00000000000..af41e2d9fba --- /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 00000000000..ca68cf16a46 --- /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 00000000000..b23e919fd55 --- /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 00000000000..398258b81e6 --- /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 0176011c04a..e2cea0c1c9c 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 730e62a8fda..9892d69c18b 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 { -- 2.11.4.GIT