diff --git a/app-emulation/wine/ChangeLog b/app-emulation/wine/ChangeLog index 593c57f3..b32d40a5 100644 --- a/app-emulation/wine/ChangeLog +++ b/app-emulation/wine/ChangeLog @@ -2,6 +2,20 @@ # Copyright 1999-2009 Gentoo Foundation; Distributed under the GPL v2 # $Header: /var/cvsroot/gentoo-x86/app-emulation/wine/ChangeLog,v 1.268 2009/07/18 22:15:36 vapier Exp $ + 01 Aug 2009; Mario Fetka + +files/0001-dib-engine-hook-the-engine-bet.patch, + +files/0002-dib-engine-initial-pass-throug.patch, + +files/0003-dib-engine-fork-ddb-dib-behavi.patch, wine-1.1.26.ebuild, + +files/0004-dib-engine-implement-most-engi.patch, + +files/0005-dib-engine-implement-alphablen.patch, + +files/0006-dib-engine-add-clipping-on-xxx.patch, + +files/0007-dib-engine-implement-polygon.patch, + +files/0008-dib-engine-fixes-clipping-text.patch, + +files/0010-dib-engine-introduction-of-bit.patch, + +files/ddraw-1.1.24.diff, + +files/0009-dib-engine-fixes-against-wine-.patch, +files/hack.reg: + add direct draw hack and the dib engine + *wine-1.1.26 (18 Jul 2009) 18 Jul 2009; Mike Frysinger +wine-1.1.26.ebuild: diff --git a/app-emulation/wine/Manifest b/app-emulation/wine/Manifest index 61027a82..f5d50c01 100644 --- a/app-emulation/wine/Manifest +++ b/app-emulation/wine/Manifest @@ -1,10 +1,22 @@ +AUX 0001-dib-engine-hook-the-engine-bet.patch 5834 RMD160 706331c400aee2ed871101ab8b2718eba776fd29 SHA1 911ccd084668c992cd82c05ec54336330107c442 SHA256 9e624da5f55eb5c0f38868144dfe29f25defab101e5ad9c843bce0c54d98b38b +AUX 0002-dib-engine-initial-pass-throug.patch 58751 RMD160 6a9ffead85fc07222fc1b4f605177e8b5f11dfa4 SHA1 76a29e7f83afea41e28fff0764be0ff44f966065 SHA256 2049b7358d7fe8274d0ffc4248d49a90e7b5f909316a2765f8ce7cd809b38c27 +AUX 0003-dib-engine-fork-ddb-dib-behavi.patch 71105 RMD160 240d9f7343f1d44cad683f523e7bc0b039da5c21 SHA1 6f2112e267e88d5f85fa1f48b1566edc424b03ce SHA256 0b9f9301165d6b2de352f9f24b512daef0a9f696561dbde91e11286b17f477b1 +AUX 0004-dib-engine-implement-most-engi.patch 321458 RMD160 e8c19b55863eaff1325a3d468a7da7becacdfb19 SHA1 0c383eb74db081b09b7f2b4c6b432fce5f7dc850 SHA256 0de2d30595e71691b8b84df418a0f7102735defc5ebdfc52cc2db70a6b4b5c21 +AUX 0005-dib-engine-implement-alphablen.patch 19263 RMD160 ab524654fbb2f1c449fc6d55ce94c59362822687 SHA1 d56d5ba2d2bb11296aba5e9c8c77ba8d30dd011c SHA256 50861a914db94eb00de2e202da22ea3e07ba612cf17856494c83251266fb7a16 +AUX 0006-dib-engine-add-clipping-on-xxx.patch 21707 RMD160 dc04ac758bb8aaa33e823caf7201cada242b06d6 SHA1 02905f3913a8f6c28848cffe6fe896d5eac8e8bc SHA256 c2f98915b8f6e7c76ee1bce78b1179a1311925ffc3adcc0a3e9f2559d5cff00d +AUX 0007-dib-engine-implement-polygon.patch 13978 RMD160 8e030449a13a13206d9aacf0504d9e5b33830c18 SHA1 e72837cf2b8e964e67a40a8e35545d64d916b00e SHA256 9d517ce464b78350c9b6654cdb216b7f4ce7e895b6200ea3fef86176261d99f7 +AUX 0008-dib-engine-fixes-clipping-text.patch 68553 RMD160 ac63728c2655b676c2fa5fb0eea3e02af07913a5 SHA1 69c4f4c4197102fd9c1e0f4c288b46124a7c1f34 SHA256 08b64f3679538ded626f5cafe0090a64936572bac3480497331ed2d124fe7abb +AUX 0009-dib-engine-fixes-against-wine-.patch 66734 RMD160 3008c58918e4412b87b2608d22e71ad4a6d52283 SHA1 399f3624a59d88ca847d09f68030d9f240d0014e SHA256 2345e604481c0781b61618656f3e5ee2c9efd16671a207dad5e4913a621705a1 +AUX 0010-dib-engine-introduction-of-bit.patch 86639 RMD160 4df26b6b2c51b79f3d4a1d3d1dddac51d298e825 SHA1 f347761b2c64d67ff98d2407408673cc30cf760d SHA256 2fb6b2fceab6a2d383e992831f0323dbdec537231b744f457c90f396fbb7c6dd AUX acceptex.patch 46857 RMD160 154c2f6ea1c32de52e99d640322d17512aad816a SHA1 49878e892c72c19f9ca12fd9c416dff9f23a235c SHA256 ccbd476a97b7c74956fe906723f029f0c3078768f434680869508dc6107bf31c +AUX ddraw-1.1.24.diff 1781 RMD160 ff268de228a0d9ede41e7e3c2ee6c3a0669e9b16 SHA1 8a00fe11adef8252bb94e689b63066754566dc6b SHA256 e7e66970a91dee220c598320fb838a62e4ef171c7454db7a26fc5b948e9c8c1d AUX dinput.patch 3094 RMD160 05c8550c4a75a77dd4674635a29503c059f0b0fd SHA1 04570397eb182d68fc18b0badca5f9d52977c7df SHA256 b75c2b3e7db47d7221b2fc6065f4fb37807b9a8acf0903519e21d5ec1e1325f6 +AUX hack.reg 87 RMD160 6240dce28bb01a7863e366bbb94be513480d34c2 SHA1 079a5bb9d8f71ad02cb9798fb1fd739ad80a95a6 SHA256 a5e6f4cf2ed92718d347c343762a9051dfabb0ca77c7f168ef67a7f65720ea6f AUX revert-ntdll.patch 686 RMD160 ee2ebf8e0af7b7310e70b1f3652ad40f6576232e SHA1 7ba005f9bc22702e5461e22f6a4dc6a032237af1 SHA256 ceeb1e503e8cbe9804b31478997061ba54c77b4966e6407fcc9a49ada49616e8 AUX schannel.patch 4761 RMD160 191ef5eb1156262fd0bb3092a9214cb3ed04f548 SHA1 01adfd89c1fd7de75651fb7051ff79d10167d64d SHA256 41d1a34b69d6d1cdff80ab8e7e267385de3334af0fbff84393bc827a56ba632a AUX wine-1.1.15-winegcc.patch 1550 RMD160 086fbdd7dbe5da98c3457f00cb30705150d58b1f SHA1 0aa5a9d0947e15af9fe103797a0c993cbb3eedab SHA256 fcf4a0578774d817b8de094abae85e370683a77805a59efe6c5f7b8b87935de9 DIST wine-1.1.26.tar.bz2 15666433 RMD160 7949d7abbb62ee1db23940e348a5f9dc4a74fd4d SHA1 d39314e002c540d1852d10124473513cfb857dfd SHA256 0285b346ca7af8def0773cece1e9b01f47e7340577d6c780cd38863c948a1f5a DIST wine_gecko-0.9.1.cab 7806837 RMD160 8b16a4d065cd28d87a2e226400fa0a3ed600c2f1 SHA1 9a49fc691740596517e381b47096a4bdf19a87d8 SHA256 76345852b844c4b624a1beaf3f47f261ad956dbee97316ea26b3c587b363be84 -EBUILD wine-1.1.26.ebuild 3590 RMD160 ab167fad7e4629dd5ba9eef16083070a977d2824 SHA1 60e31508a7e915064e3ce4270b084a4ae24be52e SHA256 df22d1d1c91fc5a200f1795b0eb607a0a72e9d141d7f26fde64b12b7af170e8e -MISC ChangeLog 46467 RMD160 898b3d7fa7f8d8e0f9268e3598112fbc21aacb97 SHA1 71a2cf14877b6713dfdcfe02fdf17c14a0b7049d SHA256 eafa6ca2d3d5c67dfbfc3f55dc6742a89ee853a1ccf51b4afbbe8ae008309940 +EBUILD wine-1.1.26.ebuild 4268 RMD160 30e744d30dfb9d7e757cd1a8e870d825a3d8bb53 SHA1 9113a7324de4ae47d4daedd7d394f0cbc9fe13d4 SHA256 e4306e6d3f218e8f4c6ffea95b85b6c5113cefb4b46fa52cf46775096e5177a3 +MISC ChangeLog 47144 RMD160 15a460c2eba5dc09d41d03ad653cb480794e9954 SHA1 d658603ffa767fec71df7e1816333416c38e0b25 SHA256 74be5474c9665e0655238603b8f4261bb5978d91af91a07e65e93dd19493a842 MISC metadata.xml 1123 RMD160 168b7d83724ac65a23a10ad8bbe04d4dee180f6f SHA1 f8bb8f4eb1e4dab230f9f8d8b87fe04c6e638334 SHA256 eeee6aabb900286b05e81427597d143fb5fe74cc9b503d58464abd2534eaa569 diff --git a/app-emulation/wine/files/0001-dib-engine-hook-the-engine-bet.patch b/app-emulation/wine/files/0001-dib-engine-hook-the-engine-bet.patch new file mode 100644 index 00000000..2394b3cb --- /dev/null +++ b/app-emulation/wine/files/0001-dib-engine-hook-the-engine-bet.patch @@ -0,0 +1,185 @@ +DIB Engine: Hook the engine between GDI32 and Display driver + +From: Massimo Del Fedele + + +--- + + dlls/gdi32/driver.c | 139 +++++++++++++++++++++++++++++++++++++++++++++------ + 1 files changed, 123 insertions(+), 16 deletions(-) + + +diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c +index 20d3f36..95a69c7 100644 +--- a/dlls/gdi32/driver.c ++++ b/dlls/gdi32/driver.c +@@ -3,6 +3,7 @@ + * + * Copyright 1994 Bob Amstadt + * Copyright 1996, 2001 Alexandre Julliard ++ * 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 +@@ -25,6 +26,7 @@ + #include + #include + #include ++#include + #include "windef.h" + #include "winbase.h" + #include "winreg.h" +@@ -220,6 +222,104 @@ static struct graphics_driver *create_driver( HMODULE module ) + + + /********************************************************************** ++ * Load_Dib_Driver ++ * ++ * Check if we want the DIB engine and try to load it ++ */ ++static HMODULE Load_Dib_Driver(void) ++{ ++ HMODULE module; ++ ++ static const char *winedib_drv = "winedib.drv"; ++ ++ /* we do want use DIB Engine ? */ ++ BOOL driverRequired = TRUE; ++ ++ /* already checked env/registry for DIB driver ? */ ++ BOOL envChecked = FALSE; ++ ++ char *winedib; ++ char buffer[10]; ++ ++ /* environment variable WINEDIB takes precedence */ ++ if( (winedib = getenv("WINEDIB")) != NULL) ++ { ++ if(!strcasecmp(winedib, "ON") || ++ !strcasecmp(winedib, "TRUE") || ++ !strcasecmp(winedib, "ENABLE") || ++ !strcasecmp(winedib, "ENABLED") ++ ) ++ { ++ TRACE("DIB Engine enabled by environment\n"); ++ envChecked = TRUE; ++ driverRequired = TRUE; ++ } ++ else if(!strcasecmp(winedib, "OFF") || ++ !strcasecmp(winedib, "FALSE") || ++ !strcasecmp(winedib, "DISABLE") || ++ !strcasecmp(winedib, "DISABLED") ++ ) ++ { ++ TRACE("DIB Engine disabled by environment\n"); ++ envChecked = TRUE; ++ driverRequired = FALSE; ++ } ++ else ++ ERR("Bad WINEDIB environment variable\n"); ++ } ++ ++ /* no WINEDIB environment var found or wrong value, we check registry */ ++ if(!envChecked) ++ { ++ HKEY hkey; ++ buffer[0] = 0; ++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\DIB Engine", &hkey )) ++ { ++ DWORD type, count = sizeof(buffer); ++ RegQueryValueExA( hkey, "Enable", 0, &type, (LPBYTE) buffer, &count ); ++ RegCloseKey( hkey ); ++ } ++ if(*buffer) ++ { ++ /* registry value found, must be Y or y to enable driver, N or n to disable */ ++ if(!strncasecmp(buffer, "Y", 1)) ++ { ++ TRACE("DIB Engine enabled by registry\n"); ++ envChecked = TRUE; ++ driverRequired = TRUE; ++ } ++ else if(!strncasecmp(buffer, "N", 1)) ++ { ++ TRACE("DIB Engine disabled by registry\n"); ++ envChecked = TRUE; ++ driverRequired = FALSE; ++ } ++ } ++ } ++ ++ /* none of above, we assume we don't want to use engine */ ++ if(!envChecked) ++ { ++ TRACE("DIB Engine disabled by default\n"); ++ envChecked = TRUE; ++ driverRequired = FALSE; ++ } ++ ++ /* if DIB Engine is required, try to load it ++ * otherwise just return NULL module */ ++ if(driverRequired) ++ { ++ if( (module = LoadLibraryA( winedib_drv )) != 0) ++ TRACE("Succesfully loaded DIB Engine\n"); ++ else ++ ERR("Couldn't load DIB Engine\n"); ++ return module; ++ } ++ else ++ return 0; ++} ++ ++/********************************************************************** + * load_display_driver + * + * Special case for loading the display driver: get the name from the config file +@@ -235,25 +335,32 @@ static struct graphics_driver *load_display_driver(void) + display_driver->count++; + return display_driver; + } +- +- strcpy( buffer, "x11" ); /* default value */ +- /* @@ Wine registry key: HKCU\Software\Wine\Drivers */ +- if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey )) ++ ++ /* check at first if DIB engine is present and if we want ++ * to use it */ ++ if( (module = Load_Dib_Driver()) == 0) + { +- DWORD type, count = sizeof(buffer); +- RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count ); +- RegCloseKey( hkey ); +- } ++ /* no DIB Engine loaded, just load normal display driver */ ++ ++ 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; ++ 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; ++ snprintf( libname, sizeof(libname), "wine%s.drv", name ); ++ if ((module = LoadLibraryA( libname )) != 0) break; ++ name = next; ++ } + } + + if (!(display_driver = create_driver( module ))) diff --git a/app-emulation/wine/files/0002-dib-engine-initial-pass-throug.patch b/app-emulation/wine/files/0002-dib-engine-initial-pass-throug.patch new file mode 100644 index 00000000..01c444e4 --- /dev/null +++ b/app-emulation/wine/files/0002-dib-engine-initial-pass-throug.patch @@ -0,0 +1,1601 @@ +DIB Engine: initial pass-through implementation + +From: Massimo Del Fedele + + +--- + + configure.ac | 1 + dlls/winedib.drv/Makefile.in | 28 +++++ + dlls/winedib.drv/bitblt.c | 80 +++++++++++++ + dlls/winedib.drv/bitmap.c | 77 ++++++++++++ + dlls/winedib.drv/clipping.c | 36 ++++++ + dlls/winedib.drv/dc.c | 104 +++++++++++++++++ + dlls/winedib.drv/dib.c | 92 +++++++++++++++ + dlls/winedib.drv/dibdrv.h | 84 ++++++++++++++ + dlls/winedib.drv/dibdrv_main.c | 50 ++++++++ + dlls/winedib.drv/font.c | 83 +++++++++++++ + dlls/winedib.drv/graphics.c | 230 +++++++++++++++++++++++++++++++++++++ + dlls/winedib.drv/opengl.c | 221 ++++++++++++++++++++++++++++++++++++ + dlls/winedib.drv/palette.c | 90 ++++++++++++++ + dlls/winedib.drv/pen_brush.c | 98 ++++++++++++++++ + dlls/winedib.drv/text.c | 55 +++++++++ + dlls/winedib.drv/video.c | 48 ++++++++ + dlls/winedib.drv/winedib.drv.spec | 74 ++++++++++++ + 17 files changed, 1451 insertions(+), 0 deletions(-) + create mode 100644 dlls/winedib.drv/Makefile.in + create mode 100644 dlls/winedib.drv/bitblt.c + create mode 100644 dlls/winedib.drv/bitmap.c + create mode 100644 dlls/winedib.drv/clipping.c + create mode 100644 dlls/winedib.drv/dc.c + create mode 100644 dlls/winedib.drv/dib.c + create mode 100644 dlls/winedib.drv/dibdrv.h + create mode 100644 dlls/winedib.drv/dibdrv_main.c + create mode 100644 dlls/winedib.drv/font.c + create mode 100644 dlls/winedib.drv/graphics.c + create mode 100644 dlls/winedib.drv/opengl.c + create mode 100644 dlls/winedib.drv/palette.c + create mode 100644 dlls/winedib.drv/pen_brush.c + create mode 100644 dlls/winedib.drv/text.c + create mode 100644 dlls/winedib.drv/video.c + create mode 100644 dlls/winedib.drv/winedib.drv.spec + + +diff --git a/configure.ac b/configure.ac +index 4ab3f6a..94136c2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2270,6 +2270,7 @@ WINE_CONFIG_MAKEFILE([dlls/wineaudioio.drv/Makefile],[dlls/Makedll.rules],[dlls] + WINE_CONFIG_MAKEFILE([dlls/winecoreaudio.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/winecrt0/Makefile],[dlls/Makeimplib.rules],[dlls],[ALL_IMPLIB_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/wined3d/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) ++WINE_CONFIG_MAKEFILE([dlls/winedib.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/winedos/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/wineesd.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/winejack.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) +diff --git a/dlls/winedib.drv/Makefile.in b/dlls/winedib.drv/Makefile.in +new file mode 100644 +index 0000000..66ad14f +--- /dev/null ++++ b/dlls/winedib.drv/Makefile.in +@@ -0,0 +1,28 @@ ++TOPSRCDIR = @top_srcdir@ ++TOPOBJDIR = ../.. ++SRCDIR = @srcdir@ ++VPATH = @srcdir@ ++EXTRAINCL = @FREETYPEINCL@ @FONTCONFIGINCL@ ++EXTRALIBS = @XLIB@ ++MODULE = winedib.drv ++IMPORTS = user32 gdi32 advapi32 kernel32 ntdll ++ ++C_SRCS = \ ++ bitblt.c \ ++ bitmap.c \ ++ clipping.c \ ++ dc.c \ ++ dib.c \ ++ dibdrv_main.c \ ++ driver.c \ ++ font.c \ ++ graphics.c \ ++ opengl.c \ ++ palette.c \ ++ pen_brush.c \ ++ text.c \ ++ video.c ++ ++@MAKE_DLL_RULES@ ++ ++@DEPENDENCIES@ # everything below this line is overwritten by make depend +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +new file mode 100644 +index 0000000..fa9e2ec +--- /dev/null ++++ b/dlls/winedib.drv/bitblt.c +@@ -0,0 +1,80 @@ ++/* ++ * DIBDRV bit-blit operations ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV_AlphaBlend ++ */ ++BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst, ++ DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, ++ BLENDFUNCTION blendfn) ++{ ++ 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); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, ++ physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, ++ blendfn); ++} ++ ++/*********************************************************************** ++ * DIBDRV_BitBlt ++ */ ++BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop ) ++{ ++ 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); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, ++ physDevSrc->X11PhysDev, xSrc, ySrc, rop); ++} ++ ++/*********************************************************************** ++ * DIBDRV_StretchBlt ++ */ ++BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT widthDst, INT heightDst, ++ DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, ++ INT widthSrc, INT heightSrc, DWORD rop ) ++{ ++ 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); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc, ++ physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop); ++} ++ ++/*********************************************************************** ++ * DIBDRV_PatBlt ++ */ ++BOOL DIBDRV_PatBlt( DIBDRVPHYSDEV *physDev, INT left, INT top, INT width, INT height, DWORD rop ) ++{ ++ TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, left, top, width, height, rop); ++} +diff --git a/dlls/winedib.drv/bitmap.c b/dlls/winedib.drv/bitmap.c +new file mode 100644 +index 0000000..09cca69 +--- /dev/null ++++ b/dlls/winedib.drv/bitmap.c +@@ -0,0 +1,77 @@ ++/* ++ * DIB driver bitmap objects ++ * ++ * 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); ++ ++ ++/**************************************************************************** ++ * SelectBitmap (WINEDIB.DRV.@) ++ */ ++HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) ++{ ++ TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap); ++} ++ ++/**************************************************************************** ++ * DIBDRV_CreateBitmap ++ */ ++BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits ) ++{ ++ TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pCreateBitmap(physDev->X11PhysDev, hbitmap, bmBits); ++} ++ ++/*********************************************************************** ++ * DIBDRV_DeleteBitmap ++ */ ++BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) ++{ ++ TRACE("hbitmap:%p\n", hbitmap); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetBitmapBits ++ */ ++LONG DIBDRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count ) ++{ ++ TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetBitmapBits(hbitmap, buffer, count); ++} ++ ++/****************************************************************************** ++ * DIBDRV_SetBitmapBits ++ */ ++LONG DIBDRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count ) ++{ ++ TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetBitmapBits(hbitmap, bits, count); ++} +diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c +new file mode 100644 +index 0000000..b3c18ef +--- /dev/null ++++ b/dlls/winedib.drv/clipping.c +@@ -0,0 +1,36 @@ ++/* ++ * DIBDRV clipping functions ++ * ++ * 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); ++ ++/*********************************************************************** ++ * 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); ++ ONCE(FIXME("stub\n")); ++ _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); ++} +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +new file mode 100644 +index 0000000..e0ffb4d +--- /dev/null ++++ b/dlls/winedib.drv/dc.c +@@ -0,0 +1,104 @@ ++/* ++ * DIB driver initialization functions ++ * ++ * 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); ++ ++/********************************************************************** ++ * DIBDRV_CreateDC ++ */ ++BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR device, ++ LPCWSTR output, const DEVMODEW* initData ) ++{ ++ 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); ++ ++ /* allocates physical device */ ++ physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBDRVPHYSDEV) ); ++ if (!physDev) ++ return FALSE; ++ ++ /* creates X11 physical device */ ++ if(!_DIBDRV_GetDisplayDriver()->pCreateDC(hdc, &X11PhysDev, driver, device, output, initData)) ++ { ++ HeapFree(GetProcessHeap(), 0, physDev); ++ return FALSE; ++ } ++ ++ /* sets X11 Device pointer in DIB Engine device */ ++ physDev->X11PhysDev = X11PhysDev; ++ ++ /* sets the result value and returns */ ++ *pdev = physDev; ++ ++ ONCE(FIXME("stub\n")); ++ return TRUE; ++} ++ ++/********************************************************************** ++ * DIBDRV_DeleteDC ++ */ ++BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev ) ++{ ++ BOOL res; ++ ++ TRACE("physDev:%p\n", physDev); ++ ++ /* frees X11 device */ ++ res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev); ++ physDev->X11PhysDev = NULL; ++ ++ /* frees DIB Engine device */ ++ HeapFree(GetProcessHeap(), 0, physDev); ++ ++ ONCE(FIXME("stub\n")); ++ return res; ++} ++ ++/********************************************************************** ++ * DIBDRV_ExtEscape ++ */ ++INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID in_data, ++ INT out_count, LPVOID out_data ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetDeviceCaps ++ */ ++INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap ) ++{ ++ TRACE("physDev:%p, cap:%d\n", physDev, cap); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap); ++} +diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c +new file mode 100644 +index 0000000..47dce0e +--- /dev/null ++++ b/dlls/winedib.drv/dib.c +@@ -0,0 +1,92 @@ ++/* ++ * DIBDRV device-independent bitmaps ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV_CreateDIBSection ++ */ ++HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, ++ const BITMAPINFO *bmi, UINT usage ) ++{ ++ TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pCreateDIBSection(physDev->X11PhysDev, hbitmap, bmi, usage); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetDIBits ++*/ ++INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, ++ UINT lines, LPCVOID bits, const BITMAPINFO *bmi, UINT coloruse ) ++{ ++ TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", ++ physDev, hbitmap, startscan, lines, bits, bmi, coloruse); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, bmi, coloruse); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetDIBColorTable ++ */ ++UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, ++ const RGBQUAD *colors ) ++{ ++ TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDIBColorTable(physDev->X11PhysDev, start, count, colors); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetDIBits ++ */ ++INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, ++ UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse ) ++{ ++ TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", ++ physDev, hbitmap, startscan, lines, bits, info, coloruse); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse); ++} ++ ++/************************************************************************* ++ * DIBDRV_SetDIBitsToDevice ++ */ ++INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWORD cx, ++ DWORD cy, INT xSrc, INT ySrc, ++ UINT startscan, UINT lines, LPCVOID bits, ++ const BITMAPINFO *info, UINT coloruse ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, ++ startscan, lines, bits, info, coloruse); ++} +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +new file mode 100644 +index 0000000..6dfba06 +--- /dev/null ++++ b/dlls/winedib.drv/dibdrv.h +@@ -0,0 +1,84 @@ ++/* ++ * DIB driver private definitions ++ * ++ * 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_H ++#define __WINE_DIBDRV_H ++ ++#include ++#include ++#include ++ ++#include "windef.h" ++#include "winbase.h" ++#include "winerror.h" ++#include "wingdi.h" ++#include "wine/list.h" ++#include "wine/library.h" ++#include "wine/debug.h" ++#include "wingdi.h" ++#include "winreg.h" ++#include "wine/winbase16.h" /* GlobalLock16 */ ++ ++/* data structures needed to access opaque pointers ++ * defined in gdi32.h */ ++#include "dibdrv_gdi32.h" ++ ++/* provide a way to make debugging output appear ++ only once. Usage example: ++ ONCE(FIXME("Some message\n")); */ ++#define ONCE(x) \ ++{ \ ++ static BOOL done = FALSE; \ ++ if(!done) \ ++ { \ ++ done = TRUE; \ ++ x; \ ++ } \ ++} ++ ++ ++/* DIB driver physical device */ ++typedef struct _DIBDRVPHYSDEV ++{ ++ /* X11 driver physical device */ ++ PHYSDEV X11PhysDev; ++ ++ /* active ROP2 */ ++ INT rop2; ++ ++} DIBDRVPHYSDEV; ++ ++ ++/* ********************************************************************* ++ * DISPLAY DRIVER ACCESS FUNCTIONS ++ * ********************************************************************/ ++ ++/* LoadDisplayDriver ++ * Loads display driver - partially grabbed from gdi32 */ ++DC_FUNCTIONS *_DIBDRV_LoadDisplayDriver(void); ++ ++/* FreeDisplayDriver ++ Frees resources allocated by Display driver */ ++void _DIBDRV_FreeDisplayDriver(void); ++ ++/* GetDisplayDriver ++ Gets a pointer to display drives'function table */ ++inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void); ++ ++#endif /* __WINE_DIBDRV_H */ +diff --git a/dlls/winedib.drv/dibdrv_main.c b/dlls/winedib.drv/dibdrv_main.c +new file mode 100644 +index 0000000..28429d2 +--- /dev/null ++++ b/dlls/winedib.drv/dibdrv_main.c +@@ -0,0 +1,50 @@ ++/* ++ * DIBDRV initialization code ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV initialization routine ++ */ ++BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) ++{ ++ BOOL ret = TRUE; ++ ++ switch(reason) ++ { ++ case DLL_PROCESS_ATTACH: ++ /* Loads display driver */ ++ _DIBDRV_LoadDisplayDriver(); ++ break; ++ case DLL_THREAD_DETACH: ++ /* do thread detach */ ++ break; ++ case DLL_PROCESS_DETACH: ++ /* unloads display driver */ ++ _DIBDRV_FreeDisplayDriver(); ++ break; ++ } ++ return ret; ++} +diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c +new file mode 100644 +index 0000000..85f9198 +--- /dev/null ++++ b/dlls/winedib.drv/font.c +@@ -0,0 +1,83 @@ ++/* ++ * DIBDRV font objects ++ * ++ * 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); ++ ++/********************************************************************** ++ * DIBDRV_SetTextColor ++ */ ++COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) ++{ ++ TRACE("physDev:%p, color:%08x\n", physDev, color); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetTextColor(physDev->X11PhysDev, color); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SelectFont ++ */ ++HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, HANDLE gdiFont ) ++{ ++ TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSelectFont(physDev->X11PhysDev, hfont, gdiFont); ++} ++ ++/*********************************************************************** ++ * DIBDRV_EnumDeviceFonts ++ */ ++BOOL DIBDRV_EnumDeviceFonts( DIBDRVPHYSDEV *physDev, LPLOGFONTW plf, ++ FONTENUMPROCW proc, LPARAM lp ) ++{ ++ TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pEnumDeviceFonts(physDev->X11PhysDev, plf, proc, lp); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetTextMetrics ++ */ ++BOOL DIBDRV_GetTextMetrics( DIBDRVPHYSDEV *physDev, TEXTMETRICW *metrics ) ++{ ++ TRACE("physDev:%p, metrics:%p\n", physDev, metrics); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetTextMetrics(physDev->X11PhysDev, metrics); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetCharWidth ++ */ ++BOOL DIBDRV_GetCharWidth( DIBDRVPHYSDEV *physDev, UINT firstChar, UINT lastChar, ++ LPINT buffer ) ++{ ++ TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetCharWidth(physDev->X11PhysDev, firstChar, lastChar, buffer); ++} +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +new file mode 100644 +index 0000000..b746af2 +--- /dev/null ++++ b/dlls/winedib.drv/graphics.c +@@ -0,0 +1,230 @@ ++/* ++ * DIBDRV implementation of GDI driver graphics functions ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV_Arc ++ */ ++BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom, ++ INT xstart, INT ystart, INT xend, INT yend ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, left, top, right, bottom, ++ xstart, ystart, xend, yend); ++} ++ ++/*********************************************************************** ++ * DIBDRV_Chord ++ */ ++BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom, ++ INT xstart, INT ystart, INT xend, INT yend ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, left, top, right, bottom, ++ xstart, ystart, xend, yend); ++} ++ ++/*********************************************************************** ++ * DIBDRV_Ellipse ++ */ ++BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom ) ++{ ++ TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", ++ physDev, left, top, right, bottom); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, left, top, right, bottom); ++} ++ ++/********************************************************************** ++ * DIBDRV_ExtFloodFill ++ */ ++BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color, ++ UINT fillType ) ++{ ++ TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n", ++ physDev, x, y, color, fillType); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, x, y, color, fillType); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetDCOrgEx ++ */ ++BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp ) ++{ ++ TRACE("physDev:%p, lpp:%p\n", physDev, lpp); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, lpp); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetPixel ++ */ ++COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y ) ++{ ++ TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, x, y); ++} ++ ++/*********************************************************************** ++ * DIBDRV_LineTo ++ */ ++BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y ) ++{ ++ TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, x, y); ++} ++ ++/*********************************************************************** ++ * DIBDRV_PaintRgn ++ */ ++BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn ) ++{ ++ TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, hrgn); ++} ++ ++/*********************************************************************** ++ * DIBDRV_Pie ++ */ ++BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom, ++ INT xstart, INT ystart, INT xend, INT yend ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, left, top, right, bottom, ++ xstart, ystart, xend, yend); ++} ++ ++/********************************************************************** ++ * DIBDRV_Polygon ++ */ ++BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) ++{ ++ TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, pt, count); ++} ++ ++/********************************************************************** ++ * DIBDRV_Polyline ++ */ ++BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) ++{ ++ TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, pt, count); ++} ++ ++/********************************************************************** ++ * DIBDRV_PolyPolygon ++ */ ++BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const INT* counts, UINT polygons) ++{ ++ TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, pt, counts, polygons); ++} ++ ++/********************************************************************** ++ * DIBDRV_PolyPolyline ++ */ ++BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* counts, ++ DWORD polylines ) ++{ ++ TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, pt, counts, polylines); ++} ++ ++/*********************************************************************** ++ * DIBDRV_Rectangle ++ */ ++BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom) ++{ ++ TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", ++ physDev, left, top, right, bottom); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, left, top, right, bottom); ++} ++ ++/*********************************************************************** ++ * DIBDRV_RoundRect ++ */ ++BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, ++ INT bottom, INT ell_width, INT ell_height ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, left, top, right, bottom, ++ ell_width, ell_height); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetPixel ++ */ ++COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color ) ++{ ++ TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, x, y, color); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetDCOrg ++ */ ++DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, INT x, INT y ) ++{ ++ TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, x, y); ++} +diff --git a/dlls/winedib.drv/opengl.c b/dlls/winedib.drv/opengl.c +new file mode 100644 +index 0000000..27e4229 +--- /dev/null ++++ b/dlls/winedib.drv/opengl.c +@@ -0,0 +1,221 @@ ++/* ++ * DIBDRV OpenGL functions ++ * ++ * 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" ++ ++#define HPBUFFERARB void * ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++int DIBDRV_ChoosePixelFormat( DIBDRVPHYSDEV *physDev, ++ const PIXELFORMATDESCRIPTOR *ppfd ) ++{ ++ TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pChoosePixelFormat(physDev->X11PhysDev, ppfd); ++} ++ ++int DIBDRV_DescribePixelFormat( DIBDRVPHYSDEV *physDev, ++ int iPixelFormat, ++ UINT nBytes, ++ PIXELFORMATDESCRIPTOR *ppfd ) ++{ ++ TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pDescribePixelFormat(physDev->X11PhysDev, iPixelFormat, nBytes, ppfd); ++} ++ ++int DIBDRV_GetPixelFormat( DIBDRVPHYSDEV *physDev) ++{ ++ TRACE("physDev:%p\n", physDev); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetPixelFormat(physDev->X11PhysDev); ++} ++ ++BOOL DIBDRV_SetPixelFormat( DIBDRVPHYSDEV *physDev, ++ int iPixelFormat, ++ const PIXELFORMATDESCRIPTOR *ppfd ) ++{ ++ TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetPixelFormat(physDev->X11PhysDev, iPixelFormat, ppfd); ++} ++ ++BOOL DIBDRV_SwapBuffers( DIBDRVPHYSDEV *physDev ) ++{ ++ TRACE("physDev:%p\n", physDev); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSwapBuffers(physDev->X11PhysDev); ++} ++ ++/** ++ * DIBDRV_wglCopyContext ++ * ++ * For OpenGL32 wglCopyContext. ++ */ ++BOOL CDECL DIBDRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) ++{ ++ TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglCopyContext(hglrcSrc, hglrcDst, mask); ++} ++ ++/** ++ * DIBDRV_wglCreateContext ++ * ++ * For OpenGL32 wglCreateContext. ++ */ ++HGLRC CDECL DIBDRV_wglCreateContext(DIBDRVPHYSDEV *physDev) ++{ ++ TRACE("physDev:%p\n", physDev); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglCreateContext(physDev->X11PhysDev); ++} ++ ++/** ++ * DIBDRV_wglDeleteContext ++ * ++ * For OpenGL32 wglDeleteContext. ++ */ ++BOOL CDECL DIBDRV_wglDeleteContext(HGLRC hglrc) ++{ ++ TRACE("hglrc:%p\n", hglrc); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglDeleteContext(hglrc); ++} ++ ++/** ++ * DIBDRV_wglGetProcAddress ++ * ++ * For OpenGL32 wglGetProcAddress. ++ */ ++PROC CDECL DIBDRV_wglGetProcAddress(LPCSTR lpszProc) ++{ ++ TRACE("lpszProc:%p\n", lpszProc); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglGetProcAddress(lpszProc); ++} ++ ++/** ++ * DIBDRV_wglGetPbufferDCARB ++ * ++ * WGL_ARB_pbuffer: wglGetPbufferDCARB ++ * The function wglGetPbufferDCARB returns a device context for a pbuffer. ++ * Gdi32 implements the part of this function which creates a device context. ++ * This part associates the physDev with the X drawable of the pbuffer. ++ */ ++HDC CDECL DIBDRV_wglGetPbufferDCARB(DIBDRVPHYSDEV *physDev, HPBUFFERARB hPbuffer) ++{ ++ TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglGetPbufferDCARB(physDev->X11PhysDev, hPbuffer); ++} ++ ++/** ++ * DIBDRV_wglMakeContextCurrentARB ++ * ++ * For OpenGL32 wglMakeContextCurrentARB ++ */ ++BOOL CDECL DIBDRV_wglMakeContextCurrentARB(DIBDRVPHYSDEV* pDrawDev, DIBDRVPHYSDEV* pReadDev, HGLRC hglrc) ++{ ++ TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc); ++} ++ ++/** ++ * DIBDRV_wglMakeCurrent ++ * ++ * For OpenGL32 wglMakeCurrent. ++ */ ++BOOL CDECL DIBDRV_wglMakeCurrent(DIBDRVPHYSDEV *physDev, HGLRC hglrc) ++{ ++ TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglMakeCurrent(physDev->X11PhysDev, hglrc); ++} ++ ++/** ++ * DIBDRV_wglSetPixelFormatWINE ++ * ++ * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE ++ * This is a WINE-specific wglSetPixelFormat which can set the pixel format multiple times. ++ */ ++BOOL CDECL DIBDRV_wglSetPixelFormatWINE(DIBDRVPHYSDEV *physDev, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd) ++{ ++ TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglSetPixelFormatWINE(physDev->X11PhysDev, iPixelFormat, ppfd); ++} ++ ++/** ++ * DIBDRV_wglShareLists ++ * ++ * For OpenGL32 wglShareLists. ++ */ ++BOOL CDECL DIBDRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) ++{ ++ TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglShareLists(hglrc1, hglrc2); ++} ++ ++/** ++ * DIBDRV_wglUseFontBitmapsA ++ * ++ * For OpenGL32 wglUseFontBitmapsA. ++ */ ++BOOL CDECL DIBDRV_wglUseFontBitmapsA(DIBDRVPHYSDEV *physDev, DWORD first, DWORD count, DWORD listBase) ++{ ++ TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsA(physDev->X11PhysDev, first, count, listBase); ++} ++ ++/** ++ * DIBDRV_wglUseFontBitmapsW ++ * ++ * For OpenGL32 wglUseFontBitmapsW. ++ */ ++BOOL CDECL DIBDRV_wglUseFontBitmapsW(DIBDRVPHYSDEV *physDev, DWORD first, DWORD count, DWORD listBase) ++{ ++ TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsW(physDev->X11PhysDev, first, count, listBase); ++} +diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c +new file mode 100644 +index 0000000..28fae09 +--- /dev/null ++++ b/dlls/winedib.drv/palette.c +@@ -0,0 +1,90 @@ ++/* ++ * DIBDRV palette objects ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV_RealizePalette ++ */ ++UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary ) ++{ ++ TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE")); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev->X11PhysDev, hpal, primary); ++} ++ ++/*********************************************************************** ++ * DIBDRV_UnrealizePalette ++ */ ++BOOL DIBDRV_UnrealizePalette( HPALETTE hpal ) ++{ ++ TRACE("hpal:%p\n", hpal); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pUnrealizePalette(hpal); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetSystemPaletteEntries ++ */ ++UINT DIBDRV_GetSystemPaletteEntries( DIBDRVPHYSDEV *physDev, UINT start, UINT count, ++ LPPALETTEENTRY entries ) ++{ ++ TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetSystemPaletteEntries(physDev->X11PhysDev, start, count, entries); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetNearestColor ++ */ ++COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color ) ++{ ++ TRACE("physDev:%p, color:%x\n", physDev, color); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetNearestColor(physDev->X11PhysDev, color); ++} ++ ++/*********************************************************************** ++ * DIBDRV_RealizeDefaultPalette ++ */ ++UINT DIBDRV_RealizeDefaultPalette( DIBDRVPHYSDEV *physDev ) ++{ ++ TRACE("physDev:%p\n", physDev); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev); ++} ++ ++BOOL DIBDRV_GetICMProfile(DIBDRVPHYSDEV *physDev, LPDWORD lpcbName, LPWSTR lpszFilename) ++{ ++ TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetICMProfile(physDev->X11PhysDev, lpcbName, lpszFilename); ++} +diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c +new file mode 100644 +index 0000000..1e992e0 +--- /dev/null ++++ b/dlls/winedib.drv/pen_brush.c +@@ -0,0 +1,98 @@ ++/* ++ * DIBDRV pen objects ++ * ++ * 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); ++ ++ ++/*********************************************************************** ++ * DIBDRV_SelectPen ++ */ ++HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) ++{ ++ TRACE("physDev:%p, hpen:%p\n", physDev, hpen); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSelectPen(physDev->X11PhysDev, hpen); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetDCPenColor ++ */ ++COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) ++{ ++ TRACE("physDev:%p, crColor:%x\n", physDev, crColor); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev->X11PhysDev, crColor); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SelectBrush ++ */ ++HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) ++{ ++ TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetDCBrushColor ++ */ ++COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) ++{ ++ TRACE("physDev:%p, crColor:%x\n", physDev, crColor); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev->X11PhysDev, crColor); ++} ++ ++/*********************************************************************** ++ * SetROP2 ++ */ ++INT DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, INT rop ) ++{ ++ INT prevRop; ++ ++ TRACE("physDev:%p, rop:%x\n", physDev, rop); ++ ++ ONCE(FIXME("stub\n")); ++ prevRop = physDev->rop2; ++ physDev->rop2 = rop; ++ return prevRop; ++ /* note : X11 Driver don't have SetROP2() function exported */ ++} ++ ++/*********************************************************************** ++ * SetBkColor ++ */ ++COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color ) ++{ ++ TRACE("physDev:%p, color:%x\n", physDev, color); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev->X11PhysDev, color); ++} +diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c +new file mode 100644 +index 0000000..fdb075f +--- /dev/null ++++ b/dlls/winedib.drv/text.c +@@ -0,0 +1,55 @@ ++/* ++ * DIBDRV text functions ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV_ExtTextOut ++ */ ++BOOL ++DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, ++ const RECT *lprect, LPCWSTR wstr, UINT count, ++ const INT *lpDx ) ++{ ++ 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); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect, ++ wstr, count, lpDx); ++} ++ ++/*********************************************************************** ++ * DIBDRV_GetTextExtentExPoint ++ */ ++BOOL DIBDRV_GetTextExtentExPoint( DIBDRVPHYSDEV *physDev, LPCWSTR str, INT count, ++ INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size ) ++{ ++ 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); ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetTextExtentExPoint(physDev->X11PhysDev, str, count, maxExt, ++ lpnFit, alpDx, size); ++} +diff --git a/dlls/winedib.drv/video.c b/dlls/winedib.drv/video.c +new file mode 100644 +index 0000000..6490ac6 +--- /dev/null ++++ b/dlls/winedib.drv/video.c +@@ -0,0 +1,48 @@ ++/* ++ * DIBDRV video functions ++ * ++ * 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); ++ ++/*********************************************************************** ++ * DIBDRV_GetDeviceGammaRamp ++ */ ++BOOL DIBDRV_GetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) ++{ ++ TRACE("physDev:%p, ramp:%p\n", physDev, ramp); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pGetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++} ++ ++/*********************************************************************** ++ * DIBDRV_SetDeviceGammaRamp ++ */ ++BOOL DIBDRV_SetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) ++{ ++ TRACE("physDev:%p, ramp:%p\n", physDev, ramp); ++ ++ ONCE(FIXME("stub\n")); ++ return _DIBDRV_GetDisplayDriver()->pSetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++} +diff --git a/dlls/winedib.drv/winedib.drv.spec b/dlls/winedib.drv/winedib.drv.spec +new file mode 100644 +index 0000000..3743b2b +--- /dev/null ++++ b/dlls/winedib.drv/winedib.drv.spec +@@ -0,0 +1,74 @@ ++@ cdecl AlphaBlend(ptr long long long long ptr long long long long long) DIBDRV_AlphaBlend ++@ cdecl Arc(ptr long long long long long long long long) DIBDRV_Arc ++@ cdecl BitBlt(ptr long long long long ptr long long long) DIBDRV_BitBlt ++@ cdecl ChoosePixelFormat(ptr ptr) DIBDRV_ChoosePixelFormat ++@ cdecl Chord(ptr long long long long long long long long) DIBDRV_Chord ++@ cdecl CreateBitmap(ptr long ptr) DIBDRV_CreateBitmap ++@ cdecl CreateDC(long ptr wstr wstr wstr ptr) DIBDRV_CreateDC ++@ cdecl CreateDIBSection(ptr long ptr long) DIBDRV_CreateDIBSection ++@ cdecl DeleteBitmap(long) DIBDRV_DeleteBitmap ++@ cdecl DeleteDC(ptr) DIBDRV_DeleteDC ++@ cdecl DescribePixelFormat(ptr long long ptr) DIBDRV_DescribePixelFormat ++@ cdecl Ellipse(ptr long long long long) DIBDRV_Ellipse ++@ cdecl EnumDeviceFonts(ptr ptr ptr long) DIBDRV_EnumDeviceFonts ++@ cdecl ExtEscape(ptr long long ptr long ptr) DIBDRV_ExtEscape ++@ cdecl ExtFloodFill(ptr long long long long) DIBDRV_ExtFloodFill ++@ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) DIBDRV_ExtTextOut ++@ cdecl GetBitmapBits(long ptr long) DIBDRV_GetBitmapBits ++@ cdecl GetCharWidth(ptr long long ptr) DIBDRV_GetCharWidth ++@ cdecl GetDCOrgEx(ptr ptr) DIBDRV_GetDCOrgEx ++@ cdecl GetDIBits(ptr long long long ptr ptr long) DIBDRV_GetDIBits ++@ cdecl GetDeviceCaps(ptr long) DIBDRV_GetDeviceCaps ++@ cdecl GetDeviceGammaRamp(ptr ptr) DIBDRV_GetDeviceGammaRamp ++@ cdecl GetICMProfile(ptr ptr ptr) DIBDRV_GetICMProfile ++@ cdecl GetNearestColor(ptr long) DIBDRV_GetNearestColor ++@ cdecl GetPixel(ptr long long) DIBDRV_GetPixel ++@ cdecl GetPixelFormat(ptr) DIBDRV_GetPixelFormat ++@ cdecl GetSystemPaletteEntries(ptr long long ptr) DIBDRV_GetSystemPaletteEntries ++@ cdecl GetTextExtentExPoint(ptr ptr long long ptr ptr ptr) DIBDRV_GetTextExtentExPoint ++@ cdecl GetTextMetrics(ptr ptr) DIBDRV_GetTextMetrics ++@ cdecl LineTo(ptr long long) DIBDRV_LineTo ++@ cdecl PaintRgn(ptr long) DIBDRV_PaintRgn ++@ cdecl PatBlt(ptr long long long long long) DIBDRV_PatBlt ++@ cdecl Pie(ptr long long long long long long long long) DIBDRV_Pie ++@ cdecl PolyPolygon(ptr ptr ptr long) DIBDRV_PolyPolygon ++@ cdecl PolyPolyline(ptr ptr ptr long) DIBDRV_PolyPolyline ++@ cdecl Polygon(ptr ptr long) DIBDRV_Polygon ++@ cdecl Polyline(ptr ptr long) DIBDRV_Polyline ++@ cdecl RealizeDefaultPalette(ptr) DIBDRV_RealizeDefaultPalette ++@ cdecl RealizePalette(ptr long long) DIBDRV_RealizePalette ++@ cdecl Rectangle(ptr long long long long) DIBDRV_Rectangle ++@ cdecl RoundRect(ptr long long long long long long) DIBDRV_RoundRect ++@ cdecl SelectBitmap(ptr long) DIBDRV_SelectBitmap ++@ cdecl SelectBrush(ptr long) DIBDRV_SelectBrush ++@ cdecl SelectFont(ptr long long) DIBDRV_SelectFont ++@ cdecl SelectPen(ptr long) DIBDRV_SelectPen ++@ cdecl SetBitmapBits(long ptr long) DIBDRV_SetBitmapBits ++@ cdecl SetBkColor(ptr long) DIBDRV_SetBkColor ++@ cdecl SetDCBrushColor(ptr long) DIBDRV_SetDCBrushColor ++@ cdecl SetDCOrg(ptr long long) DIBDRV_SetDCOrg ++@ cdecl SetDCPenColor(ptr long) DIBDRV_SetDCPenColor ++@ cdecl SetDIBColorTable(ptr long long ptr) DIBDRV_SetDIBColorTable ++@ cdecl SetDIBits(ptr long long long ptr ptr long) DIBDRV_SetDIBits ++@ cdecl SetDIBitsToDevice(ptr long long long long long long long long ptr ptr long) DIBDRV_SetDIBitsToDevice ++@ cdecl SetDeviceClipping(ptr long long) DIBDRV_SetDeviceClipping ++@ cdecl SetDeviceGammaRamp(ptr ptr) DIBDRV_SetDeviceGammaRamp ++@ cdecl SetPixel(ptr long long long) DIBDRV_SetPixel ++@ cdecl SetPixelFormat(ptr long ptr) DIBDRV_SetPixelFormat ++@ cdecl SetTextColor(ptr long) DIBDRV_SetTextColor ++@ cdecl StretchBlt(ptr long long long long ptr long long long long long) DIBDRV_StretchBlt ++@ cdecl SwapBuffers(ptr) DIBDRV_SwapBuffers ++@ cdecl UnrealizePalette(long) DIBDRV_UnrealizePalette ++@ cdecl SetROP2(ptr long) DIBDRV_SetROP2 ++# OpenGL ++@ cdecl wglCopyContext(long long long) DIBDRV_wglCopyContext ++@ cdecl wglCreateContext(ptr) DIBDRV_wglCreateContext ++@ cdecl wglDeleteContext(long) DIBDRV_wglDeleteContext ++@ cdecl wglGetProcAddress(str) DIBDRV_wglGetProcAddress ++@ cdecl wglGetPbufferDCARB(ptr ptr) DIBDRV_wglGetPbufferDCARB ++@ cdecl wglMakeContextCurrentARB(ptr ptr long) DIBDRV_wglMakeContextCurrentARB ++@ cdecl wglMakeCurrent(ptr long) DIBDRV_wglMakeCurrent ++@ cdecl wglSetPixelFormatWINE(ptr long ptr) DIBDRV_wglSetPixelFormatWINE ++@ cdecl wglShareLists(long long) DIBDRV_wglShareLists ++@ cdecl wglUseFontBitmapsA(ptr long long long) DIBDRV_wglUseFontBitmapsA ++@ cdecl wglUseFontBitmapsW(ptr long long long) DIBDRV_wglUseFontBitmapsW diff --git a/app-emulation/wine/files/0003-dib-engine-fork-ddb-dib-behavi.patch b/app-emulation/wine/files/0003-dib-engine-fork-ddb-dib-behavi.patch new file mode 100644 index 00000000..741e427e --- /dev/null +++ b/app-emulation/wine/files/0003-dib-engine-fork-ddb-dib-behavi.patch @@ -0,0 +1,1858 @@ +DIB Engine: Fork DDB-DIB behaviour + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/bitblt.c | 116 ++++++++++++++++- + dlls/winedib.drv/bitmap.c | 82 +++++++++++- + dlls/winedib.drv/clipping.c | 14 ++ + dlls/winedib.drv/dc.c | 39 +++++- + dlls/winedib.drv/dib.c | 42 +++++- + dlls/winedib.drv/dibdrv.h | 9 + + dlls/winedib.drv/font.c | 81 +++++++++++- + dlls/winedib.drv/graphics.c | 284 ++++++++++++++++++++++++++++++++++++------ + dlls/winedib.drv/opengl.c | 227 +++++++++++++++++++++++++++++----- + dlls/winedib.drv/palette.c | 91 ++++++++++++- + dlls/winedib.drv/pen_brush.c | 81 ++++++++++-- + dlls/winedib.drv/text.c | 44 +++++-- + dlls/winedib.drv/video.c | 32 ++++- + 13 files changed, 995 insertions(+), 147 deletions(-) + + +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index fa9e2ec..022f223 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -32,12 +32,43 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, + BLENDFUNCTION blendfn) + { ++ 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); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, ++ ++ 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); ++ } ++ else if(!physDevDst->hasDIB && !physDevSrc->hasDIB) ++ { ++ /* DDB selected in noth source and dest DC, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, ++ physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, ++ blendfn); ++ } ++ else if(physDevSrc->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()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, ++ physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, ++ blendfn); ++ } ++ 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); ++ } ++ return res; + } + + /*********************************************************************** +@@ -47,11 +78,39 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + INT width, INT height, DIBDRVPHYSDEV *physDevSrc, + INT xSrc, INT ySrc, DWORD rop ) + { ++ 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); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, 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) ++ { ++ /* 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); ++ } ++ 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()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, ++ physDevSrc->X11PhysDev, xSrc, ySrc, rop); ++ } ++ return res; + } + + /*********************************************************************** +@@ -62,11 +121,39 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, + INT widthSrc, INT heightSrc, DWORD rop ) + { ++ 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); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, 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) ++ { ++ /* 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); ++ } ++ 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()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc, ++ physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop); ++ } ++ return res; + } + + /*********************************************************************** +@@ -74,7 +161,20 @@ 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); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, left, top, width, height, rop); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/bitmap.c b/dlls/winedib.drv/bitmap.c +index 09cca69..df7c03a 100644 +--- a/dlls/winedib.drv/bitmap.c ++++ b/dlls/winedib.drv/bitmap.c +@@ -31,9 +31,31 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + */ + HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) + { ++ DIBSECTION dibSection; ++ HBITMAP res; ++ + TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, 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 */ ++ physDev->hasDIB = FALSE; ++ res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap); ++ if(res) ++ 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) ++ physDev->hbitmap = hbitmap; ++ } ++ return res; ++ + } + + /**************************************************************************** +@@ -41,9 +63,24 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) + */ + BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits ) + { ++ DIBSECTION dibSection; ++ BOOL res; ++ + TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pCreateBitmap(physDev->X11PhysDev, hbitmap, bmBits); ++ ++ /* try to get the DIBSECTION data from the bitmap */ ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP)) ++ { ++ /* not a DIB section, use X11 behaviour */ ++ res = _DIBDRV_GetDisplayDriver()->pCreateBitmap(physDev->X11PhysDev, hbitmap, 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); ++ } ++ return res; + } + + /*********************************************************************** +@@ -51,9 +88,24 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits + */ + BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) + { ++ DIBSECTION dibSection; ++ BOOL res; ++ + TRACE("hbitmap:%p\n", hbitmap); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap); ++ ++ /* try to get the DIBSECTION data from the bitmap */ ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP)) ++ { ++ /* not a DIB section, use X11 behaviour */ ++ res = _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap); ++ } ++ else ++ { ++ /* it's a DIB section, use DIB Engine behaviour */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap); ++ } ++ return res; + } + + /*********************************************************************** +@@ -61,9 +113,14 @@ BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) + */ + LONG DIBDRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count ) + { ++ LONG res; ++ + TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetBitmapBits(hbitmap, buffer, count); ++ ++ /* GetBitmapBits is only valid for DDBs, so use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetBitmapBits(hbitmap, buffer, count); ++ ++ return res; + } + + /****************************************************************************** +@@ -71,7 +128,12 @@ LONG DIBDRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count ) + */ + LONG DIBDRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count ) + { ++ LONG res; ++ + TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetBitmapBits(hbitmap, bits, count); ++ ++ /* SetBitmapBits is only valid for DDBs, so use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetBitmapBits(hbitmap, bits, count); ++ ++ return res; + } +diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c +index b3c18ef..1ddbb1b 100644 +--- a/dlls/winedib.drv/clipping.c ++++ b/dlls/winedib.drv/clipping.c +@@ -31,6 +31,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + 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); +- ONCE(FIXME("stub\n")); +- _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); ++ } + } +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +index e0ffb4d..c8e3b91 100644 +--- a/dlls/winedib.drv/dc.c ++++ b/dlls/winedib.drv/dc.c +@@ -52,10 +52,15 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + /* sets X11 Device pointer in DIB Engine device */ + physDev->X11PhysDev = X11PhysDev; + ++ /* stock bitmap selected on DC creation */ ++ physDev->hbitmap = GetStockObject(DEFAULT_BITMAP); ++ ++ /* no DIB selected into DC on creation */ ++ physDev->hasDIB = FALSE; ++ + /* sets the result value and returns */ + *pdev = physDev; + +- ONCE(FIXME("stub\n")); + return TRUE; + } + +@@ -85,11 +90,23 @@ BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev ) + INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID in_data, + INT out_count, LPVOID out_data ) + { ++ 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data); ++ } ++ return res; + } + + /*********************************************************************** +@@ -97,8 +114,20 @@ INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID + */ + INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap ) + { ++ INT res; ++ + TRACE("physDev:%p, cap:%d\n", physDev, cap); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c +index 47dce0e..28330fa 100644 +--- a/dlls/winedib.drv/dib.c ++++ b/dlls/winedib.drv/dib.c +@@ -31,10 +31,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, + const BITMAPINFO *bmi, UINT usage ) + { ++ HBITMAP res; ++ + TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pCreateDIBSection(physDev->X11PhysDev, 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); ++ ++ return res; + } + + /*********************************************************************** +@@ -43,11 +48,15 @@ HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, + INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + UINT lines, LPCVOID bits, const BITMAPINFO *bmi, UINT coloruse ) + { ++ 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, 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); ++ ++ return res; + } + + /*********************************************************************** +@@ -56,10 +65,15 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + const RGBQUAD *colors ) + { ++ UINT res; ++ + TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDIBColorTable(physDev->X11PhysDev, 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); ++ ++ return res; + } + + /*********************************************************************** +@@ -68,11 +82,15 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse ) + { ++ 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, 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); ++ ++ return res; + } + + /************************************************************************* +@@ -83,10 +101,14 @@ INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWOR + UINT startscan, UINT lines, LPCVOID bits, + const BITMAPINFO *info, UINT coloruse ) + { ++ 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, ++ /* SetDIBitsToDevice operates on a physical device, so we should use the X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, + startscan, lines, bits, info, coloruse); ++ ++ return res; + } +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index 6dfba06..8a2e139 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -52,6 +52,9 @@ + } \ + } + ++/* extra stock object: default 1x1 bitmap for memory DCs ++ grabbed from gdi_private.h */ ++#define DEFAULT_BITMAP (STOCK_LAST+1) + + /* DIB driver physical device */ + typedef struct _DIBDRVPHYSDEV +@@ -59,6 +62,12 @@ typedef struct _DIBDRVPHYSDEV + /* X11 driver physical device */ + PHYSDEV X11PhysDev; + ++ /* is a DIB selected into DC ? */ ++ BOOL hasDIB; ++ ++ /* currently selected HBITMAP */ ++ HBITMAP hbitmap; ++ + /* active ROP2 */ + INT rop2; + +diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c +index 85f9198..675145f 100644 +--- a/dlls/winedib.drv/font.c ++++ b/dlls/winedib.drv/font.c +@@ -31,10 +31,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + */ + COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, color:%08x\n", physDev, color); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetTextColor(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetTextColor(physDev->X11PhysDev, color); ++ } ++ return res; + } + + /*********************************************************************** +@@ -42,10 +54,22 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + */ + HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, HANDLE gdiFont ) + { ++ HFONT res; ++ + TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSelectFont(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSelectFont(physDev->X11PhysDev, hfont, gdiFont); ++ } ++ return res; + } + + /*********************************************************************** +@@ -54,10 +78,22 @@ HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, HANDLE gdiFont ) + BOOL DIBDRV_EnumDeviceFonts( DIBDRVPHYSDEV *physDev, LPLOGFONTW plf, + FONTENUMPROCW proc, LPARAM lp ) + { ++ BOOL res; ++ + TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pEnumDeviceFonts(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pEnumDeviceFonts(physDev->X11PhysDev, plf, proc, lp); ++ } ++ return res; + } + + /*********************************************************************** +@@ -65,9 +101,22 @@ BOOL DIBDRV_EnumDeviceFonts( DIBDRVPHYSDEV *physDev, LPLOGFONTW plf, + */ + BOOL DIBDRV_GetTextMetrics( DIBDRVPHYSDEV *physDev, TEXTMETRICW *metrics ) + { ++ BOOL res; ++ + TRACE("physDev:%p, metrics:%p\n", physDev, metrics); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetTextMetrics(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetTextMetrics(physDev->X11PhysDev, metrics); ++ } ++ return res; + } + + /*********************************************************************** +@@ -76,8 +125,20 @@ BOOL DIBDRV_GetTextMetrics( DIBDRVPHYSDEV *physDev, TEXTMETRICW *metrics ) + BOOL DIBDRV_GetCharWidth( DIBDRVPHYSDEV *physDev, UINT firstChar, UINT lastChar, + LPINT buffer ) + { ++ BOOL res; ++ + TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetCharWidth(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetCharWidth(physDev->X11PhysDev, firstChar, lastChar, buffer); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +index b746af2..b74c08e 100644 +--- a/dlls/winedib.drv/graphics.c ++++ b/dlls/winedib.drv/graphics.c +@@ -31,12 +31,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, left, top, right, bottom, ++ xstart, ystart, xend, yend); ++ } ++ return res; + } + + /*********************************************************************** +@@ -45,12 +58,25 @@ BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT botto + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, left, top, right, bottom, ++ xstart, ystart, xend, yend); ++ } ++ return res; + } + + /*********************************************************************** +@@ -58,11 +84,23 @@ BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bot + */ + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, left, top, right, bottom); ++ } ++ return res; + } + + /********************************************************************** +@@ -71,11 +109,23 @@ BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT b + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, x, y, color, fillType); ++ } ++ return res; + } + + /*********************************************************************** +@@ -83,10 +133,22 @@ BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color, + */ + BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp ) + { ++ BOOL res; ++ + TRACE("physDev:%p, lpp:%p\n", physDev, lpp); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, lpp); ++ } ++ return res; + } + + /*********************************************************************** +@@ -94,10 +156,22 @@ BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp ) + */ + COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, x, y); ++ } ++ return res; + } + + /*********************************************************************** +@@ -105,10 +179,22 @@ COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y ) + */ + BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y ) + { ++ BOOL res; ++ + TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, x, y); ++ } ++ return res; + } + + /*********************************************************************** +@@ -116,10 +202,22 @@ BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y ) + */ + BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn ) + { ++ BOOL res; ++ + TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, hrgn); ++ } ++ return res; + } + + /*********************************************************************** +@@ -128,12 +226,25 @@ BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn ) + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, left, top, right, bottom, ++ xstart, ystart, xend, yend); ++ } ++ return res; + } + + /********************************************************************** +@@ -141,10 +252,22 @@ BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT botto + */ + BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) + { ++ BOOL res; ++ + TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, pt, count); ++ } ++ return res; + } + + /********************************************************************** +@@ -152,10 +275,22 @@ BOOL DIBDRV_Polygon( 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, pt, count); ++ } ++ return res; + } + + /********************************************************************** +@@ -163,10 +298,22 @@ BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) + */ + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, pt, counts, polygons); ++ } ++ return res; + } + + /********************************************************************** +@@ -175,10 +322,22 @@ BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const INT* cou + BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* counts, + DWORD polylines ) + { ++ BOOL res; ++ + TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, pt, counts, polylines); ++ } ++ return res; + } + + /*********************************************************************** +@@ -186,11 +345,23 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* + */ + BOOL DIBDRV_Rectangle( 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, 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()->pRectangle(physDev->X11PhysDev, left, top, right, bottom); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, left, top, right, bottom); ++ } ++ return res; + } + + /*********************************************************************** +@@ -199,12 +370,25 @@ BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, left, top, right, bottom, ++ ell_width, ell_height); ++ } ++ return res; + } + + /*********************************************************************** +@@ -212,10 +396,22 @@ BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, + */ + COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, x, y, color); ++ } ++ return res; + } + + /*********************************************************************** +@@ -223,8 +419,20 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color ) + */ + DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, INT x, INT y ) + { ++ DWORD res; ++ + TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, x, y); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/opengl.c b/dlls/winedib.drv/opengl.c +index 27e4229..e8ec96c 100644 +--- a/dlls/winedib.drv/opengl.c ++++ b/dlls/winedib.drv/opengl.c +@@ -30,10 +30,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + int DIBDRV_ChoosePixelFormat( DIBDRVPHYSDEV *physDev, + const PIXELFORMATDESCRIPTOR *ppfd ) + { ++ int res; ++ + TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pChoosePixelFormat(physDev->X11PhysDev, ppfd); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pChoosePixelFormat(physDev->X11PhysDev, ppfd); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pChoosePixelFormat(physDev->X11PhysDev, ppfd); ++ } ++ return res; + } + + int DIBDRV_DescribePixelFormat( DIBDRVPHYSDEV *physDev, +@@ -41,36 +53,84 @@ int DIBDRV_DescribePixelFormat( DIBDRVPHYSDEV *physDev, + UINT nBytes, + PIXELFORMATDESCRIPTOR *ppfd ) + { ++ int res; ++ + TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pDescribePixelFormat(physDev->X11PhysDev, iPixelFormat, nBytes, ppfd); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pDescribePixelFormat(physDev->X11PhysDev, iPixelFormat, nBytes, ppfd); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pDescribePixelFormat(physDev->X11PhysDev, iPixelFormat, nBytes, ppfd); ++ } ++ return res; + } + + int DIBDRV_GetPixelFormat( DIBDRVPHYSDEV *physDev) + { ++ int res; ++ + TRACE("physDev:%p\n", physDev); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetPixelFormat(physDev->X11PhysDev); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pGetPixelFormat(physDev->X11PhysDev); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetPixelFormat(physDev->X11PhysDev); ++ } ++ return res; + } + + BOOL DIBDRV_SetPixelFormat( DIBDRVPHYSDEV *physDev, + int iPixelFormat, + const PIXELFORMATDESCRIPTOR *ppfd ) + { ++ BOOL res; ++ + TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetPixelFormat(physDev->X11PhysDev, iPixelFormat, ppfd); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pSetPixelFormat(physDev->X11PhysDev, iPixelFormat, ppfd); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetPixelFormat(physDev->X11PhysDev, iPixelFormat, ppfd); ++ } ++ return res; + } + + BOOL DIBDRV_SwapBuffers( DIBDRVPHYSDEV *physDev ) + { ++ BOOL res; ++ + TRACE("physDev:%p\n", physDev); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSwapBuffers(physDev->X11PhysDev); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pSwapBuffers(physDev->X11PhysDev); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSwapBuffers(physDev->X11PhysDev); ++ } ++ return res; + } + + /** +@@ -80,10 +140,14 @@ BOOL DIBDRV_SwapBuffers( DIBDRVPHYSDEV *physDev ) + */ + BOOL CDECL DIBDRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) + { ++ BOOL res; ++ + TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask); + + ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglCopyContext(hglrcSrc, hglrcDst, mask); ++ res = _DIBDRV_GetDisplayDriver()->pwglCopyContext(hglrcSrc, hglrcDst, mask); ++ ++ return res; + } + + /** +@@ -93,10 +157,22 @@ BOOL CDECL DIBDRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) + */ + HGLRC CDECL DIBDRV_wglCreateContext(DIBDRVPHYSDEV *physDev) + { ++ HGLRC res; ++ + TRACE("physDev:%p\n", physDev); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglCreateContext(physDev->X11PhysDev); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglCreateContext(physDev->X11PhysDev); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglCreateContext(physDev->X11PhysDev); ++ } ++ return res; + } + + /** +@@ -106,10 +182,13 @@ HGLRC CDECL DIBDRV_wglCreateContext(DIBDRVPHYSDEV *physDev) + */ + BOOL CDECL DIBDRV_wglDeleteContext(HGLRC hglrc) + { ++ BOOL res; ++ + TRACE("hglrc:%p\n", hglrc); + + ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglDeleteContext(hglrc); ++ res = _DIBDRV_GetDisplayDriver()->pwglDeleteContext(hglrc); ++ return res; + } + + /** +@@ -119,10 +198,14 @@ BOOL CDECL DIBDRV_wglDeleteContext(HGLRC hglrc) + */ + PROC CDECL DIBDRV_wglGetProcAddress(LPCSTR lpszProc) + { ++ PROC res; ++ + TRACE("lpszProc:%p\n", lpszProc); + + ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglGetProcAddress(lpszProc); ++ res = _DIBDRV_GetDisplayDriver()->pwglGetProcAddress(lpszProc); ++ ++ return res; + } + + /** +@@ -135,10 +218,22 @@ PROC CDECL DIBDRV_wglGetProcAddress(LPCSTR lpszProc) + */ + HDC CDECL DIBDRV_wglGetPbufferDCARB(DIBDRVPHYSDEV *physDev, HPBUFFERARB hPbuffer) + { ++ HDC res; ++ + TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglGetPbufferDCARB(physDev->X11PhysDev, hPbuffer); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglGetPbufferDCARB(physDev->X11PhysDev, hPbuffer); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglGetPbufferDCARB(physDev->X11PhysDev, hPbuffer); ++ } ++ return res; + } + + /** +@@ -148,10 +243,34 @@ HDC CDECL DIBDRV_wglGetPbufferDCARB(DIBDRVPHYSDEV *physDev, HPBUFFERARB hPbuffer + */ + BOOL CDECL DIBDRV_wglMakeContextCurrentARB(DIBDRVPHYSDEV* pDrawDev, DIBDRVPHYSDEV* pReadDev, HGLRC hglrc) + { ++ BOOL res; ++ + TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc); ++ if(pDrawDev->hasDIB && pReadDev->hasDIB) ++ { ++ /* DIB section selected both in source and dest DCs, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc); ++ } ++ if(!pDrawDev->hasDIB && !pReadDev->hasDIB) ++ { ++ /* DDB selected both in source and dest DCs, use X11 Driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc); ++ } ++ else if(pDrawDev->hasDIB) ++ { ++ /* DIB selected in pDrawDev, must convert pReadDev to DIB and use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc); ++ } ++ else /* if(pReadDev->hasDIB) */ ++ { ++ /* DIB selected in pReadDev, must convert pReadDev to DDB and use X11 Driver */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglMakeContextCurrentARB(pDrawDev->X11PhysDev, pReadDev->X11PhysDev, hglrc); ++ } ++ return res; + } + + /** +@@ -161,10 +280,22 @@ BOOL CDECL DIBDRV_wglMakeContextCurrentARB(DIBDRVPHYSDEV* pDrawDev, DIBDRVPHYSDE + */ + BOOL CDECL DIBDRV_wglMakeCurrent(DIBDRVPHYSDEV *physDev, HGLRC hglrc) + { ++ BOOL res; ++ + TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglMakeCurrent(physDev->X11PhysDev, hglrc); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglMakeCurrent(physDev->X11PhysDev, hglrc); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglMakeCurrent(physDev->X11PhysDev, hglrc); ++ } ++ return res; + } + + /** +@@ -175,10 +306,22 @@ BOOL CDECL DIBDRV_wglMakeCurrent(DIBDRVPHYSDEV *physDev, HGLRC hglrc) + */ + BOOL CDECL DIBDRV_wglSetPixelFormatWINE(DIBDRVPHYSDEV *physDev, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd) + { ++ BOOL res; ++ + TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglSetPixelFormatWINE(physDev->X11PhysDev, iPixelFormat, ppfd); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglSetPixelFormatWINE(physDev->X11PhysDev, iPixelFormat, ppfd); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglSetPixelFormatWINE(physDev->X11PhysDev, iPixelFormat, ppfd); ++ } ++ return res; + } + + /** +@@ -188,10 +331,14 @@ BOOL CDECL DIBDRV_wglSetPixelFormatWINE(DIBDRVPHYSDEV *physDev, int iPixelFormat + */ + BOOL CDECL DIBDRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) + { ++ BOOL res; ++ + TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2); + + ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglShareLists(hglrc1, hglrc2); ++ res = _DIBDRV_GetDisplayDriver()->pwglShareLists(hglrc1, hglrc2); ++ ++ return res; + } + + /** +@@ -201,10 +348,22 @@ BOOL CDECL DIBDRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) + */ + BOOL CDECL DIBDRV_wglUseFontBitmapsA(DIBDRVPHYSDEV *physDev, DWORD first, DWORD count, DWORD listBase) + { ++ BOOL res; ++ + TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsA(physDev->X11PhysDev, first, count, listBase); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsA(physDev->X11PhysDev, first, count, listBase); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsA(physDev->X11PhysDev, first, count, listBase); ++ } ++ return res; + } + + /** +@@ -214,8 +373,20 @@ BOOL CDECL DIBDRV_wglUseFontBitmapsA(DIBDRVPHYSDEV *physDev, DWORD first, DWORD + */ + BOOL CDECL DIBDRV_wglUseFontBitmapsW(DIBDRVPHYSDEV *physDev, DWORD first, DWORD count, DWORD listBase) + { ++ BOOL res; ++ + TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsW(physDev->X11PhysDev, first, count, listBase); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsW(physDev->X11PhysDev, first, count, listBase); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pwglUseFontBitmapsW(physDev->X11PhysDev, first, count, listBase); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c +index 28fae09..9daf47d 100644 +--- a/dlls/winedib.drv/palette.c ++++ b/dlls/winedib.drv/palette.c +@@ -30,10 +30,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + */ + UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary ) + { ++ UINT res; ++ + TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE")); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev->X11PhysDev, hpal, primary); ++ /* we should in any case call X11 function, as UnrealizePalette() doesn't ++ * take a physDev parameter */ ++ res = _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev->X11PhysDev, hpal, primary); ++ ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, additional (if needed) engine code */ ++ ONCE(FIXME("STUB\n")); ++ } ++ ++ return res; + } + + /*********************************************************************** +@@ -41,10 +52,18 @@ UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary + */ + BOOL DIBDRV_UnrealizePalette( HPALETTE hpal ) + { ++ BOOL res; ++ + TRACE("hpal:%p\n", hpal); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pUnrealizePalette(hpal); ++ /* we should in any case call X11 function, as UnrealizePalette() doesn't ++ * take a physDev parameter */ ++ res = _DIBDRV_GetDisplayDriver()->pUnrealizePalette(hpal); ++ ++ /* additional Engine code here, if needed */ ++ ONCE(FIXME("STUB\n")); ++ ++ return res; + } + + /*********************************************************************** +@@ -53,10 +72,22 @@ BOOL DIBDRV_UnrealizePalette( HPALETTE hpal ) + UINT DIBDRV_GetSystemPaletteEntries( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + LPPALETTEENTRY entries ) + { ++ UINT res; ++ + TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetSystemPaletteEntries(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetSystemPaletteEntries(physDev->X11PhysDev, start, count, entries); ++ } ++ return res; + } + + /*********************************************************************** +@@ -64,10 +95,22 @@ UINT DIBDRV_GetSystemPaletteEntries( DIBDRVPHYSDEV *physDev, UINT start, UINT co + */ + COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, color:%x\n", physDev, color); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetNearestColor(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetNearestColor(physDev->X11PhysDev, color); ++ } ++ return res; + } + + /*********************************************************************** +@@ -75,16 +118,40 @@ COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + */ + UINT DIBDRV_RealizeDefaultPalette( DIBDRVPHYSDEV *physDev ) + { ++ UINT res; ++ + TRACE("physDev:%p\n", physDev); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev); ++ } ++ return res; + } + + BOOL DIBDRV_GetICMProfile(DIBDRVPHYSDEV *physDev, LPDWORD lpcbName, LPWSTR lpszFilename) + { ++ BOOL res; ++ + TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetICMProfile(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetICMProfile(physDev->X11PhysDev, lpcbName, lpszFilename); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c +index 1e992e0..bde2f23 100644 +--- a/dlls/winedib.drv/pen_brush.c ++++ b/dlls/winedib.drv/pen_brush.c +@@ -31,10 +31,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + */ + HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) + { ++ HPEN res; ++ + TRACE("physDev:%p, hpen:%p\n", physDev, hpen); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSelectPen(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSelectPen(physDev->X11PhysDev, hpen); ++ } ++ return res; + } + + /*********************************************************************** +@@ -42,10 +54,22 @@ HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) + */ + COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, crColor:%x\n", physDev, crColor); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev->X11PhysDev, crColor); ++ } ++ return res; + } + + /*********************************************************************** +@@ -53,10 +77,22 @@ COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + */ + HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + { ++ HBRUSH res; ++ + TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush); ++ } ++ return res; + } + + /*********************************************************************** +@@ -64,10 +100,22 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + */ + COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, crColor:%x\n", physDev, crColor); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev->X11PhysDev, crColor); ++ } ++ return res; + } + + /*********************************************************************** +@@ -79,7 +127,6 @@ INT DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, INT rop ) + + TRACE("physDev:%p, rop:%x\n", physDev, rop); + +- ONCE(FIXME("stub\n")); + prevRop = physDev->rop2; + physDev->rop2 = rop; + return prevRop; +@@ -91,8 +138,20 @@ INT DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, INT rop ) + */ + COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { ++ COLORREF res; ++ + TRACE("physDev:%p, color:%x\n", physDev, color); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev->X11PhysDev, color); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c +index fdb075f..0176011 100644 +--- a/dlls/winedib.drv/text.c ++++ b/dlls/winedib.drv/text.c +@@ -28,17 +28,29 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + /*********************************************************************** + * DIBDRV_ExtTextOut + */ +-BOOL +-DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, +- const RECT *lprect, LPCWSTR wstr, UINT count, +- const INT *lpDx ) ++BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, ++ const RECT *lprect, LPCWSTR wstr, UINT count, ++ const INT *lpDx ) + { ++ BOOL res; ++ + 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); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect, ++ 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect, ++ wstr, count, lpDx); ++ } ++ return res; + } + + /*********************************************************************** +@@ -47,9 +59,23 @@ DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + BOOL DIBDRV_GetTextExtentExPoint( DIBDRVPHYSDEV *physDev, LPCWSTR str, INT count, + INT maxExt, LPINT lpnFit, LPINT alpDx, LPSIZE size ) + { ++ 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); +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetTextExtentExPoint(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetTextExtentExPoint(physDev->X11PhysDev, str, count, maxExt, ++ lpnFit, alpDx, size); ++ } ++ return res; + } +diff --git a/dlls/winedib.drv/video.c b/dlls/winedib.drv/video.c +index 6490ac6..730e62a 100644 +--- a/dlls/winedib.drv/video.c ++++ b/dlls/winedib.drv/video.c +@@ -30,10 +30,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + */ + BOOL DIBDRV_GetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) + { ++ BOOL res; ++ + TRACE("physDev:%p, ramp:%p\n", physDev, ramp); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pGetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); ++ res = _DIBDRV_GetDisplayDriver()->pGetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++ } ++ return res; + } + + /*********************************************************************** +@@ -41,8 +53,20 @@ BOOL DIBDRV_GetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) + */ + BOOL DIBDRV_SetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) + { ++ BOOL res; ++ + TRACE("physDev:%p, ramp:%p\n", physDev, ramp); + +- ONCE(FIXME("stub\n")); +- return _DIBDRV_GetDisplayDriver()->pSetDeviceGammaRamp(physDev->X11PhysDev, 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); ++ } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++ } ++ return res; + } diff --git a/app-emulation/wine/files/0004-dib-engine-implement-most-engi.patch b/app-emulation/wine/files/0004-dib-engine-implement-most-engi.patch new file mode 100644 index 00000000..2d9f7aea --- /dev/null +++ b/app-emulation/wine/files/0004-dib-engine-implement-most-engi.patch @@ -0,0 +1,9088 @@ +DIB Engine: implement most engine functions + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/Makefile.in | 12 + dlls/winedib.drv/bitblt.c | 525 ++++++++++++++-- + dlls/winedib.drv/bitmap.c | 49 +- + dlls/winedib.drv/clipping.c | 6 + dlls/winedib.drv/convert.c | 309 +++++++++ + dlls/winedib.drv/dc.c | 280 ++++++++- + dlls/winedib.drv/dib.c | 24 - + dlls/winedib.drv/dibdrv.h | 292 +++++++++ + dlls/winedib.drv/dibdrv_gdi32.h | 168 +++++ + dlls/winedib.drv/dibdrv_main.c | 11 + dlls/winedib.drv/dibdrvbitmap.c | 650 ++++++++++++++++++++ + dlls/winedib.drv/driver.c | 254 ++++++++ + dlls/winedib.drv/font.c | 116 +++- + dlls/winedib.drv/freetype.c | 136 ++++ + dlls/winedib.drv/freetype.h | 186 ++++++ + dlls/winedib.drv/graphics.c | 264 +++++--- + dlls/winedib.drv/opengl.c | 32 - + dlls/winedib.drv/palette.c | 51 +- + dlls/winedib.drv/pen_brush.c | 492 ++++++++++++++- + dlls/winedib.drv/primitives.c | 274 ++++++++ + dlls/winedib.drv/primitives_bitblt.c | 1075 +++++++++++++++++++++++++++++++++ + dlls/winedib.drv/primitives_color.c | 142 ++++ + dlls/winedib.drv/primitives_convert.c | 559 +++++++++++++++++ + dlls/winedib.drv/primitives_font.c | 310 ++++++++++ + dlls/winedib.drv/primitives_line.c | 434 +++++++++++++ + dlls/winedib.drv/primitives_pixel.c | 244 +++++++ + dlls/winedib.drv/primitives_rop2.c | 112 +++ + dlls/winedib.drv/primitives_rop3.c | 786 ++++++++++++++++++++++++ + dlls/winedib.drv/text.c | 179 +++++ + dlls/winedib.drv/video.c | 8 + 30 files changed, 7706 insertions(+), 274 deletions(-) + create mode 100644 dlls/winedib.drv/convert.c + create mode 100644 dlls/winedib.drv/dibdrv_gdi32.h + create mode 100644 dlls/winedib.drv/dibdrvbitmap.c + create mode 100644 dlls/winedib.drv/driver.c + create mode 100644 dlls/winedib.drv/freetype.c + create mode 100644 dlls/winedib.drv/freetype.h + create mode 100644 dlls/winedib.drv/primitives.c + create mode 100644 dlls/winedib.drv/primitives_bitblt.c + create mode 100644 dlls/winedib.drv/primitives_color.c + create mode 100644 dlls/winedib.drv/primitives_convert.c + create mode 100644 dlls/winedib.drv/primitives_font.c + create mode 100644 dlls/winedib.drv/primitives_line.c + create mode 100644 dlls/winedib.drv/primitives_pixel.c + create mode 100644 dlls/winedib.drv/primitives_rop2.c + create mode 100644 dlls/winedib.drv/primitives_rop3.c + + +diff --git a/dlls/winedib.drv/Makefile.in b/dlls/winedib.drv/Makefile.in +index 66ad14f..722785e 100644 +--- a/dlls/winedib.drv/Makefile.in ++++ b/dlls/winedib.drv/Makefile.in +@@ -11,15 +11,27 @@ C_SRCS = \ + bitblt.c \ + bitmap.c \ + clipping.c \ ++ convert.c \ + dc.c \ + dib.c \ + dibdrv_main.c \ ++ dibdrvbitmap.c \ + driver.c \ + font.c \ ++ freetype.c \ + graphics.c \ + opengl.c \ + palette.c \ + pen_brush.c \ ++ primitives.c \ ++ primitives_bitblt.c \ ++ primitives_color.c \ ++ primitives_convert.c \ ++ primitives_font.c \ ++ primitives_line.c \ ++ primitives_pixel.c \ ++ primitives_rop2.c \ ++ primitives_rop3.c \ + text.c \ + video.c + +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index 022f223..20cdcaa 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -25,6 +25,117 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++static inline void intSwap(int *a, int *b) ++{ ++ int tmp; ++ tmp = *a; ++ *a = *b; ++ *b = tmp; ++} ++ ++/* clips a source and destination areas to their respective clip rectangles ++ returning both source and dest modified; result is TRUE if clipping ++ leads to a non null rectangle, FALSE otherwise */ ++static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT*dstClip) ++{ ++ int xs1, ys1, xs2, ys2; ++ int xsc1, ysc1, xsc2, ysc2; ++ int xd1, yd1, xd2, yd2; ++ int xdc1, ydc1, xdc2, ydc2; ++ int w, h, dx, dy; ++ ++ /* extract sizes */ ++ w = sz->cx; h = sz->cy; ++ ++ /* if sizes null or negative, just return false */ ++ if(w <= 0 || h <= 0) ++ return FALSE; ++ ++ /* extract dest area data */ ++ xd1 = pd->x; ++ yd1 = pd->y; ++ xd2 = xd1 + w; ++ yd2 = yd1 + h; ++ ++ /* extract source data */ ++ xs1 = ps->x; ++ ys1 = ps->y; ++ xs2 = xs1 + w; ++ ys2 = ys1 + h; ++ ++ /* if source clip area is not null, do first clipping on it */ ++ if(srcClip) ++ { ++ /* extract source clipping area */ ++ xsc1 = srcClip->left; ++ ysc1 = srcClip->top; ++ xsc2 = srcClip->right; ++ ysc2 = srcClip->bottom; ++ ++ /* order clip area rectangle points */ ++ if(xsc1 > xsc2) intSwap(&xsc1, &xsc2); ++ if(ysc1 > ysc2) intSwap(&ysc1, &ysc2); ++ ++ /* clip on source clipping start point */ ++ if(xs1 < xsc1) { dx = xsc1 - xs1; w -= dx; xd1 += dx; xs1 = xsc1; } ++ if(ys1 < ysc1) { dy = ysc1 - ys1; h -= dy; yd1 += dy; ys1 = ysc1; } ++ ++ /* clip on source clipping end point */ ++ if(xs2 > xsc2) { dx = xs2 - xsc2; w -= dx; xd2 -= dx; xs2 = xsc2; } ++ if(ys2 > ysc2) { dy = ys2 - ysc2; h -= dy; yd2 -= dy; ys2 = ysc2; } ++ ++ /* if already zero area, return false */ ++ if(w <= 0 || h <= 0) ++ return FALSE; ++ } ++ /* now do clipping on destination area */ ++ ++ if(dstClip) ++ { ++ /* extract destination clipping area */ ++ xdc1 = dstClip->left; ++ ydc1 = dstClip->top; ++ xdc2 = dstClip->right; ++ ydc2 = dstClip->bottom; ++ ++ /* order clip area rectangle points */ ++ if(xdc1 > xdc2) intSwap(&xdc1, &xdc2); ++ if(ydc1 > ydc2) intSwap(&ydc1, &ydc2); ++ ++ /* clip on dest clipping start point */ ++ if(xd1 < xdc1) { dx = xdc1 - xd1; w -= dx; xs1 += dx; xd1 = xdc1; } ++ if(yd1 < ydc1) { dy = ydc1 - yd1; h -= dy; ys1 += dy; yd1 = ydc1; } ++ ++ /* clip on dest clipping end point */ ++ if(xd2 > xdc2) { dx = xd2 - xdc2; w -= dx; xs2 -= dx; xd2 = xdc2; } ++ if(yd2 > ydc2) { dy = yd2 - ydc2; h -= dy; ys2 -= dy; yd2 = ydc2; } ++ ++ /* if already zero area, return false */ ++ if(w <= 0 || h <= 0) ++ return FALSE; ++ } ++ ++ /* sets clipped/translated points and sizes and returns TRUE */ ++ ps->x = xs1; ps->y = ys1; ++ pd->x = xd1; pd->y = yd1; ++ sz->cx = w; sz->cy = h; ++ ++ return TRUE; ++ ++} ++ ++ ++/* clips a source and destination areas to their respective clip rectangles ++ returning both source and dest modified; result is TRUE if clipping ++ leads to a non null rectangle, FALSE otherwise */ ++static BOOL StretchBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *szSrc, SIZE *szDst, RECT*srcClip, RECT*dstClip) ++{ ++ ONCE(FIXME("TO DO\n")); ++ ++ return TRUE; ++ ++} ++ + /*********************************************************************** + * DIBDRV_AlphaBlend + */ +@@ -34,16 +145,17 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + { + BOOL res; + +- TRACE("physDevDst:%p, xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p, xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n", +- physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc); ++ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n", ++ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "", ++ xDst, yDst, widthDst, heightDst, ++ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "", ++ xSrc, ySrc, widthSrc, heightSrc)); + + if(physDevDst->hasDIB && physDevSrc->hasDIB) + { + /* DIB section selected in both source and dest DC, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, +- blendfn); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else if(!physDevDst->hasDIB && !physDevSrc->hasDIB) + { +@@ -63,10 +175,8 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + else /* if(physDevDst->hasDIB) */ + { + /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, +- blendfn); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + return res; + } +@@ -80,35 +190,171 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + { + BOOL res; + +- TRACE("physDevDst:%p, xDst:%d, yDst:%d, width:%d, height:%d, physDevSrc:%p, xSrc:%d, ySrc:%d, rop:%08x\n", +- physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop); ++ /* clip blit area */ ++ POINT pd = {xDst, yDst}; ++ POINT ps = {xSrc, ySrc}; ++ SIZE sz = {width, height}; + +- if(physDevDst->hasDIB && physDevSrc->hasDIB) +- { +- /* DIB section selected in both source and dest DC, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, +- physDevSrc->X11PhysDev, xSrc, ySrc, rop); +- } +- else if(!physDevDst->hasDIB && !physDevSrc->hasDIB) +- { +- /* DDB selected in noth source and dest DC, use X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, +- physDevSrc->X11PhysDev, xSrc, ySrc, rop); +- } +- else if(physDevSrc->hasDIB) ++ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, width:%d, height:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, rop:%08x\n", ++ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "", ++ xDst, yDst, width, height, ++ physDevSrc, physDevSrc ? (physDevSrc->hasDIB ? "DIB-" : "DDB"): "---", physDevSrc && physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "", ++ xSrc, ySrc, rop)); ++ ++ if(physDevDst->hasDIB) + { +- /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, +- physDevSrc->X11PhysDev, xSrc, ySrc, rop); ++ /* DIB section selected in dest DC, use DIB Engine */ ++ ++ /* clip blit area */ ++ RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height}; ++ ++ if(!physDevSrc || physDevSrc->hasDIB) ++ { ++ /* clip blit area */ ++ if(physDevSrc) ++ { ++ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; ++ res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, &dstClip); ++ } ++ else ++ res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip); ++ if(!res) ++ goto noBlt2; ++ xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y; ++ ++ /* source is null or has a DIB, no need to convert anyting */ ++ res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop); ++ } ++ else ++ { ++ /* source is a DDB, must convert it to DIB */ ++ ++ /* don't clip on source */ ++ res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip); ++ if(!res) ++ goto noBlt2; ++ xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y; ++ ++ /* we must differentiate from 2 cases : ++ 1) source DC is a memory DC ++ 2) source DC is a device DC */ ++ if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC) ++ { ++ /* memory DC */ ++ HBITMAP dib, ddb; ++ ++ ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP)); ++ if(!ddb) ++ { ++ ERR("Couldn't select out DDB from source HDC\n"); ++ res = 0; ++ goto noBlt1; ++ } ++ dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, ySrc, height); ++ if(!dib) ++ { ++ ERR("Failed converting source DDB to DIB\n"); ++ SelectObject(physDevSrc->hdc, ddb); ++ res = 0; ++ goto noBlt1; ++ } ++ SelectObject(physDevSrc->hdc, dib); ++ res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height, ++ physDevSrc, xSrc, 0, rop); ++ SelectObject(physDevSrc->hdc, ddb); ++ DeleteObject(dib); ++ noBlt1: ++ ; ++ } ++ else ++ { ++ /* device DC */ ++ HBITMAP dib, stock; ++ HDC memHdc; ++ ++ dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, xSrc, ySrc, width, height); ++ if(!dib) ++ { ++ ERR("Failed converting source DDB tp DIB for device DC\n"); ++ res = 0; ++ goto noBlt2; ++ } ++ memHdc = CreateCompatibleDC(physDevDst->hdc); ++ if(!memHdc) ++ { ++ ERR("Failed creating temporary memory DC\n"); ++ DeleteObject(dib); ++ res = 0; ++ goto noBlt2; ++ } ++ stock = SelectObject(memHdc, dib); ++ if(!stock) ++ { ++ ERR("Failed selecting converted DIB into temporary memory DC\n"); ++ DeleteObject(dib); ++ DeleteDC(memHdc); ++ res = 0; ++ goto noBlt2; ++ } ++ res = BitBlt(physDevDst->hdc, xDst, yDst, width, height, memHdc, 0, 0, rop); ++ ++ SelectObject(memHdc, stock); ++ DeleteObject(dib); ++ DeleteDC(memHdc); ++ noBlt2: ++ ; ++ } ++ } + } +- else /* if(physDevDst->hasDIB) */ ++ else /* dest is a DDB */ + { +- /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, +- physDevSrc->X11PhysDev, xSrc, ySrc, rop); ++ /* DDB selected on dest DC, use X11 Driver */ ++ if(!physDevSrc || !physDevSrc->hasDIB) ++ { ++ /* source is null or has also a DDB, no need to convert anything */ ++ res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, ++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, rop); ++ } ++ else ++ { ++ /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */ ++ HBITMAP dib, ddb; ++ ++ /* clip blit area */ ++ if(physDevSrc) ++ { ++ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; ++ res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0); ++ } ++ else ++ res = TRUE; ++ if(!res) ++ goto noBlt3; ++ xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y; ++ ++ dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP)); ++ if(!dib) ++ { ++ ERR("Couldn't select out DIB from source HDC\n"); ++ res = 0; ++ goto noBlt3; ++ } ++ ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, ySrc, height); ++ if(!ddb) ++ { ++ ERR("Failed converting source DIB to DDB\n"); ++ SelectObject(physDevSrc->hdc, dib); ++ res = 0; ++ goto noBlt3; ++ } ++ SelectObject(physDevSrc->hdc, ddb); ++ res = _DIBDRV_GetDisplayDriver()->pBitBlt(physDevDst->X11PhysDev, xDst, yDst, width, height, ++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, 0, rop); ++ SelectObject(physDevSrc->hdc, dib); ++ DeleteObject(ddb); ++noBlt3: ++ ; ++ } + } + return res; + } +@@ -123,35 +369,186 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + { + BOOL res; + +- TRACE("physDevDst:%p, xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p, xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d, rop:%8x\n", +- physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop); ++ /* clip blit area */ ++ POINT pd = {xDst, yDst}; ++ POINT ps = {xSrc, ySrc}; ++ SIZE szDst = {widthDst, heightDst}; ++ SIZE szSrc = {widthSrc, heightSrc}; + +- if(physDevDst->hasDIB && physDevSrc->hasDIB) +- { +- /* DIB section selected in both source and dest DC, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop); +- } +- else if(!physDevDst->hasDIB && !physDevSrc->hasDIB) +- { +- /* DDB selected in noth source and dest DC, use X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop); +- } +- else if(physDevSrc->hasDIB) ++ /* if source and dest sizes match, just call BitBlt(), it's faster */ ++ if(!physDevSrc || (widthDst == widthSrc && heightDst == heightSrc)) ++ return DIBDRV_BitBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, rop); ++ ++ MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d, rop:%08x\n", ++ physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "", ++ xDst, yDst, widthDst, heightDst, ++ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "", ++ xSrc, ySrc, widthSrc, heightSrc, rop)); ++ ++ if(physDevDst->hasDIB) + { +- /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop); ++ /* DIB section selected in dest DC, use DIB Engine */ ++ ++ /* clip blit area */ ++ RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height}; ++ ++ if(!physDevSrc || physDevSrc->hasDIB) ++ { ++ /* clip blit area */ ++ if(physDevSrc) ++ { ++ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; ++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip); ++ } ++ else ++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip); ++ if(!res) ++ goto noBlt2; ++ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy; ++ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ ++ /* source is null or has a DIB, no need to convert anyting */ ++ res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, physDevSrc, xSrc, ySrc, widthSrc, heightSrc, rop); ++ } ++ else ++ { ++ /* source is a DDB, must convert it to DIB */ ++ ++ /* don't clip on source */ ++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip); ++ if(!res) ++ goto noBlt2; ++ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy; ++ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ ++ /* we must differentiate from 2 cases : ++ 1) source DC is a memory DC ++ 2) source DC is a device DC */ ++ if(GetObjectType(physDevSrc->hdc) == OBJ_MEMDC) ++ { ++ /* memory DC */ ++ HBITMAP dib, ddb; ++ ++ ddb = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP)); ++ if(!ddb) ++ { ++ ERR("Couldn't select out DDB from source HDC\n"); ++ res = 0; ++ goto noBlt1; ++ } ++ dib = _DIBDRV_ConvertDDBtoDIB(physDevSrc->hdc, ddb, ySrc, heightSrc); ++ if(!dib) ++ { ++ ERR("Failed converting source DDB to DIB\n"); ++ SelectObject(physDevSrc->hdc, ddb); ++ res = 0; ++ goto noBlt1; ++ } ++ SelectObject(physDevSrc->hdc, dib); ++ res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, ++ physDevSrc, xSrc, 0, widthSrc, heightSrc, rop); ++ SelectObject(physDevSrc->hdc, ddb); ++ DeleteObject(dib); ++ noBlt1: ++ ; ++ } ++ else ++ { ++ /* device DC */ ++ HBITMAP dib, stock; ++ HDC memHdc; ++ ++ dib = _DIBDRV_ConvertDevDDBtoDIB(physDevSrc->hdc, physDevDst->hdc, xSrc, ySrc, widthSrc, heightSrc); ++ if(!dib) ++ { ++ ERR("Failed converting source DDB tp DIB for device DC\n"); ++ res = 0; ++ goto noBlt2; ++ } ++ memHdc = CreateCompatibleDC(physDevDst->hdc); ++ if(!memHdc) ++ { ++ ERR("Failed creating temporary memory DC\n"); ++ DeleteObject(dib); ++ res = 0; ++ goto noBlt2; ++ } ++ stock = SelectObject(memHdc, dib); ++ if(!stock) ++ { ++ ERR("Failed selecting converted DIB into temporary memory DC\n"); ++ DeleteObject(dib); ++ DeleteDC(memHdc); ++ res = 0; ++ goto noBlt2; ++ } ++ res = StretchBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, memHdc, 0, 0, widthSrc, widthDst, rop); ++ ++ SelectObject(memHdc, stock); ++ DeleteObject(dib); ++ DeleteDC(memHdc); ++ noBlt2: ++ ; ++ } ++ } + } +- else /* if(physDevDst->hasDIB) */ ++ else /* dest is a DDB */ + { +- /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthSrc, heightSrc, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthDst, heightDst, rop); ++ /* DDB selected on dest DC, use X11 Driver */ ++ if(!physDevSrc || !physDevSrc->hasDIB) ++ { ++ /* source is null or has also a DDB, no need to convert anything */ ++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, ++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, ySrc, widthSrc, heightSrc, rop); ++ } ++ else ++ { ++ /* DIB on source, DDB on dest -- must convert source DIB to DDB and use X11 driver for blit */ ++ HBITMAP dib, ddb; ++ ++ /* clip blit area */ ++ if(physDevSrc) ++ { ++ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; ++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0); ++ } ++ else ++ res = TRUE; ++ if(!res) ++ goto noBlt3; ++ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy; ++ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ ++ dib = SelectObject(physDevSrc->hdc, GetStockObject(DEFAULT_BITMAP)); ++ if(!dib) ++ { ++ ERR("Couldn't select out DIB from source HDC\n"); ++ res = 0; ++ goto noBlt3; ++ } ++ ddb = _DIBDRV_ConvertDIBtoDDB(physDevSrc->hdc, dib, ySrc, heightSrc); ++ if(!ddb) ++ { ++ ERR("Failed converting source DIB to DDB\n"); ++ SelectObject(physDevSrc->hdc, dib); ++ res = 0; ++ goto noBlt3; ++ } ++ if(!SelectObject(physDevSrc->hdc, ddb)) ++ { ++ ERR("Failed to select converted DDB into source HDC\n"); ++ SelectObject(physDevSrc->hdc, dib); ++ DeleteObject(ddb); ++ res = 0; ++ goto noBlt3; ++ } ++ res = _DIBDRV_GetDisplayDriver()->pStretchBlt(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, ++ physDevSrc ? physDevSrc->X11PhysDev : 0, xSrc, 0, widthSrc, heightSrc, rop); ++ SelectObject(physDevSrc->hdc, dib); ++ DeleteObject(ddb); ++noBlt3: ++ ; ++ } + } + return res; + } +@@ -162,14 +559,14 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + BOOL DIBDRV_PatBlt( DIBDRVPHYSDEV *physDev, INT left, INT top, INT width, INT height, DWORD rop ) + { + BOOL res; +- +- TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop); ++ ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, width:%d, height:%d, rop:%06x\n", physDev, left, top, width, height, rop)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPatBlt(physDev->X11PhysDev, left, top, width, height, rop); ++ ONCE(FIXME("TEMPORARY - use BitBlt by now\n")); ++ res = DIBDRV_BitBlt(physDev, left, top, width, height, NULL, 0, 0, rop); + } + else + { +diff --git a/dlls/winedib.drv/bitmap.c b/dlls/winedib.drv/bitmap.c +index df7c03a..f3d3b9c 100644 +--- a/dlls/winedib.drv/bitmap.c ++++ b/dlls/winedib.drv/bitmap.c +@@ -34,12 +34,12 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) + DIBSECTION dibSection; + HBITMAP res; + +- TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap); +- + /* try to get the DIBSECTION data from the bitmap */ + if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP)) + { + /* not a DIB section, sets it on physDev and use X11 behaviour */ ++ ++ MAYBE(TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap)); + physDev->hasDIB = FALSE; + res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap); + if(res) +@@ -48,11 +48,30 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) + else + { + /* it's a DIB section, sets it on physDev and use DIB Engine behaviour */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- physDev->hasDIB = TRUE; +- res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap); +- if(res) ++ ++ MAYBE(TRACE("physDev:%p, hbitmap:%p, physBitmap=%p\n", physDev, hbitmap, &physDev->physBitmap)); ++ ++ /* frees any previously physical bitmap */ ++ _DIBDRVBITMAP_Free(&physDev->physBitmap); ++ ++ /* WARNING : the color table can't be grabbed here, since it's still ++ not initialized. It'll be grabbed on RealizeDefaultPalette(), ++ which is presumably the first call made after palette initialization. ++ So, by now we just set up palette size and leave NULL the palette pointer */ ++ if(_DIBDRVBITMAP_InitFromBMIH(&physDev->physBitmap, &dibSection.dsBmih, dibSection.dsBitfields, NULL, dibSection.dsBm.bmBits)) ++ { ++ /* stores the active bitmap */ ++ res = physDev->hbitmap; + physDev->hbitmap = hbitmap; ++ ++ /* remember there's a DIB selected in */ ++ physDev->hasDIB = TRUE; ++ } ++ else ++ { ++ ERR("Failed to initialize physical bitmap\n"); ++ res = 0; ++ } + } + return res; + +@@ -66,7 +85,7 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits + DIBSECTION dibSection; + BOOL res; + +- TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits); ++ MAYBE(TRACE("physDev:%p, hbitmap:%p, bmBits:%p\n", physDev, hbitmap, bmBits)); + + /* try to get the DIBSECTION data from the bitmap */ + if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP)) +@@ -76,9 +95,9 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits + } + else + { +- /* it's a DIB section, use DIB Engine behaviour */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pCreateBitmap(physDev->X11PhysDev, hbitmap, bmBits); ++ /* it's a DIB section, use DIB Engine behaviour - should not happen, but.... */ ++ ONCE(FIXME("CreateBitmap() called for a DIB section - shouldn't happen\n")); ++ res = TRUE; + } + return res; + } +@@ -91,7 +110,7 @@ BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) + DIBSECTION dibSection; + BOOL res; + +- TRACE("hbitmap:%p\n", hbitmap); ++ MAYBE(TRACE("hbitmap:%p\n", hbitmap)); + + /* try to get the DIBSECTION data from the bitmap */ + if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP)) +@@ -102,8 +121,8 @@ BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) + else + { + /* it's a DIB section, use DIB Engine behaviour */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + return res; + } +@@ -115,7 +134,7 @@ LONG DIBDRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count ) + { + LONG res; + +- TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count); ++ MAYBE(TRACE("hbitmap:%p, buffer:%p, count:%d\n", hbitmap, buffer, count)); + + /* GetBitmapBits is only valid for DDBs, so use X11 driver */ + res = _DIBDRV_GetDisplayDriver()->pGetBitmapBits(hbitmap, buffer, count); +@@ -130,7 +149,7 @@ LONG DIBDRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count ) + { + LONG res; + +- TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count); ++ MAYBE(TRACE("hbitmap:%p, bits:%p, count:%d\n", hbitmap, bits, count)); + + /* SetBitmapBits is only valid for DDBs, so use X11 driver */ + res = _DIBDRV_GetDisplayDriver()->pSetBitmapBits(hbitmap, bits, count); +diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c +index 1ddbb1b..81dec25 100644 +--- a/dlls/winedib.drv/clipping.c ++++ b/dlls/winedib.drv/clipping.c +@@ -25,18 +25,18 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++ + /*********************************************************************** + * DIBDRV_SetDeviceClipping + */ + void DIBDRV_SetDeviceClipping( DIBDRVPHYSDEV *physDev, HRGN vis_rgn, HRGN clip_rgn ) + { +- TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn); ++ MAYBE(TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); ++ ONCE(FIXME("STUB\n")); + } + else + { +diff --git a/dlls/winedib.drv/convert.c b/dlls/winedib.drv/convert.c +new file mode 100644 +index 0000000..dc18e14 +--- /dev/null ++++ b/dlls/winedib.drv/convert.c +@@ -0,0 +1,309 @@ ++/* ++ * DIB Engine conversion routines ++ * Converts DDB <--> DIB ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++#include "winuser.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/*********************************************************************** ++ * Creates DDB that is compatible with source hdc. ++ * hdc is the HDC on where the DIB MUST be selected in ++ * srcBmp is the source DIB ++ * startScan and scanLines specify the portion of DIB to convert ++ * in order to avoid unneeded conversion of large DIBs on blitting ++ * ++ * NOTE : the srcBmp DIB MUST NOT be selected in any DC */ ++HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines ) ++{ ++ DIBSECTION ds; ++ BITMAPINFO *bmi; ++ HBITMAP hBmp = NULL; ++ ++ int dibWidth, dibHeight; ++ BOOL topDown; ++ void *bits; ++ int stride; ++ UINT colorUsed; ++ int bitFields; ++ HDC tmpHdc; ++ HBITMAP tmpBmp; ++ int res; ++ ++ /* gets DIBSECTION data from source DIB */ ++ if(GetObjectW(srcBmp, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION)) ++ { ++ ERR("Couldn't get DIBSECTION data\n"); ++ return 0; ++ } ++ ++ /* gets DIB info */ ++ dibWidth = ds.dsBmih.biWidth; ++ dibHeight = ds.dsBmih.biHeight; ++ bits = ds.dsBm.bmBits; ++ stride = ((dibWidth * ds.dsBmih.biBitCount +31) &~31) / 8; ++ ++ /* adjust bits to point at needed starting stripe */ ++ if(dibHeight < 0) ++ { ++ /* top-down DIB */ ++ topDown = TRUE; ++ dibHeight = -dibHeight; ++ bits = (BYTE *)bits + startScan * stride; ++ } ++ else ++ { ++ topDown = FALSE; ++ bits = (BYTE *)bits + (dibHeight - startScan - scanLines) * stride; ++ } ++ ++ /* if requested part is out of source bitmap, returns 0 */ ++ if(startScan >= dibHeight) ++ return 0; ++ if(startScan + scanLines >= dibHeight) ++ scanLines = dibHeight - startScan; ++ ++ /* gets the size of DIB palette and bitfields, if any */ ++ bitFields = 0; ++ if(ds.dsBmih.biBitCount > 8) ++ { ++ colorUsed = 0; ++ if(ds.dsBmih.biCompression == BI_BITFIELDS) ++ bitFields = 3; ++ } ++ else ++ { ++ colorUsed = ds.dsBmih.biClrUsed; ++ if(!colorUsed) ++ colorUsed = 1 << ds.dsBmih.biBitCount; ++ } ++ ++ /* builds the needed BITMAPINFOHEADER */ ++ bmi = HeapAlloc( GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER)+ ++ sizeof(RGBQUAD)*colorUsed + sizeof(DWORD) * bitFields ); ++ if (!bmi) ++ { ++ ERR("HeapAlloc failed\n"); ++ return 0; ++ } ++ ++ /* copy the header part */ ++ memcpy( &bmi->bmiHeader, &ds.dsBmih, sizeof(BITMAPINFOHEADER) ); ++ ++ /* gets the color table part, if any */ ++ if(colorUsed) ++ { ++ /* create a temporary DC, GetDIBColorTable() requests that ++ the DIB is selected in a DC.... */ ++ if(!(tmpHdc = CreateCompatibleDC(hdc))) ++ { ++ ERR("Couldn't create the temporary HDC\n"); ++ HeapFree(GetProcessHeap(), 0, bmi); ++ return 0; ++ } ++ /* selects the DIB into the temporary DC */ ++ if( !(tmpBmp = SelectObject(tmpHdc, srcBmp))) ++ { ++ ERR("Couldn't select source DIB into temporary DC\n"); ++ DeleteDC(tmpHdc); ++ HeapFree(GetProcessHeap(), 0, bmi); ++ return 0; ++ } ++ GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors); ++ SelectObject(tmpHdc, tmpBmp); ++ DeleteDC(tmpHdc); ++ } ++ ++ /* fill the bitfields part, if any */ ++ if(bitFields) ++ memcpy(bmi->bmiColors, ds.dsBitfields, 3 * sizeof(DWORD)); ++ ++ /* adjust dib size for SetDIBits, as it needs it to reverse top-down dibs ++ it must be set to the number of scanLines to transfer */ ++ bmi->bmiHeader.biHeight = topDown ? -scanLines : scanLines; ++ ++ /* creates destination compatible bitmap */ ++ tmpHdc = GetDC(NULL); ++ hBmp = CreateCompatibleBitmap(tmpHdc, dibWidth, scanLines); ++ ReleaseDC(NULL, tmpHdc); ++ if(!hBmp) ++ { ++ ERR("CreateCompatibleBitmap failed\n"); ++ HeapFree( GetProcessHeap(), 0, bmi ); ++ return 0; ++ } ++ ++ /* copies the requested scan lines from DIB to DDB */ ++ /* FIXME : still no support for RLE packed DIBs */ ++ res = SetDIBits( hdc, hBmp, 0, scanLines, bits, bmi, DIB_RGB_COLORS ); ++ HeapFree( GetProcessHeap(), 0, bmi ); ++ if(!res) ++ { ++ ERR("SetDIBits failed\n"); ++ DeleteObject( hBmp ); ++ return 0; ++ } ++ return hBmp; ++} ++ ++/*********************************************************************** ++ * Creates DIB that is compatible with the target hdc. ++ * startScan and scanLines specify the portion of DDB to convert ++ * in order to avoid unneeded conversion of large DDBs on blitting ++ * ++ * NOTE : the srcBmp DDB MUST NOT be selected in any DC */ ++HBITMAP _DIBDRV_ConvertDDBtoDIB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines ) ++{ ++ HBITMAP hBmp = NULL; ++ BITMAP bitmap; ++ BITMAPINFO *bi; ++ void *bits = NULL; ++ ++ if (!GetObjectW( srcBmp, sizeof(bitmap), &bitmap )) ++ { ++ ERR("Couldn't retrieve source bitmap\n"); ++ return 0; ++ } ++ ++ if(startScan + scanLines >= bitmap.bmHeight) ++ scanLines = bitmap.bmHeight - startScan; ++ ++ bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) /* + 256 * sizeof(RGBQUAD) */); ++ if (!bi) ++ { ++ ERR("HeapAlloc failed\n"); ++ return 0; ++ } ++ ++ bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); ++ bi->bmiHeader.biWidth = bitmap.bmWidth; ++ bi->bmiHeader.biHeight = scanLines; ++ bi->bmiHeader.biPlanes = bitmap.bmPlanes; ++ bi->bmiHeader.biBitCount = 32; /* bitmap.bmBitsPixel; */ ++ bi->bmiHeader.biCompression = BI_RGB; ++ bi->bmiHeader.biSizeImage = 0; ++ ++ /* Get the color table or the color masks */ ++ /* NO NEED -- WE'RE REQUESTING A 32 bit DIB */ ++#if 0 ++ if (!GetDIBits(hdc, srcBmp, startScan, scanLines, NULL, bi, DIB_RGB_COLORS)) ++ { ++ ERR("Couldn't get the color table/masks\n"); ++ HeapFree( GetProcessHeap(), 0, bi ); ++ return 0; ++ } ++#endif ++ ++ /* Create bitmap and fill in bits */ ++ hBmp = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0); ++ if(!hBmp) ++ { ++ ERR("Failed to create DIB section\n"); ++ HeapFree( GetProcessHeap(), 0, bi ); ++ return 0; ++ } ++ if (bits) ++ { ++ if(!GetDIBits(hdc, srcBmp, startScan, scanLines, bits, bi, DIB_RGB_COLORS)) ++ { ++ ERR("GetDIBits failed\n"); ++ DeleteObject( hBmp ); ++ HeapFree( GetProcessHeap(), 0, bi ); ++ return 0; ++ } ++ } ++ else ++ { ++ ERR("CreateDibSection couldn't allocate DIB bits\n"); ++ DeleteObject( hBmp ); ++ HeapFree( GetProcessHeap(), 0, bi ); ++ return 0; ++ } ++ HeapFree( GetProcessHeap(), 0, bi ); ++ return hBmp; ++} ++ ++/*********************************************************************** ++ * BITBLT_ConvertDevDDBtoDIB ++ * ++ * Creates DIB that is compatible with the target hdc for a device (non memory) source DC */ ++HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, int width, int height ) ++{ ++ HBITMAP bmp, dib; ++ HDC memHDC = NULL; ++ ++ /* at first, we create a compatible DC and a bitmap with needed sizes */ ++ memHDC = CreateCompatibleDC(hdcSrc); ++ if(!memHDC) ++ { ++ ERR("CreateCompatibleDC failed\n"); ++ return 0; ++ } ++ bmp = CreateCompatibleBitmap(hdcSrc, width, height); ++ if(!bmp) ++ { ++ ERR("CreateCompatibleBitmap failed\n"); ++ DeleteDC(memHDC); ++ return 0; ++ } ++ ++ /* select the newly created DDB into the temporary DC */ ++ bmp = SelectObject(memHDC, bmp); ++ if(!bmp) ++ { ++ ERR("Failed selecting DDB into temporary DC\n"); ++ DeleteObject(bmp); ++ DeleteDC(memHDC); ++ return 0; ++ } ++ ++ /* next, we blit pixels from device to the compatible bitmap */ ++ if(!BitBlt(memHDC, 0, 0, width, height, hdcSrc, xSrc, ySrc, SRCCOPY)) ++ { ++ ERR("BitBlt failed\n"); ++ DeleteObject(bmp); ++ DeleteDC(memHDC); ++ return 0; ++ } ++ ++ /* select out the DDB from the temporary DC */ ++ bmp = SelectObject(memHDC, bmp); ++ DeleteDC(memHDC); ++ if(!bmp) ++ { ++ ERR("Failed selecting DDB out temporary DC\n"); ++ DeleteObject(bmp); ++ return 0; ++ } ++ ++ /*now we can convert the bitmap to a DIB */ ++ dib = _DIBDRV_ConvertDDBtoDIB( hdcDst, bmp, 0, height ); ++ if(!dib) ++ FIXME("ConvertDDBtoDIB failed\n"); ++ ++ /* free resources and return the created dib */ ++ DeleteObject(bmp); ++ return dib; ++} +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +index c8e3b91..6184677 100644 +--- a/dlls/winedib.drv/dc.c ++++ b/dlls/winedib.drv/dc.c +@@ -25,6 +25,100 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++ ++/* some screen caps */ ++static unsigned int screen_width; ++static unsigned int screen_height; ++static unsigned int screen_bpp; ++static unsigned int screen_depth; ++static RECT virtual_screen_rect; ++ ++/* a few dynamic device caps */ ++static int log_pixels_x; /* pixels per logical inch in x direction */ ++static int log_pixels_y; /* pixels per logical inch in y direction */ ++static int horz_size; /* horz. size of screen in millimeters */ ++static int vert_size; /* vert. size of screen in millimeters */ ++static int palette_size; ++static int device_init_done; ++ ++/* NOTE : ++ Removing TC_RA_ABLE avoids bitmapped fonts, so FT_Face is always non-NULL ++ Adding TC_VA_ABLE forces to use gdi fonts always, so we can get an FT_Face ++*/ ++unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE | ++ TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER | ++ TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE /* | TC_RA_ABLE */ | TC_VA_ABLE); ++ /* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */ ++ ++ ++static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'}; ++static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'}; ++ ++/****************************************************************************** ++ * get_dpi ++ * ++ * get the dpi from the registry ++ */ ++static DWORD get_dpi( void ) ++{ ++ DWORD dpi = 96; ++ HKEY hkey; ++ ++ if (RegOpenKeyW(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS) ++ { ++ DWORD type, size, new_dpi; ++ ++ size = sizeof(new_dpi); ++ if(RegQueryValueExW(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS) ++ { ++ if(type == REG_DWORD && new_dpi != 0) ++ dpi = new_dpi; ++ } ++ RegCloseKey(hkey); ++ } ++ return dpi; ++} ++ ++/********************************************************************** ++ * device_init ++ * ++ * Perform initializations needed upon creation of the first device. ++ */ ++static void device_init(void) ++{ ++ Display *display; ++ Screen *screen; ++ ++ /* opens default X11 Display */ ++ if( (display = XOpenDisplay(NULL)) == NULL) ++ return; ++ ++ /* gets default screen */ ++ screen = XDefaultScreenOfDisplay(display); ++ ++ /* gets screen sizes */ ++ screen_width = XWidthOfScreen(screen); ++ screen_height = XHeightOfScreen(screen); ++ ++ /* not sure about these ones... */ ++ screen_bpp = XDefaultDepthOfScreen(screen); ++ screen_depth = XPlanesOfScreen(screen); ++ virtual_screen_rect.left = 0; ++ virtual_screen_rect.top = 0; ++ virtual_screen_rect.right = screen_width; ++ virtual_screen_rect.bottom = screen_height; ++ ++ /* dummy ? */ ++ palette_size = 0; ++ ++ /* Initialize device caps */ ++ log_pixels_x = log_pixels_y = get_dpi(); ++ horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 ); ++ vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 ); ++ ++ device_init_done = TRUE; ++} ++ + /********************************************************************** + * DIBDRV_CreateDC + */ +@@ -34,8 +128,8 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + DIBDRVPHYSDEV *physDev; + PHYSDEV X11PhysDev; + +- TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n", +- hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData); ++ MAYBE(TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n", ++ hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData)); + + /* allocates physical device */ + physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBDRVPHYSDEV) ); +@@ -52,12 +146,53 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + /* sets X11 Device pointer in DIB Engine device */ + physDev->X11PhysDev = X11PhysDev; + ++ /* stores the HDC */ ++ physDev->hdc = hdc; ++ ++ /* initializes device data (for GetDeviceCaps() ) ++ on first DC creation */ ++ if (!device_init_done) ++ device_init(); ++ + /* stock bitmap selected on DC creation */ + physDev->hbitmap = GetStockObject(DEFAULT_BITMAP); + + /* no DIB selected into DC on creation */ + physDev->hasDIB = FALSE; + ++ /* clear physical bitmap */ ++ _DIBDRVBITMAP_Clear(&physDev->physBitmap); ++ ++ /* clears pen and brush */ ++ physDev->rop2 = R2_COPYPEN; ++ ++ physDev->backgroundColor = 0; ++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor); ++ ++ physDev->penColor = 0; ++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor); ++ ++ physDev->brushColor = 0; ++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor); ++ physDev->brushAnds = NULL; ++ physDev->brushXors = NULL; ++ ++ physDev->brushStyle = BS_NULL; ++ ++ physDev->isBrushBitmap = FALSE; ++ _DIBDRVBITMAP_Clear(&physDev->brushBitmap); ++ _DIBDRVBITMAP_Clear(&physDev->brushBmpCache); ++ ++ /* text color */ ++ physDev->textColor = 0; ++ physDev->textBackground = 0; ++ ++ /* text color table for antialiased fonts */ ++ memset(physDev->textColorTable, 0, 256); ++ ++ /* freetype face associated to current DC HFONT */ ++ physDev->face = NULL; ++ + /* sets the result value and returns */ + *pdev = physDev; + +@@ -71,16 +206,31 @@ BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev ) + { + BOOL res; + +- TRACE("physDev:%p\n", physDev); ++ MAYBE(TRACE("physDev:%p\n", physDev)); + + /* frees X11 device */ + res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev); + physDev->X11PhysDev = NULL; + ++ /* frees physical bitmap */ ++ _DIBDRVBITMAP_Free(&physDev->physBitmap); ++ ++ /* frees brush bitmap */ ++ _DIBDRVBITMAP_Free(&physDev->brushBitmap); ++ _DIBDRVBITMAP_Free(&physDev->brushBmpCache); ++ ++ /* free brush ands and xors */ ++ if(physDev->brushAnds) ++ { ++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds); ++ HeapFree(GetProcessHeap(), 0, physDev->brushXors); ++ } ++ physDev->brushAnds = NULL; ++ physDev->brushXors = NULL; ++ + /* frees DIB Engine device */ + HeapFree(GetProcessHeap(), 0, physDev); + +- ONCE(FIXME("stub\n")); + return res; + } + +@@ -92,8 +242,8 @@ INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID + { + INT res; + +- TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n", +- physDev, escape, in_count, in_data, out_count, out_data); ++ MAYBE(TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n", ++ physDev, escape, in_count, in_data, out_count, out_data)); + + if(physDev->hasDIB) + { +@@ -116,13 +266,125 @@ INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap ) + { + INT res; + +- TRACE("physDev:%p, cap:%d\n", physDev, cap); ++ MAYBE(TRACE("physDev:%p, cap:%d\n", physDev, cap)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap); ++ switch(cap) ++ { ++ case DRIVERVERSION: ++ res = 0x300; ++ break; ++ case TECHNOLOGY: ++ res = DT_RASDISPLAY; ++ break; ++ case HORZSIZE: ++ res = horz_size; ++ break; ++ case VERTSIZE: ++ res = vert_size; ++ break; ++ case HORZRES: ++ res = screen_width; ++ break; ++ case VERTRES: ++ res = screen_height; ++ break; ++ case DESKTOPHORZRES: ++ res = virtual_screen_rect.right - virtual_screen_rect.left; ++ break; ++ case DESKTOPVERTRES: ++ res = virtual_screen_rect.bottom - virtual_screen_rect.top; ++ break; ++ case BITSPIXEL: ++ res = screen_bpp; ++ break; ++ case PLANES: ++ res = 1; ++ break; ++ case NUMBRUSHES: ++ res = -1; ++ break; ++ case NUMPENS: ++ res = -1; ++ break; ++ case NUMMARKERS: ++ res = 0; ++ break; ++ case NUMFONTS: ++ res = 0; ++ break; ++ case NUMCOLORS: ++ /* MSDN: Number of entries in the device's color table, if the device has ++ * a color depth of no more than 8 bits per pixel.For devices with greater ++ * color depths, -1 is returned. */ ++ res = (screen_depth > 8) ? -1 : (1 << screen_depth); ++ break; ++ case CURVECAPS: ++ res = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE | ++ CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT); ++ break; ++ case LINECAPS: ++ res = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE | ++ LC_STYLED | LC_WIDESTYLED | LC_INTERIORS); ++ break; ++ case POLYGONALCAPS: ++ res = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE | ++ PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS); ++ break; ++ case TEXTCAPS: ++ res = text_caps; ++ break; ++ case CLIPCAPS: ++ res = CP_REGION; ++ break; ++ case RASTERCAPS: ++ res = (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP | ++ RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS | ++ (palette_size ? RC_PALETTE : 0)); ++ break; ++ case SHADEBLENDCAPS: ++ res = (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA); ++ case ASPECTX: ++ case ASPECTY: ++ res = 36; ++ break; ++ case ASPECTXY: ++ res = 51; ++ break; ++ case LOGPIXELSX: ++ res = log_pixels_x; ++ break; ++ case LOGPIXELSY: ++ res = log_pixels_y; ++ break; ++ case CAPS1: ++ FIXME("(%p): CAPS1 is unimplemented, will return 0\n", physDev->hdc ); ++ /* please see wingdi.h for the possible bit-flag values that need ++ to be returned. */ ++ res = 0; ++ break; ++ case SIZEPALETTE: ++ res = palette_size; ++ break; ++ case NUMRESERVED: ++ case COLORRES: ++ case PHYSICALWIDTH: ++ case PHYSICALHEIGHT: ++ case PHYSICALOFFSETX: ++ case PHYSICALOFFSETY: ++ case SCALINGFACTORX: ++ case SCALINGFACTORY: ++ case VREFRESH: ++ case BLTALIGNMENT: ++ res = 0; ++ break; ++ default: ++ FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap ); ++ res = 0; ++ break; ++ } + } + else + { +diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c +index 28330fa..b72c34a 100644 +--- a/dlls/winedib.drv/dib.c ++++ b/dlls/winedib.drv/dib.c +@@ -33,11 +33,11 @@ HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, + { + HBITMAP res; + +- TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage); ++ MAYBE(TRACE("physDev:%p, hbitmap:%p, bmi:%p, usage:%d\n", physDev, hbitmap, bmi, usage)); + + /* createDIBSection is only DIB-related, so we just use the engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pCreateDIBSection(physDev->X11PhysDev, hbitmap, bmi, usage); ++ ONCE(FIXME("STUB\n")); ++ res = hbitmap; + + return res; + } +@@ -50,8 +50,8 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + { + INT res; + +- TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", +- physDev, hbitmap, startscan, lines, bits, bmi, coloruse); ++ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", ++ physDev, hbitmap, startscan, lines, bits, bmi, coloruse)); + + /* GetDIBits reads bits from a DDB, so we should use the X11 driver */ + res = _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, bmi, coloruse); +@@ -67,11 +67,11 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + { + UINT res; + +- TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors); ++ MAYBE(TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors)); + + /* SetDIBColorTable operates on a DIB, so we use the engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetDIBColorTable(physDev->X11PhysDev, start, count, colors); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + + return res; + } +@@ -84,8 +84,8 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + { + INT res; + +- TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", +- physDev, hbitmap, startscan, lines, bits, info, coloruse); ++ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", ++ physDev, hbitmap, startscan, lines, bits, info, coloruse)); + + /* SetDIBits writes bits to a DDB, so we should use the X11 driver */ + res = _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse); +@@ -103,8 +103,8 @@ INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWOR + { + INT res; + +- TRACE("physDev:%p, xDest:%d, yDest:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", +- physDev, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse); ++ MAYBE(TRACE("physDev:%p, xDest:%d, yDest:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", ++ physDev, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse)); + + /* SetDIBitsToDevice operates on a physical device, so we should use the X11 driver */ + res = _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index 8a2e139..773941e 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -35,10 +35,15 @@ + #include "winreg.h" + #include "wine/winbase16.h" /* GlobalLock16 */ + ++#include "freetype.h" ++ + /* data structures needed to access opaque pointers + * defined in gdi32.h */ + #include "dibdrv_gdi32.h" + ++/* enable this if you want debugging (i.e. TRACEs) output */ ++#define DIBDRV_ENABLE_MAYBE ++ + /* provide a way to make debugging output appear + only once. Usage example: + ONCE(FIXME("Some message\n")); */ +@@ -52,25 +57,197 @@ + } \ + } + ++/* provide a way to make debugging output appear ++ only if enabled here. Can speed up stuffs ++ avoiding long traces.Usage example: ++ MAYBE(TRACE("Some message\n")); */ ++#ifdef DIBDRV_ENABLE_MAYBE ++#define MAYBE(x) x ++#else ++#define MAYBE(x) ++#endif ++ ++ + /* extra stock object: default 1x1 bitmap for memory DCs + grabbed from gdi_private.h */ + #define DEFAULT_BITMAP (STOCK_LAST+1) + ++struct _DIBDRVBITMAP; ++struct _DIBDRVPHYSDEV; ++typedef struct _DIBDRV_PRIMITIVE_FUNCS ++{ ++ /* color to pixel data conversion */ ++ DWORD (* ColorToPixel) (const struct _DIBDRVBITMAP *bmp, COLORREF color); ++ ++ /* pixel primitives */ ++ void* (* GetPixelPointer) (const struct _DIBDRVBITMAP *bmp, int x, int y); ++ void (* SetPixel) ( struct _DIBDRVBITMAP *bmp, int x, int y, DWORD and, DWORD xor); ++ DWORD (* GetPixel) (const struct _DIBDRVBITMAP *bmp, int x, int y); ++ ++ /* line drawing primitives */ ++ void (* SolidHLine) ( struct _DIBDRVBITMAP *bmp, int x1, int x2, int y, DWORD and, DWORD xor); ++ void (* PatternHLine) ( struct _DIBDRVBITMAP *bmp, int x1, int x2, int y, const void *and, const void *xor, DWORD offset, DWORD count); ++ void (* SolidVLine) ( struct _DIBDRVBITMAP *bmp, int x, int y1, int y2, DWORD and, DWORD xor); ++ ++ /* bitmap conversion helpers */ ++ BOOL (* GetLine) (const struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf); ++ BOOL (* PutLine) ( struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf); ++ ++ /* BitBlt primitives */ ++ BOOL (* BitBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int width, int height, ++ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, DWORD rop ); ++ BOOL (* StretchBlt) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst, ++ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, DWORD rop ); ++ ++ /* font drawing helper */ ++ void (* FreetypeBlit) ( struct _DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp); ++ ++} DIBDRV_PRIMITIVE_FUNCS; ++ ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4; ++extern DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1; ++ ++/* DIB bitmaps formats */ ++typedef enum _DIBFORMAT ++{ ++ DIBFMT_UNKNOWN = 0, ++ DIBFMT_DIB1 = 1, ++ DIBFMT_DIB4 = 2, ++ DIBFMT_DIB4_RLE = 3, ++ DIBFMT_DIB8 = 4, ++ DIBFMT_DIB8_RLE = 5, ++ DIBFMT_DIB16_RGB = 6, ++ DIBFMT_DIB16_BITFIELDS = 7, ++ DIBFMT_DIB24 = 8, ++ DIBFMT_DIB32_RGB = 9, ++ DIBFMT_DIB32_BITFIELDS = 10 ++} DIBFORMAT; ++ ++/* DIB driver's generic bitmap structure */ ++typedef struct _DIBDRVBITMAP ++{ ++ /* bitmap format of dib */ ++ DIBFORMAT format; ++ ++ /* pointer to top left corner of bitmap */ ++ void *bits; ++ ++ /* flags indicating if bits array is owned ++ by the bitmap */ ++ BOOL ownsBits; ++ ++ /* bitmap dimensions */ ++ int width; ++ int height; ++ ++ /* bitmap stride (== width in bytes) of a bitmap line */ ++ /* negative for a bottom-up bitmap */ ++ int stride; ++ ++ /* number of bits/pixel in bitmap */ ++ int bitCount; ++ ++ /* calculated numbers for bitfields */ ++ ++ /* bitfields masks */ ++ DWORD redMask, greenMask, blueMask; ++ /* shifting required within a COLORREF's BYTE */ ++ int redShift, greenShift, blueShift; ++ /* size of the fields */ ++ int redLen, greenLen, blueLen; ++ ++ /* color table and its size */ ++ RGBQUAD *colorTable; ++ DWORD colorTableSize; ++ ++ /* flag indicating that color table has been grabbed */ ++ BOOL colorTableGrabbed; ++ ++ /* primitive function pointers */ ++ DIBDRV_PRIMITIVE_FUNCS *funcs; ++ ++} DIBDRVBITMAP; ++ ++/* dash patterns */ ++typedef struct _DASHPATTERN ++{ ++ DWORD count; ++ DWORD dashes[6]; ++ ++} DASHPATTERN; ++ + /* DIB driver physical device */ + typedef struct _DIBDRVPHYSDEV + { + /* X11 driver physical device */ + PHYSDEV X11PhysDev; + ++ /* HDC associated with physDev */ ++ HDC hdc; ++ + /* is a DIB selected into DC ? */ + BOOL hasDIB; + + /* currently selected HBITMAP */ + HBITMAP hbitmap; ++ ++ /* physical bitmap */ ++ DIBDRVBITMAP physBitmap; + + /* active ROP2 */ + INT rop2; + ++ /* background color and active ROP2 precalculated ++ AND and XOR values for it */ ++ COLORREF backgroundColor; ++ DWORD backgroundAnd, backgroundXor; ++ ++ /* pen color and active ROP2 precalculated ++ AND and XOR values for it */ ++ COLORREF penColorref; ++ DWORD penColor; ++ DWORD penAnd, penXor; ++ const DASHPATTERN *penPattern; ++ DWORD curDash, leftInDash; ++ enum MARKSPACE { mark, space } markSpace; ++ ++ /* pen drawing functions */ ++ void (* penHLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y); ++ void (* penVLine) (struct _DIBDRVPHYSDEV *physDev, int x, int y1, int y2); ++ void (* penLine) (struct _DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2); ++ void (* brushHLine)(struct _DIBDRVPHYSDEV *physDev, int x1, int x2, int y); ++ ++ /* brush color and active ROP2 precalculated ++ AND and XOR values for it */ ++ COLORREF brushColorref; ++ DWORD brushColor; ++ DWORD brushAnd, brushXor; ++ DWORD *brushAnds, *brushXors; ++ ++ /* brush style */ ++ UINT brushStyle; ++ ++ /* brush bitmap, if needed, and its converted/resized cache copy */ ++ BOOL isBrushBitmap; ++ DIBDRVBITMAP brushBitmap; ++ DIBDRVBITMAP brushBmpCache; ++ ++ /* text color */ ++ COLORREF textColor; ++ COLORREF textBackground; ++ ++ /* text color table for antialiased fonts */ ++ COLORREF textColorTable[256]; ++ ++ /* freetype face associated to current DC HFONT */ ++ FT_Face face; ++ + } DIBDRVPHYSDEV; + + +@@ -90,4 +267,117 @@ void _DIBDRV_FreeDisplayDriver(void); + Gets a pointer to display drives'function table */ + inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void); + +-#endif /* __WINE_DIBDRV_H */ ++/* ********************************************************************* ++ * ROP2 AND OTHER DRAWING RELATED FUNCTIONS ++ * ********************************************************************/ ++ ++void _DIBDRV_CalcAndXorMasks(INT rop, DWORD color, DWORD *and, DWORD *xor); ++ ++inline void _DIBDRV_rop32(DWORD *ptr, DWORD and, DWORD xor); ++inline void _DIBDRV_rop16(WORD *ptr, WORD and, WORD xor); ++inline void _DIBDRV_rop8(BYTE *ptr, BYTE and, BYTE xor); ++ ++void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev); ++ ++/* ********************************************************************* ++ * ROP2 FUNCTIONS ++ * ********************************************************************/ ++ ++/* the ROP3 operations ++ this is a BIG case block; beware that some ++ commons ROP3 operations will be optimized ++ from inside blt routines */ ++DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop); ++ ++/* ********************************************************************* ++ * PHYSICAL BITMAP FUNCTIONS ++ * ********************************************************************/ ++ ++/* gets human-readable dib format name */ ++const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp); ++ ++/* initializes dib from a bitmap : ++ dib dib being initialized ++ bi source BITMAPINFOHEADER with required DIB format info ++ bit_fields color masks ++ color_table color table, if any ++ bits pointer to image data array ++ NOTE : DIBDRVBITMAP doesn't owns bits, but do own color table */ ++BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields, ++ const RGBQUAD *color_table, void *bits); ++ ++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi); ++ ++/* initializes a DIBRDVBITMAP copying it from a source one ++ Parameters : ++ dib destination DIBDRVBITMAP ++ src source DIBDRVBITMAP ++ copy TRUE->copy source pixel array FALSE->link to source pixel array */ ++BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy); ++ ++/* creates a DIBRDVBITMAP copying format info from a source one ++ Parameters : ++ dib destination DIBDRVBITMAP ++ src source DIBDRVBITMAP ++ widht, height sizes of newly created bitmap */ ++BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height); ++ ++/* Clears a DIBDRVBITMAP structure data ++ WARNING : doesn't free anything */ ++void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp); ++ ++/* Frees a DIBDRVBITMAP structure data */ ++void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp); ++ ++/* checks whether the format of 2 DIBs are identical ++ it checks the pixel bit count and the color table size ++ and content, if needed */ ++BOOL _DIBDRVBITMAP_FormatMatch(const DIBDRVBITMAP *d1, const DIBDRVBITMAP *d2); ++ ++/* convert a given dib into another format given by 'format' parameter */ ++BOOL _DIBDRVBITMAP_Convert(DIBDRVBITMAP *dst, const DIBDRVBITMAP *src, const DIBDRVBITMAP *format); ++ ++/* creates a solid-filled DIB of given color and format ++ DIB format is given by 'format' parameter */ ++BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int width, int height, DWORD Color); ++ ++/* expands horizontally a bitmap to reach a minimum size, ++ keeping its width as a multiple of a base width ++ Used to widen brushes in order to optimize blitting */ ++BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth); ++ ++/* ********************************************************************* ++ * DIB <--> DDB CONVERSION ROUTINES ++ * ********************************************************************/ ++ ++/*********************************************************************** ++ * Creates DDB that is compatible with source hdc. ++ * hdc is the HDC on where the DIB MUST be selected in ++ * srcBmp is the source DIB ++ * startScan and scanLines specify the portion of DIB to convert ++ * in order to avoid unneeded conversion of large DIBs on blitting ++ * ++ * NOTE : the srcBmp DIB MUST NOT be selected in any DC */ ++HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines ); ++ ++/*********************************************************************** ++ * Creates DIB that is compatible with the target hdc. ++ * startScan and scanLines specify the portion of DDB to convert ++ * in order to avoid unneeded conversion of large DDBs on blitting ++ * ++ * NOTE : the srcBmp DDB MUST NOT be selected in any DC */ ++HBITMAP _DIBDRV_ConvertDDBtoDIB( HDC hdc, HBITMAP srcBmp, int startScan, int scanLines ); ++ ++/*********************************************************************** ++ * Creates DIB that is compatible with the target hdc for a device (non memory) source DC */ ++HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, int width, int height ); ++ ++/* ********************************************************************* ++ * QUERY FUNCTIONS ++ * ********************************************************************/ ++ ++/*********************************************************************** ++ * DIBDRV_GetDeviceCaps */ ++INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap ); ++ ++#endif +diff --git a/dlls/winedib.drv/dibdrv_gdi32.h b/dlls/winedib.drv/dibdrv_gdi32.h +new file mode 100644 +index 0000000..8e4eb05 +--- /dev/null ++++ b/dlls/winedib.drv/dibdrv_gdi32.h +@@ -0,0 +1,168 @@ ++/* ++ * GDI structures - grabbed from dlls/gdi32/gdi_private.h ++ * Those are needed to access some opaque gdi32 pointers ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#ifndef __WINE_DIBDRV_GDI32_H ++#define __WINE_DIBDRV_GDI32_H ++ ++ ++/* driver function pointers - used here to forward calls to X11 driver when needed */ ++typedef struct { int opaque; } *PHYSDEV; /* PHYSDEV is an opaque pointer */ ++typedef struct tagDC_FUNCS ++{ ++ INT (CDECL *pAbortDoc)(PHYSDEV); ++ BOOL (CDECL *pAbortPath)(PHYSDEV); ++ BOOL (CDECL *pAlphaBlend)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,BLENDFUNCTION); ++ BOOL (CDECL *pAngleArc)(PHYSDEV,INT,INT,DWORD,FLOAT,FLOAT); ++ BOOL (CDECL *pArc)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); ++ BOOL (CDECL *pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); ++ BOOL (CDECL *pBeginPath)(PHYSDEV); ++ BOOL (CDECL *pBitBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,DWORD); ++ INT (CDECL *pChoosePixelFormat)(PHYSDEV,const PIXELFORMATDESCRIPTOR *); ++ BOOL (CDECL *pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); ++ BOOL (CDECL *pCloseFigure)(PHYSDEV); ++ BOOL (CDECL *pCreateBitmap)(PHYSDEV,HBITMAP,LPVOID); ++ BOOL (CDECL *pCreateDC)(HDC,PHYSDEV *,LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*); ++ HBITMAP (CDECL *pCreateDIBSection)(PHYSDEV,HBITMAP,const BITMAPINFO *,UINT); ++ BOOL (CDECL *pDeleteBitmap)(HBITMAP); ++ BOOL (CDECL *pDeleteDC)(PHYSDEV); ++ BOOL (CDECL *pDeleteObject)(PHYSDEV,HGDIOBJ); ++ INT (CDECL *pDescribePixelFormat)(PHYSDEV,INT,UINT,PIXELFORMATDESCRIPTOR *); ++ DWORD (CDECL *pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA); ++ BOOL (CDECL *pEllipse)(PHYSDEV,INT,INT,INT,INT); ++ INT (CDECL *pEndDoc)(PHYSDEV); ++ INT (CDECL *pEndPage)(PHYSDEV); ++ BOOL (CDECL *pEndPath)(PHYSDEV); ++ BOOL (CDECL *pEnumDeviceFonts)(PHYSDEV,LPLOGFONTW,FONTENUMPROCW,LPARAM); ++ INT (CDECL *pExcludeClipRect)(PHYSDEV,INT,INT,INT,INT); ++ INT (CDECL *pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,DWORD); ++ INT (CDECL *pExtEscape)(PHYSDEV,INT,INT,LPCVOID,INT,LPVOID); ++ BOOL (CDECL *pExtFloodFill)(PHYSDEV,INT,INT,COLORREF,UINT); ++ INT (CDECL *pExtSelectClipRgn)(PHYSDEV,HRGN,INT); ++ BOOL (CDECL *pExtTextOut)(PHYSDEV,INT,INT,UINT,const RECT*,LPCWSTR,UINT,const INT*); ++ BOOL (CDECL *pFillPath)(PHYSDEV); ++ BOOL (CDECL *pFillRgn)(PHYSDEV,HRGN,HBRUSH); ++ BOOL (CDECL *pFlattenPath)(PHYSDEV); ++ BOOL (CDECL *pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT); ++ BOOL (CDECL *pGdiComment)(PHYSDEV,UINT,CONST BYTE*); ++ LONG (CDECL *pGetBitmapBits)(HBITMAP,void*,LONG); ++ BOOL (CDECL *pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT); ++ BOOL (CDECL *pGetDCOrgEx)(PHYSDEV,LPPOINT); ++ UINT (CDECL *pGetDIBColorTable)(PHYSDEV,UINT,UINT,RGBQUAD*); ++ INT (CDECL *pGetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT); ++ INT (CDECL *pGetDeviceCaps)(PHYSDEV,INT); ++ BOOL (CDECL *pGetDeviceGammaRamp)(PHYSDEV,LPVOID); ++ BOOL (CDECL *pGetICMProfile)(PHYSDEV,LPDWORD,LPWSTR); ++ COLORREF (CDECL *pGetNearestColor)(PHYSDEV,COLORREF); ++ COLORREF (CDECL *pGetPixel)(PHYSDEV,INT,INT); ++ INT (CDECL *pGetPixelFormat)(PHYSDEV); ++ UINT (CDECL *pGetSystemPaletteEntries)(PHYSDEV,UINT,UINT,LPPALETTEENTRY); ++ BOOL (CDECL *pGetTextExtentExPoint)(PHYSDEV,LPCWSTR,INT,INT,LPINT,LPINT,LPSIZE); ++ BOOL (CDECL *CDECL pGetTextMetrics)(PHYSDEV,TEXTMETRICW*); ++ INT (CDECL *pIntersectClipRect)(PHYSDEV,INT,INT,INT,INT); ++ BOOL (CDECL *pInvertRgn)(PHYSDEV,HRGN); ++ BOOL (CDECL *pLineTo)(PHYSDEV,INT,INT); ++ BOOL (CDECL *pModifyWorldTransform)(PHYSDEV,const XFORM*,INT); ++ BOOL (CDECL *pMoveTo)(PHYSDEV,INT,INT); ++ INT (CDECL *pOffsetClipRgn)(PHYSDEV,INT,INT); ++ INT (CDECL *pOffsetViewportOrg)(PHYSDEV,INT,INT); ++ INT (CDECL *pOffsetWindowOrg)(PHYSDEV,INT,INT); ++ BOOL (CDECL *pPaintRgn)(PHYSDEV,HRGN); ++ BOOL (CDECL *pPatBlt)(PHYSDEV,INT,INT,INT,INT,DWORD); ++ BOOL (CDECL *pPie)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT); ++ BOOL (CDECL *pPolyBezier)(PHYSDEV,const POINT*,DWORD); ++ BOOL (CDECL *pPolyBezierTo)(PHYSDEV,const POINT*,DWORD); ++ BOOL (CDECL *pPolyDraw)(PHYSDEV,const POINT*,const BYTE *,DWORD); ++ BOOL (CDECL *pPolyPolygon)(PHYSDEV,const POINT*,const INT*,UINT); ++ BOOL (CDECL *pPolyPolyline)(PHYSDEV,const POINT*,const DWORD*,DWORD); ++ BOOL (CDECL *pPolygon)(PHYSDEV,const POINT*,INT); ++ BOOL (CDECL *pPolyline)(PHYSDEV,const POINT*,INT); ++ BOOL (CDECL *pPolylineTo)(PHYSDEV,const POINT*,INT); ++ UINT (CDECL *pRealizeDefaultPalette)(PHYSDEV); ++ UINT (CDECL *pRealizePalette)(PHYSDEV,HPALETTE,BOOL); ++ BOOL (CDECL *pRectangle)(PHYSDEV,INT,INT,INT,INT); ++ HDC (CDECL *pResetDC)(PHYSDEV,const DEVMODEW*); ++ BOOL (CDECL *pRestoreDC)(PHYSDEV,INT); ++ BOOL (CDECL *pRoundRect)(PHYSDEV,INT,INT,INT,INT,INT,INT); ++ INT (CDECL *pSaveDC)(PHYSDEV); ++ INT (CDECL *pScaleViewportExt)(PHYSDEV,INT,INT,INT,INT); ++ INT (CDECL *pScaleWindowExt)(PHYSDEV,INT,INT,INT,INT); ++ HBITMAP (CDECL *pSelectBitmap)(PHYSDEV,HBITMAP); ++ HBRUSH (CDECL *pSelectBrush)(PHYSDEV,HBRUSH); ++ BOOL (CDECL *pSelectClipPath)(PHYSDEV,INT); ++ HFONT (CDECL *pSelectFont)(PHYSDEV,HFONT,HANDLE); ++ HPALETTE (CDECL *pSelectPalette)(PHYSDEV,HPALETTE,BOOL); ++ HPEN (CDECL *pSelectPen)(PHYSDEV,HPEN); ++ INT (CDECL *pSetArcDirection)(PHYSDEV,INT); ++ LONG (CDECL *pSetBitmapBits)(HBITMAP,const void*,LONG); ++ COLORREF (CDECL *pSetBkColor)(PHYSDEV,COLORREF); ++ INT (CDECL *pSetBkMode)(PHYSDEV,INT); ++ COLORREF (CDECL *pSetDCBrushColor)(PHYSDEV, COLORREF); ++ DWORD (CDECL *pSetDCOrg)(PHYSDEV,INT,INT); ++ COLORREF (CDECL *pSetDCPenColor)(PHYSDEV, COLORREF); ++ UINT (CDECL *pSetDIBColorTable)(PHYSDEV,UINT,UINT,const RGBQUAD*); ++ INT (CDECL *pSetDIBits)(PHYSDEV,HBITMAP,UINT,UINT,LPCVOID,const BITMAPINFO*,UINT); ++ INT (CDECL *pSetDIBitsToDevice)(PHYSDEV,INT,INT,DWORD,DWORD,INT,INT,UINT,UINT,LPCVOID, ++ const BITMAPINFO*,UINT); ++ VOID (CDECL *pSetDeviceClipping)(PHYSDEV,HRGN,HRGN); ++ BOOL (CDECL *pSetDeviceGammaRamp)(PHYSDEV,LPVOID); ++ INT (CDECL *pSetMapMode)(PHYSDEV,INT); ++ DWORD (CDECL *pSetMapperFlags)(PHYSDEV,DWORD); ++ COLORREF (CDECL *pSetPixel)(PHYSDEV,INT,INT,COLORREF); ++ BOOL (CDECL *pSetPixelFormat)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *); ++ INT (CDECL *pSetPolyFillMode)(PHYSDEV,INT); ++ INT (CDECL *pSetROP2)(PHYSDEV,INT); ++ INT (CDECL *pSetRelAbs)(PHYSDEV,INT); ++ INT (CDECL *pSetStretchBltMode)(PHYSDEV,INT); ++ UINT (CDECL *pSetTextAlign)(PHYSDEV,UINT); ++ INT (CDECL *pSetTextCharacterExtra)(PHYSDEV,INT); ++ DWORD (CDECL *pSetTextColor)(PHYSDEV,DWORD); ++ INT (CDECL *pSetTextJustification)(PHYSDEV,INT,INT); ++ INT (CDECL *pSetViewportExt)(PHYSDEV,INT,INT); ++ INT (CDECL *pSetViewportOrg)(PHYSDEV,INT,INT); ++ INT (CDECL *pSetWindowExt)(PHYSDEV,INT,INT); ++ INT (CDECL *pSetWindowOrg)(PHYSDEV,INT,INT); ++ BOOL (CDECL *pSetWorldTransform)(PHYSDEV,const XFORM*); ++ INT (CDECL *pStartDoc)(PHYSDEV,const DOCINFOW*); ++ INT (CDECL *pStartPage)(PHYSDEV); ++ BOOL (CDECL *pStretchBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,INT,INT,DWORD); ++ INT (CDECL *pStretchDIBits)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT,const void *, ++ const BITMAPINFO*,UINT,DWORD); ++ BOOL (CDECL *pStrokeAndFillPath)(PHYSDEV); ++ BOOL (CDECL *pStrokePath)(PHYSDEV); ++ BOOL (CDECL *pSwapBuffers)(PHYSDEV); ++ BOOL (CDECL *pUnrealizePalette)(HPALETTE); ++ BOOL (CDECL *pWidenPath)(PHYSDEV); ++ ++ /* OpenGL32 */ ++ BOOL (CDECL *pwglCopyContext)(HGLRC, HGLRC, UINT); ++ HGLRC (CDECL *pwglCreateContext)(PHYSDEV); ++ BOOL (CDECL *pwglDeleteContext)(HGLRC); ++ PROC (CDECL *pwglGetProcAddress)(LPCSTR); ++ HDC (CDECL *pwglGetPbufferDCARB)(PHYSDEV, void*); ++ BOOL (CDECL *pwglMakeCurrent)(PHYSDEV, HGLRC); ++ BOOL (CDECL *pwglMakeContextCurrentARB)(PHYSDEV, PHYSDEV, HGLRC); ++ BOOL (CDECL *pwglSetPixelFormatWINE)(PHYSDEV,INT,const PIXELFORMATDESCRIPTOR *); ++ BOOL (CDECL *pwglShareLists)(HGLRC hglrc1, HGLRC hglrc2); ++ BOOL (CDECL *pwglUseFontBitmapsA)(PHYSDEV, DWORD, DWORD, DWORD); ++ BOOL (CDECL *pwglUseFontBitmapsW)(PHYSDEV, DWORD, DWORD, DWORD); ++} DC_FUNCTIONS; ++ ++#endif +diff --git a/dlls/winedib.drv/dibdrv_main.c b/dlls/winedib.drv/dibdrv_main.c +index 28429d2..e436440 100644 +--- a/dlls/winedib.drv/dibdrv_main.c ++++ b/dlls/winedib.drv/dibdrv_main.c +@@ -35,15 +35,26 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) + switch(reason) + { + case DLL_PROCESS_ATTACH: ++ + /* Loads display driver */ + _DIBDRV_LoadDisplayDriver(); ++ ++ /* initializes freetype library */ ++ if(!_DIBDRV_FreeType_Init()) ++ ERR("Couldn't initialize freetype library.\n"); ++ + break; + case DLL_THREAD_DETACH: + /* do thread detach */ + break; + case DLL_PROCESS_DETACH: ++ ++ /* terminates freetype library */ ++ _DIBDRV_FreeType_Terminate(); ++ + /* unloads display driver */ + _DIBDRV_FreeDisplayDriver(); ++ + break; + } + return ret; +diff --git a/dlls/winedib.drv/dibdrvbitmap.c b/dlls/winedib.drv/dibdrvbitmap.c +new file mode 100644 +index 0000000..2c8c367 +--- /dev/null ++++ b/dlls/winedib.drv/dibdrvbitmap.c +@@ -0,0 +1,650 @@ ++/* ++ * DIB Engine DIBDRVBITMAP handling ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* gets human-readable dib format name */ ++const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp) ++{ ++ if(!bmp) ++ { ++ ERR("Null bitmap\n"); ++ return "NULL BITMAP DETECTED"; ++ } ++ switch(bmp->format) ++ { ++ case DIBFMT_DIB1: ++ return "DIBFMT_DIB1"; ++ case DIBFMT_DIB4: ++ return "DIBFMT_DIB4"; ++ case DIBFMT_DIB4_RLE: ++ return "DIBFMT_DIB4_RLE"; ++ case DIBFMT_DIB8: ++ return "DIBFMT_DIB8"; ++ case DIBFMT_DIB8_RLE: ++ return "DIBFMT_DIB8_RLE"; ++ case DIBFMT_DIB16_RGB: ++ return "DIBFMT_DIB_RGB"; ++ case DIBFMT_DIB16_BITFIELDS: ++ return "DIBFMT_DIB16_BITFIELDS"; ++ case DIBFMT_DIB24: ++ return "DIBFMT_DIB24"; ++ case DIBFMT_DIB32_RGB: ++ return "DIBFMT_DIB32_RGB"; ++ case DIBFMT_DIB32_BITFIELDS: ++ return "DIBFMT_DIB32_BITFIELDS"; ++ case DIBFMT_UNKNOWN: ++ default: ++ return "DIBFMT_UNKNOWN"; ++ } ++} ++ ++/* calculates shift and length given a bit mask */ ++static void CalcShiftAndLen(DWORD mask, int *shift, int *len) ++{ ++ int s, l; ++ ++ /* FIXME----*/ ++ if(mask == 0) ++ { ++ FIXME("color mask == 0 -- problem on init_dib\n"); ++ *shift = 0; ++ *len = 0; ++ return; ++ } ++ ++ /* calculates bit shift ++ (number of 0's on right of bit field */ ++ s = 0; ++ while ((mask & 1) == 0) ++ { ++ mask >>= 1; ++ s++; ++ } ++ ++ /* calculates bitfield length ++ (number of 1's in bit field */ ++ l = 0; ++ while ((mask & 1) == 1) ++ { ++ mask >>= 1; ++ l++; ++ } ++ *shift = s; ++ *len = l; ++} ++ ++/* initializes bit fields from bit masks */ ++static void InitBitFields(DIBDRVBITMAP *dib, const DWORD *bit_fields) ++{ ++ dib->redMask = bit_fields[0]; ++ dib->greenMask = bit_fields[1]; ++ dib->blueMask = bit_fields[2]; ++ CalcShiftAndLen(dib->redMask, &dib->redShift, &dib->redLen); ++ CalcShiftAndLen(dib->greenMask, &dib->greenShift, &dib->greenLen); ++ CalcShiftAndLen(dib->blueMask, &dib->blueShift, &dib->blueLen); ++} ++ ++/* initializes dib from a bitmap : ++ dib dib being initialized ++ bi source BITMAPINFOHEADER with required DIB format info ++ bit_fields color masks ++ colorTable color table, if any ++ bits pointer to image data array ++ NOTE : DIBDRVBITMAP doesn't owns bits, but do own color table ++*/ ++BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields, ++ const RGBQUAD *colorTable, void *bits) ++{ ++ MAYBE(TRACE("dib=%p, bi=%p, bit_fields=%p, colorTable=%p, bits=%p\n", dib, bi, bit_fields, colorTable, bits)); ++ ++ /* initializes DIB dimensions and color depth */ ++ dib->bitCount = bi->biBitCount; ++ dib->width = bi->biWidth; ++ dib->height = bi->biHeight; ++ dib->stride = ((dib->width * dib->bitCount + 31) >> 3) & ~3; ++ ++ /* initializes image data pointer */ ++ dib->bits = bits; ++ dib->ownsBits = FALSE; ++ ++ /* initializes color table */ ++ dib->colorTableSize = 0; ++ dib->colorTable = NULL; ++ dib->colorTableGrabbed = FALSE; ++ ++ /* checks whether dib is top-down or bottom-up one */ ++ if(dib->height < 0) ++ { ++ /* top-down dib */ ++ dib->height = -dib->height; ++ } ++ else ++ { ++ /* bottom-up dib */ ++ /* data->bits always points to the top-left corner and the stride is -ve */ ++ dib->bits = (BYTE*)dib->bits + (dib->height - 1) * dib->stride; ++ dib->stride = -dib->stride; ++ } ++ ++ /* gets and stores bitmap format */ ++ switch(dib->bitCount) ++ { ++ case 24: ++ dib->format = DIBFMT_DIB24; ++ dib->funcs = &DIBDRV_funcs_DIB24; ++ break; ++ ++ case 32: ++ ++ if(bi->biCompression == BI_RGB) ++ { ++ dib->format = DIBFMT_DIB32_RGB; ++ dib->funcs = &DIBDRV_funcs_DIB32_RGB; ++ } ++ else ++ { ++ InitBitFields(dib, bit_fields); ++ dib->format = DIBFMT_DIB32_BITFIELDS; ++ dib->funcs = &DIBDRV_funcs_DIB32_BITFIELDS; ++ } ++ break; ++ ++ case 16: ++ if(bi->biCompression == BI_RGB) ++ { ++ dib->format = DIBFMT_DIB16_RGB; ++ dib->funcs = &DIBDRV_funcs_DIB16_RGB; ++ } ++ else ++ { ++ InitBitFields(dib, bit_fields); ++ dib->format = DIBFMT_DIB16_BITFIELDS; ++ dib->funcs = &DIBDRV_funcs_DIB16_BITFIELDS; ++ } ++ break; ++ ++ case 8: ++ dib->format = DIBFMT_DIB8; ++ dib->funcs = &DIBDRV_funcs_DIB8; ++ dib->colorTableSize = 256; ++ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed; ++ break; ++ ++ case 4: ++ dib->format = DIBFMT_DIB4; ++ dib->funcs = &DIBDRV_funcs_DIB4; ++ dib->colorTableSize = 16; ++ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed; ++ break; ++ ++ case 1: ++ dib->format = DIBFMT_DIB1; ++ dib->funcs = &DIBDRV_funcs_DIB1; ++ dib->colorTableSize = 2; ++ if(bi->biClrUsed) dib->colorTableSize = bi->biClrUsed; ++ break; ++ ++ default: ++ dib->format = DIBFMT_UNKNOWN; ++ dib->funcs = NULL; ++ FIXME("bpp %d not supported\n", dib->bitCount); ++ return FALSE; ++ } ++ MAYBE(TRACE("DIB FORMAT : %s\n", _DIBDRVBITMAP_GetFormatName(dib))); ++ ++ /* allocates color table and copy it from source, *if* source is ++ not null */ ++ if(dib->colorTableSize && colorTable) ++ { ++ if(!(dib->colorTable = HeapAlloc(GetProcessHeap(), 0, ++ dib->colorTableSize * sizeof(dib->colorTable[0])) ++ )) ++ { ++ ERR("HeapAlloc failed\n"); ++ return FALSE; ++ } ++ memcpy(dib->colorTable, colorTable, ++ dib->colorTableSize * sizeof(dib->colorTable[0])); ++ dib->colorTableGrabbed = TRUE; ++ } ++ else if(!dib->colorTableSize) ++ /* no color table on more than 8 bits/pixel */ ++ dib->colorTableGrabbed = TRUE; ++ ++ MAYBE(TRACE("END\n")); ++ return TRUE; ++} ++ ++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi) ++{ ++ static const DWORD bit_fields_DIB32_RGB[3] = {0xff0000, 0x00ff00, 0x0000ff}; ++ static const DWORD bit_fields_DIB16_RGB[3] = {0x7c00, 0x03e0, 0x001f}; ++ BITMAPINFOHEADER *bi = (BITMAPINFOHEADER *)bmi; ++ const DWORD *masks = NULL; ++ RGBQUAD *colorTable = NULL; ++ BYTE *ptr = (BYTE*)bmi + bi->biSize; ++ int num_colors = bi->biClrUsed; ++ BOOL res; ++ ++ MAYBE(TRACE("dib=%p, bmi=%p\n", dib, bmi)); ++ ++ if(bi->biCompression == BI_BITFIELDS) ++ { ++ masks = (DWORD *)ptr; ++ ptr += 3 * sizeof(DWORD); ++ } ++ else if(bi->biBitCount == 32) ++ masks = bit_fields_DIB32_RGB; ++ else if(bi->biBitCount == 16) ++ masks = bit_fields_DIB16_RGB; ++ ++ if(!num_colors && bi->biBitCount <= 8) ++ num_colors = 1 << bi->biBitCount; ++ if(num_colors) ++ colorTable = (RGBQUAD*)ptr; ++ ptr += num_colors * sizeof(*colorTable); ++ ++ res = _DIBDRVBITMAP_InitFromBMIH(dib, bi, masks, colorTable, ptr); ++ MAYBE(TRACE("END\n")); ++ return res; ++} ++ ++/* initializes a DIBRDVBITMAP copying it from a source one ++ Parameters : ++ dib destination DIBDRVBITMAP ++ src source DIBDRVBITMAP ++ copy TRUE->copy source pixel array FALSE->link to source pixel array ++*/ ++BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy) ++{ ++ MAYBE(TRACE("dib=%p, src=%p, copy=%d\n", dib, src, copy)); ++ ++ dib->format = src->format; ++ dib->width = src->width; ++ dib->height = src->height; ++ dib->stride = src->stride; ++ dib->bitCount = src->bitCount; ++ ++ dib->redMask = src->redMask; ++ dib->greenMask = src->greenMask; ++ dib->blueMask = src->blueMask; ++ dib->redShift = src->redShift; ++ dib->greenShift = src->greenShift; ++ dib->blueShift = src->blueShift; ++ dib->redLen = src->redLen; ++ dib->greenLen = src->greenLen; ++ dib->blueLen = src->blueLen; ++ ++ dib->funcs = src->funcs; ++ ++ if(copy) ++ { ++ int size = dib->height*abs(dib->stride); ++ if(!(dib->bits = HeapAlloc(GetProcessHeap(), 0, size))) ++ { ++ ERR("Failed to allocate bits buffer\n"); ++ return FALSE; ++ } ++ dib->ownsBits = TRUE; ++ ++ /* check for bottom-up DIB */ ++ if(dib->stride < 0) ++ { ++ /* copy the bitmap array */ ++ memcpy(dib->bits, (BYTE *)src->bits + (src->height - 1) * src->stride, size); ++ ++ dib->bits = (BYTE *)dib->bits - (dib->height-1) * dib->stride; ++ } ++ else ++ { ++ /* copy the bitmap array */ ++ memcpy(dib->bits, src->bits, size); ++ } ++ } ++ else ++ { ++ dib->bits = src->bits; ++ dib->ownsBits = FALSE; ++ } ++ ++ if(src->colorTable) ++ { ++ dib->colorTable = HeapAlloc(GetProcessHeap(), 0, src->colorTableSize * sizeof(src->colorTable[0])); ++ memcpy(dib->colorTable, src->colorTable, src->colorTableSize * sizeof(src->colorTable[0])); ++ } ++ else ++ dib->colorTable = NULL; ++ dib->colorTableSize = src->colorTableSize; ++ dib->colorTableGrabbed = TRUE; ++ MAYBE(TRACE("END\n")); ++ return TRUE; ++} ++ ++/* creates a DIBRDVBITMAP copying format info from a source one ++ Parameters : ++ dib destination DIBDRVBITMAP ++ src source DIBDRVBITMAP ++ widht, height sizes of newly created bitmap ++*/ ++BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height) ++{ ++ MAYBE(TRACE("dib=%p, src=%p, width=%d, height=%d\n", dib, src, width, height)); ++ ++ /* grab color and format info from source DIB */ ++ if(!_DIBDRVBITMAP_InitFromDibdrvbitmap(dib, src, FALSE)) ++ { ++ ERR("Failed grabbing source dib format\n"); ++ return FALSE; ++ } ++ ++ /* sets up new DIB dimensions */ ++ dib->width = width; ++ dib->height = height; ++ ++ /* calculates new stride basing of new width */ ++ dib->stride = ((width * dib->bitCount +31) &~31) / 8; ++ if(src->stride < 0) ++ dib->stride = -dib->stride; ++ ++ /* allocates bits for newly created DIB */ ++ if(!(dib->bits = HeapAlloc(GetProcessHeap(), 0, height*abs(dib->stride)))) ++ { ++ ERR("Failed to allocate bits buffer\n"); ++ return FALSE; ++ } ++ /* check for bottom-up DIB */ ++ if(dib->stride < 0) ++ dib->bits = (BYTE *)dib->bits - (dib->height-1) * dib->stride; ++ dib->ownsBits = TRUE; ++ ++ MAYBE(TRACE("END\n")); ++ return TRUE; ++ } ++ ++/* Clears a DIBDRVBITMAP structure data ++ WARNING : doesn't free anything */ ++void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp) ++{ ++ MAYBE(TRACE("bmp=%p\n", bmp)); ++ ++ bmp->bits = NULL; ++ bmp->ownsBits = FALSE; ++ bmp->colorTable = NULL; ++ bmp->colorTableSize = 0; ++ bmp->colorTableGrabbed = FALSE; ++ ++ MAYBE(TRACE("END\n")); ++} ++ ++/* Frees a DIBDRVBITMAP structure data */ ++void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp) ++{ ++ MAYBE(TRACE("bmp=%p\n", bmp)); ++ ++ /* frees bits, if needed */ ++ if(bmp->bits && bmp->ownsBits) ++ { ++ /* on bottom-up dibs, bits doesn't point to starting ++ of buffer.... bad design choice */ ++ if(bmp->stride < 0) ++ bmp->bits = (BYTE *)bmp->bits + bmp->stride * (bmp->height -1); ++ HeapFree(GetProcessHeap(), 0, bmp->bits); ++ } ++ bmp->ownsBits = FALSE; ++ bmp->bits = NULL; ++ ++ /* frees color table */ ++ if(bmp->colorTable) ++ HeapFree(GetProcessHeap(), 0, bmp->colorTable); ++ bmp->colorTable = NULL; ++ bmp->colorTableSize = 0; ++ bmp->colorTableGrabbed = FALSE; ++ ++ MAYBE(TRACE("END\n")); ++} ++ ++ ++/* checks whether the format of 2 DIBs are identical ++ it checks the pixel bit count and the color table size ++ and content, if needed */ ++BOOL _DIBDRVBITMAP_FormatMatch(const DIBDRVBITMAP *d1, const DIBDRVBITMAP *d2) ++{ ++ /* checks at first the format (bit count and color masks) */ ++ if(d1->format != d2->format) ++ return FALSE; ++ ++ /* formats matches, now checks color tables if needed */ ++ switch(d1->format) ++ { ++ case DIBFMT_DIB32_RGB : ++ case DIBFMT_DIB32_BITFIELDS : ++ case DIBFMT_DIB24 : ++ case DIBFMT_DIB16_RGB : ++ case DIBFMT_DIB16_BITFIELDS : ++ return TRUE; ++ ++ case DIBFMT_DIB1 : ++ case DIBFMT_DIB4 : ++ /*case DIBFMT_DIB4_RLE :*/ ++ case DIBFMT_DIB8 : ++ /*case DIBFMT_DIB8_RLE :*/ ++ if(d1->colorTableSize != d2->colorTableSize) ++ return FALSE; ++ return !memcmp(d1->colorTable, d2->colorTable, d1->colorTableSize * sizeof(d1->colorTable[0])); ++ ++ default: ++ ERR("Unexpected depth %d\n", d1->bitCount); ++ return FALSE; ++ } ++} ++ ++/* convert a given dib into another format given by 'format' parameter */ ++BOOL _DIBDRVBITMAP_Convert(DIBDRVBITMAP *dst, const DIBDRVBITMAP *src, const DIBDRVBITMAP *format) ++{ ++ int width, height; ++ int iLine; ++ void *buf; ++ BOOL res; ++ ++ MAYBE(TRACE("dst=%p, src=%p, format=%p\n", dst, src, format)); ++ ++ /* free, if needed, destination bitmap */ ++ _DIBDRVBITMAP_Free(dst); ++ ++ /* if format and source bitmaps format match, ++ just copy source on destination */ ++ if(_DIBDRVBITMAP_FormatMatch(src, format)) ++ { ++ res = _DIBDRVBITMAP_InitFromDibdrvbitmap(dst, src, TRUE); ++ MAYBE(TRACE("END - Identical formats\n")); ++ return res; ++ } ++ ++ /* formats don't match, we create the dest bitmap with same format as format's one ++ but with source's one dimensions */ ++ width = src->width; ++ height = src->height; ++ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(dst, format, width, height)) ++ { ++ ERR("Couldn't create destination bmp\n"); ++ return FALSE; ++ } ++ ++ /* we now copy/convert from source to dest */ ++ if(!(buf = HeapAlloc(GetProcessHeap(), 0, width * 4))) ++ { ++ ERR("HeapAlloc failed\n"); ++ return FALSE; ++ } ++ ++ for(iLine = 0; iLine < height; iLine++) ++ { ++ src->funcs->GetLine(src, iLine, 0, width, buf); ++ dst->funcs->PutLine(dst, iLine, 0, width, buf); ++ } ++ HeapFree(GetProcessHeap(), 0, buf); ++ ++ MAYBE(TRACE("END - different formats\n")); ++ return TRUE; ++} ++ ++/* creates a solid-filled DIB of given color and format ++ DIB format is given by 'format' parameter */ ++BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int width, int height, DWORD Color) ++{ ++ DWORD *buf, *bufPnt; ++ int i; ++ ++ MAYBE(TRACE("bmp=%p, format=%p, width=%d, height=%d, Color=%08x\n", bmp, format, width, height, Color)); ++ ++ /* swaps color bytes....*/ ++ Color = RGB((Color >> 8) & 0xff, (Color >> 16) &0xff, Color &0xff); ++ ++ /* creates the destination bitmap */ ++ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(bmp, format, width, height)) ++ { ++ ERR("Couldn't create destination bmp\n"); ++ return FALSE; ++ } ++ ++ /* creates a temporary line filled with given color */ ++ if(!(buf = HeapAlloc(GetProcessHeap(), 0, width * 4))) ++ { ++ ERR("HeapAlloc failed\n"); ++ return FALSE; ++ } ++ ++ for(i = 0, bufPnt = buf; i < width; i++) ++ *bufPnt++ = Color; ++ ++ /* fills the bitmap */ ++ for(i = 0; i < height; i++) ++ bmp->funcs->PutLine(bmp, i, 0, width, buf); ++ ++ /* frees temporaty line */ ++ HeapFree(GetProcessHeap(), 0, buf); ++ ++ MAYBE(TRACE("END\n")); ++ return TRUE; ++} ++ ++/* expands horizontally a bitmap to reach a minimum size, ++ keeping its width as a multiple of a base width ++ Used to widen brushes in order to optimize blitting */ ++BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth) ++{ ++ BYTE *srcBuf, *dstBuf; ++ int chunkSize; ++ int iLine, iCol; ++ DIBDRVBITMAP tmpDib; ++ void *bits; ++ BOOL ownsBits; ++ ++ MAYBE(TRACE("dib=%p, baseWidth=%d, minWidth=%d\n", dib, baseWidth, minWidth)); ++ ++ /* if dst dib already wide enough, just do nothing */ ++ if(dib->width >= minWidth) ++ { ++ MAYBE(TRACE("END - No need to expand\n")); ++ return TRUE; ++ } ++ ++ /* source DIB can't be NULL */ ++ if(!dib->bits) ++ { ++ ERR("Empty source DIB detected\n"); ++ return FALSE; ++ } ++ ++ /* round up minWidth to be a multiple of source width */ ++ minWidth += (baseWidth - (minWidth % baseWidth)); ++ ++ /* creates a temporary destination bitmap with required sizes */ ++ _DIBDRVBITMAP_Clear(&tmpDib); ++ if(!_DIBDRVBITMAP_CreateFromDibdrvbitmap(&tmpDib, dib, minWidth, dib->height)) ++ { ++ ERR("Couldn't create the temporary DIB for brush cache\n"); ++ return FALSE; ++ } ++ ++ /* if format uses almost 1 byte/pixel, fast copy path */ ++ if(dib->bitCount >= 8) ++ { ++ chunkSize = dib->width * dib->bitCount / 8; ++ for(iLine = 0; iLine < dib->height; iLine++) ++ { ++ srcBuf = (BYTE *)dib->bits + iLine * dib->stride; ++ dstBuf = (BYTE *)tmpDib.bits + iLine * tmpDib.stride; ++ for(iCol = 0; iCol < tmpDib.width; iCol += dib->width) ++ { ++ memcpy(dstBuf, srcBuf, chunkSize); ++ dstBuf += chunkSize; ++ } ++ } ++ } ++ /* otherwise slow path -- could be optimized */ ++ else ++ { ++ chunkSize = dib->width * 4; ++ /* allocates a line buffer */ ++ if(!(srcBuf = HeapAlloc(GetProcessHeap(), 0, tmpDib.width * 4))) ++ { ++ ERR("HeapAlloc failed\n"); ++ return FALSE; ++ } ++ ++ FIXME("dib:format=%s, funcs=%p, bits=%p, width=%d, height=%d, stride=%d\n", ++ _DIBDRVBITMAP_GetFormatName(dib), dib->funcs, dib->bits, dib->width, dib->height, dib->stride); ++ for(iLine = 0; iLine < dib->height; iLine++) ++ { ++ /* fills the line buffer repeating source's line data */ ++ dib->funcs->GetLine(dib, iLine, 0, dib->width, srcBuf); ++ dstBuf = srcBuf + chunkSize; ++ for(iCol = dib->width; iCol < tmpDib.width; iCol += dib->width) ++ { ++ memcpy(dstBuf, srcBuf, chunkSize); ++ dstBuf += chunkSize; ++ } ++ /* stores the line on destination bmp */ ++ tmpDib.funcs->PutLine(&tmpDib, iLine, 0, tmpDib.width, srcBuf); ++ } ++ HeapFree(GetProcessHeap(), 0, srcBuf); ++ } ++ ++ /* swaps temp DIB and source one */ ++ bits = dib->bits; ++ ownsBits = dib->ownsBits; ++ dib->bits = tmpDib.bits; ++ dib->ownsBits = tmpDib.ownsBits; ++ tmpDib.bits = bits; ++ tmpDib.ownsBits = ownsBits; ++ ++ /* frees the temporary DIB */ ++ _DIBDRVBITMAP_Free(&tmpDib); ++ ++ MAYBE(TRACE("END\n")); ++ return TRUE; ++} +diff --git a/dlls/winedib.drv/driver.c b/dlls/winedib.drv/driver.c +new file mode 100644 +index 0000000..46fa7a1 +--- /dev/null ++++ b/dlls/winedib.drv/driver.c +@@ -0,0 +1,254 @@ ++/* ++ * Access to display driver ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++#include ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* CreateDriver ++ * Allocate and fill the function pointer structure for a given module. */ ++static DC_FUNCTIONS *CreateDriver( HMODULE module ) ++{ ++ DC_FUNCTIONS *funcs; ++ ++ if (!(funcs = HeapAlloc( GetProcessHeap(), 0, sizeof(*funcs)))) ++ return NULL; ++ ++ /* fill the function table */ ++ if (module) ++ { ++#define GET_FUNC(name) funcs->p##name = (void*)GetProcAddress( module, #name ) ++ GET_FUNC(AbortDoc); ++ GET_FUNC(AbortPath); ++ GET_FUNC(AlphaBlend); ++ GET_FUNC(AngleArc); ++ GET_FUNC(Arc); ++ GET_FUNC(ArcTo); ++ GET_FUNC(BeginPath); ++ GET_FUNC(BitBlt); ++ GET_FUNC(ChoosePixelFormat); ++ GET_FUNC(Chord); ++ GET_FUNC(CloseFigure); ++ GET_FUNC(CreateBitmap); ++ GET_FUNC(CreateDC); ++ GET_FUNC(CreateDIBSection); ++ GET_FUNC(DeleteBitmap); ++ GET_FUNC(DeleteDC); ++ GET_FUNC(DescribePixelFormat); ++ GET_FUNC(DeviceCapabilities); ++ GET_FUNC(Ellipse); ++ GET_FUNC(EndDoc); ++ GET_FUNC(EndPage); ++ GET_FUNC(EndPath); ++ GET_FUNC(EnumDeviceFonts); ++ GET_FUNC(ExcludeClipRect); ++ GET_FUNC(ExtDeviceMode); ++ GET_FUNC(ExtEscape); ++ GET_FUNC(ExtFloodFill); ++ GET_FUNC(ExtSelectClipRgn); ++ GET_FUNC(ExtTextOut); ++ GET_FUNC(FillPath); ++ GET_FUNC(FillRgn); ++ GET_FUNC(FlattenPath); ++ GET_FUNC(FrameRgn); ++ GET_FUNC(GdiComment); ++ GET_FUNC(GetBitmapBits); ++ GET_FUNC(GetCharWidth); ++ GET_FUNC(GetDCOrgEx); ++ GET_FUNC(GetDIBColorTable); ++ GET_FUNC(GetDIBits); ++ GET_FUNC(GetDeviceCaps); ++ GET_FUNC(GetDeviceGammaRamp); ++ GET_FUNC(GetICMProfile); ++ GET_FUNC(GetNearestColor); ++ GET_FUNC(GetPixel); ++ GET_FUNC(GetPixelFormat); ++ GET_FUNC(GetSystemPaletteEntries); ++ GET_FUNC(GetTextExtentExPoint); ++ GET_FUNC(GetTextMetrics); ++ GET_FUNC(IntersectClipRect); ++ GET_FUNC(InvertRgn); ++ GET_FUNC(LineTo); ++ GET_FUNC(MoveTo); ++ GET_FUNC(ModifyWorldTransform); ++ GET_FUNC(OffsetClipRgn); ++ GET_FUNC(OffsetViewportOrg); ++ GET_FUNC(OffsetWindowOrg); ++ GET_FUNC(PaintRgn); ++ GET_FUNC(PatBlt); ++ GET_FUNC(Pie); ++ GET_FUNC(PolyBezier); ++ GET_FUNC(PolyBezierTo); ++ GET_FUNC(PolyDraw); ++ GET_FUNC(PolyPolygon); ++ GET_FUNC(PolyPolyline); ++ GET_FUNC(Polygon); ++ GET_FUNC(Polyline); ++ GET_FUNC(PolylineTo); ++ GET_FUNC(RealizeDefaultPalette); ++ GET_FUNC(RealizePalette); ++ GET_FUNC(Rectangle); ++ GET_FUNC(ResetDC); ++ GET_FUNC(RestoreDC); ++ GET_FUNC(RoundRect); ++ GET_FUNC(SaveDC); ++ GET_FUNC(ScaleViewportExt); ++ GET_FUNC(ScaleWindowExt); ++ GET_FUNC(SelectBitmap); ++ GET_FUNC(SelectBrush); ++ GET_FUNC(SelectClipPath); ++ GET_FUNC(SelectFont); ++ GET_FUNC(SelectPalette); ++ GET_FUNC(SelectPen); ++ GET_FUNC(SetArcDirection); ++ GET_FUNC(SetBitmapBits); ++ GET_FUNC(SetBkColor); ++ GET_FUNC(SetBkMode); ++ GET_FUNC(SetDCBrushColor); ++ GET_FUNC(SetDCOrg); ++ GET_FUNC(SetDCPenColor); ++ GET_FUNC(SetDIBColorTable); ++ GET_FUNC(SetDIBits); ++ GET_FUNC(SetDIBitsToDevice); ++ GET_FUNC(SetDeviceClipping); ++ GET_FUNC(SetDeviceGammaRamp); ++ GET_FUNC(SetMapMode); ++ GET_FUNC(SetMapperFlags); ++ GET_FUNC(SetPixel); ++ GET_FUNC(SetPixelFormat); ++ GET_FUNC(SetPolyFillMode); ++ GET_FUNC(SetROP2); ++ GET_FUNC(SetRelAbs); ++ GET_FUNC(SetStretchBltMode); ++ GET_FUNC(SetTextAlign); ++ GET_FUNC(SetTextCharacterExtra); ++ GET_FUNC(SetTextColor); ++ GET_FUNC(SetTextJustification); ++ GET_FUNC(SetViewportExt); ++ GET_FUNC(SetViewportOrg); ++ GET_FUNC(SetWindowExt); ++ GET_FUNC(SetWindowOrg); ++ GET_FUNC(SetWorldTransform); ++ GET_FUNC(StartDoc); ++ GET_FUNC(StartPage); ++ GET_FUNC(StretchBlt); ++ GET_FUNC(StretchDIBits); ++ GET_FUNC(StrokeAndFillPath); ++ GET_FUNC(StrokePath); ++ GET_FUNC(SwapBuffers); ++ GET_FUNC(UnrealizePalette); ++ GET_FUNC(WidenPath); ++ ++ /* OpenGL32 */ ++ GET_FUNC(wglCreateContext); ++ GET_FUNC(wglDeleteContext); ++ GET_FUNC(wglGetProcAddress); ++ GET_FUNC(wglGetPbufferDCARB); ++ GET_FUNC(wglMakeContextCurrentARB); ++ GET_FUNC(wglMakeCurrent); ++ GET_FUNC(wglSetPixelFormatWINE); ++ GET_FUNC(wglShareLists); ++ GET_FUNC(wglUseFontBitmapsA); ++ GET_FUNC(wglUseFontBitmapsW); ++#undef GET_FUNC ++ } ++ else ++ memset( funcs, 0, sizeof(*funcs) ); ++ ++ /* add it to the list */ ++ return funcs; ++} ++ ++ ++/* LoadDisplayDriver ++ * Loads display driver - partially grabbed from gdi32 */ ++static DC_FUNCTIONS *X11DrvFuncs = NULL; ++static HMODULE X11DrvModule = 0; ++DC_FUNCTIONS *_DIBDRV_LoadDisplayDriver(void) ++{ ++ char buffer[MAX_PATH], libname[32], *name, *next; ++ HMODULE module = 0; ++ HKEY hkey; ++ ++ if (X11DrvFuncs) /* already loaded */ ++ return X11DrvFuncs; ++ ++ strcpy( buffer, "x11" ); /* default value */ ++ /* @@ Wine registry key: HKCU\Software\Wine\Drivers */ ++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hkey )) ++ { ++ DWORD type, count = sizeof(buffer); ++ RegQueryValueExA( hkey, "Graphics", 0, &type, (LPBYTE) buffer, &count ); ++ RegCloseKey( hkey ); ++ } ++ ++ name = buffer; ++ while (name) ++ { ++ next = strchr( name, ',' ); ++ if (next) ++ *next++ = 0; ++ ++ snprintf( libname, sizeof(libname), "wine%s.drv", name ); ++ if ((module = LoadLibraryA( libname )) != 0) ++ break; ++ name = next; ++ } ++ ++ if (!(X11DrvFuncs = CreateDriver(module))) ++ { ++ ERR( "Could not create graphics driver '%s'\n", buffer ); ++ FreeLibrary( module ); ++ ExitProcess(1); ++ } ++ ++ X11DrvModule = module; ++ return X11DrvFuncs; ++} ++ ++/* FreeDisplayDriver ++ Frees resources allocated by Display driver */ ++void _DIBDRV_FreeDisplayDriver(void) ++{ ++ /* frees function table */ ++ if(X11DrvFuncs) ++ { ++ HeapFree(GetProcessHeap(), 0, X11DrvFuncs); ++ X11DrvFuncs = 0; ++ } ++ /* and unload the module */ ++ if(X11DrvModule) ++ { ++ FreeLibrary(X11DrvModule); ++ X11DrvModule = 0; ++ } ++} ++ ++/* GetDisplayDriver ++ Gets a pointer to display drives'function table */ ++inline DC_FUNCTIONS *_DIBDRV_GetDisplayDriver(void) ++{ ++ return X11DrvFuncs; ++ ++} +diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c +index 675145f..215b27d 100644 +--- a/dlls/winedib.drv/font.c ++++ b/dlls/winedib.drv/font.c +@@ -32,14 +32,40 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { + COLORREF res; ++ INT r, g, b; ++ INT i; + +- TRACE("physDev:%p, color:%08x\n", physDev, color); ++ MAYBE(TRACE("physDev:%p, color:%08x\n", physDev, color)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetTextColor(physDev->X11PhysDev, color); ++ ++ /* do nothing if color is the same as actual one */ ++ if(color == physDev->textColor) ++ return color; ++ ++ /* stores old color */ ++ res = physDev->textColor; ++ ++ /* fills the text color table used on antialiased font display */ ++ if(physDev->physBitmap.funcs) ++ { ++ r = GetRValue(color); ++ g = GetGValue(color); ++ b = GetBValue(color); ++ for(i = 0; i < 256; i++) ++ { ++ physDev->textColorTable[i] = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, RGB( ++ MulDiv(r, i, 256), ++ MulDiv(g, i, 256), ++ MulDiv(b, i, 256) ++ )); ++ } ++ } ++ ++ /* returns previous text color */ ++ return res; + } + else + { +@@ -52,17 +78,75 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + /*********************************************************************** + * DIBDRV_SelectFont + */ +-HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, HANDLE gdiFont ) ++HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, GdiFont *gdiFont ) + { + HFONT res; ++ FT_Int i; ++ FT_Error error; ++ FT_CharMap charmap = NULL; ++ LOGFONTW lf; + +- TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont); ++ MAYBE(TRACE("physDev:%p, hfont:%p, gdiFont:%p\n", physDev, hfont, gdiFont)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSelectFont(physDev->X11PhysDev, hfont, gdiFont); ++ ++ /* gets font information */ ++ GetObjectW(hfont, sizeof(lf), &lf); ++ MAYBE(TRACE("Font is : '%s'\n", debugstr_w(lf.lfFaceName))); ++ ++ /* FIXME: just handles gdifont, don't know if it needs to handle hfont too ++ BTW, still don't know how to get FT_Face from non-gdi font here ++ */ ++ if(!gdiFont) ++ { ++ FIXME("No gdi font - unhandled by now.\n"); ++ return hfont; ++ } ++ ++ physDev->face = gdiFont->ft_face; ++ if(!physDev->face) ++ { ++ FIXME("Error, null Ft_Face\n"); ++ return hfont; ++ } ++ ++ /* setup the correct charmap.... maybe */ ++ for (i = 0; i < physDev->face->num_charmaps; ++i) ++ { ++ if (physDev->face->charmaps[i]->platform_id != TT_PLATFORM_MICROSOFT) ++ continue; ++ ++ if (physDev->face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS) ++ { ++ charmap = physDev->face->charmaps[i]; ++ break; ++ } ++ ++ if (charmap == NULL) ++ { ++ WARN("Selected fallout charmap #%d\n", i); ++ charmap = physDev->face->charmaps[i]; ++ } ++ } ++ if (charmap == NULL) ++ { ++ WARN("No Windows character map found\n"); ++ charmap = physDev->face->charmaps[0]; ++ return 0; ++ } ++ ++ error = pFT_Set_Charmap(physDev->face, charmap); ++ if (error != FT_Err_Ok) ++ { ++ ERR("%s returned %i\n", "FT_Set_Charmap", error); ++ return 0; ++ } ++ ++ /* we use GDI fonts, so just return false */ ++ return 0; ++ + } + else + { +@@ -80,13 +164,13 @@ BOOL DIBDRV_EnumDeviceFonts( DIBDRVPHYSDEV *physDev, LPLOGFONTW plf, + { + BOOL res; + +- TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp); ++ MAYBE(TRACE("physDev:%p, plf:%p, proc:%p, lp:%lx\n", physDev, plf, proc, lp)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pEnumDeviceFonts(physDev->X11PhysDev, plf, proc, lp); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + } + else + { +@@ -103,13 +187,13 @@ BOOL DIBDRV_GetTextMetrics( DIBDRVPHYSDEV *physDev, TEXTMETRICW *metrics ) + { + BOOL res; + +- TRACE("physDev:%p, metrics:%p\n", physDev, metrics); ++ MAYBE(TRACE("physDev:%p, metrics:%p\n", physDev, metrics)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetTextMetrics(physDev->X11PhysDev, metrics); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + } + else + { +@@ -127,13 +211,13 @@ BOOL DIBDRV_GetCharWidth( DIBDRVPHYSDEV *physDev, UINT firstChar, UINT lastChar, + { + BOOL res; + +- TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer); ++ MAYBE(TRACE("physDev:%p, firstChar:%d, lastChar:%d, buffer:%pn", physDev, firstChar, lastChar, buffer)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetCharWidth(physDev->X11PhysDev, firstChar, lastChar, buffer); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + } + else + { +diff --git a/dlls/winedib.drv/freetype.c b/dlls/winedib.drv/freetype.c +new file mode 100644 +index 0000000..111a18b +--- /dev/null ++++ b/dlls/winedib.drv/freetype.c +@@ -0,0 +1,136 @@ ++/* ++ * Truetype font functions ++ * ++ * Copyright 2008 Massimo Del Fedele ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++#define MAKE_FUNCPTR(f) typeof(f) * p##f = NULL; ++MAKE_FUNCPTR(FT_Done_Face) ++MAKE_FUNCPTR(FT_Done_FreeType) ++MAKE_FUNCPTR(FT_Get_Char_Index) ++MAKE_FUNCPTR(FT_Get_Glyph_Name) ++MAKE_FUNCPTR(FT_Get_Sfnt_Name) ++MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count) ++MAKE_FUNCPTR(FT_Get_Sfnt_Table) ++MAKE_FUNCPTR(FT_Init_FreeType) ++MAKE_FUNCPTR(FT_Load_Glyph) ++MAKE_FUNCPTR(FT_Load_Char) ++MAKE_FUNCPTR(FT_Get_Glyph) ++MAKE_FUNCPTR(FT_Glyph_Copy) ++MAKE_FUNCPTR(FT_Glyph_To_Bitmap) ++MAKE_FUNCPTR(FT_Done_Glyph) ++MAKE_FUNCPTR(FT_New_Face) ++MAKE_FUNCPTR(FT_Set_Charmap) ++MAKE_FUNCPTR(FT_Set_Char_Size) ++MAKE_FUNCPTR(FT_Set_Pixel_Sizes) ++MAKE_FUNCPTR(FT_Get_First_Char) ++MAKE_FUNCPTR(FT_Render_Glyph) ++MAKE_FUNCPTR(FT_Glyph_Transform) ++#undef MAKE_FUNCPTR ++ ++/* freetype initialization flag */ ++static BOOL FreeType_Initialized = FALSE; ++ ++/* freetype dll handle */ ++static void *ft_handle = NULL; ++ ++/* freetype library handle */ ++FT_Library DIBDRV_ftLibrary = NULL; ++ ++/* initialize freetype library */ ++BOOL _DIBDRV_FreeType_Init(void) ++{ ++ FT_Int error; ++ ++ ft_handle = wine_dlopen(SONAME_LIBFREETYPE, RTLD_NOW, NULL, 0); ++ if(!ft_handle) ++ { ++ WINE_MESSAGE( ++ "Wine cannot find the FreeType font library. To enable Wine to\n" ++ "use TrueType fonts please install a version of FreeType greater than\n" ++ "or equal to 2.0.5.\n" ++ "http://www.freetype.org\n"); ++ return FALSE; ++ } ++ ++#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL) goto sym_not_found; ++ LOAD_FUNCPTR(FT_Done_Face) ++ LOAD_FUNCPTR(FT_Done_FreeType) ++ LOAD_FUNCPTR(FT_Get_Char_Index) ++ LOAD_FUNCPTR(FT_Get_Glyph_Name) ++ LOAD_FUNCPTR(FT_Get_Sfnt_Name) ++ LOAD_FUNCPTR(FT_Get_Sfnt_Name_Count) ++ LOAD_FUNCPTR(FT_Get_Sfnt_Table) ++ LOAD_FUNCPTR(FT_Init_FreeType) ++ LOAD_FUNCPTR(FT_Load_Glyph) ++ LOAD_FUNCPTR(FT_Load_Char) ++ LOAD_FUNCPTR(FT_Get_Glyph) ++ LOAD_FUNCPTR(FT_Glyph_Copy) ++ LOAD_FUNCPTR(FT_Glyph_To_Bitmap) ++ LOAD_FUNCPTR(FT_Done_Glyph) ++ LOAD_FUNCPTR(FT_New_Face) ++ LOAD_FUNCPTR(FT_Set_Charmap) ++ LOAD_FUNCPTR(FT_Set_Char_Size) ++ LOAD_FUNCPTR(FT_Set_Pixel_Sizes) ++ LOAD_FUNCPTR(FT_Get_First_Char) ++ LOAD_FUNCPTR(FT_Render_Glyph) ++ LOAD_FUNCPTR(FT_Glyph_Transform) ++#undef LOAD_FUNCPTR ++ ++ error = pFT_Init_FreeType(&DIBDRV_ftLibrary); ++ if (error != FT_Err_Ok) ++ { ++ ERR("%s returned %i\n", "FT_Init_FreeType", error); ++ wine_dlclose(ft_handle, NULL, 0); ++ return FALSE; ++ } ++ ++ /* marks library as initialized */ ++ FreeType_Initialized = TRUE; ++ ++ return TRUE; ++ ++sym_not_found: ++ WINE_MESSAGE( ++ "Wine cannot find certain functions that it needs inside the FreeType\n" ++ "font library. To enable Wine to use TrueType fonts please upgrade\n" ++ "FreeType to at least version 2.0.5.\n" ++ "http://www.freetype.org\n"); ++ wine_dlclose(ft_handle, NULL, 0); ++ ft_handle = NULL; ++ return FALSE; ++} ++ ++/* terminates freetype library */ ++void _DIBDRV_FreeType_Terminate(void) ++{ ++ if(!FreeType_Initialized) ++ return; ++ ++ /* terminates and unload freetype library */ ++ pFT_Done_FreeType(DIBDRV_ftLibrary); ++ wine_dlclose(ft_handle, NULL, 0); ++ ft_handle = NULL; ++ FreeType_Initialized = FALSE; ++ ++} +diff --git a/dlls/winedib.drv/freetype.h b/dlls/winedib.drv/freetype.h +new file mode 100644 +index 0000000..93619ff +--- /dev/null ++++ b/dlls/winedib.drv/freetype.h +@@ -0,0 +1,186 @@ ++/* ++ * Truetype font functions ++ * ++ * Copyright 2008 Massimo Del Fedele ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++#ifndef __WINE_DIBDRV_FREETYPE_H ++#define __WINE_DIBDRV__FREETYPE_H ++ ++/* freetype library for font support */ ++#ifdef HAVE_FREETYPE ++ ++#include ++#include FT_FREETYPE_H ++#include FT_GLYPH_H ++#include FT_TRUETYPE_TABLES_H ++#include FT_SFNT_NAMES_H ++#include FT_TRUETYPE_IDS_H ++ ++/* freetype library handle */ ++extern FT_Library DIBDRV_ftLibrary; ++ ++/******************************************************************************************/ ++/* FREETYPE STUFFS */ ++/* grabbed from winex11.drv/freetype.c */ ++/******************************************************************************************/ ++ ++/* This is basically a copy of FT_Bitmap_Size with an extra element added */ ++typedef struct { ++ FT_Short height; ++ FT_Short width; ++ FT_Pos size; ++ FT_Pos x_ppem; ++ FT_Pos y_ppem; ++ FT_Short internal_leading; ++} Bitmap_Size; ++ ++/* FT_Bitmap_Size gained 3 new elements between FreeType 2.1.4 and 2.1.5 ++ So to let this compile on older versions of FreeType we'll define the ++ new structure here. */ ++typedef struct { ++ FT_Short height, width; ++ FT_Pos size, x_ppem, y_ppem; ++} My_FT_Bitmap_Size; ++ ++struct enum_data ++{ ++ ENUMLOGFONTEXW elf; ++ NEWTEXTMETRICEXW ntm; ++ DWORD type; ++}; ++ ++typedef struct tagFace { ++ struct list entry; ++ WCHAR *StyleName; ++ char *file; ++ void *font_data_ptr; ++ DWORD font_data_size; ++ FT_Long face_index; ++ FONTSIGNATURE fs; ++ FONTSIGNATURE fs_links; ++ DWORD ntmFlags; ++ FT_Fixed font_version; ++ BOOL scalable; ++ Bitmap_Size size; /* set if face is a bitmap */ ++ BOOL external; /* TRUE if we should manually add this font to the registry */ ++ struct tagFamily *family; ++ /* Cached data for Enum */ ++ struct enum_data *cached_enum_data; ++} Face; ++ ++typedef struct tagFamily { ++ struct list entry; ++ const WCHAR *FamilyName; ++ struct list faces; ++} Family; ++ ++typedef struct { ++ GLYPHMETRICS gm; ++ INT adv; /* These three hold to widths of the unrotated chars */ ++ INT lsb; ++ INT bbx; ++ BOOL init; ++} GM; ++ ++typedef struct { ++ FLOAT eM11, eM12; ++ FLOAT eM21, eM22; ++} FMAT2; ++ ++typedef struct { ++ DWORD hash; ++ LOGFONTW lf; ++ FMAT2 matrix; ++ BOOL can_use_bitmap; ++} FONT_DESC; ++ ++typedef struct tagHFONTLIST { ++ struct list entry; ++ HFONT hfont; ++} HFONTLIST; ++ ++typedef struct { ++ struct list entry; ++ Face *face; ++ struct tagGdiFont *font; ++} CHILD_FONT; ++ ++typedef struct tagGdiFont { ++ struct list entry; ++ GM **gm; ++ DWORD gmsize; ++ struct list hfontlist; ++ OUTLINETEXTMETRICW *potm; ++ DWORD total_kern_pairs; ++ KERNINGPAIR *kern_pairs; ++ struct list child_fonts; ++ ++ /* the following members can be accessed without locking, they are never modified after creation */ ++ FT_Face ft_face; ++ struct font_mapping *mapping; ++ LPWSTR name; ++ int charset; ++ int codepage; ++ BOOL fake_italic; ++ BOOL fake_bold; ++ BYTE underline; ++ BYTE strikeout; ++ INT orientation; ++ FONT_DESC font_desc; ++ LONG aveWidth, ppem; ++ double scale_y; ++ SHORT yMax; ++ SHORT yMin; ++ DWORD ntmFlags; ++ FONTSIGNATURE fs; ++ struct tagGdiFont *base_font; ++ VOID *GSUB_Table; ++ DWORD cache_num; ++} GdiFont; ++ ++/* initialize freetype library */ ++BOOL _DIBDRV_FreeType_Init(void); ++ ++/* terminates freetype library */ ++void _DIBDRV_FreeType_Terminate(void); ++ ++#define MAKE_FUNCPTR(f) extern typeof(f) * p##f; ++MAKE_FUNCPTR(FT_Done_Face) ++MAKE_FUNCPTR(FT_Done_FreeType) ++MAKE_FUNCPTR(FT_Get_Char_Index) ++MAKE_FUNCPTR(FT_Get_Glyph_Name) ++MAKE_FUNCPTR(FT_Get_Sfnt_Name) ++MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count) ++MAKE_FUNCPTR(FT_Get_Sfnt_Table) ++MAKE_FUNCPTR(FT_Init_FreeType) ++MAKE_FUNCPTR(FT_Load_Glyph) ++MAKE_FUNCPTR(FT_Load_Char) ++MAKE_FUNCPTR(FT_Get_Glyph) ++MAKE_FUNCPTR(FT_Glyph_Copy) ++MAKE_FUNCPTR(FT_Glyph_To_Bitmap) ++MAKE_FUNCPTR(FT_Done_Glyph) ++MAKE_FUNCPTR(FT_New_Face) ++MAKE_FUNCPTR(FT_Set_Charmap) ++MAKE_FUNCPTR(FT_Set_Char_Size) ++MAKE_FUNCPTR(FT_Set_Pixel_Sizes) ++MAKE_FUNCPTR(FT_Get_First_Char) ++MAKE_FUNCPTR(FT_Render_Glyph) ++MAKE_FUNCPTR(FT_Glyph_Transform) ++#undef MAKE_FUNCPTR ++ ++#endif /* HAVE_FREETYPE */ ++ ++#endif +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +index b74c08e..8dda082 100644 +--- a/dlls/winedib.drv/graphics.c ++++ b/dlls/winedib.drv/graphics.c +@@ -25,23 +25,33 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++static inline void OrderInt(int *i1, int *i2) ++{ ++ if(*i1 > *i2) ++ { ++ int tmp; ++ tmp = *i1; ++ *i1 = *i2; ++ *i2 = tmp; ++ } ++} ++ + /*********************************************************************** + * DIBDRV_Arc + */ +-BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom, +- INT xstart, INT ystart, INT xend, INT yend ) ++BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom, ++ int xstart, int ystart, int xend, int yend ) + { + BOOL res; + +- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n", +- physDev, left, top, right, bottom, xstart, ystart, xend, yend); ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n", ++ physDev, left, top, right, bottom, xstart, ystart, xend, yend)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, left, top, right, bottom, +- xstart, ystart, xend, yend); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -55,20 +65,19 @@ BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT botto + /*********************************************************************** + * DIBDRV_Chord + */ +-BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom, +- INT xstart, INT ystart, INT xend, INT yend ) ++BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom, ++ int xstart, int ystart, int xend, int yend ) + { + BOOL res; + +- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n", +- physDev, left, top, right, bottom, xstart, ystart, xend, yend); ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n", ++ physDev, left, top, right, bottom, xstart, ystart, xend, yend)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, left, top, right, bottom, +- xstart, ystart, xend, yend); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -82,18 +91,18 @@ BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bot + /*********************************************************************** + * DIBDRV_Ellipse + */ +-BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom ) ++BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom ) + { + BOOL res; + +- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", +- physDev, left, top, right, bottom); ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", ++ physDev, left, top, right, bottom)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, left, top, right, bottom); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -106,19 +115,19 @@ BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT b + /********************************************************************** + * DIBDRV_ExtFloodFill + */ +-BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color, ++BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color, + UINT fillType ) + { + BOOL res; + +- TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n", +- physDev, x, y, color, fillType); ++ MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n", ++ physDev, x, y, color, fillType)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, x, y, color, fillType); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -135,13 +144,13 @@ BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp ) + { + BOOL res; + +- TRACE("physDev:%p, lpp:%p\n", physDev, lpp); ++ MAYBE(TRACE("physDev:%p, lpp:%p\n", physDev, lpp)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, lpp); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -154,17 +163,15 @@ BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp ) + /*********************************************************************** + * DIBDRV_GetPixel + */ +-COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y ) ++COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y ) + { + COLORREF res; + +- TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); ++ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, x, y); ++ res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y); + } + else + { +@@ -177,17 +184,26 @@ COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y ) + /*********************************************************************** + * DIBDRV_LineTo + */ +-BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y ) ++BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, int x, int y ) + { + BOOL res; ++ POINT curPos; + +- TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); ++ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, x, y); ++ GetCurrentPositionEx(physDev->hdc, &curPos); ++ ++ _DIBDRV_ResetDashOrigin(physDev); ++ ++ if(curPos.y == y) ++ physDev->penHLine(physDev, curPos.x, x, y); ++ else if(curPos.x == x) ++ physDev->penVLine(physDev, x, curPos.y, y); ++ else ++ physDev->penLine(physDev, curPos.x, curPos.y, x, y); ++ res = TRUE; + } + else + { +@@ -200,17 +216,43 @@ BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, INT x, INT y ) + /*********************************************************************** + * DIBDRV_PaintRgn + */ ++BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom); + BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn ) + { +- BOOL res; ++ BOOL res = FALSE; ++ int i; ++ RECT *rect; ++ RGNDATA *data; ++ int size; + +- TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn); ++ MAYBE(TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, hrgn); ++ /* gets needed region data size */ ++ if(!(size = GetRegionData(hrgn, 0, NULL))) ++ goto fin; ++ ++ /* allocates buffer and gets actual region data */ ++ if(!(data = HeapAlloc(GetProcessHeap(), 0, size))) ++ goto fin; ++ if(!GetRegionData(hrgn, size, data)) ++ { ++ HeapFree(GetProcessHeap(), 0, data); ++ goto fin; ++ } ++ ++ /* paints the filled rectangles */ ++ rect = (RECT *)data->Buffer; ++ for(i = 0; i < data->rdh.nCount; i++) ++ { ++ DIBDRV_Rectangle( physDev, rect->left, rect->top, rect->right, rect->bottom); ++ rect++; ++ } ++ HeapFree( GetProcessHeap(), 0, data ); ++ res = TRUE; ++fin: ++ ; + } + else + { +@@ -223,20 +265,19 @@ BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn ) + /*********************************************************************** + * DIBDRV_Pie + */ +-BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom, +- INT xstart, INT ystart, INT xend, INT yend ) ++BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom, ++ int xstart, int ystart, int xend, int yend ) + { + BOOL res; + +- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n", +- physDev, left, top, right, bottom, xstart, ystart, xend, yend); ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n", ++ physDev, left, top, right, bottom, xstart, ystart, xend, yend)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, left, top, right, bottom, +- xstart, ystart, xend, yend); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -250,17 +291,17 @@ BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT botto + /********************************************************************** + * DIBDRV_Polygon + */ +-BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) ++BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, int count ) + { + BOOL res; + +- TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count); ++ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, pt, count); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -273,17 +314,17 @@ BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) + /********************************************************************** + * DIBDRV_Polyline + */ +-BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) ++BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, int count ) + { + BOOL res; + +- TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count); ++ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, pt, count); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -296,17 +337,17 @@ BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, INT count ) + /********************************************************************** + * DIBDRV_PolyPolygon + */ +-BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const INT* counts, UINT polygons) ++BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const int* counts, UINT polygons) + { + BOOL res; + +- TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons); ++ MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, pt, counts, polygons); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -324,13 +365,13 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* + { + BOOL res; + +- TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines); ++ MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, pt, counts, polylines); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -343,23 +384,65 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* + /*********************************************************************** + * DIBDRV_Rectangle + */ +-BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT bottom) ++BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) + { +- BOOL res; ++ BOOL res = TRUE; ++ int i; ++ DIBDRVBITMAP *bmp = &physDev->physBitmap; + +- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", +- physDev, left, top, right, bottom); ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev, x1, y1, x2, y2)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, left, top, right, bottom); ++ OrderInt(&x1, &x2); ++ OrderInt(&y1, &y2); ++ ++ /* temporary fix.... should be done by clipping */ ++ if(x1 < 0) x1 = 0; ++ if(x2 < 0) x2 = 0; ++ if(y1 < 0) y1 = 0; ++ if(y2 < 0) y2 = 0; ++ if(x1 >= bmp->width) x1 = bmp->width - 1; ++ if(y1 >= bmp->height) y1 = bmp->height - 1; ++ if(x2 > bmp->width) x2 = bmp->width; ++ if(y2 > bmp->height) y2 = bmp->height ; ++ if(x1 >= x2 || y1 >= y2) ++ goto fin; ++ ++ _DIBDRV_ResetDashOrigin(physDev); ++ ++ /* particular case where the rectangle ++ degenerates to a line or a point */ ++ if(x1 >= x2 - 1) ++ { ++ physDev->penVLine(physDev, x1, y1, y2); ++ goto fin; ++ } ++ else if (y1 >= y2 -1) ++ { ++ physDev->penHLine(physDev, x1, x2, y1); ++ goto fin; ++ } ++ ++ /* Draw the perimeter */ ++ physDev->penHLine(physDev, x1 , x2 , y1 ); ++ physDev->penHLine(physDev, x1 , x2 , y2 - 1); ++ physDev->penVLine(physDev, x1 , y1 + 1, y2 - 1); ++ physDev->penVLine(physDev, x2 - 1, y1 + 1, y2 - 1); ++ ++ /* fill the inside */ ++ if(x2 >= x1 + 2) ++ for (i = y1 + 1; i < y2 - 1; i++) ++ physDev->brushHLine(physDev, x1 + 1, x2 - 1, i); ++ ++ res = TRUE; ++fin: ++ ; + } + else + { + /* DDB selected in, use X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, left, top, right, bottom); ++ res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, x1, y1, x2, y2); + } + return res; + } +@@ -367,20 +450,19 @@ BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, INT + /*********************************************************************** + * DIBDRV_RoundRect + */ +-BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, +- INT bottom, INT ell_width, INT ell_height ) ++BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, int left, int top, int right, ++ int bottom, int ell_width, int ell_height ) + { + BOOL res; + +- TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n", +- physDev, left, top, right, bottom, ell_width, ell_height); ++ MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n", ++ physDev, left, top, right, bottom, ell_width, ell_height)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, left, top, right, bottom, +- ell_width, ell_height); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +@@ -394,17 +476,23 @@ BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, INT left, INT top, INT right, + /*********************************************************************** + * DIBDRV_SetPixel + */ +-COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color ) ++COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color ) + { + COLORREF res; ++ DWORD and, xor; + +- TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color); ++ MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, x, y, color); ++ /* gets previous pixel */ ++ res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y); ++ ++ /* calculates AND and XOR from color */ ++ _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), color, &and, &xor); ++ ++ /* sets the pixel */ ++ physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, and, xor); + } + else + { +@@ -417,17 +505,17 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, INT x, INT y, COLORREF color ) + /*********************************************************************** + * DIBDRV_SetDCOrg + */ +-DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, INT x, INT y ) ++DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, int x, int y ) + { + DWORD res; + +- TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y); ++ MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, x, y); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + } + else + { +diff --git a/dlls/winedib.drv/opengl.c b/dlls/winedib.drv/opengl.c +index e8ec96c..f7855f6 100644 +--- a/dlls/winedib.drv/opengl.c ++++ b/dlls/winedib.drv/opengl.c +@@ -32,7 +32,7 @@ int DIBDRV_ChoosePixelFormat( DIBDRVPHYSDEV *physDev, + { + int res; + +- TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd); ++ MAYBE(TRACE("physDev:%p, ppfd:%p\n", physDev, ppfd)); + + if(physDev->hasDIB) + { +@@ -55,7 +55,7 @@ int DIBDRV_DescribePixelFormat( DIBDRVPHYSDEV *physDev, + { + int res; + +- TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd); ++ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, nBytes:%d, ppfd:%p\n", physDev, iPixelFormat, nBytes, ppfd)); + + if(physDev->hasDIB) + { +@@ -75,7 +75,7 @@ int DIBDRV_GetPixelFormat( DIBDRVPHYSDEV *physDev) + { + int res; + +- TRACE("physDev:%p\n", physDev); ++ MAYBE(TRACE("physDev:%p\n", physDev)); + + if(physDev->hasDIB) + { +@@ -97,7 +97,7 @@ BOOL DIBDRV_SetPixelFormat( DIBDRVPHYSDEV *physDev, + { + BOOL res; + +- TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd); ++ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd)); + + if(physDev->hasDIB) + { +@@ -117,7 +117,7 @@ BOOL DIBDRV_SwapBuffers( DIBDRVPHYSDEV *physDev ) + { + BOOL res; + +- TRACE("physDev:%p\n", physDev); ++ MAYBE(TRACE("physDev:%p\n", physDev)); + + if(physDev->hasDIB) + { +@@ -142,7 +142,7 @@ BOOL CDECL DIBDRV_wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) + { + BOOL res; + +- TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask); ++ MAYBE(TRACE("hglrcSrc:%p, hglrcDst:%p, mask:%x\n", hglrcSrc, hglrcDst, mask)); + + ONCE(FIXME("stub\n")); + res = _DIBDRV_GetDisplayDriver()->pwglCopyContext(hglrcSrc, hglrcDst, mask); +@@ -159,7 +159,7 @@ HGLRC CDECL DIBDRV_wglCreateContext(DIBDRVPHYSDEV *physDev) + { + HGLRC res; + +- TRACE("physDev:%p\n", physDev); ++ MAYBE(TRACE("physDev:%p\n", physDev)); + + if(physDev->hasDIB) + { +@@ -184,7 +184,7 @@ BOOL CDECL DIBDRV_wglDeleteContext(HGLRC hglrc) + { + BOOL res; + +- TRACE("hglrc:%p\n", hglrc); ++ MAYBE(TRACE("hglrc:%p\n", hglrc)); + + ONCE(FIXME("stub\n")); + res = _DIBDRV_GetDisplayDriver()->pwglDeleteContext(hglrc); +@@ -200,7 +200,7 @@ PROC CDECL DIBDRV_wglGetProcAddress(LPCSTR lpszProc) + { + PROC res; + +- TRACE("lpszProc:%p\n", lpszProc); ++ MAYBE(TRACE("lpszProc:%p\n", lpszProc)); + + ONCE(FIXME("stub\n")); + res = _DIBDRV_GetDisplayDriver()->pwglGetProcAddress(lpszProc); +@@ -220,7 +220,7 @@ HDC CDECL DIBDRV_wglGetPbufferDCARB(DIBDRVPHYSDEV *physDev, HPBUFFERARB hPbuffer + { + HDC res; + +- TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer); ++ MAYBE(TRACE("physDev:%p, hPbuffer:%p\n", physDev, hPbuffer)); + + if(physDev->hasDIB) + { +@@ -245,7 +245,7 @@ BOOL CDECL DIBDRV_wglMakeContextCurrentARB(DIBDRVPHYSDEV* pDrawDev, DIBDRVPHYSDE + { + BOOL res; + +- TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc); ++ MAYBE(TRACE("pDrawDev:%p, pReadDev:%p, hglrc:%p\n", pDrawDev, pReadDev, hglrc)); + + if(pDrawDev->hasDIB && pReadDev->hasDIB) + { +@@ -282,7 +282,7 @@ BOOL CDECL DIBDRV_wglMakeCurrent(DIBDRVPHYSDEV *physDev, HGLRC hglrc) + { + BOOL res; + +- TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc); ++ MAYBE(TRACE("physDev:%p, hglrc:%p\n", physDev, hglrc)); + + if(physDev->hasDIB) + { +@@ -308,7 +308,7 @@ BOOL CDECL DIBDRV_wglSetPixelFormatWINE(DIBDRVPHYSDEV *physDev, int iPixelFormat + { + BOOL res; + +- TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd); ++ MAYBE(TRACE("physDev:%p, iPixelFormat:%d, ppfd:%p\n", physDev, iPixelFormat, ppfd)); + + if(physDev->hasDIB) + { +@@ -333,7 +333,7 @@ BOOL CDECL DIBDRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) + { + BOOL res; + +- TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2); ++ MAYBE(TRACE("hglrc1:%p, hglrc2:%p\n", hglrc1, hglrc2)); + + ONCE(FIXME("stub\n")); + res = _DIBDRV_GetDisplayDriver()->pwglShareLists(hglrc1, hglrc2); +@@ -350,7 +350,7 @@ BOOL CDECL DIBDRV_wglUseFontBitmapsA(DIBDRVPHYSDEV *physDev, DWORD first, DWORD + { + BOOL res; + +- TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase); ++ MAYBE(TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase)); + + if(physDev->hasDIB) + { +@@ -375,7 +375,7 @@ BOOL CDECL DIBDRV_wglUseFontBitmapsW(DIBDRVPHYSDEV *physDev, DWORD first, DWORD + { + BOOL res; + +- TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase); ++ MAYBE(TRACE("physDev:%p, first:%d, count:%d, listBase:%d\n", physDev, first, count, listBase)); + + if(physDev->hasDIB) + { +diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c +index 9daf47d..148a6d5 100644 +--- a/dlls/winedib.drv/palette.c ++++ b/dlls/winedib.drv/palette.c +@@ -32,7 +32,7 @@ UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary + { + UINT res; + +- TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE")); ++ MAYBE(TRACE("physDev:%p, hpal:%p, primary:%s\n", physDev, hpal, (primary ? "TRUE" : "FALSE"))); + + /* we should in any case call X11 function, as UnrealizePalette() doesn't + * take a physDev parameter */ +@@ -54,7 +54,7 @@ BOOL DIBDRV_UnrealizePalette( HPALETTE hpal ) + { + BOOL res; + +- TRACE("hpal:%p\n", hpal); ++ MAYBE(TRACE("hpal:%p\n", hpal)); + + /* we should in any case call X11 function, as UnrealizePalette() doesn't + * take a physDev parameter */ +@@ -74,13 +74,13 @@ UINT DIBDRV_GetSystemPaletteEntries( DIBDRVPHYSDEV *physDev, UINT start, UINT co + { + UINT res; + +- TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries); ++ MAYBE(TRACE("physDev:%p, start:%d, count:%d, entries:%p\n", physDev, start, count, entries)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetSystemPaletteEntries(physDev->X11PhysDev, start, count, entries); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + } + else + { +@@ -97,13 +97,13 @@ COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { + COLORREF res; + +- TRACE("physDev:%p, color:%x\n", physDev, color); ++ MAYBE(TRACE("physDev:%p, color:%x\n", physDev, color)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetNearestColor(physDev->X11PhysDev, color); ++ ONCE(FIXME("STUB\n")); ++ res = 0; + } + else + { +@@ -119,14 +119,36 @@ COLORREF DIBDRV_GetNearestColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + UINT DIBDRV_RealizeDefaultPalette( DIBDRVPHYSDEV *physDev ) + { + UINT res; ++#ifdef DIBDRV_ENABLE_MAYBE ++ int i; ++ RGBQUAD *q; ++#endif + +- TRACE("physDev:%p\n", physDev); ++ MAYBE(TRACE("physDev:%p\n", physDev)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pRealizeDefaultPalette(physDev->X11PhysDev); ++ ONCE(FIXME("STUB\n")); ++ /* HACK - we can't get the dib color table during SelectBitmap since it hasn't ++ been initialized yet. This is called from DC_InitDC so it's a convenient place ++ to grab the color table. */ ++ MAYBE(TRACE("Color table size = %d, Color table = %p\n", physDev->physBitmap.colorTableSize, physDev->physBitmap.colorTable)); ++ if(!physDev->physBitmap.colorTableGrabbed) ++ { ++ MAYBE(TRACE("Grabbing palette\n")); ++ physDev->physBitmap.colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(physDev->physBitmap.colorTable[0]) * physDev->physBitmap.colorTableSize); ++ GetDIBColorTable(physDev->hdc, 0, physDev->physBitmap.colorTableSize, physDev->physBitmap.colorTable); ++#ifdef DIBDRV_ENABLE_MAYBE ++ for(i = 0; i < physDev->physBitmap.colorTableSize; i++) ++ { ++ q = physDev->physBitmap.colorTable + i; ++ TRACE(" %03d : R%03d G%03d B%03d\n", i, q->rgbRed, q->rgbGreen, q->rgbBlue); ++ } ++#endif ++ physDev->physBitmap.colorTableGrabbed = TRUE; ++ } ++ res = 0; + } + else + { +@@ -140,13 +162,14 @@ BOOL DIBDRV_GetICMProfile(DIBDRVPHYSDEV *physDev, LPDWORD lpcbName, LPWSTR lpszF + { + BOOL res; + +- TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename); ++ MAYBE(TRACE("physDev:%p, lpcpName:%p, lpszFilename:%p\n", physDev, lpcbName, lpszFilename)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetICMProfile(physDev->X11PhysDev, lpcbName, lpszFilename); ++ ONCE(FIXME("STUB\n")); ++ ++ res = 0; + } + else + { +diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c +index bde2f23..31c9cd2 100644 +--- a/dlls/winedib.drv/pen_brush.c ++++ b/dlls/winedib.drv/pen_brush.c +@@ -26,20 +26,317 @@ + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + + ++static const DASHPATTERN dashPatterns[4] = ++{ ++ {2, {18, 6}}, ++ {2, {3, 3}}, ++ {4, {9, 6, 3, 6}}, ++ {6, {9, 3, 3, 3, 3, 3}} ++}; ++ ++static inline void OrderEndPoints(int *s, int *e) ++{ ++ if(*s > *e) ++ { ++ int tmp; ++ tmp = *s + 1; ++ *s = *e + 1; ++ *e = tmp; ++ } ++} ++ ++static void SolidPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) ++{ ++ OrderEndPoints(&x1, &x2); ++ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x1, x2, y, physDev->penAnd, physDev->penXor); ++} ++ ++static void SolidPenVline(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) ++{ ++ OrderEndPoints(&y1, &y2); ++ physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y1, y2, physDev->penAnd, physDev->penXor); ++} ++ ++static void WINAPI SolidPenLineCallback(int x, int y, LPARAM lparam) ++{ ++ DIBDRVPHYSDEV *physDev = (DIBDRVPHYSDEV *)lparam; ++ ++ physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, physDev->penAnd, physDev->penXor); ++ return; ++} ++ ++void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) ++{ ++ LineDDA(x1, y1, x2, y2, SolidPenLineCallback, (LPARAM)physDev); ++} ++ ++static inline void GetDashColors(DIBDRVPHYSDEV *physDev, DWORD *and, DWORD *xor) ++{ ++ if(physDev->markSpace == mark) ++ { ++ *and = physDev->penAnd; ++ *xor = physDev->penXor; ++ } ++ else if(GetBkMode(physDev->hdc) == OPAQUE) ++ { ++ *and = physDev->backgroundAnd; ++ *xor = physDev->backgroundXor; ++ } ++ else ++ { ++ *and = 0xffffffff; ++ *xor = 0; ++ } ++} ++ ++static inline void NextDash(DIBDRVPHYSDEV *physDev) ++{ ++ if(physDev->leftInDash != 0) ++ return; ++ ++ physDev->curDash++; ++ if(physDev->curDash == physDev->penPattern->count) ++ physDev->curDash = 0; ++ physDev->leftInDash = physDev->penPattern->dashes[physDev->curDash]; ++ if(physDev->markSpace == mark) ++ physDev->markSpace = space; ++ else ++ physDev->markSpace = mark; ++} ++ ++static void DashedPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) ++{ ++ int x = x1; ++ DWORD and, xor; ++ DWORD dashLen; ++ ++ if(x1 <= x2) ++ { ++ while(x != x2) ++ { ++ GetDashColors(physDev, &and, &xor); ++ ++ dashLen = physDev->leftInDash; ++ if(x + dashLen > x2) ++ dashLen = x2 - x; ++ ++ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x, x + dashLen, y, and, xor); ++ x += dashLen; ++ ++ physDev->leftInDash -= dashLen; ++ NextDash(physDev); ++ } ++ } ++ else ++ { ++ while(x != x2) ++ { ++ GetDashColors(physDev, &and, &xor); ++ ++ dashLen = physDev->leftInDash; ++ if(x - (int)dashLen < x2) ++ dashLen = x - x2; ++ ++ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x - dashLen + 1, x + 1, y, and, xor); ++ x -= dashLen; ++ ++ physDev->leftInDash -= dashLen; ++ NextDash(physDev); ++ } ++ } ++} ++ ++static void DashedPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) ++{ ++ int y = y1; ++ DWORD and, xor; ++ DWORD dashLen; ++ ++ if(y1 <= y2) ++ { ++ while(y != y2) ++ { ++ GetDashColors(physDev, &and, &xor); ++ ++ dashLen = physDev->leftInDash; ++ if(y + dashLen > y2) ++ dashLen = y2 - y; ++ ++ physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y, y + dashLen, and, xor); ++ y += dashLen; ++ ++ physDev->leftInDash -= dashLen; ++ NextDash(physDev); ++ } ++ } ++ else ++ { ++ while(y != y2) ++ { ++ GetDashColors(physDev, &and, &xor); ++ ++ dashLen = physDev->leftInDash; ++ if(y - (int)dashLen < y2) ++ dashLen = y - y2; ++ ++ physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y - dashLen + 1, y + 1, and, xor); ++ y -= dashLen; ++ ++ physDev->leftInDash -= dashLen; ++ NextDash(physDev); ++ } ++ } ++} ++ ++static void WINAPI DashedPenLineCallback(int x, int y, LPARAM lparam) ++{ ++ DIBDRVPHYSDEV *physDev = (DIBDRVPHYSDEV *)lparam; ++ DWORD and, xor; ++ ++ GetDashColors(physDev, &and, &xor); ++ ++ physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, and, xor); ++ ++ physDev->leftInDash--; ++ NextDash(physDev); ++ ++ return; ++} ++ ++static void DashedPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) ++{ ++ LineDDA(x1, y1, x2, y2, DashedPenLineCallback, (LPARAM)physDev); ++} ++ ++void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev) ++{ ++ physDev->curDash = 0; ++ if(physDev->penPattern) ++ physDev->leftInDash = physDev->penPattern->dashes[0]; ++ physDev->markSpace = mark; ++} ++ ++ ++/* For 1bpp bitmaps, unless the selected foreground color exactly ++ matches foreground's colortable OR it's the WHITE color, ++ the background color is used -- tested on WinXP */ ++static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color) ++{ ++ RGBQUAD *fore = physDev->physBitmap.colorTable+1; ++ ++ if((color & 0x00ffffff) == 0x00ffffff || ++ ( ++ fore->rgbRed == GetRValue(color) && ++ fore->rgbGreen == GetGValue(color) && ++ fore->rgbBlue == GetBValue(color) ++ )) ++ return 1; ++ return 0; ++} ++ ++static void FixupFgColors1(DIBDRVPHYSDEV *physDev) ++{ ++ int rop = GetROP2(physDev->hdc); ++ ++ physDev->penColor = AdjustFgColor(physDev, physDev->penColorref); ++ physDev->brushColor = AdjustFgColor(physDev, physDev->brushColorref); ++ ++ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor); ++ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor); ++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds); ++ HeapFree(GetProcessHeap(), 0, physDev->brushXors); ++ physDev->brushAnds = NULL; ++ physDev->brushXors = NULL; ++} ++ ++static void SolidBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) ++{ ++ OrderEndPoints(&x1, &x2); ++ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x1, x2, y, physDev->brushAnd, physDev->brushXor); ++} ++ ++ ++static void GenerateMasks(DIBDRVPHYSDEV *physDev, DIBDRVBITMAP *bmp, DWORD **and, DWORD **xor) ++{ ++ int rop = GetROP2(physDev->hdc); ++ DWORD *color_ptr, *and_ptr, *xor_ptr; ++ DWORD size = bmp->height * abs(bmp->stride); ++ ++ *and = HeapAlloc(GetProcessHeap(), 0, size); ++ *xor = HeapAlloc(GetProcessHeap(), 0, size); ++ ++ color_ptr = bmp->bits; ++ and_ptr = *and; ++ xor_ptr = *xor; ++ ++ while(size) ++ { ++ _DIBDRV_CalcAndXorMasks(rop, *color_ptr++, and_ptr++, xor_ptr++); ++ size -= 4; ++ } ++} ++ ++static void PatternBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) ++{ ++ DWORD *and, *xor, brushY = y % physDev->brushBitmap.height; ++ ++ if(!physDev->brushAnds) ++ GenerateMasks(physDev, &physDev->brushBitmap, &physDev->brushAnds, &physDev->brushXors); ++ ++ OrderEndPoints(&x1, &x2); ++ and = (DWORD *)((char *)physDev->brushAnds + brushY * physDev->brushBitmap.stride); ++ xor = (DWORD *)((char *)physDev->brushXors + brushY * physDev->brushBitmap.stride); ++ ++ physDev->physBitmap.funcs->PatternHLine(&physDev->physBitmap, x1, x2, y, and, xor, physDev->brushBitmap.width, x1 % physDev->brushBitmap.width); ++} ++ + /*********************************************************************** + * DIBDRV_SelectPen + */ + HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) + { + HPEN res; ++ LOGPEN logpen; + +- TRACE("physDev:%p, hpen:%p\n", physDev, hpen); ++ MAYBE(TRACE("physDev:%p, hpen:%p\n", physDev, hpen)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSelectPen(physDev->X11PhysDev, hpen); ++ GetObjectW(hpen, sizeof(logpen), &logpen); ++ ++ physDev->penColorref = logpen.lopnColor; ++ ++ if(physDev->physBitmap.bitCount == 1) ++ FixupFgColors1(physDev); ++ else ++ physDev->penColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, logpen.lopnColor); ++ ++ _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), physDev->penColor, &physDev->penAnd, &physDev->penXor); ++ ++ switch(logpen.lopnStyle) ++ { ++ default: ++ ONCE(FIXME("Unhandled pen style %d\n", logpen.lopnStyle)); ++ /* fall through */ ++ case PS_SOLID: ++ physDev->penHLine = SolidPenHLine; ++ physDev->penVLine = SolidPenVline; ++ physDev->penLine = SolidPenLine; ++ physDev->penPattern = NULL; ++ break; ++ ++ case PS_DASH: ++ case PS_DOT: ++ case PS_DASHDOT: ++ case PS_DASHDOTDOT: ++ physDev->penHLine = DashedPenHLine; ++ physDev->penVLine = DashedPenVLine; ++ physDev->penLine = DashedPenLine; ++ physDev->penPattern = &dashPatterns[logpen.lopnStyle - PS_DASH]; ++ _DIBDRV_ResetDashOrigin(physDev); ++ break; ++ } ++ res = hpen; + } + else + { +@@ -56,13 +353,13 @@ COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + { + COLORREF res; + +- TRACE("physDev:%p, crColor:%x\n", physDev, crColor); ++ MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev, crColor)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetDCPenColor(physDev->X11PhysDev, crColor); ++ ONCE(FIXME("STUB\n")); ++ res = crColor; + } + else + { +@@ -77,19 +374,151 @@ COLORREF DIBDRV_SetDCPenColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + */ + HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + { +- HBRUSH res; ++ HBRUSH res = hbrush; ++ LOGBRUSH logbrush; ++ + +- TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush); ++ MAYBE(TRACE("physDev:%p, hbrush:%p\n", physDev, hbrush)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush); ++ GetObjectW(hbrush, sizeof(logbrush), &logbrush); ++ ++ /* frees any currently selected DIB brush and cache */ ++ _DIBDRVBITMAP_Free(&physDev->brushBitmap); ++ _DIBDRVBITMAP_Free(&physDev->brushBmpCache); ++ if(physDev->brushAnds) ++ { ++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds); ++ HeapFree(GetProcessHeap(), 0, physDev->brushXors); ++ } ++ physDev->brushAnds = NULL; ++ physDev->brushXors = NULL; ++ ++ switch (logbrush.lbStyle) ++ { ++ default: ++ FIXME("Unhandled brush style %d\n", logbrush.lbStyle); ++ physDev->brushColorref = 0; ++ goto solid; ++ ++ case BS_SOLID: ++ physDev->brushColorref = logbrush.lbColor; ++ solid: ++ MAYBE(TRACE("SOLID Pattern -- color is %x\n", physDev->brushColorref)); ++ physDev->brushStyle = BS_SOLID; ++ physDev->brushHLine = SolidBrushHLine; ++ ++ if(physDev->physBitmap.bitCount == 1) ++ FixupFgColors1(physDev); ++ else ++ physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, logbrush.lbColor); ++ ++ _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->brushColor, ++ &physDev->brushAnd, &physDev->brushXor); ++ ++ /* set the physDev brush style */ ++ physDev->brushStyle = BS_SOLID; ++ physDev->isBrushBitmap = FALSE; ++ ++ break; ++ ++ case BS_DIBPATTERN8X8: ++ case BS_DIBPATTERN: ++ { ++ DIBDRVBITMAP src; ++ BITMAPINFO *bmi; ++ ++ FIXME("DIB Pattern\n"); ++ ++ /* if no DIB selected in, fallback to null brush */ ++ if(!physDev->physBitmap.bits) ++ { ++ physDev->brushColorref = 0; ++ goto solid; ++ } ++ ++ /* gets brush DIB's pointer */ ++ bmi = GlobalLock16(logbrush.lbHatch); ++ ++ /* initializes a temporary DIB with brush's one */ ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&src, bmi)) ++ { ++ ERR("Failed to initialize brush DIB\n"); ++ res = 0; ++ goto err; ++ } ++ ++ /* converts brush bitmap to match currently selected one's format */ ++ if(!_DIBDRVBITMAP_Convert(&physDev->brushBitmap, &src, &physDev->physBitmap)) ++ { ++ ERR("Failed to convert brush DIB\n"); ++ _DIBDRVBITMAP_Free(&src); ++ res = 0; ++ goto err; ++ } ++ ++ /* frees temporary DIB's data */ ++ _DIBDRVBITMAP_Free(&src); ++ ++ /* use DIB pattern for brush lines */ ++ physDev->brushHLine = PatternBrushHLine; ++ ++ err: ++ /* frees brush's DIB pointer */ ++ GlobalUnlock16(logbrush.lbHatch); ++ ++ break; ++ } ++ case BS_DIBPATTERNPT: ++ FIXME("BS_DIBPATTERNPT not supported\n"); ++ physDev->brushColorref = 0; ++ goto solid; ++ ++ case BS_HATCHED: ++ FIXME("BS_HATCHED not supported\n"); ++ physDev->brushColorref = 0; ++ goto solid; ++ ++ case BS_NULL: ++ { ++ MAYBE(TRACE("NULL Pattern\n")); ++ physDev->brushColorref = 0; ++ goto solid; ++ } ++ ++ case BS_PATTERN: ++ case BS_PATTERN8X8: ++ FIXME("BS_PATTERN not supported\n"); ++ physDev->brushColorref = 0; ++ goto solid; ++ } ++ ++ MAYBE(TRACE("END\n")); ++ return hbrush; + } + else + { + /* DDB selected in, use X11 driver */ ++ ++ /* we must check if a DIB pattern is requested */ ++ GetObjectW(hbrush, sizeof(logbrush), &logbrush); ++ switch (logbrush.lbStyle) ++ { ++ case BS_DIBPATTERN8X8: ++ case BS_DIBPATTERN: ++ case BS_DIBPATTERNPT: ++ FIXME("A DIB pattern was requested for a DDB bitmap\n"); ++ break; ++ ++ case BS_SOLID: ++ case BS_HATCHED: ++ case BS_NULL: ++ case BS_PATTERN: ++ case BS_PATTERN8X8: ++ default: ++ break; ++ } + res = _DIBDRV_GetDisplayDriver()->pSelectBrush(physDev->X11PhysDev, hbrush); + } + return res; +@@ -102,13 +531,13 @@ COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + { + COLORREF res; + +- TRACE("physDev:%p, crColor:%x\n", physDev, crColor); ++ MAYBE(TRACE("physDev:%p, crColor:%x\n", physDev, crColor)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetDCBrushColor(physDev->X11PhysDev, crColor); ++ ONCE(FIXME("STUB\n")); ++ res = crColor; + } + else + { +@@ -121,14 +550,29 @@ COLORREF DIBDRV_SetDCBrushColor( DIBDRVPHYSDEV *physDev, COLORREF crColor ) + /*********************************************************************** + * SetROP2 + */ +-INT DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, INT rop ) ++int DIBDRV_SetROP2( DIBDRVPHYSDEV *physDev, int rop ) + { +- INT prevRop; ++ int prevRop; + +- TRACE("physDev:%p, rop:%x\n", physDev, rop); ++ MAYBE(TRACE("physDev:%p, rop:%x\n", physDev, rop)); + + prevRop = physDev->rop2; + physDev->rop2 = rop; ++ ++ if(prevRop != rop) ++ { ++ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor); ++ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor); ++ _DIBDRV_CalcAndXorMasks(rop, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor); ++ if(physDev->brushAnds) ++ { ++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds); ++ HeapFree(GetProcessHeap(), 0, physDev->brushXors); ++ } ++ physDev->brushAnds = NULL; ++ physDev->brushXors = NULL; ++ } ++ + return prevRop; + /* note : X11 Driver don't have SetROP2() function exported */ + } +@@ -140,13 +584,17 @@ COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { + COLORREF res; + +- TRACE("physDev:%p, color:%x\n", physDev, color); ++ MAYBE(TRACE("physDev:%p, color:%x\n", physDev, color)); + + if(physDev->hasDIB) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetBkColor(physDev->X11PhysDev, color); ++ physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color); ++ ++ if(physDev->physBitmap.bitCount == 1) ++ FixupFgColors1(physDev); ++ _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor); ++ ++ res = TRUE; + } + else + { +diff --git a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c +new file mode 100644 +index 0000000..cbad239 +--- /dev/null ++++ b/dlls/winedib.drv/primitives.c +@@ -0,0 +1,274 @@ ++/* ++ * DIB Engine Primitives function pointers ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* ------------------------------------------------------------*/ ++/* COLOR FUNCTIONS */ ++DWORD _DIBDRV_ColorToPixel32_RGB (const DIBDRVBITMAP *dib, COLORREF color); ++DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color); ++DWORD _DIBDRV_ColorToPixel24 (const DIBDRVBITMAP *dib, COLORREF color); ++DWORD _DIBDRV_ColorToPixel16_RGB (const DIBDRVBITMAP *dib, COLORREF color); ++DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color); ++DWORD _DIBDRV_ColorToPixelColortable (const DIBDRVBITMAP *dib, COLORREF color); ++ ++/* ------------------------------------------------------------*/ ++/* PIXEL POINTER READING */ ++void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y); ++void *_DIBDRV_GetPixelPointer24(const DIBDRVBITMAP *dib, int x, int y); ++void *_DIBDRV_GetPixelPointer16(const DIBDRVBITMAP *dib, int x, int y); ++void *_DIBDRV_GetPixelPointer8 (const DIBDRVBITMAP *dib, int x, int y); ++void *_DIBDRV_GetPixelPointer4 (const DIBDRVBITMAP *dib, int x, int y); ++void *_DIBDRV_GetPixelPointer1 (const DIBDRVBITMAP *dib, int x, int y); ++ ++/* ------------------------------------------------------------*/ ++/* PIXEL WRITING */ ++void _DIBDRV_SetPixel32(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor); ++void _DIBDRV_SetPixel24(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor); ++void _DIBDRV_SetPixel16(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor); ++void _DIBDRV_SetPixel8 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor); ++void _DIBDRV_SetPixel4 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor); ++void _DIBDRV_SetPixel1 (DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor); ++ ++/* ------------------------------------------------------------*/ ++/* PIXEL READING */ ++DWORD _DIBDRV_GetPixel32_RGB (const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel24 (const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel16_RGB (const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel8 (const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel4 (const DIBDRVBITMAP *dib, int x, int y); ++DWORD _DIBDRV_GetPixel1 (const DIBDRVBITMAP *dib, int x, int y); ++ ++/* ------------------------------------------------------------*/ ++/* HORIZONTAL SOLID LINES */ ++void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor); ++void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor); ++void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor); ++void _DIBDRV_SolidHLine8 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor); ++void _DIBDRV_SolidHLine4 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor); ++void _DIBDRV_SolidHLine1 (DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor); ++ ++/* ------------------------------------------------------------*/ ++/* HORIZONTAL PATTERN LINES */ ++void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset); ++void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset); ++void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset); ++void _DIBDRV_PatternHLine8 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset); ++void _DIBDRV_PatternHLine4 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset); ++void _DIBDRV_PatternHLine1 (DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset); ++ ++/* ------------------------------------------------------------*/ ++/* VERTICAL LINES */ ++void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor); ++void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor); ++void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor); ++void _DIBDRV_SolidVLine8 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor); ++void _DIBDRV_SolidVLine4 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor); ++void _DIBDRV_SolidVLine1 (DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor); ++ ++/* ----------------------------------------------------------------*/ ++/* CONVERT PRIMITIVES */ ++/* converts (part of) line of any DIB format from/to DIB32_RGB one */ ++BOOL _DIBDRV_GetLine32_RGB (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine24 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine16_RGB (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine8 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine4 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_GetLine1 (const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++ ++BOOL _DIBDRV_PutLine32_RGB (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine32_BITFIELDS(DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine24 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine16_RGB (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine16_BITFIELDS(DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine8 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine4 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++BOOL _DIBDRV_PutLine1 (DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf); ++ ++/* ------------------------------------------------------------*/ ++/* BLITTING PRIMITIVES */ ++BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop); ++BOOL _DIBDRV_BitBlt_32(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop); ++BOOL _DIBDRV_BitBlt_24(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop); ++BOOL _DIBDRV_BitBlt_16(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop); ++BOOL _DIBDRV_BitBlt_8(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop); ++ ++BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop); ++ ++/* ------------------------------------------------------------*/ ++/* FREETYPE FONT BITMAP BLITTING */ ++void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_32_RGB (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_24 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_16_RGB (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_8 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_4 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_1 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB = ++{ ++ _DIBDRV_ColorToPixel32_RGB, ++ _DIBDRV_GetPixelPointer32, ++ _DIBDRV_SetPixel32, ++ _DIBDRV_GetPixel32_RGB, ++ _DIBDRV_SolidHLine32, ++ _DIBDRV_PatternHLine32, ++ _DIBDRV_SolidVLine32, ++ _DIBDRV_GetLine32_RGB, ++ _DIBDRV_PutLine32_RGB, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_32_RGB ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS = ++{ ++ _DIBDRV_ColorToPixel32_BITFIELDS, ++ _DIBDRV_GetPixelPointer32, ++ _DIBDRV_SetPixel32, ++ _DIBDRV_GetPixel32_BITFIELDS, ++ _DIBDRV_SolidHLine32, ++ _DIBDRV_PatternHLine32, ++ _DIBDRV_SolidVLine32, ++ _DIBDRV_GetLine32_BITFIELDS, ++ _DIBDRV_PutLine32_BITFIELDS, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_32_BITFIELDS ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24 = ++{ ++ _DIBDRV_ColorToPixel24, ++ _DIBDRV_GetPixelPointer24, ++ _DIBDRV_SetPixel24, ++ _DIBDRV_GetPixel24, ++ _DIBDRV_SolidHLine24, ++ _DIBDRV_PatternHLine24, ++ _DIBDRV_SolidVLine24, ++ _DIBDRV_GetLine24, ++ _DIBDRV_PutLine24, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_24 ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB = ++{ ++ _DIBDRV_ColorToPixel16_RGB, ++ _DIBDRV_GetPixelPointer16, ++ _DIBDRV_SetPixel16, ++ _DIBDRV_GetPixel16_RGB, ++ _DIBDRV_SolidHLine16, ++ _DIBDRV_PatternHLine16, ++ _DIBDRV_SolidVLine16, ++ _DIBDRV_GetLine16_RGB, ++ _DIBDRV_PutLine16_RGB, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_16_RGB ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS = ++{ ++ _DIBDRV_ColorToPixel16_BITFIELDS, ++ _DIBDRV_GetPixelPointer16, ++ _DIBDRV_SetPixel16, ++ _DIBDRV_GetPixel16_BITFIELDS, ++ _DIBDRV_SolidHLine16, ++ _DIBDRV_PatternHLine16, ++ _DIBDRV_SolidVLine16, ++ _DIBDRV_GetLine16_BITFIELDS, ++ _DIBDRV_PutLine16_BITFIELDS, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_16_BITFIELDS ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8 = ++{ ++ _DIBDRV_ColorToPixelColortable, ++ _DIBDRV_GetPixelPointer8, ++ _DIBDRV_SetPixel8, ++ _DIBDRV_GetPixel8, ++ _DIBDRV_SolidHLine8, ++ _DIBDRV_PatternHLine8, ++ _DIBDRV_SolidVLine8, ++ _DIBDRV_GetLine8, ++ _DIBDRV_PutLine8, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_8 ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4 = ++{ ++ _DIBDRV_ColorToPixelColortable, ++ _DIBDRV_GetPixelPointer4, ++ _DIBDRV_SetPixel4, ++ _DIBDRV_GetPixel4, ++ _DIBDRV_SolidHLine4, ++ _DIBDRV_PatternHLine4, ++ _DIBDRV_SolidVLine4, ++ _DIBDRV_GetLine4, ++ _DIBDRV_PutLine4, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_4 ++}; ++ ++DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1 = ++{ ++ _DIBDRV_ColorToPixelColortable, ++ _DIBDRV_GetPixelPointer1, ++ _DIBDRV_SetPixel1, ++ _DIBDRV_GetPixel1, ++ _DIBDRV_SolidHLine1, ++ _DIBDRV_PatternHLine1, ++ _DIBDRV_SolidVLine1, ++ _DIBDRV_GetLine1, ++ _DIBDRV_PutLine1, ++ _DIBDRV_BitBlt_generic, ++ _DIBDRV_StretchBlt_generic, ++ _DIBDRV_freetype_blit_1 ++}; +diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c +new file mode 100644 +index 0000000..da48352 +--- /dev/null ++++ b/dlls/winedib.drv/primitives_bitblt.c +@@ -0,0 +1,1075 @@ ++/* ++ * DIB Engine BitBlt Primitives ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* shrinks a line -- srcWidth >= dstWidth */ ++static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth) ++{ ++ int srcPos, dstPos; ++ int delta; ++ ++ srcPos = 0; ++ dstPos = 0; ++ delta = 0; ++ while(dstPos < dstWidth) ++ { ++ *dst++ = *src; ++ while(delta < srcWidth) ++ { ++ srcPos++; ++ src++; ++ delta += dstWidth; ++ } ++ delta -= srcWidth; ++ dstPos++; ++ } ++} ++ ++/* expands a line -- srcWidth <= dstWidth */ ++static void ExpandLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth) ++{ ++ int srcPos; ++ int delta; ++ ++ srcPos = 0; ++ delta = 0; ++ while(srcPos < srcWidth) ++ { ++ while(delta < dstWidth) ++ { ++ *dst++ = *src; ++ delta += srcWidth; ++ } ++ delta -= dstWidth; ++ src++; ++ srcPos++; ++ } ++} ++ ++/* stretch a line */ ++static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth) ++{ ++ if(srcWidth > dstWidth) ++ ShrinkLine(dst, dstWidth, src, srcWidth); ++ else if(srcWidth < dstWidth) ++ ExpandLine(dst, dstWidth, src, srcWidth); ++ else ++ memcpy(dst, src, 4 * srcWidth); ++} ++ ++/* ------------------------------------------------------------*/ ++/* BLITTING PRIMITIVES */ ++BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop) ++{ ++ int ys, yd; ++ int i; ++ DWORD *dwBuf; ++ DIBDRVBITMAP *dstBmp, *patBmp; ++ const DIBDRVBITMAP *srcBmp; ++ DWORD *wDstPnt, *wSrcPnt, *wPatPnt; ++ BOOL usePat, useSrc, useDst; ++ DWORD patColor; ++ BOOL res = FALSE; ++ ++ /* 32 bit RGB source and destination buffer, if needed */ ++ DWORD *sBuf = 0, *dBuf = 0, *pBuf = 0; ++ ++ /* get elements usage */ ++ usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000)); ++ useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000)); ++ useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000)); ++ ++ /* gets source, dest and pattern bitmaps, if available */ ++ if(usePat && physDevDst->isBrushBitmap) ++ patBmp = &physDevDst->brushBmpCache; ++ else ++ patBmp = NULL; ++ ++ if(useSrc) ++ srcBmp = &physDevSrc->physBitmap; ++ else ++ srcBmp = NULL; ++ dstBmp = &physDevDst->physBitmap; ++ ++ /* gets pattern color, in case it's needed */ ++ if(usePat) ++ patColor = physDevDst->brushColor; ++ else ++ patColor = 0; ++ ++ /* allocate 32 bit RGB destination buffer */ ++ if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ ++ MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, width:%d, height:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, rop:%8x\n", ++ dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, width, height, ++ srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, rop)); ++ ++ /* some simple ROPs optimizations */ ++ switch(rop) ++ { ++ case BLACKNESS: ++ MAYBE(TRACE("BLACKNESS\n")); ++ memset(dBuf, 0x00, width * 4); ++ for(yd = yDst; yd < yDst+height; yd++) ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ break; ++ ++ case WHITENESS: ++ MAYBE(TRACE("WHITENESS\n")); ++ for(dwBuf = dBuf, i = width; i; i--) ++ *dwBuf++ = 0x00ffffff; ++ for(yd = yDst; yd < yDst+height; yd++) ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ break; ++ ++ case SRCCOPY: ++ MAYBE(TRACE("SRCCOPY\n")); ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf); ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ break; ++ ++ /* fallback for generic ROP operation */ ++ default: ++ rop >>= 16; ++ if(useSrc && useDst && usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("BitBlt use: src+dst+pat - pattern brush\n")); ++ if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf); ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf); ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBuf; ++ wPatPnt = pBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(useSrc && useDst) ++ { ++ if(usePat) ++ MAYBE(TRACE("BitBlt use: src+dst+pat - solid brush\n")); ++ else ++ MAYBE(TRACE("BitBlt use: src+dst\n")); ++ if(!(sBuf = HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, sBuf); ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, width, dBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(useSrc && usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("BitBlt use: src+pat -- pattern brush\n")); ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf); ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf); ++ wDstPnt = sBuf; ++ wSrcPnt = sBuf; ++ wPatPnt = pBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(useSrc) ++ { ++ if(usePat) ++ MAYBE(TRACE("BitBlt use: src+pat - solid brush\n")); ++ else ++ MAYBE(TRACE("BitBlt use: src\n")); ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf); ++ wDstPnt = sBuf; ++ wSrcPnt = sBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(useDst && usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("BitBlt use: dst+pat -- pattern brush\n")); ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf); ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf); ++ wDstPnt = sBuf; ++ wPatPnt = pBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(useDst) ++ { ++ if(usePat) ++ MAYBE(TRACE("BitBlt use: dst+pat - solid brush\n")); ++ else ++ MAYBE(TRACE("BitBlt use: dst\n")); ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf); ++ wDstPnt = sBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("BitBlt use: pat -- pattern brush\n")); ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, width * 4))) ++ goto error; ++ for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) ++ { ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf); ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else if(usePat) ++ { ++ MAYBE(TRACE("BitBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor)); ++ MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp))); ++ MAYBE(TRACE("xDst = %d, yDst = %d, width = %d, height = %d\n", xDst, yDst, width, height)); ++ for(yd = yDst; yd < yDst+height; yd++) ++ { ++ wDstPnt = dBuf; ++ for(i = width; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, width, dBuf); ++ } ++ } ++ else ++ ERR("What happened ?????? \n"); ++ break; ++ } /* switch */ ++ res = TRUE; ++error: ++ if(sBuf) HeapFree( GetProcessHeap(), 0, sBuf ); ++ if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf ); ++ if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf ); ++ return res; ++} ++ ++/* ------------------------------------------------------------*/ ++/* STRETCHING PRIMITIVES */ ++BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop) ++{ ++ int ys, yd; ++ int i, delta; ++ DWORD *dwBuf; ++ DIBDRVBITMAP *dstBmp, *patBmp; ++ const DIBDRVBITMAP *srcBmp; ++ DWORD *wDstPnt, *wSrcPnt, *wPatPnt; ++ BOOL usePat, useSrc, useDst; ++ DWORD patColor; ++ BOOL res = FALSE; ++ ++ /* 32 bit RGB source and destination buffer, if needed */ ++ DWORD *sBufOrig = 0, *sBufStr = 0, *dBuf = 0, *pBuf = 0; ++ ++ /* get elements usage */ ++ usePat = (((rop >> 4) & 0x0f0000) != (rop & 0x0f0000)); ++ useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000)); ++ useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000)); ++ ++ /* gets source, dest and pattern bitmaps, if available */ ++ if(usePat && physDevDst->isBrushBitmap) ++ patBmp = &physDevDst->brushBmpCache; ++ else ++ patBmp = NULL; ++ ++ if(useSrc) ++ srcBmp = &physDevSrc->physBitmap; ++ else ++ srcBmp = NULL; ++ dstBmp = &physDevDst->physBitmap; ++ ++ /* gets pattern color, in case it's needed */ ++ if(usePat) ++ patColor = physDevDst->brushColor; ++ else ++ patColor = 0; ++ ++ /* allocate 32 bit RGB destination buffer */ ++ if(!(dBuf = (DWORD *)HeapAlloc( GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ ++ MAYBE(TRACE("dstBmp:%p(%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, srcBmp:%p(%s), xSrc:%d, ySrc:%d, , widthSrc:%d, heightSrc:%drop:%8x\n", ++ dstBmp, _DIBDRVBITMAP_GetFormatName(dstBmp), xDst, yDst, widthDst, heightDst, ++ srcBmp, _DIBDRVBITMAP_GetFormatName(srcBmp), xSrc, ySrc, widthSrc, heightSrc, rop)); ++ ++ /* some simple ROPs optimizations */ ++ switch(rop) ++ { ++ case BLACKNESS: ++ MAYBE(TRACE("BLACKNESS\n")); ++ memset(dBuf, 0x00, widthDst * 4); ++ for(yd = yDst; yd < yDst+heightDst; yd++) ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ break; ++ ++ case WHITENESS: ++ MAYBE(TRACE("WHITENESS\n")); ++ for(dwBuf = dBuf, i = widthDst; i; i--) ++ *dwBuf++ = 0x00ffffff; ++ for(yd = yDst; yd < yDst+heightDst; yd++) ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ break; ++ ++ case SRCCOPY: ++ MAYBE(TRACE("SRCCOPY\n")); ++ sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4); ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(dBuf, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(dBuf, widthDst, sBufOrig, widthSrc); ++ while(delta < heightDst) ++ { ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig); ++ StretchLine(dBuf, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ break; ++ ++ /* fallback for generic ROP operation */ ++ default: ++ rop >>= 16; ++ if(useSrc && useDst && usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("StretchBlt use: src+dst+pat - pattern brush\n")); ++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4))) ++ goto error; ++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf); ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(useSrc && useDst) ++ { ++ if(usePat) ++ MAYBE(TRACE("StretchBlt use: src+dst+pat - solid brush\n")); ++ else ++ MAYBE(TRACE("StretchBlt use: src+dst\n")); ++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4))) ++ goto error; ++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(useSrc && usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("StretchBlt use: src+pat -- pattern brush\n")); ++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4))) ++ goto error; ++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(useSrc) ++ { ++ if(usePat) ++ MAYBE(TRACE("StretchBlt use: src+pat - solid brush\n")); ++ else ++ MAYBE(TRACE("StretchBlt use: src\n")); ++ if(!(sBufOrig = HeapAlloc(GetProcessHeap(), 0, widthSrc * 4))) ++ goto error; ++ if(!(sBufStr = HeapAlloc(GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys + ySrc, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBufOrig); ++ StretchLine(sBufStr, widthDst, sBufOrig, widthSrc); ++ wDstPnt = dBuf; ++ wSrcPnt = sBufStr; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(useDst && usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("StretchBlt use: dst+pat -- pattern brush\n")); ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf); ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(useDst) ++ { ++ if(usePat) ++ MAYBE(TRACE("StretchBlt use: dst+pat - solid brush\n")); ++ else ++ MAYBE(TRACE("StretchBlt use: dst\n")); ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ wDstPnt = dBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ dstBmp->funcs->GetLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, widthDst, dBuf); ++ wDstPnt = dBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(usePat && physDevDst->isBrushBitmap) ++ { ++ MAYBE(TRACE("StretchBlt use: pat -- pattern brush\n")); ++ if(!(pBuf = HeapAlloc( GetProcessHeap(), 0, widthDst * 4))) ++ goto error; ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ patBmp->funcs->GetLine(patBmp, (yd + yDst)%patBmp->height, 0, widthDst, pBuf); ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, widthDst, pBuf); ++ wDstPnt = dBuf; ++ wPatPnt = pBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(*wPatPnt++, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else if(usePat) ++ { ++ MAYBE(TRACE("StretchBlt use: pat -- solid brush -- rop is %02x, color is %08x\n", rop, patColor)); ++ MAYBE(TRACE("Dest BMP is a '%s'\n", _DIBDRVBITMAP_GetFormatName(dstBmp))); ++ MAYBE(TRACE("xDst = %d, yDst = %d, widthDst = %d, heightDst = %d\n", xDst, yDst, widthDst, heightDst)); ++ if(heightSrc > heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(yd < heightDst) ++ { ++ wDstPnt = dBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ ys = 0; ++ yd = 0; ++ delta = 0; ++ while(ys < heightSrc) ++ { ++ while(delta < heightDst) ++ { ++ wDstPnt = dBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd + yDst, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ } ++ } ++ else ++ { ++ for(ys = ySrc, yd = yDst; ys < ySrc+heightSrc; ys++, yd++) ++ { ++ wDstPnt = dBuf; ++ for(i = widthDst; i > 0 ; i--) ++ { ++ *wDstPnt = _DIBDRV_ROP3(patColor, 0, 0, rop); ++ wDstPnt++; ++ } ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ } ++ else ++ ERR("What happened ?????? \n"); ++ break; ++ } /* switch */ ++ res = TRUE; ++error: ++ if(sBufOrig) HeapFree( GetProcessHeap(), 0, sBufOrig ); ++ if(sBufStr) HeapFree( GetProcessHeap(), 0, sBufStr ); ++ if(dBuf) HeapFree( GetProcessHeap(), 0, dBuf ); ++ if(pBuf) HeapFree( GetProcessHeap(), 0, pBuf ); ++ return res; ++} +diff --git a/dlls/winedib.drv/primitives_color.c b/dlls/winedib.drv/primitives_color.c +new file mode 100644 +index 0000000..3ccc2e0 +--- /dev/null ++++ b/dlls/winedib.drv/primitives_color.c +@@ -0,0 +1,142 @@ ++/* ++ * DIB Engine color Primitives ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* ------------------------------------------------------------*/ ++/* BITFIELD HELPERS */ ++static inline DWORD PutField32(DWORD field, int shift, int len) ++{ ++ shift = shift - (8 - len); ++ if (len <= 8) ++ field &= (((1 << len) - 1) << (8 - len)); ++ if (shift < 0) ++ field >>= -shift; ++ else ++ field <<= shift; ++ return field; ++} ++ ++static inline WORD PutField16(WORD field, int shift, int len) ++{ ++ shift = shift - (8 - len); ++ if (len <= 8) ++ field &= (((1 << len) - 1) << (8 - len)); ++ if (shift < 0) ++ field >>= -shift; ++ else ++ field <<= shift; ++ return field; ++} ++ ++/* ------------------------------------------------------------*/ ++/* COLOR FUNCTIONS */ ++DWORD _DIBDRV_ColorToPixel32_RGB(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) ); ++} ++ ++DWORD _DIBDRV_ColorToPixel32_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ DWORD r,g,b; ++ ++ r = GetRValue(color); ++ g = GetGValue(color); ++ b = GetBValue(color); ++ ++ return PutField32(r, dib->redShift, dib->redLen) | ++ PutField32(g, dib->greenShift, dib->greenLen) | ++ PutField32(b, dib->blueShift, dib->blueLen); ++} ++ ++DWORD _DIBDRV_ColorToPixel24(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ return ( ((color >> 16) & 0xff) | (color & 0xff00) | ((color << 16) & 0xff0000) ); ++} ++ ++DWORD _DIBDRV_ColorToPixel16_RGB(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ return ( ((color >> 19) & 0x001f) | ((color >> 6) & 0x03e0) | ((color << 7) & 0x7c00) ); ++} ++ ++DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ DWORD r,g,b; ++ ++ r = GetRValue(color); ++ g = GetGValue(color); ++ b = GetBValue(color); ++ ++ return PutField16(r, dib->redShift, dib->redLen) | ++ PutField16(g, dib->greenShift, dib->greenLen) | ++ PutField16(b, dib->blueShift, dib->blueLen); ++} ++ ++DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ int i, best_index = 0; ++ DWORD r, g, b; ++ DWORD diff, best_diff = 0xffffffff; ++ ++ r = GetRValue(color); ++ g = GetGValue(color); ++ b = GetBValue(color); ++ ++ /* just in case it's being called without color table ++ properly initialized */ ++ if(!dib->colorTableGrabbed) ++ return 0; ++ ++ /* for monochrome bitmaps, color is background ++ if not matching foreground */ ++ if(dib->colorTableSize == 2) ++ { ++ RGBQUAD *fore = dib->colorTable + 1; ++ if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue) ++ return 1; ++ return 0; ++ } ++ ++ for(i = 0; i < dib->colorTableSize; i++) ++ { ++ RGBQUAD *cur = dib->colorTable + i; ++ diff = (r - cur->rgbRed) * (r - cur->rgbRed) ++ + (g - cur->rgbGreen) * (g - cur->rgbGreen) ++ + (b - cur->rgbBlue) * (b - cur->rgbBlue); ++ ++ if(diff == 0) ++ { ++ best_index = i; ++ break; ++ } ++ ++ if(diff < best_diff) ++ { ++ best_diff = diff; ++ best_index = i; ++ } ++ } ++ return best_index; ++} +diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c +new file mode 100644 +index 0000000..800e3fd +--- /dev/null ++++ b/dlls/winedib.drv/primitives_convert.c +@@ -0,0 +1,559 @@ ++/* ++ * DIB Engine conversions Primitives ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++static inline COLORREF SwapColors(DWORD c) ++{ ++ return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16); ++ ++} ++ ++/* ----------------------------------------------------------------*/ ++/* CONVERT PRIMITIVES */ ++/* converts (part of) line of any DIB format from/to DIB32_RGB one */ ++BOOL _DIBDRV_GetLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ DWORD *src; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ dwBuf -= startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx); ++ for(; width; width--) ++ *dwBuf++ = *src++; ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ BYTE *bBuf = (BYTE *)buf; ++ DWORD *src; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ bBuf -= 4 * startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx); ++ for(; width ; width--) ++ { ++ *bBuf++ = (*src & bmp->blueMask ) >> bmp->blueShift; ++ *bBuf++ = (*src & bmp->greenMask) >> bmp->greenShift; ++ *bBuf++ = (*src & bmp->redMask ) >> bmp->redShift; ++ *bBuf++ = 0x0; ++ src++; ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine24(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ BYTE *bBuf = (BYTE *)buf; ++ BYTE *src; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ bBuf -= 4 * startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = ((BYTE *)bmp->bits + line * bmp->stride + 3 * startx); ++ for(; width ; width--) ++ { ++ *bBuf++ = *src++; ++ *bBuf++ = *src++; ++ *bBuf++ = *src++; ++ *bBuf++ = 0x0; ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ WORD *src; ++ DWORD b; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ dwBuf -= startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx); ++ for(; width ; width--) ++ { ++ b = *src++; ++ /* 0RRR|RRGG|GGGB|BBBB */ ++ *dwBuf++ = ((b & 0x1f) << 3) | ((b & 0x3e0) << 6) | ((b & 0x7c00) << 9); ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ WORD *src; ++ DWORD b; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ dwBuf -= startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx); ++ for(; width ; width--) ++ { ++ b = *src++; ++ *dwBuf++ =((( b & bmp->blueMask) >> bmp->blueShift ) << ( 8 - bmp->blueLen )) | ++ (((b & bmp->greenMask) >> bmp->greenShift) << (16 - bmp->greenLen)) | ++ (((b & bmp->redMask ) >> bmp->redShift ) << (24 - bmp->redLen )); ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine8(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *src; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ dwBuf -= startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = ((BYTE *)bmp->bits + line * bmp->stride + startx); ++ for(; width ; width--) ++ *dwBuf++ = *((DWORD *)bmp->colorTable + *src++); ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *src; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ dwBuf -= startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++ if(!bmp->colorTable) ++ { ++ ERR("Called with uninitialized color table\n"); ++ return FALSE; ++ } ++#endif ++ ++ src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 1)); ++ /* if startx is odd, get first nibble */ ++ if(startx & 0x01) ++ { ++ *dwBuf++ = *((DWORD *)bmp->colorTable + (*src++ & 0x0f)); ++ width--; ++ } ++ ++ /* then gets all full image bytes */ ++ for( ; width > 1 ; width -= 2) ++ { ++ *dwBuf++ = *((DWORD *)bmp->colorTable + ((*src >> 4) & 0x0f)); ++ *dwBuf++ = *((DWORD *)bmp->colorTable + (*src++ & 0x0f)); ++ } ++ ++ /* last nibble, if any */ ++ if(width) ++ *dwBuf++ = *((DWORD *)bmp->colorTable + ((*src >> 4) & 0x0f)); ++ return TRUE; ++} ++ ++BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *src; ++ BYTE b; ++ char i; ++ DWORD pixOn = *((DWORD *)bmp->colorTable + 1); ++ DWORD pixOff = *(DWORD *)bmp->colorTable; ++ ++#ifdef DIBDRV_CHECK_RANGES ++ /* range check */ ++ if(line < 0 || line >= bmp->height) ++ return FALSE; ++ if(startx < 0) ++ { ++ width += startx; ++ dwBuf -= startx; ++ startx = 0; ++ } ++ if(startx + width > bmp->width) ++ width = bmp->width - startx; ++ if(width <= 0) ++ return FALSE; ++#endif ++ ++ src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3)); ++ /* get first partial byte, if any */ ++ startx = (8 - (startx & 0x03)) & 0x03; ++ width -= startx; ++ if(startx) ++ { ++ b = *src++ << (8 - startx); ++ while(startx--) ++ { ++ if(b & 0x80) ++ *dwBuf++ = pixOn; ++ else ++ *dwBuf++ = pixOff; ++ b <<= 1; ++ } ++ } ++ ++ /* then gets full next bytes */ ++ for( ; width > 7 ; width -= 8) ++ { ++ b = *src++; ++ for(i = 0 ; i < 8 ; i++) ++ { ++ if(b & 0x80) ++ *dwBuf++ = pixOn; ++ else ++ *dwBuf++ = pixOff; ++ b <<= 1; ++ } ++ } ++ ++ /* last partial byte, if any */ ++ if(width) ++ { ++ b = *src; ++ while(width--) ++ { ++ if(b & 0x80) ++ *dwBuf++ = pixOn; ++ else ++ *dwBuf++ = pixOff; ++ b <<= 1; ++ } ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx); ++ for(; width; width--) ++ *dst++ = *dwBuf++; ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx); ++ DWORD c; ++ for(; width; width--) ++ { ++ c = *dwBuf++; ++ *dst++ = ++ ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) | ++ ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) | ++ ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask); ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine24(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + 3 * startx); ++ DWORD c; ++ for(; width; width--) ++ { ++ c = *dwBuf++; ++ *dst++ = c & 0x000000ff; ++ *dst++ = (c & 0x0000ff00) >> 8; ++ *dst++ = (c & 0x00ff0000) >> 16; ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx); ++ DWORD c; ++ for(; width; width--) ++ { ++ c = *dwBuf++; ++ *dst++ = ++ ((c & 0x000000f8) >> 3) | ++ ((c & 0x0000f800) >> 6) | ++ ((c & 0x00f80000) >> 9); ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx); ++ DWORD c; ++ for(; width; width--) ++ { ++ c = *dwBuf++; ++ *dst++ = ++ ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) | ++ ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) | ++ ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask); ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine8(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + startx); ++ DWORD c; ++ DWORD last_color = 0xffffffff; ++ int last_index = -1; ++ ++ for(; width; width--) ++ { ++ c = *dwBuf++; ++ ++ /* slight optimization, as images often have many ++ consecutive pixels with same color */ ++ if(last_index == -1 || c != last_color) ++ { ++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c)); ++ last_color = c; ++ } ++ *dst++ = last_index; ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 1)); ++ DWORD c; ++ DWORD last_color = 0xffffffff; ++ int last_index = -1; ++ ++ /* if startx is odd, put first nibble */ ++ if(startx & 0x01) ++ { ++ c = *dwBuf++; ++ ++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c)); ++ last_color = c; ++ *dst = (*dst & 0xf0) | last_index; ++ dst++; ++ width--; ++ } ++ ++ /* then gets all full image bytes */ ++ for( ; width > 1 ; width -= 2) ++ { ++ c = *dwBuf++; ++ ++ /* slight optimization, as images often have many ++ consecutive pixels with same color */ ++ if(last_index == -1 || c != last_color) ++ { ++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c)); ++ last_color = c; ++ } ++ *dst = last_index << 4; ++ ++ c = *dwBuf++; ++ ++ /* slight optimization, as images often have many ++ consecutive pixels with same color */ ++ if(last_index == -1 || c != last_color) ++ { ++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c)); ++ last_color = c; ++ } ++ *dst++ |= last_index; ++ } ++ ++ /* last nibble, if any */ ++ if(width) ++ { ++ c = *dwBuf; ++ ++ /* slight optimization, as images often have many ++ consecutive pixels with same color */ ++ if(last_index == -1 || c != last_color) ++ last_index = bmp->funcs->ColorToPixel(bmp, SwapColors(c)); ++ *dst = (*dst & 0x0f) | (last_index << 4); ++ } ++ return TRUE; ++} ++ ++BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) ++{ ++ DWORD *dwBuf = (DWORD *)buf; ++ BYTE *dst = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3)); ++ BYTE b, mask; ++ char i; ++ DWORD c; ++ ++ /* get foreground color */ ++ DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff; ++ ++ /* put first partial byte, if any */ ++ startx &= 0x03; ++ mask = 0x80 >> startx; ++ startx = (8 - startx) & 0x03; ++ if(startx) ++ { ++ width -= startx; ++ b = *dst; ++ while(startx--) ++ { ++ c = *dwBuf++ & 0x00ffffff; ++ if(c == 0x00ffffff || c == fore) ++ b |= mask; ++ else ++ b &= !mask; ++ mask >>= 1; ++ } ++ *dst++ = b; ++ } ++ ++ /* then puts full next bytes */ ++ for( ; width > 7 ; width -= 8) ++ { ++ b = 0; ++ mask = 0x80; ++ for(i = 0 ; i < 8 ; i++) ++ { ++ c = *dwBuf++ & 0x00ffffff; ++ if(c == 0x00ffffff || c == fore) ++ b |= mask; ++ mask >>= 1; ++ } ++ *dst++ = b; ++ } ++ ++ /* last partial byte, if any */ ++ if(width) ++ { ++ b = *dst; ++ mask = 0x80; ++ while(width--) ++ { ++ c = *dwBuf++ & 0x00ffffff; ++ if(c == 0x00ffffff || c == fore) ++ b |= mask; ++ else ++ b &= !mask; ++ mask >>= 1; ++ } ++ *dst = b; ++ } ++ return TRUE; ++} +diff --git a/dlls/winedib.drv/primitives_font.c b/dlls/winedib.drv/primitives_font.c +new file mode 100644 +index 0000000..dd1d64b +--- /dev/null ++++ b/dlls/winedib.drv/primitives_font.c +@@ -0,0 +1,310 @@ ++/* ++ * DIB Engine Font Primitives ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* ------------------------------------------------------------*/ ++/* FREETYPE FONT BITMAP BLITTING */ ++void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ DWORD *ptr; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ ptr = (DWORD *)((BYTE *)dib->bits + (dibY * dib->stride) + x * 4); ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ *ptr = c; ++ } ++ buf++; ++ ptr++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} ++ ++void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++{ ++ /* FIXME : MUST BE OPTIMIZED !!! */ ++ ++ DIBDRVBITMAP *dib = &physDev->physBitmap; ++ int bmpX, bmpY; ++ BYTE *buf; ++ int dibX, dibY; ++ int DIBX, DIBY; ++ DWORD c; ++ ++ /* gets DIB limits */ ++ DIBX = dib->width; ++ DIBY = dib->height; ++ ++ /* loop for every pixel in bitmap */ ++ buf = bmp->buffer; ++ for(bmpY = 0, dibY = y; bmpY < bmp->rows; bmpY++, dibY++) ++ { ++ for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) ++ { ++ if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ { ++ c = physDev->textColorTable[*buf]; ++ dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ } ++ buf++; ++ } ++ } ++} +diff --git a/dlls/winedib.drv/primitives_line.c b/dlls/winedib.drv/primitives_line.c +new file mode 100644 +index 0000000..af41e2d +--- /dev/null ++++ b/dlls/winedib.drv/primitives_line.c +@@ -0,0 +1,434 @@ ++/* ++ * DIB Engine line Primitives ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* ------------------------------------------------------------*/ ++/* HORIZONTAL LINES */ ++void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor) ++{ ++ DWORD *ptr; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ for(i = start; i < end; i++) ++ _DIBDRV_rop32(ptr++, and, xor); ++} ++ ++void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ BYTE and_bytes[3], xor_bytes[3]; ++ ++ and_bytes[0] = and & 0xff; ++ and_bytes[1] = (and >> 8) & 0xff; ++ and_bytes[2] = (and >> 16) & 0xff; ++ xor_bytes[0] = xor & 0xff; ++ xor_bytes[1] = (xor >> 8) & 0xff; ++ xor_bytes[2] = (xor >> 16) & 0xff; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr++, and_bytes[0], xor_bytes[0]); ++ _DIBDRV_rop8(ptr++, and_bytes[1], xor_bytes[1]); ++ _DIBDRV_rop8(ptr++, and_bytes[2], xor_bytes[2]); ++ } ++} ++ ++void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor) ++{ ++ WORD *ptr; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ for(i = start; i < end; i++) ++ _DIBDRV_rop16(ptr++, and, xor); ++} ++ ++void _DIBDRV_SolidHLine8(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ for(i = start; i < end; i++) ++ _DIBDRV_rop8(ptr++, and, xor); ++} ++ ++void _DIBDRV_SolidHLine4(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ BYTE byte_and, byte_xor; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ byte_and = (and & 0xf) | ((and << 4) & 0xf0); ++ byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0); ++ ++ if(start & 1) /* upper nibble untouched */ ++ _DIBDRV_rop8(ptr++, byte_and | 0xf0, byte_xor & 0x0f); ++ ++ for(i = (start + 1) / 2; i < end / 2; i++) ++ _DIBDRV_rop8(ptr++, byte_and, byte_xor); ++ ++ if(end & 1) /* lower nibble untouched */ ++ _DIBDRV_rop8(ptr, byte_and | 0x0f, byte_xor & 0xf0); ++} ++ ++void _DIBDRV_SolidHLine1(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ BYTE byte_and = 0, byte_xor = 0, mask; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ if(and & 1) byte_and = 0xff; ++ if(xor & 1) byte_xor = 0xff; ++ ++ if((start & ~7) == (end & ~7)) /* special case run inside one byte */ ++ { ++ mask = ((1L << ((end & 7) - (start & 7))) - 1) << (8 - (end & 7)); ++ _DIBDRV_rop8(ptr, byte_and | ~mask, byte_xor & mask); ++ return; ++ } ++ ++ if(start & 7) ++ { ++ mask = (1 << (8 - (start & 7))) - 1; ++ _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask); ++ } ++ ++ for(i = (start + 7) / 8; i < end / 8; i++) ++ _DIBDRV_rop8(ptr++, byte_and, byte_xor); ++ ++ if(end & 7) ++ { ++ mask = ~((1 << (8 - (end & 7))) - 1); ++ _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask); ++ } ++} ++ ++void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset) ++{ ++ DWORD *ptr; ++ const DWORD *and_ptr = and, *xor_ptr = xor; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ and_ptr += offset; ++ xor_ptr += offset; ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop32(ptr++, *and_ptr++, *xor_ptr++); ++ if(++offset == count) ++ { ++ offset = 0; ++ and_ptr = and; ++ xor_ptr = xor; ++ } ++ } ++} ++ ++void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset) ++{ ++ BYTE *ptr; ++ const BYTE *and_ptr = and, *xor_ptr = xor; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ and_ptr += offset * 3; ++ xor_ptr += offset * 3; ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++); ++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++); ++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++); ++ if(++offset == count) ++ { ++ offset = 0; ++ and_ptr = and; ++ xor_ptr = xor; ++ } ++ } ++} ++ ++void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset) ++{ ++ WORD *ptr; ++ const WORD *and_ptr = and, *xor_ptr = xor; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ and_ptr += offset; ++ xor_ptr += offset; ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop16(ptr++, *and_ptr++, *xor_ptr++); ++ if(++offset == count) ++ { ++ offset = 0; ++ and_ptr = and; ++ xor_ptr = xor; ++ } ++ } ++} ++ ++void _DIBDRV_PatternHLine8(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset) ++{ ++ BYTE *ptr; ++ const BYTE *and_ptr = and, *xor_ptr = xor; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ and_ptr += offset; ++ xor_ptr += offset; ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++); ++ if(++offset == count) ++ { ++ offset = 0; ++ and_ptr = and; ++ xor_ptr = xor; ++ } ++ } ++} ++ ++void _DIBDRV_PatternHLine4(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset) ++{ ++ BYTE *ptr; ++ const BYTE *and_ptr = and, *xor_ptr = xor; ++ int i; ++ BYTE byte_and, byte_xor; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ and_ptr += offset / 2; ++ xor_ptr += offset / 2; ++ ++ for(i = start; i < end; i++) ++ { ++ if(offset & 1) ++ { ++ byte_and = *and_ptr++ & 0x0f; ++ byte_xor = *xor_ptr++ & 0x0f; ++ } ++ else ++ { ++ byte_and = (*and_ptr & 0xf0) >> 4; ++ byte_xor = (*xor_ptr & 0xf0) >> 4; ++ } ++ ++ if(i & 1) ++ byte_and |= 0xf0; ++ else ++ { ++ byte_and = (byte_and << 4) | 0x0f; ++ byte_xor <<= 4; ++ } ++ ++ _DIBDRV_rop8(ptr, byte_and, byte_xor); ++ ++ if(i & 1) ptr++; ++ ++ if(++offset == count) ++ { ++ offset = 0; ++ and_ptr = and; ++ xor_ptr = xor; ++ } ++ } ++} ++ ++void _DIBDRV_PatternHLine1(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset) ++{ ++ BYTE *ptr; ++ const BYTE *and_ptr = and, *xor_ptr = xor; ++ int i; ++ BYTE byte_and, byte_xor, dst_mask, brush_mask; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, start, row); ++ ++ and_ptr += offset / 8; ++ xor_ptr += offset / 8; ++ ++ for(i = start; i < end; i++) ++ { ++ dst_mask = 1 << (7 - (i & 7)); ++ brush_mask = 1 << (7 - (offset & 7)); ++ ++ byte_and = (*and_ptr & brush_mask) ? 0xff : 0; ++ byte_xor = (*xor_ptr & brush_mask) ? 0xff : 0; ++ ++ byte_and |= ~dst_mask; ++ byte_xor &= dst_mask; ++ ++ _DIBDRV_rop8(ptr, byte_and, byte_xor); ++ ++ if((i & 7) == 7) ptr++; ++ if(++offset == count) ++ { ++ offset = 0; ++ and_ptr = and; ++ xor_ptr = xor; ++ } ++ else if((offset & 7) == 7) ++ { ++ and_ptr++; ++ xor_ptr++; ++ } ++ } ++} ++ ++/* ------------------------------------------------------------*/ ++/* VERTICAL LINES */ ++void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, col, start); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop32((DWORD*)ptr, and, xor); ++ ptr += dib->stride; ++ } ++} ++ ++void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ BYTE and_bytes[3], xor_bytes[3]; ++ ++ and_bytes[0] = and & 0xff; ++ and_bytes[1] = (and >> 8) & 0xff; ++ and_bytes[2] = (and >> 16) & 0xff; ++ xor_bytes[0] = xor & 0xff; ++ xor_bytes[1] = (xor >> 8) & 0xff; ++ xor_bytes[2] = (xor >> 16) & 0xff; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, col, start); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr, and_bytes[0], xor_bytes[0]); ++ _DIBDRV_rop8(ptr + 1, and_bytes[1], xor_bytes[1]); ++ _DIBDRV_rop8(ptr + 2, and_bytes[2], xor_bytes[2]); ++ ptr += dib->stride; ++ } ++} ++ ++void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, col, start); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop16((WORD*)ptr, and, xor); ++ ptr += dib->stride; ++ } ++} ++ ++void _DIBDRV_SolidVLine8(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, col, start); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr, and, xor); ++ ptr += dib->stride; ++ } ++} ++ ++void _DIBDRV_SolidVLine4(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ BYTE byte_and, byte_xor; ++ ++ if(col & 1) /* upper nibble untouched */ ++ { ++ byte_and = (and & 0xf) | 0xf0; ++ byte_xor = (xor & 0xf); ++ } ++ else ++ { ++ byte_and = ((and << 4) & 0xf0) | 0x0f; ++ byte_xor = ((xor << 4) & 0xf0); ++ } ++ ++ ptr = dib->funcs->GetPixelPointer(dib, col, start); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr, byte_and, byte_xor); ++ ptr += dib->stride; ++ } ++} ++ ++void _DIBDRV_SolidVLine1(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ int i; ++ BYTE byte_and = 0, byte_xor = 0, mask; ++ ++ if(and & 1) byte_and = 0xff; ++ if(xor & 1) byte_xor = 0xff; ++ ++ mask = 1 << (7 - (col & 7)); ++ ++ byte_and |= ~mask; ++ byte_xor &= mask; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, col, start); ++ ++ for(i = start; i < end; i++) ++ { ++ _DIBDRV_rop8(ptr, byte_and, byte_xor); ++ ptr += dib->stride; ++ } ++} +diff --git a/dlls/winedib.drv/primitives_pixel.c b/dlls/winedib.drv/primitives_pixel.c +new file mode 100644 +index 0000000..ca68cf1 +--- /dev/null ++++ b/dlls/winedib.drv/primitives_pixel.c +@@ -0,0 +1,244 @@ ++/* ++ * DIB Engine pixel Primitives ++ * ++ * Copyright 2009 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++ ++/* ------------------------------------------------------------*/ ++/* BITFIELD HELPERS */ ++static DWORD GetField32 (DWORD pixel, int shift, int len) ++{ ++ pixel = pixel & (((1 << (len)) - 1) << shift); ++ pixel = pixel << (32 - (shift + len)) >> 24; ++ return pixel; ++} ++ ++static WORD GetField16 (WORD pixel, int shift, int len) ++{ ++ FIXME("TODO\n"); ++ return 0; ++} ++ ++ ++ ++/* ------------------------------------------------------------*/ ++/* PIXEL POINTER READING */ ++void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->bits; ++ ++ ptr += (y * dib->stride); ++ ++ ptr += x * 4; ++ return ptr; ++} ++ ++void *_DIBDRV_GetPixelPointer24(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->bits; ++ ++ ptr += (y * dib->stride); ++ ++ ptr += x * 3; ++ return ptr; ++} ++ ++void *_DIBDRV_GetPixelPointer16(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->bits; ++ ++ ptr += (y * dib->stride); ++ ++ ptr += x * 2; ++ return ptr; ++} ++ ++void *_DIBDRV_GetPixelPointer8(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->bits; ++ ++ ptr += (y * dib->stride); ++ ++ ptr += x; ++ return ptr; ++} ++ ++void *_DIBDRV_GetPixelPointer4(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->bits; ++ ++ ptr += (y * dib->stride); ++ ++ ptr += x / 2; ++ return ptr; ++} ++ ++void *_DIBDRV_GetPixelPointer1(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->bits; ++ ++ ptr += (y * dib->stride); ++ ++ ptr += x / 8; ++ return ptr; ++} ++ ++/* ------------------------------------------------------------*/ ++/* PIXEL WRITING */ ++void _DIBDRV_SetPixel32(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) ++{ ++ DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ _DIBDRV_rop32(ptr, and, xor); ++} ++ ++void _DIBDRV_SetPixel24(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ _DIBDRV_rop8(ptr, and & 0xff, xor & 0xff); ++ _DIBDRV_rop8(ptr + 1, (and >> 8) & 0xff, (xor >> 8) & 0xff); ++ _DIBDRV_rop8(ptr + 2, (and >> 16) & 0xff, (xor >> 16) & 0xff); ++} ++ ++void _DIBDRV_SetPixel16(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) ++{ ++ WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ _DIBDRV_rop16(ptr, and, xor); ++} ++ ++void _DIBDRV_SetPixel8(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ _DIBDRV_rop8(ptr, and, xor); ++} ++ ++void _DIBDRV_SetPixel4(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ BYTE byte_and, byte_xor; ++ ++ if(x & 1) /* upper nibble untouched */ ++ { ++ byte_and = (and & 0xf) | 0xf0; ++ byte_xor = (xor & 0xf); ++ } ++ else ++ { ++ byte_and = ((and << 4) & 0xf0) | 0x0f; ++ byte_xor = ((xor << 4) & 0xf0); ++ } ++ ++ _DIBDRV_rop8(ptr, byte_and, byte_xor); ++} ++ ++void _DIBDRV_SetPixel1(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) ++{ ++ BYTE *ptr; ++ BYTE byte_and = 0, byte_xor = 0, mask; ++ ++ if(and & 1) byte_and = 0xff; ++ if(xor & 1) byte_xor = 0xff; ++ ++ mask = 1 << (7 - (x & 7)); ++ ++ byte_and |= ~mask; ++ byte_xor &= mask; ++ ++ ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ ++ _DIBDRV_rop8(ptr, byte_and, byte_xor); ++} ++ ++/* ------------------------------------------------------------*/ ++/* PIXEL READING */ ++DWORD _DIBDRV_GetPixel32_RGB(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ return *ptr; ++} ++ ++DWORD _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ ++ return GetField32(*ptr, dib->redShift, dib->redLen) << 16 | ++ GetField32(*ptr, dib->greenShift, dib->greenLen) << 8 | ++ GetField32(*ptr, dib->blueShift, dib->blueLen); ++} ++ ++DWORD _DIBDRV_GetPixel24(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ return (ptr[0] << 16) | (ptr[1] << 8) | ptr[2]; ++} ++ ++DWORD _DIBDRV_GetPixel16_RGB(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ return ((*ptr & 0x7c00) << 9) | ((*ptr & 0x03e0) << 6) | ((*ptr & 0x001f) << 3); ++} ++ ++DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ ++ return GetField16(*ptr, dib->redShift, dib->redLen) << 16 | ++ GetField16(*ptr, dib->greenShift, dib->greenLen) << 8 | ++ GetField16(*ptr, dib->blueShift, dib->blueLen); ++} ++ ++DWORD _DIBDRV_GetPixel8(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ RGBQUAD *color = dib->colorTable + *ptr; ++ return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue; ++} ++ ++DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y), pix; ++ RGBQUAD *color; ++ ++ if(x & 1) ++ pix = *ptr & 0x0f; ++ else ++ pix = *ptr >> 4; ++ ++ color = dib->colorTable + pix; ++ return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue; ++} ++ ++DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y) ++{ ++ BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y), pix; ++ RGBQUAD *color; ++ ++ pix = *ptr; ++ ++ pix >>= (7 - (x & 7)); ++ pix &= 1; ++ ++ color = dib->colorTable + pix; ++ return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue; ++} +diff --git a/dlls/winedib.drv/primitives_rop2.c b/dlls/winedib.drv/primitives_rop2.c +new file mode 100644 +index 0000000..b23e919 +--- /dev/null ++++ b/dlls/winedib.drv/primitives_rop2.c +@@ -0,0 +1,112 @@ ++/* ++ * DIB Engine ROP2 Primitives ++ * ++ * Copyright 2008 Huw Davies ++ * Copyright 2008 Massimo Del Fedele ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* ------------------------------------------------------------*/ ++/* BASIC ROP HELPER */ ++/* ++ * ++ * Decompose the 16 ROP2s into an expression of the form ++ * ++ * D = (D & A) ^ X ++ * ++ * Where A and X depend only on P (and so can be precomputed). ++ * ++ * A X ++ * ++ * R2_BLACK 0 0 0 ++ * R2_NOTMERGEPEN ~(D | P) ~P ~P ++ * R2_MASKNOTPEN ~P & D ~P 0 ++ * R2_NOTCOPYPEN ~P 0 ~P ++ * R2_MASKPENNOT P & ~D P P ++ * R2_NOT ~D 1 1 ++ * R2_XORPEN P ^ D 1 P ++ * R2_NOTMASKPEN ~(P & D) P 1 ++ * R2_MASKPEN P & D P 0 ++ * R2_NOTXORPEN ~(P ^ D) 1 ~P ++ * R2_NOP D 1 0 ++ * R2_MERGENOTPEN ~P | D P ~P ++ * R2_COPYPEN P 0 P ++ * R2_MERGEPENNOT P | ~D ~P 1 ++ * R2_MERGEPEN P | D ~P P ++ * R2_WHITE 1 0 1 ++ * ++ */ ++ ++/* A = (P & A1) | (~P & A2) */ ++#define ZERO {0, 0} ++#define ONE {0xffffffff, 0xffffffff} ++#define P {0xffffffff, 0} ++#define NOT_P {0, 0xffffffff} ++ ++static const DWORD rop2_and_array[16][2] = ++{ ++ ZERO, NOT_P, NOT_P, ZERO, ++ P, ONE, ONE, P, ++ P, ONE, ONE, P, ++ ZERO, NOT_P, NOT_P, ZERO ++}; ++ ++/* X = (P & X1) | (~P & X2) */ ++static const DWORD rop2_xor_array[16][2] = ++{ ++ ZERO, NOT_P, ZERO, NOT_P, ++ P, ONE, P, ONE, ++ ZERO, NOT_P, ZERO, NOT_P, ++ P, ONE, P, ONE ++}; ++ ++#undef NOT_P ++#undef P ++#undef ONE ++#undef ZERO ++ ++void _DIBDRV_CalcAndXorMasks(INT rop, DWORD color, DWORD *and, DWORD *xor) ++{ ++ /* NB The ROP2 codes start at one and the arrays are zero-based */ ++ rop = (rop - 1) & 0x0f; ++ *and = (color & rop2_and_array[rop][0]) | ((~color) & rop2_and_array[rop][1]); ++ *xor = (color & rop2_xor_array[rop][0]) | ((~color) & rop2_xor_array[rop][1]); ++} ++ ++/* ------------------------------------------------------------*/ ++/* ROP PIXEL FUNCTIONS */ ++ ++inline void _DIBDRV_rop32(DWORD *ptr, DWORD and, DWORD xor) ++{ ++ *ptr = (*ptr & and) ^ xor; ++} ++ ++inline void _DIBDRV_rop16(WORD *ptr, WORD and, WORD xor) ++{ ++ *ptr = (*ptr & and) ^ xor; ++} ++ ++inline void _DIBDRV_rop8(BYTE *ptr, BYTE and, BYTE xor) ++{ ++ *ptr = (*ptr & and) ^ xor; ++} +diff --git a/dlls/winedib.drv/primitives_rop3.c b/dlls/winedib.drv/primitives_rop3.c +new file mode 100644 +index 0000000..398258b +--- /dev/null ++++ b/dlls/winedib.drv/primitives_rop3.c +@@ -0,0 +1,786 @@ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++/* the ROP3 operations ++ this is a BIG case block; beware that some ++ commons ROP3 operations will be optimized ++ from inside blt routines */ ++DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop) ++{ ++ switch(rop) ++ { ++ case 0x00: /* 0 BLACKNESS */ ++ return 0; ++ ++ case 0x01: /* DPSoon */ ++ return (~(p | s | d)) & 0x00ffffff; ++ ++ case 0x02: /* DPSona */ ++ return (d & ~(p | s)) & 0x00ffffff; ++ ++ case 0x03: /* PSon */ ++ return (~(p | s)) & 0x00ffffff; ++ ++ case 0x04: /* SDPona */ ++ return (s & ~(d | p)) & 0x00ffffff; ++ ++ case 0x05: /* DPon */ ++ return (~(d | p)) & 0x00ffffff; ++ ++ case 0x06: /* PDSxnon */ ++ return (~(p | ~(d ^ s))) & 0x00ffffff; ++ ++ case 0x07: /* PDSaon */ ++ return (~((d & s) | p) ) & 0x00ffffff; ++ ++ case 0x08: /* SDPnaa */ ++ return (d & ~p & s) & 0x00ffffff; ++ ++ case 0x09: /* PDSxon */ ++ return (~((d ^ s) | p)) & 0x00ffffff; ++ ++ case 0x0A: /* DPna */ ++ return (~p & d) & 0x00ffffff; ++ ++ case 0x0B: /* PSDnaon */ ++ return (~((~d & s) | p)) & 0x00ffffff; ++ ++ case 0x0C: /* SPna */ ++ return (~p & s) & 0x00ffffff; ++ ++ case 0x0D: /* PDSnaon */ ++ return (~((~s & d) | p)) & 0x00ffffff; ++ ++ case 0x0E: /* PDSonon */ ++ return (~(~(d | s) | p)) & 0x00ffffff; ++ ++ case 0x0F: /* Pn */ ++ return (~p) & 0x00ffffff; ++ ++ case 0x10: /* PDSona */ ++ return (~(d | s) & p) & 0x00ffffff; ++ ++ case 0x11: /* DSon NOTSRCERASE */ ++ return (~(d | s)) & 0x00ffffff; ++ ++ case 0x12: /* SDPxnon */ ++ return (~(~(d ^ p) | s)) & 0x00ffffff; ++ ++ case 0x13: /* SDPaon */ ++ return (~((d & p) | s)) & 0x00ffffff; ++ ++ case 0x14: /* DPSxnon */ ++ return (~(~(p ^ s) | d)) & 0x00ffffff; ++ ++ case 0x15: /* DPSaon */ ++ return (~((p & s) | d)) & 0x00ffffff; ++ ++ case 0x16: /* PSDPSanaxx */ ++ return (((~(p & s) & d) ^ s) ^ p) & 0x00ffffff; ++ ++ case 0x17: /* SSPxDSxaxn */ ++ return (~(((d ^ s) & (s ^ p)) ^ s)) & 0x00ffffff; ++ ++ case 0x18: /* SPxPDxa */ ++ return ((s ^ p) & (p ^ d)) & 0x00ffffff; ++ ++ case 0x19: /* SDPSanaxn */ ++ return (~((~(p & s) & d) ^ s)) & 0x00ffffff; ++ ++ case 0x1A: /* PDSPaox */ ++ return (((s & p) | d) ^ p) & 0x00ffffff; ++ ++ case 0x1B: /* SDPSxaxn */ ++ return (~(((p ^ s) & d) ^ s)) & 0x00ffffff; ++ ++ case 0x1C: /* PSDPaox */ ++ return (((d & p) | s) ^ p) & 0x00ffffff; ++ ++ case 0x1D: /* DSPDxaxn */ ++ return (~(((p ^ d) & s) ^ d)) & 0x00ffffff; ++ ++ case 0x1E: /* PDSox */ ++ return ((d | s) ^ p) & 0x00ffffff; ++ ++ case 0x1F: /* PDSoan */ ++ return (~((d | s) & p)) & 0x00ffffff; ++ ++ case 0x20: /* DPSnaa */ ++ return (p & ~s & d) & 0x00ffffff; ++ ++ case 0x21: /* SDPxon */ ++ return (~((d ^ p) | s)) & 0x00ffffff; ++ ++ case 0x22: /* DSna */ ++ return (d & ~s) & 0x00ffffff; ++ ++ case 0x23: /* SPDnaon */ ++ return (~((p & ~d) | s)) & 0x00ffffff; ++ ++ case 0x24: /* SPxDSxa */ ++ return ((s ^ p) & (d ^ s)) & 0x00ffffff; ++ ++ case 0x25: /* PDSPanaxn */ ++ return (~((~(s & p) & d) ^ p)) & 0x00ffffff; ++ ++ case 0x26: /* SDPSaox */ ++ return (((p & s) | d) ^ s) & 0x00ffffff; ++ ++ case 0x27: /* SDPSxnox */ ++ return ((~(p ^ s) | d) ^ s) & 0x00ffffff; ++ ++ case 0x28: /* DPSxa */ ++ return ((p ^ s) & d) & 0x00ffffff; ++ ++ case 0x29: /* PSDPSaoxxn */ ++ return (~((((p & s) | d) ^ s) ^ p)) & 0x00ffffff; ++ ++ case 0x2A: /* DPSana */ ++ return (~(p & s) & d) & 0x00ffffff; ++ ++ case 0x2B: /* SSPxPDxaxn */ ++ return (~(((s ^ p) & (p ^ d)) ^ s)) & 0x00ffffff; ++ ++ case 0x2C: /* SPDSoax */ ++ return (((d | s) & p) ^ s) & 0x00ffffff; ++ ++ case 0x2D: /* PSDnox */ ++ return ((s | ~d) ^ p) & 0x00ffffff; ++ ++ case 0x2E: /* PSDPxox */ ++ return (((d ^ p) | s) ^ p) & 0x00ffffff; ++ ++ case 0x2F: /* PSDnoan */ ++ return (~((s | ~d) & p)) & 0x00ffffff; ++ ++ case 0x30: /* PSna */ ++ return (p & ~s) & 0x00ffffff; ++ ++ case 0x31: /* SDPnaon */ ++ return (~((d & ~p) | s)) & 0x00ffffff; ++ ++ case 0x32: /* SDPSoox */ ++ return ((p | s | d) ^ s) & 0x00ffffff; ++ ++ case 0x33: /* Sn NOTSRCCOPY */ ++ return (~s) & 0x00ffffff; ++ ++ case 0x34: /* SPDSaox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x35: /* SPDSxnox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x36: /* SDPox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x37: /* SDPoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x38: /* PSDPoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x39: /* SPDnox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x3A: /* SPDSxox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x3B: /* SPDnoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x3C: /* PSx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x3D: /* SPDSonox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x3E: /* SPDSnaox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x3F: /* PSan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x40: /* PSDnaa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x41: /* DPSxon */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x42: /* SDxPDxa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x43: /* SPDSanaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x44: /* SDna SRCERASE */ ++ return (s & ~d) & 0x00ffffff; ++ ++ case 0x45: /* DPSnaon */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x46: /* DSPDaox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x47: /* PSDPxaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x48: /* SDPxa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x49: /* PDSPDaoxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x4A: /* DPSDoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x4B: /* PDSnox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x4C: /* SDPana */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x4D: /* SSPxDSxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x4E: /* PDSPxox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x4F: /* PDSnoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x50: /* PDna */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x51: /* DSPnaon */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x52: /* DPSDaox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x53: /* SPDSxaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x54: /* DPSonon */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x55: /* Dn DSTINVERT */ ++ return (~d) & 0x00ffffff; ++ ++ case 0x56: /* DPSox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x57: /* DPSoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x58: /* PDSPoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x59: /* DPSnox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x5A: /* DPx PATINVERT */ ++ return (d ^ p) & 0x00ffffff; ++ ++ case 0x5B: /* DPSDonox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x5C: /* DPSDxox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x5D: /* DPSnoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x5E: /* DPSDnaox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x5F: /* DPan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x60: /* PDSxa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x61: /* DSPDSaoxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x62: /* DSPDoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x63: /* SDPnox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x64: /* SDPSoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x65: /* DSPnox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x66: /* DSx SRCINVERT */ ++ return (d ^ s) & 0x00ffffff; ++ ++ case 0x67: /* SDPSonox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x68: /* DSPDSonoxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x69: /* PDSxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x6A: /* DPSax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x6B: /* PSDPSoaxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x6C: /* SDPax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x6D: /* PDSPDoaxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x6E: /* SDPSnoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x6F: /* PDSxnan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x70: /* PDSana */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x71: /* SSDxPDxaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x72: /* SDPSxox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x73: /* SDPnoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x74: /* DSPDxox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x75: /* DSPnoan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x76: /* SDPSnaox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x77: /* DSan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x78: /* PDSax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x79: /* DSPDSoaxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x7A: /* DPSDnoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x7B: /* SDPxnan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x7C: /* SPDSnoax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x7D: /* DPSxnan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x7E: /* SPxDSxo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x7F: /* DPSaan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x80: /* DPSaa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x81: /* SPxDSxon */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x82: /* DPSxna */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x83: /* SPDSnoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x84: /* SDPxna */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x85: /* PDSPnoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x86: /* DSPDSoaxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x87: /* PDSaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x88: /* DSa SRCAND */ ++ return (d & s) & 0x00ffffff; ++ ++ case 0x89: /* SDPSnaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x8A: /* DSPnoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x8B: /* DSPDxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x8C: /* SDPnoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x8D: /* SDPSxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x8E: /* SSDxPDxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x8F: /* PDSanan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x90: /* PDSxna */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x91: /* SDPSnoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x92: /* DPSDPoaxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x93: /* SPDaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x94: /* PSDPSoaxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x95: /* DPSaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x96: /* DPSxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x97: /* PSDPSonoxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x98: /* SDPSonoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x99: /* DSxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x9A: /* DPSnax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x9B: /* SDPSoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x9C: /* SPDnax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x9D: /* DSPDoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x9E: /* DSPDSaoxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0x9F: /* PDSxan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA0: /* DPa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA1: /* PDSPnaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA2: /* DPSnoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA3: /* DPSDxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA4: /* PDSPonoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA5: /* PDxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA6: /* DSPnax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA7: /* PDSPoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA8: /* DPSoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xA9: /* DPSoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xAA: /* D */ ++ return (d) & 0x00ffffff; ++ ++ case 0xAB: /* DPSono */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xAC: /* SPDSxax */ ++ return (s ^ (p & (d ^ s))) & 0x00ffffff; ++ ++ case 0xAD: /* DPSDaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xAE: /* DSPnao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xAF: /* DPno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB0: /* PDSnoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB1: /* PDSPxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB2: /* SSPxDSxox */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB3: /* SDPanan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB4: /* PSDnax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB5: /* DPSDoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB6: /* DPSDPaoxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB7: /* SDPxan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB8: /* PSDPxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xB9: /* DSPDaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xBA: /* DPSnao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xBB: /* DSno MERGEPAINT */ ++ return (d | ~s) & 0x00ffffff; ++ ++ case 0xBC: /* SPDSanax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xBD: /* SDxPDxan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xBE: /* DPSxo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xBF: /* DPSano */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC0: /* PSa MERGECOPY */ ++ return (p & s) & 0x00ffffff; ++ ++ case 0xC1: /* SPDSnaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC2: /* SPDSonoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC3: /* PSxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC4: /* SPDnoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC5: /* SPDSxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC6: /* SDPnax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC7: /* PSDPoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC8: /* SDPoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xC9: /* SPDoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xCA: /* DPSDxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xCB: /* SPDSaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ default: ++ case 0xCC: /* S SRCCOPY */ ++ return (s) & 0x00ffffff; ++ ++ case 0xCD: /* SDPono */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xCE: /* SDPnao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xCF: /* SPno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD0: /* PSDnoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD1: /* PSDPxoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD2: /* PDSnax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD3: /* SPDSoaxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD4: /* SSPxPDxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD5: /* DPSanan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD6: /* PSDPSaoxx */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD7: /* DPSxan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD8: /* PDSPxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xD9: /* SDPSaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xDA: /* DPSDanax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xDB: /* SPxDSxan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xDC: /* SPDnao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xDD: /* SDno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xDE: /* SDPxo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xDF: /* SDPano */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE0: /* PDSoa */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE1: /* PDSoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE2: /* DSPDxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE3: /* PSDPaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE4: /* SDPSxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE5: /* PDSPaoxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE6: /* SDPSanax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE7: /* SPxPDxan */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE8: /* SSPxDSxax */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xE9: /* DSPDSanaxxn */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xEA: /* DPSao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xEB: /* DPSxno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xEC: /* SDPao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xED: /* SDPxno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xEE: /* DSo SRCPAINT */ ++ return (d | s) & 0x00ffffff; ++ ++ case 0xEF: /* SDPnoo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF0: /* P PATCOPY */ ++ return (p) & 0x00ffffff; ++ ++ case 0xF1: /* PDSono */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF2: /* PDSnao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF3: /* PSno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF4: /* PSDnao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF5: /* PDno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF6: /* PDSxo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF7: /* PDSano */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF8: /* PDSao */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xF9: /* PDSxno */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xFA: /* DPo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xFB: /* DPSnoo PATPAINT */ ++ return (p | ~s | d) & 0x00ffffff; ++ ++ case 0xFC: /* PSo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xFD: /* PSDnoo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xFE: /* DPSoo */ ++ return (0x123456) & 0x00ffffff; ++ ++ case 0xFF: /* 1 WHITENESS */ ++ return 0x00ffffff; ++ ++ } /* switch */ ++} +diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c +index 0176011..e2cea0c 100644 +--- a/dlls/winedib.drv/text.c ++++ b/dlls/winedib.drv/text.c +@@ -25,6 +25,19 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++/* converts font sizes from Word space to Device space */ ++static void FontSizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h) ++{ ++ POINT pts[2]; ++ pts[0].x = 0; ++ pts[0].y = 0; ++ pts[1].x = abs(*w); ++ pts[1].y = abs(*h); ++ LPtoDP(physDev->hdc, pts, 2); ++ *w = pts[1].x - pts[0].x; ++ *h = pts[1].y - pts[0].y; ++} ++ + /*********************************************************************** + * DIBDRV_ExtTextOut + */ +@@ -32,17 +45,163 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + const RECT *lprect, LPCWSTR wstr, UINT count, + const INT *lpDx ) + { ++ /* FIXME : TODO many, many stuffs... just trivial text support by now */ ++ + BOOL res; ++ FT_Face face; ++ FT_UInt glyph_index; ++ INT n; ++ INT error; ++ LOGFONTW lf; ++ int w, h; ++ LPCWSTR wstrPnt; ++ ++ FT_Glyph glyph; ++ FT_BitmapGlyph bitmap; ++ double cosEsc, sinEsc; ++ FT_Matrix matrix; ++ FT_Vector start; ++ int dx, dy; + +- TRACE("physDev:%p, x:%d, y:%d, flags:%x, lprect:%p, wstr:%s, count:%d, lpDx:%p\n", +- physDev, x, y, flags, lprect, debugstr_w(wstr), count, lpDx); ++ ++ MAYBE(TRACE("physDev:%p, x:%d, y:%d, flags:%x, lprect:%p, wstr:%s, count:%d, lpDx:%p\n", ++ physDev, x, y, flags, lprect, debugstr_w(wstr), count, lpDx)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect, +- wstr, count, lpDx); ++ ++ face = physDev->face; ++ if(!face) ++ { ++ ERR("FreeType face is null\n"); ++ res = FALSE; ++ goto fin; ++ } ++ ++ /* outputs the string in case it is given by glyph indexes ++ make locating it in logs much easier */ ++ if(TRACE_ON(dibdrv) && flags & ETO_GLYPH_INDEX) ++ { ++ WCHAR a = 'A'; ++ WCHAR *str = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*(count+1)); ++ int delta = a - pFT_Get_Char_Index( face, a); ++ int i; ++ memcpy(str, wstr, sizeof(WCHAR)*count); ++ for(i = 0; str[i] && i < count; i++) ++ str[i] += delta; ++ TRACE("String: '%s'\n", debugstr_w(str)); ++ HeapFree(GetProcessHeap(), 0, str); ++ } ++ ++ /* gets font data, etc */ ++ GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf); ++ ++ /* convert sizes to device space */ ++ w = lf.lfWidth; h = lf.lfHeight; ++ FontSizes_ws2ds(physDev, &w, &h); ++ ++ /* if opaque, paint the font background */ ++/* ++ if(flags | ETO_OPAQUE) ++ { ++ int iLine; ++ for(iLine = lprect->top; iLine < lprect->bottom; iLine++) ++ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, ++ lprect->left, lprect->right-1, iLine, 0, physDev->backgroundColor); ++ } ++*/ ++ /* sets character pixel size */ ++ error = pFT_Set_Pixel_Sizes( ++ face, ++ MulDiv(w, 96, DIBDRV_GetDeviceCaps(physDev, LOGPIXELSX)), ++ MulDiv(h, 96, DIBDRV_GetDeviceCaps(physDev, LOGPIXELSY)) ++ ); ++ if(error) ++ ERR("Couldn't set char size to (%d,%d)\n", lf.lfWidth, lf.lfHeight); ++ ++ /* transformation matrix and vector */ ++ start.x = 0; ++ start.y = 0; ++ if(lf.lfEscapement != 0) ++ { ++ cosEsc = cos(lf.lfEscapement * M_PI / 1800); ++ sinEsc = sin(lf.lfEscapement * M_PI / 1800); ++ } ++ else ++ { ++ cosEsc = 1; ++ sinEsc = 0; ++ } ++ matrix.xx = (FT_Fixed)( cosEsc * 0x10000L ); ++ matrix.xy = (FT_Fixed)(-sinEsc * 0x10000L ); ++ matrix.yx = (FT_Fixed)( sinEsc * 0x10000L ); ++ matrix.yy = (FT_Fixed)( cosEsc * 0x10000L ); ++ ++ /* outputs characters one by one */ ++ wstrPnt = wstr; ++ for ( n = 0; n < count; n++ ) ++ { ++ /* retrieve glyph index from character code */ ++ if(flags & ETO_GLYPH_INDEX) ++ glyph_index = *wstrPnt++; ++ else ++ glyph_index = pFT_Get_Char_Index( face, *wstrPnt++); ++ ++ /* load glyph image into the slot (erase previous one) */ ++ error = pFT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); ++ if(error) ++ { ++ ERR("Couldn't load glyph at index %d\n", glyph_index); ++ /* ignore errors */ ++ continue; ++ } ++ error = pFT_Get_Glyph(face->glyph, &glyph); ++ if ( error ) ++ { ++ FIXME("Couldn't get glyph\n"); ++ continue; ++ } ++ ++ /* apply transformation to glyph */ ++ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) ++ pFT_Glyph_Transform(glyph, &matrix, &start ); ++ ++ /* gets advance BEFORE transforming... */ ++ dx = glyph->advance.x; ++ dy = glyph->advance.y; ++ ++ /* convert to an anti-aliased bitmap, if needed */ ++ if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) ++ { ++ error = pFT_Glyph_To_Bitmap( ++ &glyph, ++ FT_RENDER_MODE_NORMAL, ++ 0, /* no additional translation */ ++ 1 /* destroy copy in "image" */ ++ ); ++ ++ /* ignore errors */ ++ if ( error ) ++ { ++ FIXME("Couldn't render glyph\n"); ++ pFT_Done_Glyph(glyph); ++ continue; ++ } ++ } ++ ++ /* now, draw to our target surface */ ++ bitmap = (FT_BitmapGlyph)glyph; ++ physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmap->left, y-bitmap->top, &bitmap->bitmap); ++ ++ /* increment pen position */ ++ x += dx>>16; ++ y -= dy>>16; ++ ++ pFT_Done_Glyph(glyph); ++ ++ res = TRUE; ++ } + } + else + { +@@ -50,6 +209,7 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + res = _DIBDRV_GetDisplayDriver()->pExtTextOut(physDev->X11PhysDev, x, y, flags, lprect, + wstr, count, lpDx); + } ++fin: + return res; + } + +@@ -61,15 +221,14 @@ BOOL DIBDRV_GetTextExtentExPoint( DIBDRVPHYSDEV *physDev, LPCWSTR str, INT count + { + BOOL res; + +- TRACE("physDev:%p, str:%s, count:%d, maxExt:%d, lpnFit:%p, alpDx:%p, size:%p\n", +- physDev, debugstr_w(str), count, maxExt, lpnFit, alpDx, size); ++ MAYBE(TRACE("physDev:%p, str:%s, count:%d, maxExt:%d, lpnFit:%p, alpDx:%p, size:%p\n", ++ physDev, debugstr_w(str), count, maxExt, lpnFit, alpDx, size)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pGetTextExtentExPoint(physDev->X11PhysDev, str, count, maxExt, +- lpnFit, alpDx, size); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { +diff --git a/dlls/winedib.drv/video.c b/dlls/winedib.drv/video.c +index 730e62a..9892d69 100644 +--- a/dlls/winedib.drv/video.c ++++ b/dlls/winedib.drv/video.c +@@ -32,7 +32,7 @@ BOOL DIBDRV_GetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) + { + BOOL res; + +- TRACE("physDev:%p, ramp:%p\n", physDev, ramp); ++ MAYBE(TRACE("physDev:%p, ramp:%p\n", physDev, ramp)); + + if(physDev->hasDIB) + { +@@ -55,13 +55,13 @@ BOOL DIBDRV_SetDeviceGammaRamp( DIBDRVPHYSDEV *physDev, LPVOID ramp ) + { + BOOL res; + +- TRACE("physDev:%p, ramp:%p\n", physDev, ramp); ++ MAYBE(TRACE("physDev:%p, ramp:%p\n", physDev, ramp)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("TEMPORARY - fallback to X11 driver\n")); +- res = _DIBDRV_GetDisplayDriver()->pSetDeviceGammaRamp(physDev->X11PhysDev, ramp); ++ ONCE(FIXME("STUB\n")); ++ res = TRUE; + } + else + { diff --git a/app-emulation/wine/files/0005-dib-engine-implement-alphablen.patch b/app-emulation/wine/files/0005-dib-engine-implement-alphablen.patch new file mode 100644 index 00000000..fe8daa44 --- /dev/null +++ b/app-emulation/wine/files/0005-dib-engine-implement-alphablen.patch @@ -0,0 +1,512 @@ +DIB Engine: implement AlphaBlend + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/bitblt.c | 88 ++++++++-- + dlls/winedib.drv/dibdrv.h | 2 + dlls/winedib.drv/primitives.c | 12 + + dlls/winedib.drv/primitives_bitblt.c | 287 ++++++++++++++++++++++++++++++++++ + 4 files changed, 370 insertions(+), 19 deletions(-) + + +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index 20cdcaa..c0227a0 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -150,34 +150,84 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + xDst, yDst, widthDst, heightDst, + physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "", + xSrc, ySrc, widthSrc, heightSrc)); ++ + +- if(physDevDst->hasDIB && physDevSrc->hasDIB) ++ /* if sizes are null or negative, returns false */ ++ if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0) + { +- /* DIB section selected in both source and dest DC, use DIB Engine */ +- ONCE(FIXME("STUB\n")); +- res = TRUE; ++ res = FALSE; ++ goto fin; + } +- else if(!physDevDst->hasDIB && !physDevSrc->hasDIB) ++ ++ /* source sould be a 32 bit DIB */ ++ if(!physDevSrc) + { +- /* DDB selected in noth source and dest DC, use X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, +- blendfn); ++ FIXME("Null source bitmap -- shouldn't happen\n"); ++ res = FALSE; ++ goto fin; + } +- else if(physDevSrc->hasDIB) ++ else if(!physDevSrc->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()->pAlphaBlend(physDevDst->X11PhysDev, xDst, yDst, widthDst, heightDst, +- physDevSrc->X11PhysDev, xSrc, ySrc, widthSrc, heightSrc, +- blendfn); ++ FIXME("DDB source bitmap -- shouldn't happen\n"); ++ res = FALSE; ++ goto fin; + } +- else /* if(physDevDst->hasDIB) */ ++ ++ if(physDevDst->hasDIB) + { +- /* DDB on source, DIB on dest -- must convert source DDB to DIB and use the engine for blit */ +- ONCE(FIXME("STUB\n")); +- res = TRUE; ++ /* DIB section selected in dest DC, use DIB Engine */ ++ MAYBE(TRACE("Blending DIB->DIB\n")); ++ res = physDevDst->physBitmap.funcs->AlphaBlend(physDevDst, xDst, yDst, widthDst, heightDst, ++ physDevSrc, xSrc, ySrc, widthSrc, heightSrc, blendfn); ++ } ++ else ++ { ++ /* DDB selected on dest DC -- must double-convert */ ++ HBITMAP tmpDIB, stock; ++ HDC tmpDC; ++ MAYBE(TRACE("Blending DIB->DDB\n")); ++ ++ /* converts dest DDB onto a temporary DIB -- just the needed part */ ++ tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst); ++ if(!tmpDIB) ++ { ++ ERR("Couldn't convert dest DDB to DIB\n"); ++ res = FALSE; ++ goto fin; ++ } ++ ++ /* selects the temporary DIB into a temporary DC */ ++ tmpDC = CreateCompatibleDC(physDevDst->hdc); ++ if(!tmpDC) ++ { ++ ERR("Couldn't create temporary DC\n"); ++ DeleteObject(tmpDIB); ++ res = FALSE; ++ goto fin; ++ } ++ stock = SelectObject(tmpDC, tmpDIB); ++ if(!stock) ++ { ++ ERR("Couldn't select temporary DIB into temporary DC\n"); ++ DeleteDC(tmpDC); ++ DeleteObject(tmpDIB); ++ res = FALSE; ++ goto fin; ++ } ++ ++ /* blends source DIB onto temp DIB and re-blits onto dest DC */ ++ res = GdiAlphaBlend(tmpDC, 0, 0, widthDst, heightDst, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn); ++ if(!res) ++ MAYBE(TRACE("AlphaBlend failed\n")); ++ else ++ res = BitBlt(physDevDst->hdc, xDst, yDst, widthDst, heightDst, tmpDC, 0, 0, SRCCOPY); ++ ++ /* frees resources */ ++ SelectObject(tmpDC, stock); ++ DeleteDC(tmpDC); ++ DeleteObject(tmpDIB); + } ++fin: + return res; + } + +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index 773941e..c801d96 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -94,6 +94,8 @@ typedef struct _DIBDRV_PRIMITIVE_FUNCS + BOOL (* PutLine) ( struct _DIBDRVBITMAP *bmp, int line, int startx, int width, void *buf); + + /* BitBlt primitives */ ++ BOOL (* AlphaBlend) ( struct _DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, int widthDst, int heightDst, ++ const struct _DIBDRVPHYSDEV *physDevSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn ); + 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, +diff --git a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c +index cbad239..a2fa04a 100644 +--- a/dlls/winedib.drv/primitives.c ++++ b/dlls/winedib.drv/primitives.c +@@ -133,6 +133,10 @@ 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); + ++BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, ++ int widthDst, int heightDst, const DIBDRVPHYSDEV *physDevSrc, ++ int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn ); ++ + /* ------------------------------------------------------------*/ + /* FREETYPE FONT BITMAP BLITTING */ + void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, FT_Bitmap *bmp); +@@ -156,6 +160,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB = + _DIBDRV_SolidVLine32, + _DIBDRV_GetLine32_RGB, + _DIBDRV_PutLine32_RGB, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_32_RGB +@@ -172,6 +177,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_BITFIELDS = + _DIBDRV_SolidVLine32, + _DIBDRV_GetLine32_BITFIELDS, + _DIBDRV_PutLine32_BITFIELDS, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_32_BITFIELDS +@@ -188,6 +194,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB24 = + _DIBDRV_SolidVLine24, + _DIBDRV_GetLine24, + _DIBDRV_PutLine24, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_24 +@@ -204,6 +211,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_RGB = + _DIBDRV_SolidVLine16, + _DIBDRV_GetLine16_RGB, + _DIBDRV_PutLine16_RGB, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_16_RGB +@@ -220,6 +228,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB16_BITFIELDS = + _DIBDRV_SolidVLine16, + _DIBDRV_GetLine16_BITFIELDS, + _DIBDRV_PutLine16_BITFIELDS, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_16_BITFIELDS +@@ -236,6 +245,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB8 = + _DIBDRV_SolidVLine8, + _DIBDRV_GetLine8, + _DIBDRV_PutLine8, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_8 +@@ -252,6 +262,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB4 = + _DIBDRV_SolidVLine4, + _DIBDRV_GetLine4, + _DIBDRV_PutLine4, ++ _DIBDRV_AlphaBlend_generic, + _DIBDRV_BitBlt_generic, + _DIBDRV_StretchBlt_generic, + _DIBDRV_freetype_blit_4 +@@ -268,6 +279,7 @@ DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB1 = + _DIBDRV_SolidVLine1, + _DIBDRV_GetLine1, + _DIBDRV_PutLine1, ++ _DIBDRV_AlphaBlend_generic, + _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 +index da48352..7540dad 100644 +--- a/dlls/winedib.drv/primitives_bitblt.c ++++ b/dlls/winedib.drv/primitives_bitblt.c +@@ -80,6 +80,293 @@ static void StretchLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth) + memcpy(dst, src, 4 * srcWidth); + } + ++/* premultiply alpha channel on a line by a constant alpha ++ note : it seems that pixels are already premultiplied ++ by alpha channel content */ ++static void PemultiplyLine(DWORD *dst, int width, BYTE constAlpha) ++{ ++ int i = width; ++ BYTE *alphaPnt = (BYTE *)dst + 3; ++ ++ /* small optimization for 0 and 255 values of constAlpha */ ++ ++ /* fully transparent -- just sets all pix to 0 */ ++ if(constAlpha == 0) ++ { ++ while(i--) ++ *dst++ = 0; ++ return; ++ } ++ ++ /* fully opaque, just do nothing */ ++ if(constAlpha == 255) ++ return; ++ ++ /* intermediate -- premultiply alpha values */ ++ while(i--) ++ { ++ *alphaPnt = MulDiv(*alphaPnt, constAlpha, 255); ++ alphaPnt += 4; ++ } ++ return; ++ ++} ++ ++/* alpha blends a source line onto a destination line ++ preconditions : ++ 1) source and dest widths must be the same ++ 2) source line should be already premultiplied by constant alpha */ ++static void BlendLine(DWORD *dst, DWORD *src, int width) ++{ ++ int i = width; ++ BYTE *blueDst = (BYTE *)dst; ++ BYTE *greenDst = blueDst + 1; ++ BYTE *redDst = greenDst + 1; ++ BYTE *blueSrc = (BYTE *)src; ++ BYTE *greenSrc = blueSrc + 1; ++ BYTE *redSrc = greenSrc + 1; ++ BYTE *alphaSrc = redSrc + 1; ++ BYTE alpha; ++ ++ /* still don't know if it must take in account an eventual dest ++ alpha channel..... */ ++ while(i--) ++ { ++ alpha = 255 - *alphaSrc; ++ ++ *blueDst = *blueSrc + MulDiv(*blueDst, alpha, 255); ++ *greenDst = *greenSrc + MulDiv(*greenDst, alpha, 255); ++ *redDst = *redSrc + MulDiv(*redDst, alpha, 255); ++ ++ blueSrc += 4; ++ greenSrc += 4; ++ redSrc += 4; ++ alphaSrc += 4; ++ blueDst += 4; ++ greenDst += 4; ++ redDst += 4; ++ } ++ ++} ++ ++/* ------------------------------------------------------------*/ ++/* ALPHABLEND PRIMITIVES */ ++BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT widthDst, INT heightDst, const DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFn) ++{ ++ /* flags indicating wether source should be stretched */ ++ BOOL horStretch = (widthSrc != widthDst); ++ BOOL verStretch = (heightSrc != heightDst); ++ ++ /* constant alpha value */ ++ BYTE constAlpha = blendFn.SourceConstantAlpha; ++ ++ /* source and dest bitmaps */ ++ const DIBDRVBITMAP *srcBmp = &physDevSrc->physBitmap; ++ DIBDRVBITMAP *dstBmp = &physDevDst->physBitmap; ++ ++ /* source and destination line buffers */ ++ DWORD *sBuf = HeapAlloc(GetProcessHeap(), 0, abs(srcBmp->stride)); ++ DWORD *dBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride)); ++ ++ int ys = ySrc; ++ int yd = yDst; ++ int iLine; ++ int delta; ++ ++ /* in order to optimize a bit, we divide the routine in 4 parts, ++ depending on stretching modes */ ++ if(!horStretch && !verStretch) ++ { ++ /* simplest case, no stretching needed */ ++ MAYBE(TRACE("No stretching\n")); ++ for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++) ++ { ++ /* load source and dest lines */ ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf); ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ /* premultiply source by constant and pixel alpha */ ++ PemultiplyLine(sBuf, widthSrc, constAlpha); ++ ++ /* blends source on dest */ ++ BlendLine(dBuf, sBuf, widthSrc); ++ ++ /* puts dest line back */ ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ } ++ else if (horStretch && !verStretch) ++ { ++ /* just horizontal stretching needed */ ++ DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride)); ++ MAYBE(TRACE("Horizontal stretching\n")); ++ ++ for(iLine = 0; iLine < heightSrc; iLine++, ys++, yd++) ++ { ++ /* load source and dest lines */ ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf); ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ /* stretch source line to match dest one */ ++ StretchLine(strBuf, widthDst, sBuf, widthSrc); ++ ++ /* premultiply source by constant and pixel alpha */ ++ PemultiplyLine(strBuf, widthDst, constAlpha); ++ ++ /* blends source on dest */ ++ BlendLine(dBuf, sBuf, widthDst); ++ ++ /* puts dest line back */ ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ } ++ HeapFree(GetProcessHeap(), 0, strBuf); ++ } ++ else if (!horStretch && verStretch) ++ { ++ /* just vertical stretching needed */ ++ MAYBE(TRACE("Vertical stretching\n")); ++ ++ if(heightSrc > heightDst) ++ { ++ iLine = 0; ++ delta = 0; ++ while(iLine < heightDst) ++ { ++ /* load source and dest lines */ ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf); ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ /* premultiply source by constant and pixel alpha */ ++ PemultiplyLine(sBuf, widthSrc, constAlpha); ++ ++ /* blends source on dest */ ++ BlendLine(dBuf, sBuf, widthDst); ++ ++ /* puts dest line back */ ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ iLine++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ iLine = 0; ++ delta = 0; ++ while(iLine < heightSrc) ++ { ++ /* load source line */ ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf); ++ ++ /* premultiply source by constant and pixel alpha */ ++ PemultiplyLine(sBuf, widthSrc, constAlpha); ++ ++ while(delta < heightDst) ++ { ++ /* load dest line */ ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ /* blends source on dest */ ++ BlendLine(dBuf, sBuf, widthDst); ++ ++ /* puts dest line back */ ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ iLine++; ++ } ++ } ++ } ++ else ++ { ++ DWORD *strBuf = HeapAlloc(GetProcessHeap(), 0, abs(dstBmp->stride)); ++ /* both stretching needed -- generic case */ ++ MAYBE(TRACE("Horizontal and vertical stretching\n")); ++ ++ if(heightSrc > heightDst) ++ { ++ iLine = 0; ++ delta = 0; ++ while(iLine < heightDst) ++ { ++ /* load source and dest lines */ ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf); ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ /* stretch source line to match dest one */ ++ StretchLine(strBuf, widthDst, sBuf, widthSrc); ++ ++ /* premultiply source by constant and pixel alpha */ ++ PemultiplyLine(strBuf, widthDst, constAlpha); ++ ++ /* blends source on dest */ ++ BlendLine(dBuf, strBuf, widthDst); ++ ++ /* puts dest line back */ ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ while(delta < heightSrc) ++ { ++ ys++; ++ delta += heightDst; ++ } ++ delta -= heightSrc; ++ yd++; ++ iLine++; ++ } ++ } ++ else if(heightSrc < heightDst) ++ { ++ iLine = 0; ++ delta = 0; ++ while(iLine < heightSrc) ++ { ++ /* load source line */ ++ srcBmp->funcs->GetLine(srcBmp, ys, xSrc, widthSrc, sBuf); ++ ++ /* stretch source line to match dest one */ ++ StretchLine(strBuf, widthDst, sBuf, widthSrc); ++ ++ /* premultiply source by constant and pixel alpha */ ++ PemultiplyLine(strBuf, widthDst, constAlpha); ++ ++ while(delta < heightDst) ++ { ++ /* load dest line */ ++ dstBmp->funcs->GetLine(dstBmp, yd, xDst, widthDst, dBuf); ++ ++ /* blends source on dest */ ++ BlendLine(dBuf, strBuf, widthDst); ++ ++ /* puts dest line back */ ++ dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); ++ yd++; ++ delta += heightSrc; ++ } ++ delta -= heightDst; ++ ys++; ++ iLine++; ++ } ++ } ++ HeapFree(GetProcessHeap(), 0, strBuf); ++ } ++ ++ HeapFree(GetProcessHeap(), 0, sBuf); ++ HeapFree(GetProcessHeap(), 0, dBuf); ++ return TRUE; ++} ++ + /* ------------------------------------------------------------*/ + /* BLITTING PRIMITIVES */ + BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, diff --git a/app-emulation/wine/files/0006-dib-engine-add-clipping-on-xxx.patch b/app-emulation/wine/files/0006-dib-engine-add-clipping-on-xxx.patch new file mode 100644 index 00000000..010c6034 --- /dev/null +++ b/app-emulation/wine/files/0006-dib-engine-add-clipping-on-xxx.patch @@ -0,0 +1,560 @@ +DIB Engine: Add clipping on xxxBlt and AlphaBlend + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/bitblt.c | 332 +++++++++++++++++++++++++++++++++++++------ + dlls/winedib.drv/clipping.c | 42 +++++ + dlls/winedib.drv/dc.c | 14 ++ + dlls/winedib.drv/dibdrv.h | 6 + + 4 files changed, 341 insertions(+), 53 deletions(-) + + +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index c0227a0..05c9392 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -33,6 +33,26 @@ static inline void intSwap(int *a, int *b) + *b = tmp; + } + ++static inline void setRect(RECT *r, int x1, int y1, int x2, int y2) ++{ ++ r->left = x1; ++ r->top = y1; ++ r->right = x2; ++ r->bottom = y2; ++} ++ ++static inline void setPoint(POINT *p, int x, int y) ++{ ++ p->x = x; ++ p->y = y; ++} ++ ++static inline void setSize(SIZE *sz, int cx, int cy) ++{ ++ sz->cx = cx; ++ sz->cy = cy; ++} ++ + /* 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 */ +@@ -130,13 +150,158 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT* + 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")); ++ int xs1, ys1, xs2, ys2; ++ int xsc1, ysc1, xsc2, ysc2; ++ int xd1, yd1, xd2, yd2; ++ int xdc1, ydc1, xdc2, ydc2; ++ int ws, hs, wd, hd, dx, dy; ++ int mulh, divh, mulv, divv; ++ ++ /* extract sizes */ ++ ws = szSrc->cx; hs = szSrc->cy; ++ wd = szDst->cx; hd = szDst->cy; ++ ++ /* if sizes null or negative, just return false */ ++ /* FIXME : add support for mirror stretch */ ++ if(ws <= 0 || hs <= 0 || wd <= 0 || hd <= 0) ++ return FALSE; ++ ++ /* stores scaling factors from source rect to dest one */ ++ mulh = wd; divh = ws; ++ mulv = hd; divv = hs; ++ ++ /* extract dest area data */ ++ xd1 = pd->x; ++ yd1 = pd->y; ++ xd2 = xd1 + wd; ++ yd2 = yd1 + hd; ++ ++ /* extract source data */ ++ xs1 = ps->x; ++ ys1 = ps->y; ++ xs2 = xs1 + ws; ++ ys2 = ys1 + hs; ++ ++ /* 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; ws -= dx; xd1 += MulDiv(dx, mulh, divh); xs1 = xsc1; } ++ if(ys1 < ysc1) { dy = ysc1 - ys1; hs -= dy; yd1 += MulDiv(dy, mulv, divv); ys1 = ysc1; } ++ ++ /* clip on source clipping end point */ ++ if(xs2 > xsc2) { dx = xs2 - xsc2; ws -= dx; xd2 -= MulDiv(dx, mulh, divh); xs2 = xsc2; } ++ if(ys2 > ysc2) { dy = ys2 - ysc2; hs -= dy; yd2 -= MulDiv(dy, mulv, divv); ys2 = ysc2; } ++ ++ /* if already zero area, return false */ ++ if(ws <= 0 || hs <= 0) ++ return FALSE; ++ wd = xd2 - xd1; ++ hd = yd2 - yd1; ++ } ++ /* 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; wd -= dx; xs1 += MulDiv(dx, divh, mulh); xd1 = xdc1; } ++ if(yd1 < ydc1) { dy = ydc1 - yd1; hd -= dy; ys1 += MulDiv(dy, divv, mulv); yd1 = ydc1; } ++ ++ /* clip on dest clipping end point */ ++ if(xd2 > xdc2) { dx = xd2 - xdc2; wd -= dx; xs2 -= MulDiv(dx, divh, mulh); xd2 = xdc2; } ++ if(yd2 > ydc2) { dy = yd2 - ydc2; hd -= dy; ys2 -= MulDiv(dy, divv, mulv); yd2 = ydc2; } ++ ++ /* if already zero area, return false */ ++ if(wd <= 0 || hd <= 0) ++ return FALSE; ++ ++ ws = xs2 - xs1; ++ hs = ys2 - ys1; ++ } ++ ++ /* sets clipped/translated points and sizes and returns TRUE */ ++ ps->x = xs1; ps->y = ys1; ++ pd->x = xd1; pd->y = yd1; ++ szSrc->cx = ws; szSrc->cy = hs; ++ szDst->cx = wd; szDst->cy = hd; ++ + return TRUE; + + } + + /*********************************************************************** ++ * _DIBDRV_InternalAlphaBlend ++ */ ++BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst, ++ DIBDRVPHYSDEV *physDevSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, ++ BLENDFUNCTION blendfn) ++{ ++ BOOL res; ++ POINT pd, ps; ++ SIZE szSrc, szDst; ++ int iRec; ++ RECT dstClip, srcClip; ++ ++ /* first clip on physical DC sizes */ ++ setPoint(&pd, xDst, yDst); ++ setPoint(&ps, xSrc, ySrc); ++ setSize(&szDst, widthDst, heightDst); ++ setSize(&szSrc, widthSrc, heightSrc); ++ setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ if(physDevSrc) ++ { ++ setRect(&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) ++ return FALSE; ++ xDst = pd.x; yDst = pd.y; ++ xSrc = ps.x; ySrc = ps.y; ++ widthDst = szDst.cx; heightDst = szDst.cy; ++ widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ ++ /* then, do blitting for each dest clip area (no clipping on source) */ ++ res = FALSE; ++ for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++) ++ { ++ RECT *r = physDevDst->regionRects + iRec; ++ setRect(&dstClip, r->left, r->top, r->right, r->bottom); ++ setPoint(&pd, xDst, yDst); ++ setPoint(&ps, xSrc, ySrc); ++ setSize(&szDst, widthDst, heightDst); ++ setSize(&szSrc, widthSrc, heightSrc); ++ if(!StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip)) ++ continue; ++ if(physDevDst->physBitmap.funcs->AlphaBlend(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy, ++ physDevSrc, ps.x, ps.y, szSrc.cx, szSrc.cy, blendfn)) ++ res = TRUE; ++ } ++ return res; ++} ++ ++/*********************************************************************** + * DIBDRV_AlphaBlend + */ + BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT widthDst, INT heightDst, +@@ -145,6 +310,11 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + { + BOOL res; + ++ POINT pd = {xDst, yDst}; ++ POINT ps = {xSrc, ySrc}; ++ SIZE szDst = {widthDst, heightDst}; ++ SIZE szSrc = {widthSrc, heightSrc}; ++ + MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n", + physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "", + xDst, yDst, widthDst, heightDst, +@@ -177,16 +347,24 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + { + /* DIB section selected in dest DC, use DIB Engine */ + MAYBE(TRACE("Blending DIB->DIB\n")); +- res = physDevDst->physBitmap.funcs->AlphaBlend(physDevDst, xDst, yDst, widthDst, heightDst, +- physDevSrc, xSrc, ySrc, widthSrc, heightSrc, blendfn); ++ res = _DIBDRV_InternalAlphaBlend(physDevDst, xDst, yDst, widthDst, heightDst, ++ physDevSrc, xSrc, ySrc, widthSrc, heightSrc, blendfn); + } + else + { + /* DDB selected on dest DC -- must double-convert */ + HBITMAP tmpDIB, stock; + HDC tmpDC; ++ RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; + MAYBE(TRACE("Blending DIB->DDB\n")); + ++ /* clip blit area */ ++ res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0); ++ if(!res) ++ goto fin; ++ xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy; ++ xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ + /* converts dest DDB onto a temporary DIB -- just the needed part */ + tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst); + if(!tmpDIB) +@@ -232,8 +410,55 @@ fin: + } + + /*********************************************************************** +- * DIBDRV_BitBlt ++ * _DIBDRV_InternalBitBlt + */ ++BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT width, INT height, DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, DWORD rop ) ++{ ++ BOOL res; ++ POINT pd, ps; ++ SIZE sz; ++ int iRec; ++ RECT dstClip, srcClip; ++ ++ /* first clip on physical DC sizes */ ++ setPoint(&pd, xDst, yDst); ++ setPoint(&ps, xSrc, ySrc); ++ setSize(&sz, width, height); ++ setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ if(physDevSrc) ++ { ++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height); ++ res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, &dstClip); ++ } ++ else ++ res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip); ++ if(!res) ++ return FALSE; ++ xDst = pd.x; yDst = pd.y; ++ xSrc = ps.x; ySrc = ps.y; ++ width = sz.cx; height = sz.cy; ++ ++ /* then, do blitting for each dest clip area (no clipping on source) */ ++ res = FALSE; ++ for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++) ++ { ++ RECT *r = physDevDst->regionRects + iRec; ++ setRect(&dstClip, r->left, r->top, r->right, r->bottom); ++ setPoint(&pd, xDst, yDst); ++ setPoint(&ps, xSrc, ySrc); ++ setSize(&sz, width, height); ++ if(!BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip)) ++ continue; ++ if(physDevDst->physBitmap.funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop)) ++ res = TRUE; ++ } ++ return res; ++} ++ ++/*********************************************************************** ++ * DIBDRV_BitBlt */ + BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + INT width, INT height, DIBDRVPHYSDEV *physDevSrc, + INT xSrc, INT ySrc, DWORD rop ) +@@ -254,26 +479,13 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + if(physDevDst->hasDIB) + { + /* 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); ++ res = _DIBDRV_InternalBitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, ySrc, rop); + } + else + { +@@ -309,8 +521,7 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + goto noBlt1; + } + SelectObject(physDevSrc->hdc, dib); +- res = physDevDst->physBitmap.funcs->BitBlt(physDevDst, xDst, yDst, width, height, +- physDevSrc, xSrc, 0, rop); ++ res = _DIBDRV_InternalBitBlt(physDevDst, xDst, yDst, width, height, physDevSrc, xSrc, 0, rop); + SelectObject(physDevSrc->hdc, ddb); + DeleteObject(dib); + noBlt1: +@@ -410,6 +621,58 @@ noBlt3: + } + + /*********************************************************************** ++ * _DIBDRV_InternalStretchBlt ++ */ ++BOOL _DIBDRV_InternalStretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, ++ INT widthDst, INT heightDst, DIBDRVPHYSDEV *physDevSrc, ++ INT xSrc, INT ySrc, int widthSrc, int heightSrc, DWORD rop ) ++{ ++ BOOL res; ++ POINT pd, ps; ++ SIZE szSrc, szDst; ++ int iRec; ++ RECT dstClip, srcClip; ++ ++ /* first clip on physical DC sizes */ ++ setPoint(&pd, xDst, yDst); ++ setPoint(&ps, xSrc, ySrc); ++ setSize(&szDst, widthDst, heightDst); ++ setSize(&szSrc, widthSrc, heightSrc); ++ setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ if(physDevSrc) ++ { ++ setRect(&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) ++ return FALSE; ++ xDst = pd.x; yDst = pd.y; ++ xSrc = ps.x; ySrc = ps.y; ++ widthDst = szDst.cx; heightDst = szDst.cy; ++ widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ ++ /* then, do blitting for each dest clip area (no clipping on source) */ ++ res = FALSE; ++ for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++) ++ { ++ RECT *r = physDevDst->regionRects + iRec; ++ setRect(&dstClip, r->left, r->top, r->right, r->bottom); ++ setPoint(&pd, xDst, yDst); ++ setPoint(&ps, xSrc, ySrc); ++ setSize(&szDst, widthDst, heightDst); ++ setSize(&szSrc, widthSrc, heightSrc); ++ if(!StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip)) ++ continue; ++ if(physDevDst->physBitmap.funcs->StretchBlt(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy, ++ physDevSrc, ps.x, ps.y, szSrc.cx, szSrc.cy, rop)) ++ res = TRUE; ++ } ++ return res; ++} ++ ++/*********************************************************************** + * DIBDRV_StretchBlt + */ + BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, +@@ -439,38 +702,15 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + { + /* 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); ++ res = _DIBDRV_InternalStretchBlt(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 */ +@@ -495,8 +735,8 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + goto noBlt1; + } + SelectObject(physDevSrc->hdc, dib); +- res = physDevDst->physBitmap.funcs->StretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, +- physDevSrc, xSrc, 0, widthSrc, heightSrc, rop); ++ res = _DIBDRV_InternalStretchBlt(physDevDst, xDst, yDst, widthDst, heightDst, ++ physDevSrc, xSrc, 0, widthSrc, heightSrc, rop); + SelectObject(physDevSrc->hdc, ddb); + DeleteObject(dib); + noBlt1: +diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c +index 81dec25..ed10b92 100644 +--- a/dlls/winedib.drv/clipping.c ++++ b/dlls/winedib.drv/clipping.c +@@ -25,22 +25,50 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + +- + /*********************************************************************** + * DIBDRV_SetDeviceClipping + */ + void DIBDRV_SetDeviceClipping( DIBDRVPHYSDEV *physDev, HRGN vis_rgn, HRGN clip_rgn ) + { ++ RGNDATA *data; ++ DWORD size; ++ int iRect; ++ + MAYBE(TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn)); + +- if(physDev->hasDIB) ++ /* sets the region for X11 driver anyways... we may change bitmap later on */ ++ _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); ++ ++ /* then we set the region for DIB engine, same reason */ ++ ++ CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY ); ++ ++ /* get region rectangles */ ++ if(!(size = GetRegionData(physDev->region, 0, NULL))) ++ return; ++ data = HeapAlloc(GetProcessHeap(), 0, size); ++ if (!GetRegionData(physDev->region, size, data)) + { +- /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("STUB\n")); ++ HeapFree( GetProcessHeap(), 0, data ); ++ return; + } +- else ++ ++ /* frees any previous regions rectangles in DC */ ++ if(physDev->regionData) ++ HeapFree(GetProcessHeap(), 0, physDev->regionData); ++ ++ /* sets the rectangles on physDev */ ++ physDev->regionData = data; ++ physDev->regionRects = (RECT *)data->Buffer; ++ physDev->regionRectCount = data->rdh.nCount; ++ ++ if(TRACE_ON(dibdrv)) + { +- /* DDB selected in, use X11 driver */ +- _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); ++ TRACE("Region dump : %d rectangles\n", physDev->regionRectCount); ++ for(iRect = 0; iRect < physDev->regionRectCount; iRect++) ++ { ++ RECT *r = physDev->regionRects + iRect; ++ TRACE("Rect #%03d, x1:%4d, y1:%4d, x2:%4d, y2:%4d\n", iRect, r->left, r->top, r->right, r->bottom); ++ } + } + } +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +index 6184677..8212d42 100644 +--- a/dlls/winedib.drv/dc.c ++++ b/dlls/winedib.drv/dc.c +@@ -165,6 +165,12 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + + /* clears pen and brush */ + physDev->rop2 = R2_COPYPEN; ++ ++ /* clipping region */ ++ physDev->region = CreateRectRgn( 0, 0, 0, 0 ); ++ physDev->regionData = NULL; ++ physDev->regionRects = NULL; ++ physDev->regionRectCount = 0; + + physDev->backgroundColor = 0; + _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor); +@@ -228,6 +234,14 @@ BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev ) + physDev->brushAnds = NULL; + physDev->brushXors = NULL; + ++ /* frees clipping region */ ++ DeleteObject(physDev->region); ++ if(physDev->regionData) ++ HeapFree(GetProcessHeap(), 0, physDev->regionData); ++ physDev->regionData = NULL; ++ physDev->regionRects = NULL; ++ physDev->regionRectCount = 0; ++ + /* frees DIB Engine device */ + HeapFree(GetProcessHeap(), 0, physDev); + +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index c801d96..b0f128e 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -204,6 +204,12 @@ typedef struct _DIBDRVPHYSDEV + + /* active ROP2 */ + INT rop2; ++ ++ /* clipping region and its rectangles */ ++ HRGN region; ++ RGNDATA *regionData; ++ RECT *regionRects; ++ int regionRectCount; + + /* background color and active ROP2 precalculated + AND and XOR values for it */ diff --git a/app-emulation/wine/files/0007-dib-engine-implement-polygon.patch b/app-emulation/wine/files/0007-dib-engine-implement-polygon.patch new file mode 100644 index 00000000..169a07ed --- /dev/null +++ b/app-emulation/wine/files/0007-dib-engine-implement-polygon.patch @@ -0,0 +1,463 @@ +DIB Engine: Implement Polygon + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/graphics.c | 405 ++++++++++++++++++++++++++++++++++++++++++- + 1 files changed, 395 insertions(+), 10 deletions(-) + + +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +index 8dda082..e416488 100644 +--- a/dlls/winedib.drv/graphics.c ++++ b/dlls/winedib.drv/graphics.c +@@ -36,6 +36,281 @@ static inline void OrderInt(int *i1, int *i2) + } + } + ++#define LEFT_SIDE 1 ++#define TOP_SIDE 2 ++#define RIGHT_SIDE 4 ++#define BOTTOM_SIDE 8 ++ ++/* clips a line segment by a rectangular window */ ++static inline BYTE outCodes(const POINT *p, const RECT *r) ++{ ++ BYTE Code = 0; ++ ++ if(p->y < r->top) ++ Code |= TOP_SIDE; ++ else if(p->y >= r->bottom) ++ Code |= BOTTOM_SIDE; ++ if(p->x >= r->right) ++ Code |= RIGHT_SIDE; ++ else if(p->x < r->left) ++ Code |= LEFT_SIDE; ++ return Code; ++} ++ ++static BOOL ClipLine(const POINT *p1, const POINT *p2, const RECT *r, POINT *pc1, POINT *pc2) ++{ ++ BYTE outCode1,outCode2; ++ int tmp; ++ BYTE tmpCode; ++ ++ pc1->x = p1->x; pc1->y = p1->y; ++ pc2->x = p2->x; pc2->y = p2->y; ++ while(TRUE) ++ { ++ outCode1 = outCodes(pc1, r); ++ outCode2 = outCodes(pc2, r); ++ if(outCode1 & outCode2) ++ return FALSE; ++ if(!outCode1 && !outCode2) ++ return TRUE; ++ if(!outCode1) ++ { ++ tmp = pc1->x; pc1->x = pc2->x; pc2->x = tmp; ++ tmp = pc1->y; pc1->y = pc2->y; pc2->y = tmp; ++ tmpCode = outCode1; outCode1 = outCode2; outCode2 = tmpCode; ++ } ++ if(outCode1 & TOP_SIDE) ++ { ++ pc1->x += MulDiv(pc2->x - pc1->x, r->top - pc1->y, pc2->y - pc1->y); ++ pc1->y = r->top; ++ } ++ else if(outCode1 & BOTTOM_SIDE) ++ { ++ pc1->x += MulDiv(pc2->x - pc1->x, r->bottom - 1 - pc1->y, pc2->y - pc1->y); ++ pc1->y = r->bottom - 1; ++ } ++ else if(outCode1 & RIGHT_SIDE) ++ { ++ pc1->y += MulDiv(pc2->y - pc1->y, r->right - 1 - pc1->x, pc2->x - pc1->x); ++ pc1->x = r->right - 1; ++ } ++ else if(outCode1 & LEFT_SIDE) ++ { ++ pc1->y += MulDiv(pc2->y - pc1->y, r->left - pc1->x, pc2->x - pc1->x); ++ pc1->x = r->left; ++ } ++ } ++} ++ ++/* Clips a polygon by an horizontal/vertical line ++ which indicates the side : ++*/ ++static inline BOOL PointInside(const POINT *p, const RECT *r, BYTE side) ++{ ++ switch(side) ++ { ++ case 1: /* left */ ++ return p->x >= r->left; ++ case 2: /* top */ ++ return p->y >= r->top; ++ case 4: /* right */ ++ return p->x < r->right; ++ case 8: /* bottom */ ++ return p->y < r->bottom; ++ default: ++ return FALSE; ++ } ++} ++ ++static inline void SideIntersect(const POINT *p1, const POINT *p2, const RECT *r, BYTE side, POINT *inters) ++{ ++ switch( side ) ++ { ++ case LEFT_SIDE: /* left */ ++ inters->x = r->left; ++ inters->y = MulDiv(p2->y - p1->y, r->left - p1->x, p2->x - p1->x) + p1->y; ++ break; ++ case TOP_SIDE: /* top */ ++ inters->x = MulDiv(p2->x - p1->x, r->top - p1->y, p2->y - p1->y) + p1->x; ++ inters->y = r->bottom; ++ break; ++ case RIGHT_SIDE: /* right */ ++ inters->x = r->right - 1; ++ inters->y = MulDiv(p2->y - p1->y, r->right - 1 - p1->x, p2->x - p1->x) + p1->y; ++ break; ++ case BOTTOM_SIDE: /* bottom */ ++ inters->x = MulDiv(p2->x - p1->x, r->bottom - 1 - p1->y, p2->y - p1->y) + p1->x; ++ inters->y = r->bottom - 1; ++ break; ++ default: ++ break; ++ } ++} ++ ++ ++static BOOL ClipPolygonBySide(const POINT *pt, int count, const RECT *r, BYTE side, POINT **clipped, int *clippedCount) ++{ ++ int iPoint; ++ const POINT *p1, *p2; ++ POINT *pOut; ++ ++ if(!(*clipped = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT) * count * 2))) ++ return FALSE; ++ pOut = *clipped; ++ *clippedCount = 0; ++ ++ p1 = pt + count - 1; ++ p2 = pt; ++ for(iPoint = 0 ; iPoint < count ; iPoint++) ++ { ++ if(PointInside(p2, r, side)) ++ { ++ /* point p is "inside" */ ++ if(!PointInside(p1, r, side)) ++ { ++ /* p is "inside" and s is "outside" */ ++ SideIntersect(p2, p1, r, side, pOut++); ++ (*clippedCount)++; ++ } ++ pOut->x = p2->x; ++ pOut->y = p2->y; ++ pOut++; ++ (*clippedCount)++; ++ } ++ else if(PointInside( p1, r, side )) ++ { ++ /* s is "inside" and p is "outside" */ ++ SideIntersect(p1, p2, r, side, pOut++); ++ (*clippedCount)++; ++ } ++ p1 = p2++; ++ } ++ return *clippedCount; ++} ++ ++ ++/* Clips a polygon by a rectangular window - returns a new polygon */ ++static BOOL ClipPolygon(const POINT* pt, int count, const RECT *r, POINT **newPt, int *newCount) ++{ ++ POINT *pc1, *pc2; ++ int count1, count2; ++ BOOL res; ++ ++ if(!ClipPolygonBySide(pt, count, r, LEFT_SIDE, &pc1, &count1)) ++ return FALSE; ++ res = ClipPolygonBySide(pc1, count1, r, TOP_SIDE, &pc2, &count2); ++ HeapFree(GetProcessHeap(), 0, pc1); ++ if(!res) ++ return FALSE; ++ res = ClipPolygonBySide(pc2, count2, r, RIGHT_SIDE, &pc1, &count1); ++ HeapFree(GetProcessHeap(), 0, pc2); ++ if(!res) ++ return FALSE; ++ res = ClipPolygonBySide(pc1, count1, r, BOTTOM_SIDE, &pc2, &count2); ++ HeapFree(GetProcessHeap(), 0, pc1); ++ if(!res) ++ return FALSE; ++ ++ *newPt = pc2; ++ *newCount = count2; ++ return TRUE; ++} ++ ++/* Intersects a line given by 2 points with an horizontal scan line at height y */ ++static BOOL ScanLine(const POINT *p1, const POINT *p2, int ys, POINT *pRes) ++{ ++ if(!pRes) ++ return FALSE; ++ ++ /* if line lies completely over or under scan line, no intersection */ ++ if((p1->y < ys && p2->y < ys) || (p1->y > ys && p2->y > ys)) ++ return FALSE; ++ ++ /* if line is parallel to x axis, we consider it not intersecting */ ++ if(p1->y == p2->y) ++ return FALSE; ++ ++ pRes->x = MulDiv(p2->x - p1->x, ys - p1->y, p2->y - p1->y) + p1->x; ++ pRes->y = ys; ++ return TRUE; ++} ++ ++/* Gets an x-ordered list of intersection points of a scanline at position y ++ with a polygon/polyline */ ++static BOOL ScanPolygon(const POINT *pt, int count, int ys, POINT **scans, int *scanCount) ++{ ++ const POINT *p1, *p2; ++ POINT *pDest; ++ int iPoint; ++ POINT *ps1, *ps2; ++ int i, j, tmp; ++ ++ /* if not at least 2 points, nothing to return */ ++ if(count < 2) ++ return FALSE; ++ ++ /* intersections count is AT MOST 'count'; we don't care to ++ allocate exact memory needed */ ++ *scans = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT)*count); ++ if(!*scans) ++ return FALSE; ++ ++ /* builds unordered intersections */ ++ pDest = *scans; ++ *scanCount = 0; ++ p2 = pt; ++ for(iPoint = 0; iPoint < count-1; iPoint++) ++ { ++ p1 = p2; ++ p2++; ++ if(ScanLine(p1, p2, ys, pDest)) ++ { ++ pDest++; ++ (*scanCount)++; ++ } ++ } ++ p1 = p2; ++ p2 = pt; ++ if(ScanLine(p1, p2, ys, pDest)) ++ { ++ pDest++; ++ (*scanCount)++; ++ } ++ ++ /* now we sort the list -- duped point are left into ++ as they're needed for the scanline fill algorithm */ ++ for(i = 0, ps1 = *scans; i < *scanCount -1; i++, ps1++) ++ for(j = i+1, ps2 = ps1+1; j < *scanCount; j++, ps2++) ++ if(ps2->x < ps1->x) ++ { ++ tmp = ps2->x; ++ ps2->x = ps1->x; ++ ps1->x = tmp; ++ tmp = ps2->y; ++ ps2->y = ps1->y; ++ ps1->y = tmp; ++ } ++ ++ return TRUE; ++} ++ ++/* gets bounding box of a polygon */ ++void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox) ++{ ++ const POINT *p; ++ int iPoint; ++ ++ bBox->left = MAXLONG; bBox->right = -MAXLONG; ++ bBox->top = MAXLONG; bBox->bottom = -MAXLONG; ++ for(p = pt, iPoint = 0; iPoint < count; iPoint++, p++) ++ { ++ if(p->x < bBox->left ) bBox->left = p->x; ++ if(p->x > bBox->right ) bBox->right = p->x; ++ if(p->y < bBox->top ) bBox->top = p->y; ++ if(p->y > bBox->bottom) bBox->bottom = p->y; ++ } ++} ++ + /*********************************************************************** + * DIBDRV_Arc + */ +@@ -291,45 +566,155 @@ 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* ptw, int count ) + { + BOOL res; ++ POINT *pt; ++ RECT *r; ++ int iRec; ++ POINT *clipped; ++ int clippedCount; ++ RECT bBox; ++ int ys; ++ POINT *scans; ++ int scanCount, iScan; ++ const POINT *p1, *p2; ++ int iPoint; ++ POINT pc1, pc2; + +- MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count)); ++ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, ptw, count)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("STUB\n")); +- res = TRUE; ++ ++ res = FALSE; ++ ++ /* first converts all points to device coords */ ++ if(!(pt = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT) * count))) ++ goto fin; ++ memcpy(pt, ptw, sizeof(POINT) * count); ++ LPtoDP(physDev->hdc, pt, count); ++ ++ /* cycle on all current clipping rectangles */ ++ r = physDev->regionRects; ++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++) ++ { ++ /* filled area */ ++ if(ClipPolygon(pt, count, r, &clipped, &clippedCount)) ++ { ++ /* gets polygon bounding box -- for ytop and ybottom */ ++ PolygonBoundingBox(clipped, clippedCount, &bBox); ++ ++ /* gets all ordered intersections of polygon with ++ current scanline */ ++ for(ys = bBox.top; ys < bBox.bottom; ys++) ++ { ++ if(ScanPolygon(clipped, clippedCount, ys, &scans, &scanCount)) ++ { ++ if(scanCount >= 2) ++ { ++ res = TRUE; ++ p1 = scans; ++ p2 = p1+1; ++ iScan = 0; ++ while(iScan < scanCount - 1) ++ { ++ physDev->brushHLine(physDev, p1->x, p2->x, ys); ++ p1 +=2; ++ p2 +=2; ++ iScan +=2; ++ } ++ } ++ HeapFree(GetProcessHeap(), 0, scans); ++ } ++ } ++ HeapFree(GetProcessHeap(), 0, clipped); ++ } ++ ++ /* perimeter -- don't use PolyLine for speed */ ++ p2 = pt; ++ for(iPoint = 0; iPoint < count -1; iPoint++) ++ { ++ p1 = p2++; ++ if(ClipLine(p1, p2, r, &pc1, &pc2)) ++ { ++ res = TRUE; ++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y); ++ } ++ } ++ p1 = p2; ++ p2 = pt; ++ if(ClipLine(p1, p2, r, &pc1, &pc2)) ++ { ++ res = TRUE; ++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y); ++ } ++ } ++ ++ HeapFree(GetProcessHeap(), 0, pt); ++ + } + else + { + /* DDB selected in, use X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, pt, count); ++ res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, ptw, count); + } ++fin: + return res; + } + + /********************************************************************** + * DIBDRV_Polyline + */ +-BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, int count ) ++BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count ) + { + BOOL res; + +- MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count)); ++ MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, ptw, count)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +- ONCE(FIXME("STUB\n")); +- res = TRUE; ++ POINT *pt; ++ RECT *r; ++ POINT pc1, pc2; ++ int iRec, iPoint; ++ ++ if(count < 2) ++ return FALSE; ++ res = FALSE; ++ ++ /* first converts all points to device coords */ ++ if(!(pt = HeapAlloc(GetProcessHeap(), 0, sizeof(POINT) * count))) ++ return FALSE; ++ memcpy(pt, ptw, sizeof(POINT) * count); ++ LPtoDP(physDev->hdc, pt, count); ++ ++ r = physDev->regionRects; ++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++) ++ { ++ const POINT *p2 = pt, *p1; ++ for(iPoint = 0; iPoint < count -1; iPoint++) ++ { ++ p1 = p2++; ++ if(ClipLine(p1, p2, r, &pc1, &pc2)) ++ { ++ res = TRUE; ++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y); ++ } ++ } ++ r++; ++ } ++ ++ HeapFree(GetProcessHeap(), 0, pt); ++ ++ return res; + } + else + { + /* DDB selected in, use X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, pt, count); ++ res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, ptw, count); + } + return res; + } diff --git a/app-emulation/wine/files/0008-dib-engine-fixes-clipping-text.patch b/app-emulation/wine/files/0008-dib-engine-fixes-clipping-text.patch new file mode 100644 index 00000000..e52324a4 --- /dev/null +++ b/app-emulation/wine/files/0008-dib-engine-fixes-clipping-text.patch @@ -0,0 +1,1804 @@ +DIB Engine: fixes clipping, text and more + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/bitblt.c | 22 +++ + dlls/winedib.drv/clipping.c | 63 +++++---- + dlls/winedib.drv/dc.c | 16 ++ + dlls/winedib.drv/dib.c | 41 +++++- + dlls/winedib.drv/dibdrv.h | 27 ++++ + dlls/winedib.drv/font.c | 68 ++++++++- + dlls/winedib.drv/freetype.c | 6 + + dlls/winedib.drv/freetype.h | 4 + + dlls/winedib.drv/graphics.c | 204 +++++++++++++++++++++------- + dlls/winedib.drv/palette.c | 16 +- + dlls/winedib.drv/pen_brush.c | 13 ++ + dlls/winedib.drv/primitives.c | 18 +- + dlls/winedib.drv/primitives_bitblt.c | 26 ++-- + dlls/winedib.drv/primitives_convert.c | 24 ++- + dlls/winedib.drv/primitives_font.c | 242 +++++++++++++++++++++++++-------- + dlls/winedib.drv/primitives_rop3.c | 2 + dlls/winedib.drv/text.c | 239 +++++++++++++++++++-------------- + 17 files changed, 738 insertions(+), 293 deletions(-) + + +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index 05c9392..db66142 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -261,6 +261,12 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + SIZE szSrc, szDst; + int iRec; + RECT dstClip, srcClip; ++ ++ /* converts to device spaces */ ++ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst); ++ _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst); ++ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc); ++ _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc); + + /* first clip on physical DC sizes */ + setPoint(&pd, xDst, yDst); +@@ -320,7 +326,6 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + xDst, yDst, widthDst, heightDst, + physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "", + xSrc, ySrc, widthSrc, heightSrc)); +- + + /* if sizes are null or negative, returns false */ + if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0) +@@ -422,6 +427,12 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + int iRec; + RECT dstClip, srcClip; + ++ /* converts to device spaces */ ++ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst); ++ _DIBDRV_Sizes_ws2ds(physDevDst, &width, &height); ++ if(physDevSrc) ++ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc); ++ + /* first clip on physical DC sizes */ + setPoint(&pd, xDst, yDst); + setPoint(&ps, xSrc, ySrc); +@@ -633,6 +644,15 @@ BOOL _DIBDRV_InternalStretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + int iRec; + RECT dstClip, srcClip; + ++ /* converts to device spaces */ ++ _DIBDRV_Position_ws2ds(physDevDst, &xDst, &yDst); ++ _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst); ++ if(physDevSrc) ++ { ++ _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc); ++ _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc); ++ } ++ + /* first clip on physical DC sizes */ + setPoint(&pd, xDst, yDst); + setPoint(&ps, xSrc, ySrc); +diff --git a/dlls/winedib.drv/clipping.c b/dlls/winedib.drv/clipping.c +index ed10b92..ada1f7f 100644 +--- a/dlls/winedib.drv/clipping.c ++++ b/dlls/winedib.drv/clipping.c +@@ -36,39 +36,44 @@ void DIBDRV_SetDeviceClipping( DIBDRVPHYSDEV *physDev, HRGN vis_rgn, HRGN clip_r + + MAYBE(TRACE("physDev:%p, vis_rgn:%p, clip_rgn:%p\n", physDev, vis_rgn, clip_rgn)); + +- /* sets the region for X11 driver anyways... we may change bitmap later on */ +- _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); +- +- /* then we set the region for DIB engine, same reason */ ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ + +- CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY ); ++ CombineRgn( physDev->region, vis_rgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY ); + +- /* get region rectangles */ +- if(!(size = GetRegionData(physDev->region, 0, NULL))) +- return; +- data = HeapAlloc(GetProcessHeap(), 0, size); +- if (!GetRegionData(physDev->region, size, data)) +- { +- HeapFree( GetProcessHeap(), 0, data ); +- return; +- } +- +- /* frees any previous regions rectangles in DC */ +- if(physDev->regionData) +- HeapFree(GetProcessHeap(), 0, physDev->regionData); ++ /* get region rectangles */ ++ if(!(size = GetRegionData(physDev->region, 0, NULL))) ++ return; ++ data = HeapAlloc(GetProcessHeap(), 0, size); ++ if (!GetRegionData(physDev->region, size, data)) ++ { ++ HeapFree( GetProcessHeap(), 0, data ); ++ return; ++ } + +- /* sets the rectangles on physDev */ +- physDev->regionData = data; +- physDev->regionRects = (RECT *)data->Buffer; +- physDev->regionRectCount = data->rdh.nCount; +- +- if(TRACE_ON(dibdrv)) +- { +- TRACE("Region dump : %d rectangles\n", physDev->regionRectCount); +- for(iRect = 0; iRect < physDev->regionRectCount; iRect++) ++ /* frees any previous regions rectangles in DC */ ++ if(physDev->regionData) ++ HeapFree(GetProcessHeap(), 0, physDev->regionData); ++ ++ /* sets the rectangles on physDev */ ++ physDev->regionData = data; ++ physDev->regionRects = (RECT *)data->Buffer; ++ physDev->regionRectCount = data->rdh.nCount; ++ ++ if(TRACE_ON(dibdrv)) + { +- RECT *r = physDev->regionRects + iRect; +- TRACE("Rect #%03d, x1:%4d, y1:%4d, x2:%4d, y2:%4d\n", iRect, r->left, r->top, r->right, r->bottom); ++ TRACE("Region dump : %d rectangles\n", physDev->regionRectCount); ++ for(iRect = 0; iRect < physDev->regionRectCount; iRect++) ++ { ++ RECT *r = physDev->regionRects + iRect; ++ TRACE("Rect #%03d, x1:%4d, y1:%4d, x2:%4d, y2:%4d\n", iRect, r->left, r->top, r->right, r->bottom); ++ } + } + } ++ else ++ { ++ /* DDB selected in, use X11 driver */ ++ _DIBDRV_GetDisplayDriver()->pSetDeviceClipping(physDev->X11PhysDev, vis_rgn, clip_rgn); ++ } + } +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +index 8212d42..9ffceee 100644 +--- a/dlls/winedib.drv/dc.c ++++ b/dlls/winedib.drv/dc.c +@@ -43,11 +43,12 @@ static int device_init_done; + + /* NOTE : + Removing TC_RA_ABLE avoids bitmapped fonts, so FT_Face is always non-NULL ++ UPDATE : remove TC_RA_ABLE seems unneeded + 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); ++ 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 */ + + +@@ -119,6 +120,10 @@ static void device_init(void) + device_init_done = TRUE; + } + ++/* dummy null function for pen and brush */ ++static void dummy3(DIBDRVPHYSDEV *p, int a, int b, int c) {} ++static void dummy4(DIBDRVPHYSDEV *p, int a, int b, int c, int d) {} ++ + /********************************************************************** + * DIBDRV_CreateDC + */ +@@ -178,12 +183,19 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + physDev->penColor = 0; + _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor); + ++ physDev->penStyle = PS_NULL; ++ physDev->penHLine = dummy3; ++ physDev->penVLine = dummy3; ++ physDev->penLine = dummy4; ++ physDev->penPattern = NULL; ++ + physDev->brushColor = 0; + _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor); + physDev->brushAnds = NULL; + physDev->brushXors = NULL; + + physDev->brushStyle = BS_NULL; ++ physDev->brushHLine = dummy3; + + physDev->isBrushBitmap = FALSE; + _DIBDRVBITMAP_Clear(&physDev->brushBitmap); +@@ -193,8 +205,10 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + physDev->textColor = 0; + physDev->textBackground = 0; + ++#ifdef DIBDRV_ANTIALIASED_FONTS + /* text color table for antialiased fonts */ + memset(physDev->textColorTable, 0, 256); ++#endif + + /* freetype face associated to current DC HFONT */ + physDev->face = NULL; +diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c +index b72c34a..653148d 100644 +--- a/dlls/winedib.drv/dib.c ++++ b/dlls/winedib.drv/dib.c +@@ -65,15 +65,46 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + const RGBQUAD *colors ) + { +- UINT res; ++ DIBDRVBITMAP *dib = &physDev->physBitmap; + + 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("STUB\n")); +- res = 0; +- +- return res; ++ ++ /* if bpp > 8, some error occurred... */ ++ if(dib->bitCount > 8) ++ { ++ ERR("Called for BPP > 8\n"); ++ return 0; ++ } ++ ++ /* if dib hasn't a color table, or has a small one, we must before ++ create/extend it */ ++ if(!(dib->colorTable)) ++ { ++ dib->colorTableSize = (1 << dib->bitCount); ++ dib->colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(RGBQUAD) * dib->colorTableSize); ++ } ++ else if(dib->colorTableSize < (1 << dib->bitCount)) ++ { ++ int newSize = (1 << dib->bitCount); ++ RGBQUAD *newTable = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RGBQUAD) * newSize); ++ memcpy(newTable, dib->colorTable, sizeof(RGBQUAD) * dib->colorTableSize); ++ HeapFree(GetProcessHeap(), 0, dib->colorTable); ++ dib->colorTable = newTable; ++ dib->colorTableSize = newSize; ++ } ++ ++ /* sanity check */ ++ if(start + count > dib->colorTableSize) ++ { ++ ERR("Out of range setting color table, size is %d, requested is %d\n", dib->colorTableSize, start+count); ++ return 0; ++ } ++ memcpy(dib->colorTable + start, colors, sizeof(RGBQUAD) * count); ++ dib->colorTableGrabbed = TRUE; ++ ++ return TRUE; + } + + /*********************************************************************** +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index b0f128e..66cc114 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -44,6 +44,9 @@ + /* enable this if you want debugging (i.e. TRACEs) output */ + #define DIBDRV_ENABLE_MAYBE + ++/* enable this if you want antialiased fonts */ ++#define DIBDRV_ANTIALIASED_FONTS ++ + /* provide a way to make debugging output appear + only once. Usage example: + ONCE(FIXME("Some message\n")); */ +@@ -102,7 +105,7 @@ typedef struct _DIBDRV_PRIMITIVE_FUNCS + 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); ++ void (* FreetypeBlit) ( struct _DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp); + + } DIBDRV_PRIMITIVE_FUNCS; + +@@ -225,6 +228,9 @@ typedef struct _DIBDRVPHYSDEV + DWORD curDash, leftInDash; + enum MARKSPACE { mark, space } markSpace; + ++ /* pen style */ ++ UINT penStyle; ++ + /* 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); +@@ -250,8 +256,10 @@ typedef struct _DIBDRVPHYSDEV + COLORREF textColor; + COLORREF textBackground; + ++#ifdef DIBDRV_ANTIALIASED_FONTS + /* text color table for antialiased fonts */ + COLORREF textColorTable[256]; ++#endif + + /* freetype face associated to current DC HFONT */ + FT_Face face; +@@ -388,4 +396,21 @@ HBITMAP _DIBDRV_ConvertDevDDBtoDIB( HDC hdcSrc, HDC hdcDst, int xSrc, int ySrc, + * DIBDRV_GetDeviceCaps */ + INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap ); + ++/* ********************************************************************* ++ * GEOMETRIC UTILITIES ++ * ********************************************************************/ ++ ++/* intersect 2 rectangles (just to not use USER32 one...) */ ++BOOL _DIBDRV_IntersectRect(RECT *d, const RECT *s1, const RECT *s2); ++ ++/* converts positions from Word space to Device space */ ++void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV *physDev, int *x, int *y); ++void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2); ++ ++/* converts sizes from Word space to Device space */ ++void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h); ++ ++/* converts a rectangle form Word space to Device space */ ++void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst); ++ + #endif +diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c +index 215b27d..f7ea8dc 100644 +--- a/dlls/winedib.drv/font.c ++++ b/dlls/winedib.drv/font.c +@@ -26,14 +26,56 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++ ++#if 0 ++/* prints out some info about face */ ++void PrintFaceInfo(FT_Face face) ++{ ++ int i; ++ ++ fprintf(stderr, "----------------------------------------------------------\n"); ++ fprintf(stderr, "Family name :%s\n", face->family_name); ++ fprintf(stderr, "Style name :%s\n", face->style_name); ++ fprintf(stderr, "Num fixed sizes : %d\n", face->num_fixed_sizes); ++ if(face->num_fixed_sizes) ++ { ++ fprintf(stderr, "Fixed sizes :"); ++ for(i = 0; i < face->num_fixed_sizes; i++) ++ fprintf(stderr, " (%d, %d)", face->available_sizes[i].width, face->available_sizes[i].height); ++ fprintf(stderr, "\n"); ++ } ++ fprintf(stderr, "Face flags: "); ++ if(face->face_flags & FT_FACE_FLAG_SCALABLE ) fprintf(stderr, "FT_FACE_FLAG_SCALABLE "); ++ if(face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) fprintf(stderr, "FT_FACE_FLAG_FIXED_SIZES "); ++ if(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) fprintf(stderr, "FT_FACE_FLAG_FIXED_WIDTH "); ++ if(face->face_flags & FT_FACE_FLAG_SFNT ) fprintf(stderr, "FT_FACE_FLAG_SFNT "); ++ if(face->face_flags & FT_FACE_FLAG_HORIZONTAL ) fprintf(stderr, "FT_FACE_FLAG_HORIZONTAL "); ++ if(face->face_flags & FT_FACE_FLAG_VERTICAL ) fprintf(stderr, "FT_FACE_FLAG_VERTICAL "); ++ if(face->face_flags & FT_FACE_FLAG_KERNING ) fprintf(stderr, "FT_FACE_FLAG_KERNING "); ++ if(face->face_flags & FT_FACE_FLAG_FAST_GLYPHS ) fprintf(stderr, "FT_FACE_FLAG_FAST_GLYPHS "); ++ if(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) fprintf(stderr, "FT_FACE_FLAG_MULTIPLE_MASTERS "); ++ if(face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) fprintf(stderr, "FT_FACE_FLAG_GLYPH_NAMES "); ++ if(face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) fprintf(stderr, "FT_FACE_FLAG_EXTERNAL_STREAM "); ++ if(face->face_flags & FT_FACE_FLAG_HINTER ) fprintf(stderr, "FT_FACE_FLAG_HINTER "); ++ if(face->face_flags & FT_FACE_FLAG_CID_KEYED ) fprintf(stderr, "FT_FACE_FLAG_CID_KEYED "); ++ if(face->face_flags & FT_FACE_FLAG_TRICKY ) fprintf(stderr, "FT_FACE_FLAG_TRICKY "); ++ fprintf(stderr, "\n"); ++ ++ fprintf(stderr, "Style flags: "); ++ if(face->style_flags & FT_STYLE_FLAG_ITALIC) fprintf(stderr, "FT_STYLE_FLAG_ITALIC "); ++ if(face->style_flags & FT_STYLE_FLAG_BOLD) fprintf(stderr, "FT_STYLE_FLAG_BOLD "); ++ fprintf(stderr, "\n"); ++ fprintf(stderr, "----------------------------------------------------------\n"); ++} ++#endif ++ ++ + /********************************************************************** + * DIBDRV_SetTextColor + */ + COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + { + COLORREF res; +- INT r, g, b; +- INT i; + + MAYBE(TRACE("physDev:%p, color:%08x\n", physDev, color)); + +@@ -45,24 +87,30 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + if(color == physDev->textColor) + return color; + +- /* stores old color */ ++ /* stores old color and sets new one */ + res = physDev->textColor; +- ++ physDev->textColor = color; ++ ++#ifdef DIBDRV_ANTIALIASED_FONTS + /* fills the text color table used on antialiased font display */ + if(physDev->physBitmap.funcs) + { ++ BYTE r, g, b; ++ INT i; ++ + 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) ++ MulDiv(r, i, 255), ++ MulDiv(g, i, 255), ++ MulDiv(b, i, 255) + )); + } + } ++#endif + + /* returns previous text color */ + return res; +@@ -111,7 +159,11 @@ HFONT DIBDRV_SelectFont( DIBDRVPHYSDEV *physDev, HFONT hfont, GdiFont *gdiFont ) + FIXME("Error, null Ft_Face\n"); + return hfont; + } +- ++ ++#if 0 ++ /* prints out some info about face */ ++ if(TRACE_ON(dibdrv)) MAYBE(PrintFaceInfo(physDev->face)); ++#endif + /* setup the correct charmap.... maybe */ + for (i = 0; i < physDev->face->num_charmaps; ++i) + { +diff --git a/dlls/winedib.drv/freetype.c b/dlls/winedib.drv/freetype.c +index 111a18b..f1cd7b4 100644 +--- a/dlls/winedib.drv/freetype.c ++++ b/dlls/winedib.drv/freetype.c +@@ -46,6 +46,9 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes) + MAKE_FUNCPTR(FT_Get_First_Char) + MAKE_FUNCPTR(FT_Render_Glyph) + MAKE_FUNCPTR(FT_Glyph_Transform) ++MAKE_FUNCPTR(FT_Bitmap_New) ++MAKE_FUNCPTR(FT_Bitmap_Done) ++MAKE_FUNCPTR(FT_Bitmap_Convert) + #undef MAKE_FUNCPTR + + /* freetype initialization flag */ +@@ -95,6 +98,9 @@ BOOL _DIBDRV_FreeType_Init(void) + LOAD_FUNCPTR(FT_Get_First_Char) + LOAD_FUNCPTR(FT_Render_Glyph) + LOAD_FUNCPTR(FT_Glyph_Transform) ++ LOAD_FUNCPTR(FT_Bitmap_New) ++ LOAD_FUNCPTR(FT_Bitmap_Done) ++ LOAD_FUNCPTR(FT_Bitmap_Convert) + #undef LOAD_FUNCPTR + + error = pFT_Init_FreeType(&DIBDRV_ftLibrary); +diff --git a/dlls/winedib.drv/freetype.h b/dlls/winedib.drv/freetype.h +index 93619ff..3517af5 100644 +--- a/dlls/winedib.drv/freetype.h ++++ b/dlls/winedib.drv/freetype.h +@@ -28,6 +28,7 @@ + #include FT_TRUETYPE_TABLES_H + #include FT_SFNT_NAMES_H + #include FT_TRUETYPE_IDS_H ++#include FT_BITMAP_H + + /* freetype library handle */ + extern FT_Library DIBDRV_ftLibrary; +@@ -179,6 +180,9 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes) + MAKE_FUNCPTR(FT_Get_First_Char) + MAKE_FUNCPTR(FT_Render_Glyph) + MAKE_FUNCPTR(FT_Glyph_Transform) ++MAKE_FUNCPTR(FT_Bitmap_New) ++MAKE_FUNCPTR(FT_Bitmap_Done) ++MAKE_FUNCPTR(FT_Bitmap_Convert) + #undef MAKE_FUNCPTR + + #endif /* HAVE_FREETYPE */ +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +index e416488..af264d0 100644 +--- a/dlls/winedib.drv/graphics.c ++++ b/dlls/winedib.drv/graphics.c +@@ -295,7 +295,7 @@ static BOOL ScanPolygon(const POINT *pt, int count, int ys, POINT **scans, int * + } + + /* gets bounding box of a polygon */ +-void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox) ++static void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox) + { + const POINT *p; + int iPoint; +@@ -311,6 +311,76 @@ void PolygonBoundingBox(const POINT *pt, int count, RECT *bBox) + } + } + ++/* intersect 2 rectangles (just to not use USER32 one...) ++ bottom and tight sides are considered OUTSIDE */ ++BOOL _DIBDRV_IntersectRect(RECT *d, const RECT *s1, const RECT *s2) ++{ ++ if(s1->right <= s2->left || ++ s2->right <= s1->left || ++ s1->bottom <= s2->top || ++ s2->bottom <= s1->top ++ ) ++ return FALSE; ++ d->left = s1->left > s2->left ? s1->left : s2->left; ++ d->top = s1->top > s2->top ? s1->top : s2->top; ++ d->right = s1->right < s2->right ? s1->right : s2->right; ++ d->bottom = s1->bottom < s2->bottom ? s1->bottom : s2->bottom; ++ return TRUE; ++} ++ ++/* converts a rectangle form Word space to Device space */ ++void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst) ++{ ++ POINT pts[2]; ++ pts[0].x = src->left; ++ pts[0].y = src->top; ++ pts[1].x = src->right; ++ pts[1].y = src->bottom; ++ LPtoDP(physDev->hdc, pts, 2); ++ dst->left = pts[0].x; ++ dst->top = pts[0].y; ++ dst->right = pts[1].x; ++ dst->bottom = pts[1].y; ++} ++ ++/* converts positions from Word space to Device space */ ++void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV *physDev, int *x, int *y) ++{ ++ POINT p; ++ p.x = *x; ++ p.y = *y; ++ LPtoDP(physDev->hdc, &p, 1); ++ *x = p.x; ++ *y = p.y; ++} ++ ++void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV *physDev, int *x1, int *y1, int *x2, int *y2) ++{ ++ POINT pts[2]; ++ pts[0].x = *x1; ++ pts[0].y = *y1; ++ pts[1].x = *x2; ++ pts[1].y = *y2; ++ LPtoDP(physDev->hdc, pts, 2); ++ *x1 = pts[0].x; ++ *y1 = pts[0].y; ++ *x2 = pts[1].x; ++ *y2 = pts[1].y; ++} ++ ++/* converts sizes from Word space to Device space */ ++void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h) ++{ ++ POINT pts[2]; ++ pts[0].x = 0; ++ pts[0].y = 0; ++ pts[1].x = *w; ++ pts[1].y = *h; ++ LPtoDP(physDev->hdc, pts, 2); ++ *w = pts[1].x - pts[0].x; ++ *h = pts[1].y - pts[0].y; ++} ++ + /*********************************************************************** + * DIBDRV_Arc + */ +@@ -446,6 +516,7 @@ COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y ) + + if(physDev->hasDIB) + { ++ _DIBDRV_Position_ws2ds(physDev, &x, &y); + res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y); + } + else +@@ -463,22 +534,44 @@ BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, int x, int y ) + { + BOOL res; + POINT curPos; ++ RECT *r; ++ int iRec; ++ POINT p1, p2, pc1, pc2; + + MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y)); + + if(physDev->hasDIB) + { ++ res = FALSE; + GetCurrentPositionEx(physDev->hdc, &curPos); + +- _DIBDRV_ResetDashOrigin(physDev); ++ /* converts position to device space */ ++ p1.x = curPos.x; p1.y = curPos.y; ++ p2.x = x; p2.y = y; ++ LPtoDP(physDev->hdc, &p1, 1); ++ LPtoDP(physDev->hdc, &p2, 1); + +- 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; ++ /* cycle on all current clipping rectangles */ ++ r = physDev->regionRects; ++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++) ++ { ++ _DIBDRV_ResetDashOrigin(physDev); ++ ++ /* clipe line on current region area */ ++ if(ClipLine(&p1, &p2, r, &pc1, &pc2)) ++ { ++ if(pc1.y == pc2.y) ++ physDev->penHLine(physDev, pc1.x, pc2.x, pc1.y); ++ else if(pc1.x == pc2.x) ++ physDev->penVLine(physDev, pc1.x, pc1.y, pc2.y); ++ else ++ physDev->penLine(physDev, pc1.x, pc1.y, pc2.x, pc2.y); ++ res = TRUE; ++ } ++ } ++ ++ /* moves current position to next point */ ++ MoveToEx(physDev->hdc, x, y, NULL); + } + else + { +@@ -583,7 +676,7 @@ BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count ) + POINT pc1, pc2; + + MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, ptw, count)); +- ++ + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ +@@ -771,58 +864,67 @@ BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* + */ + BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) + { +- BOOL res = TRUE; ++ BOOL res; + int i; +- DIBDRVBITMAP *bmp = &physDev->physBitmap; ++ RECT rWorld, rDevice, rClipped; ++ RECT *r; ++ int iRec; + + MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev, x1, y1, x2, y2)); + + if(physDev->hasDIB) + { ++ res = FALSE; ++ + 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; ++ /* converts to device space */ ++ rWorld.left = x1; rWorld.top = y1; rWorld.right = x2; rWorld.bottom = y2; ++ _DIBDRV_Rect_ws2ds(physDev, &rWorld, &rDevice); + +- _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) ++ /* loop on all clip region rectangles */ ++ r = physDev->regionRects; ++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++) + { +- 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); ++ /* clips rectangle to current region */ ++ if(_DIBDRV_IntersectRect(&rClipped, &rDevice, r)) ++ { ++ x1 = rClipped.left; y1 = rClipped.top; ++ x2 = rClipped.right; y2 = rClipped.bottom; ++ ++ _DIBDRV_ResetDashOrigin(physDev); ++ ++ /* fill the inside, if not null brush */ ++ if(physDev->brushStyle != BS_NULL) ++ { ++ if(x2 > x1) ++ for (i = y1; i < y2; i++) ++ physDev->brushHLine(physDev, x1, x2, i); ++ } + +- res = TRUE; +-fin: +- ; ++ /* draw perimeter, if not null pen */ ++ if(physDev->penStyle != PS_NULL) ++ { ++ ++ /* particular case where the rectangle ++ degenerates to a line or a point */ ++ if(x1 >= x2 - 1) ++ physDev->penVLine(physDev, x1, y1, y2); ++ else if (y1 >= y2 -1) ++ physDev->penHLine(physDev, x1, x2, y1); ++ else ++ { ++ /* 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); ++ } ++ } ++ res = TRUE; ++ } ++ } + } + else + { +@@ -870,6 +972,8 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color ) + + if(physDev->hasDIB) + { ++ _DIBDRV_Position_ws2ds(physDev, &x, &y); ++ + /* gets previous pixel */ + res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y); + +diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c +index 148a6d5..a1aa648 100644 +--- a/dlls/winedib.drv/palette.c ++++ b/dlls/winedib.drv/palette.c +@@ -30,18 +30,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + */ + UINT DIBDRV_RealizePalette( DIBDRVPHYSDEV *physDev, HPALETTE hpal, BOOL primary ) + { +- UINT res; ++ UINT res = 0; + + 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 */ +- res = _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev->X11PhysDev, hpal, primary); +- +- if(physDev->hasDIB) ++ if(physDev && physDev->hasDIB) + { + /* DIB section selected in, additional (if needed) engine code */ + ONCE(FIXME("STUB\n")); ++ res = 0; ++ } ++ else ++ { ++ /* we should in any case call X11 function, as UnrealizePalette() doesn't ++ * take a physDev parameter */ ++ res = _DIBDRV_GetDisplayDriver()->pRealizePalette(physDev ? physDev->X11PhysDev : NULL, hpal, primary); ++ + } + + return res; +diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c +index 31c9cd2..7b15ece 100644 +--- a/dlls/winedib.drv/pen_brush.c ++++ b/dlls/winedib.drv/pen_brush.c +@@ -290,6 +290,12 @@ static void PatternBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) + physDev->physBitmap.funcs->PatternHLine(&physDev->physBitmap, x1, x2, y, and, xor, physDev->brushBitmap.width, x1 % physDev->brushBitmap.width); + } + ++/* null function for PS_NULL and BS_NULL pen and brush styles */ ++void NullPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) {} ++void NullPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) {} ++void NullPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) {} ++void NullBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) {} ++ + /*********************************************************************** + * DIBDRV_SelectPen + */ +@@ -335,6 +341,12 @@ HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) + physDev->penPattern = &dashPatterns[logpen.lopnStyle - PS_DASH]; + _DIBDRV_ResetDashOrigin(physDev); + break; ++ case PS_NULL: ++ physDev->penHLine = NullPenHLine; ++ physDev->penVLine = NullPenVLine; ++ physDev->penLine = NullPenLine; ++ physDev->penPattern = NULL; ++ break; + } + res = hpen; + } +@@ -484,6 +496,7 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + { + MAYBE(TRACE("NULL Pattern\n")); + physDev->brushColorref = 0; ++ physDev->brushHLine = NullBrushHLine; + goto solid; + } + +diff --git a/dlls/winedib.drv/primitives.c b/dlls/winedib.drv/primitives.c +index a2fa04a..2b0fc6e 100644 +--- a/dlls/winedib.drv/primitives.c ++++ b/dlls/winedib.drv/primitives.c +@@ -139,15 +139,15 @@ BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, int xDst, int yDst, + + /* ------------------------------------------------------------*/ + /* 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); ++void _DIBDRV_freetype_blit_8888 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_32_RGB (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_24 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_16_RGB (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_8 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_4 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); ++void _DIBDRV_freetype_blit_1 (DIBDRVPHYSDEV *dib, int x, int y, RECT *clipRec, FT_Bitmap *bmp); + + DIBDRV_PRIMITIVE_FUNCS DIBDRV_funcs_DIB32_RGB = + { +diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c +index 7540dad..7feeb49 100644 +--- a/dlls/winedib.drv/primitives_bitblt.c ++++ b/dlls/winedib.drv/primitives_bitblt.c +@@ -216,7 +216,7 @@ BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + PemultiplyLine(strBuf, widthDst, constAlpha); + + /* blends source on dest */ +- BlendLine(dBuf, sBuf, widthDst); ++ BlendLine(dBuf, strBuf, widthDst); + + /* puts dest line back */ + dstBmp->funcs->PutLine(dstBmp, yd, xDst, widthDst, dBuf); +@@ -391,6 +391,10 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000)); + useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000)); + ++ /* sanity check -- MSN messenger crashes without */ ++ if(useSrc && !physDevSrc) ++ return FALSE; ++ + /* gets source, dest and pattern bitmaps, if available */ + if(usePat && physDevDst->isBrushBitmap) + patBmp = &physDevDst->brushBmpCache; +@@ -501,8 +505,8 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + { + srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf); + patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf); +- wDstPnt = sBuf; +- wSrcPnt = sBuf; ++ wDstPnt = dBuf; ++ wSrcPnt = dBuf; + wPatPnt = pBuf; + for(i = width; i > 0 ; i--) + { +@@ -521,8 +525,8 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) + { + srcBmp->funcs->GetLine(srcBmp, ys, xSrc, width, dBuf); +- wDstPnt = sBuf; +- wSrcPnt = sBuf; ++ wDstPnt = dBuf; ++ wSrcPnt = dBuf; + for(i = width; i > 0 ; i--) + { + *wDstPnt = _DIBDRV_ROP3(patColor, *wSrcPnt++, 0, rop); +@@ -538,9 +542,9 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + goto error; + for(ys = ySrc, yd = yDst; ys < ySrc+height; ys++, yd++) + { +- dstBmp->funcs->GetLine(srcBmp, ys, xDst, width, dBuf); ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf); + patBmp->funcs->GetLine(patBmp, ys%patBmp->height, 0, width, pBuf); +- wDstPnt = sBuf; ++ wDstPnt = dBuf; + wPatPnt = pBuf; + for(i = width; i > 0 ; i--) + { +@@ -558,8 +562,8 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + 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; ++ dstBmp->funcs->GetLine(dstBmp, ys, xDst, width, dBuf); ++ wDstPnt = dBuf; + for(i = width; i > 0 ; i--) + { + *wDstPnt = _DIBDRV_ROP3(patColor, 0, *wDstPnt, rop); +@@ -638,6 +642,10 @@ BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + useSrc = (((rop >> 2) & 0x330000) != (rop & 0x330000)); + useDst = (((rop >> 1) & 0x550000) != (rop & 0x550000)); + ++ /* sanity check -- MSN messenger crashes without */ ++ if(useSrc && !physDevSrc) ++ return FALSE; ++ + /* gets source, dest and pattern bitmaps, if available */ + if(usePat && physDevDst->isBrushBitmap) + patBmp = &physDevDst->brushBmpCache; +diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c +index 800e3fd..f8f87ce 100644 +--- a/dlls/winedib.drv/primitives_convert.c ++++ b/dlls/winedib.drv/primitives_convert.c +@@ -292,7 +292,7 @@ BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + + src = ((BYTE *)bmp->bits + line * bmp->stride + (startx >> 3)); + /* get first partial byte, if any */ +- startx = (8 - (startx & 0x03)) & 0x03; ++ startx = (8 - (startx & 0x07)) & 0x07; + width -= startx; + if(startx) + { +@@ -322,7 +322,7 @@ BOOL _DIBDRV_GetLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + } + + /* last partial byte, if any */ +- if(width) ++ if(width > 0) + { + b = *src; + while(width--) +@@ -398,13 +398,17 @@ BOOL _DIBDRV_PutLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, + DWORD *dwBuf = (DWORD *)buf; + WORD *dst = (WORD *)((BYTE *)bmp->bits + line * bmp->stride + 2 * startx); + DWORD c; ++ ++ BYTE bShift = 8 - bmp->blueLen; ++ BYTE gShift = 16 - bmp->greenLen; ++ BYTE rShift = 24 - bmp->redLen; + 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); ++ ((((c & 0x000000ff) >> bShift) << bmp->blueShift) & bmp->blueMask) | ++ ((((c & 0x0000ff00) >> gShift) << bmp->greenShift) & bmp->greenMask) | ++ ((((c & 0x00ff0000) >> rShift) << bmp->redShift) & bmp->redMask); + } + return TRUE; + } +@@ -480,7 +484,7 @@ BOOL _DIBDRV_PutLine4(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + } + + /* last nibble, if any */ +- if(width) ++ if(width > 0) + { + c = *dwBuf; + +@@ -500,14 +504,14 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + 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; ++ startx &= 0x07; + mask = 0x80 >> startx; +- startx = (8 - startx) & 0x03; ++ startx = (8 - startx) & 0x07; + if(startx) + { + width -= startx; +@@ -540,7 +544,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + } + + /* last partial byte, if any */ +- if(width) ++ if(width > 0) + { + b = *dst; + mask = 0x80; +diff --git a/dlls/winedib.drv/primitives_font.c b/dlls/winedib.drv/primitives_font.c +index dd1d64b..e604a39 100644 +--- a/dlls/winedib.drv/primitives_font.c ++++ b/dlls/winedib.drv/primitives_font.c +@@ -27,7 +27,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + + /* ------------------------------------------------------------*/ + /* FREETYPE FONT BITMAP BLITTING */ +-void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -35,13 +35,20 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; +- DWORD c; ++ int xMin, xMax, yMin, yMax; + DWORD *ptr; ++#ifdef DIBDRV_ANTIALIASED_FONTS ++ DWORD c; ++ BYTE r, g, b, negColor; ++#else ++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor); ++#endif + +- /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ /* gets clip limits */ ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -50,9 +57,21 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap + 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) ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + { ++#ifdef DIBDRV_ANTIALIASED_FONTS + c = physDev->textColorTable[*buf]; ++ if(*buf < 255) ++ { ++ negColor = 255 - *buf; ++ r = (*ptr >> 16) & 0xff; ++ g = (*ptr >> 8) & 0xff; ++ b = *ptr & 0xff; ++ c += MulDiv(r, 255 - *buf, 255) << 16 | ++ MulDiv(g, 255 - *buf, 255) << 8 | ++ MulDiv(r, 255 - *buf, 255); ++ } ++#endif + *ptr = c; + } + buf++; +@@ -61,7 +80,7 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap + } + } + +-void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -69,30 +88,52 @@ void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; ++ int xMin, xMax, yMin, yMax; ++ DWORD *ptr; ++#ifdef DIBDRV_ANTIALIASED_FONTS + DWORD c; ++ BYTE r, g, b, negColor; ++#else ++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor); ++#endif + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* 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) ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + { ++#ifdef DIBDRV_ANTIALIASED_FONTS + c = physDev->textColorTable[*buf]; +- dib->funcs->SetPixel(dib, dibX, dibY, 0, c); ++ if(*buf < 255) ++ { ++ negColor = 255 - *buf; ++ r = (*ptr >> 16) & 0xff; ++ g = (*ptr >> 8) & 0xff; ++ b = *ptr & 0xff; ++ c += MulDiv(r, 255 - *buf, 255) << 16 | ++ MulDiv(g, 255 - *buf, 255) << 8 | ++ MulDiv(r, 255 - *buf, 255); ++ } ++#endif ++ *ptr = c; + } + buf++; ++ ptr++; + } + } + } + +-void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -100,12 +141,20 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; ++ int xMin, xMax, yMin, yMax; ++#ifdef DIBDRV_ANTIALIASED_FONTS + DWORD c; ++ COLORREF pix; ++ BYTE r, g, b, negColor; ++#else ++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor); ++#endif + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -113,9 +162,22 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + { ++#ifdef DIBDRV_ANTIALIASED_FONTS + c = physDev->textColorTable[*buf]; ++ if(*buf < 255) ++ { ++ negColor = 255 - *buf; ++ pix = dib->funcs->GetPixel(dib, dibX, dibY); ++ r = pix & 0xff; ++ g = (pix >> 8) & 0xff; ++ b = (pix >> 16) & 0xff; ++ c += MulDiv(r, 255 - *buf, 255) << 16 | ++ MulDiv(g, 255 - *buf, 255) << 8 | ++ MulDiv(r, 255 - *buf, 255); ++ } ++#endif + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); + } + buf++; +@@ -123,7 +185,7 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT + } + } + +-void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -131,12 +193,20 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *b + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; ++ int xMin, xMax, yMin, yMax; ++#ifdef DIBDRV_ANTIALIASED_FONTS + DWORD c; ++ COLORREF pix; ++ BYTE r, g, b, negColor; ++#else ++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor); ++#endif + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -144,9 +214,22 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *b + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + { ++#ifdef DIBDRV_ANTIALIASED_FONTS + c = physDev->textColorTable[*buf]; ++ if(*buf < 255) ++ { ++ negColor = 255 - *buf; ++ pix = dib->funcs->GetPixel(dib, dibX, dibY); ++ r = pix & 0xff; ++ g = (pix >> 8) & 0xff; ++ b = (pix >> 16) & 0xff; ++ c += MulDiv(r, 255 - *buf, 255) << 16 | ++ MulDiv(g, 255 - *buf, 255) << 8 | ++ MulDiv(r, 255 - *buf, 255); ++ } ++#endif + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); + } + buf++; +@@ -154,7 +237,7 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *b + } + } + +-void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -162,12 +245,20 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; ++ int xMin, xMax, yMin, yMax; ++#ifdef DIBDRV_ANTIALIASED_FONTS + DWORD c; ++ COLORREF pix; ++ BYTE r, g, b, negColor; ++#else ++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor); ++#endif + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -175,9 +266,22 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + { ++#ifdef DIBDRV_ANTIALIASED_FONTS + c = physDev->textColorTable[*buf]; ++ if(*buf < 255) ++ { ++ negColor = 255 - *buf; ++ pix = dib->funcs->GetPixel(dib, dibX, dibY); ++ r = pix & 0xff; ++ g = (pix >> 8) & 0xff; ++ b = (pix >> 16) & 0xff; ++ c += MulDiv(r, 255 - *buf, 255) << 16 | ++ MulDiv(g, 255 - *buf, 255) << 8 | ++ MulDiv(r, 255 - *buf, 255); ++ } ++#endif + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); + } + buf++; +@@ -185,7 +289,7 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitma + } + } + +-void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -193,12 +297,20 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; ++ int xMin, xMax, yMin, yMax; ++#ifdef DIBDRV_ANTIALIASED_FONTS + DWORD c; ++ COLORREF pix; ++ BYTE r, g, b, negColor; ++#else ++ DWORD c = dib->funcs->ColorToPixel(dib, physDev->textColor); ++#endif + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -206,9 +318,22 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + { ++#ifdef DIBDRV_ANTIALIASED_FONTS + c = physDev->textColorTable[*buf]; ++ if(*buf < 255) ++ { ++ negColor = 255 - *buf; ++ pix = dib->funcs->GetPixel(dib, dibX, dibY); ++ r = pix & 0xff; ++ g = (pix >> 8) & 0xff; ++ b = (pix >> 16) & 0xff; ++ c += MulDiv(r, 255 - *buf, 255) << 16 | ++ MulDiv(g, 255 - *buf, 255) << 8 | ++ MulDiv(r, 255 - *buf, 255); ++ } ++#endif + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); + } + buf++; +@@ -216,7 +341,7 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, FT + } + } + +-void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -224,12 +349,14 @@ void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; +- DWORD c; ++ int xMin, xMax, yMin, yMax; ++ DWORD c = physDev->textColor; + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -237,17 +364,14 @@ void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) +- { +- c = physDev->textColorTable[*buf]; ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); +- } + buf++; + } + } + } + +-void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -255,12 +379,14 @@ void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; +- DWORD c; ++ int xMin, xMax, yMin, yMax; ++ DWORD c = physDev->textColor; + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -268,17 +394,14 @@ void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) +- { +- c = physDev->textColorTable[*buf]; ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); +- } + buf++; + } + } + } + +-void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bmp) ++void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec, FT_Bitmap *bmp) + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +@@ -286,12 +409,14 @@ void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +- int DIBX, DIBY; +- DWORD c; ++ int xMin, xMax, yMin, yMax; ++ DWORD c = physDev->textColor; + + /* gets DIB limits */ +- DIBX = dib->width; +- DIBY = dib->height; ++ xMin = clipRec->left; ++ yMin = clipRec->top; ++ xMax = clipRec->right; ++ yMax = clipRec->bottom; + + /* loop for every pixel in bitmap */ + buf = bmp->buffer; +@@ -299,11 +424,8 @@ void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, FT_Bitmap *bm + { + for(bmpX = 0, dibX = x; bmpX < bmp->width; bmpX++, dibX++) + { +- if(dibX < DIBX && dibY < DIBY && dibX > 0 && dibY > 0 && *buf) +- { +- c = physDev->textColorTable[*buf]; ++ if(dibX < xMax && dibY < yMax && dibX >= xMin && dibY >= yMin && *buf) + dib->funcs->SetPixel(dib, dibX, dibY, 0, c); +- } + buf++; + } + } +diff --git a/dlls/winedib.drv/primitives_rop3.c b/dlls/winedib.drv/primitives_rop3.c +index 398258b..05ce494 100644 +--- a/dlls/winedib.drv/primitives_rop3.c ++++ b/dlls/winedib.drv/primitives_rop3.c +@@ -413,7 +413,7 @@ DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop) + return (0x123456) & 0x00ffffff; + + case 0x85: /* PDSPnoaxn */ +- return (0x123456) & 0x00ffffff; ++ return (~(p ^ (d & (s | ~p)))) & 0x00ffffff; + + case 0x86: /* DSPDSoaxx */ + return (0x123456) & 0x00ffffff; +diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c +index e2cea0c..0ae3575 100644 +--- a/dlls/winedib.drv/text.c ++++ b/dlls/winedib.drv/text.c +@@ -25,19 +25,6 @@ + + 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 + */ +@@ -57,12 +44,17 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + LPCWSTR wstrPnt; + + FT_Glyph glyph; +- FT_BitmapGlyph bitmap; ++ FT_BitmapGlyph bitmapGlyph; ++ FT_Bitmap *bitmap, bitmap8; + double cosEsc, sinEsc; + FT_Matrix matrix; + FT_Vector start; + int dx, dy; + ++ RECT *r; ++ int iRec; ++ RECT clipRec; ++ DWORD backPixel; + + 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)); +@@ -94,114 +86,155 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + HeapFree(GetProcessHeap(), 0, str); + } + ++ /* gets background pixel value for opaque text */ ++ backPixel = physDev->backgroundColor; ++ + /* 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) ++ w = abs(lf.lfWidth); h = abs(lf.lfHeight); ++ _DIBDRV_Sizes_ws2ds(physDev, &w, &h); ++ ++ /* loop on all clip region rectangles */ ++ r = physDev->regionRects; ++ for(iRec = 0; iRec < physDev->regionRectCount; iRec++, r++) + { +- 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++; ++ /* if clipped on text rect, intersect with current region */ ++ if(flags & ETO_CLIPPED) ++ { ++ if(!_DIBDRV_IntersectRect(&clipRec, r, lprect)) ++ continue; ++ } + else +- glyph_index = pFT_Get_Char_Index( face, *wstrPnt++); ++ memcpy(&clipRec, r, sizeof(RECT)); ++ ++ /* if opaque, paint the font background */ ++ if(flags & ETO_OPAQUE) ++ { ++ int iLine; ++ RECT tr; ++ ++ /* clips text rectangle */ ++ if(_DIBDRV_IntersectRect(&tr, r, lprect)) ++ { ++ /* paints the backgound */ ++ for(iLine = tr.top; iLine < tr.bottom; iLine++) ++ physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, ++ tr.left, tr.right-1, iLine, 0, backPixel); ++ } ++ } + +- /* load glyph image into the slot (erase previous one) */ +- error = pFT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); ++ /* sets character pixel size */ ++ error = pFT_Set_Pixel_Sizes(face, w, h); + if(error) ++ ONCE(ERR("Couldn't set char size to (%d,%d), code %d\n", lf.lfWidth, lf.lfHeight, error)); ++ ++ /* transformation matrix and vector */ ++ start.x = 0; ++ start.y = 0; ++ if(lf.lfEscapement != 0) + { +- ERR("Couldn't load glyph at index %d\n", glyph_index); +- /* ignore errors */ +- continue; ++ cosEsc = cos(lf.lfEscapement * M_PI / 1800); ++ sinEsc = sin(lf.lfEscapement * M_PI / 1800); + } +- error = pFT_Get_Glyph(face->glyph, &glyph); +- if ( error ) ++ else + { +- FIXME("Couldn't get glyph\n"); +- continue; ++ cosEsc = 1; ++ sinEsc = 0; + } +- +- /* 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 ) ++ 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++ ) + { +- error = pFT_Glyph_To_Bitmap( +- &glyph, +- FT_RENDER_MODE_NORMAL, +- 0, /* no additional translation */ +- 1 /* destroy copy in "image" */ +- ); +- +- /* ignore errors */ +- if ( error ) ++ /* 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) + { +- FIXME("Couldn't render glyph\n"); +- pFT_Done_Glyph(glyph); ++ 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, ++ #ifdef DIBDRV_ANTIALIASED_FONTS ++ physDev->physBitmap.bitCount > 8 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, ++ #else ++ FT_RENDER_MODE_MONO, ++ #endif ++ 0, /* no additional translation */ ++ 1 /* destroy copy in "image" */ ++ ); ++ ++ /* ignore errors */ ++ if ( error ) ++ { ++ FIXME("Couldn't render glyph\n"); ++ pFT_Done_Glyph(glyph); ++ continue; ++ } ++ } ++ bitmapGlyph = (FT_BitmapGlyph)glyph; ++ ++ /* convert the bitmap in an 8bpp 1 byte aligned one if needed */ ++ bitmap = &bitmapGlyph->bitmap; ++ if(bitmap->pixel_mode != FT_PIXEL_MODE_GRAY) ++ { ++ pFT_Bitmap_New(&bitmap8); ++ if(pFT_Bitmap_Convert(glyph->library, bitmap, &bitmap8, 1)) ++ { ++ FIXME("Couldn't convert bitmap to 8 bit grayscale\n"); ++ pFT_Done_Glyph(glyph); ++ continue; ++ } ++ bitmap = &bitmap8; ++ } + +- /* now, draw to our target surface */ +- bitmap = (FT_BitmapGlyph)glyph; +- physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmap->left, y-bitmap->top, &bitmap->bitmap); ++ /* now, draw to our target surface */ ++ physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmapGlyph->left, y-bitmapGlyph->top, &clipRec, bitmap); ++ ++ /* frees converted bitmap, if any */ ++ if(bitmap != &bitmapGlyph->bitmap) ++ pFT_Bitmap_Done(glyph->library, bitmap); + +- /* increment pen position */ +- x += dx>>16; +- y -= dy>>16; ++ /* increment pen position */ ++ x += dx>>16; ++ y -= dy>>16; + +- pFT_Done_Glyph(glyph); +- +- res = TRUE; +- } ++ pFT_Done_Glyph(glyph); ++ ++ res = TRUE; ++ } ++ } /* end region rects loop */ + } + else + { diff --git a/app-emulation/wine/files/0009-dib-engine-fixes-against-wine-.patch b/app-emulation/wine/files/0009-dib-engine-fixes-against-wine-.patch new file mode 100644 index 00000000..b664aef8 --- /dev/null +++ b/app-emulation/wine/files/0009-dib-engine-fixes-against-wine-.patch @@ -0,0 +1,1695 @@ +DIB Engine: fixes against wine tests + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/bitblt.c | 68 +++--- + dlls/winedib.drv/convert.c | 16 + + dlls/winedib.drv/dc.c | 32 +-- + dlls/winedib.drv/dib.c | 405 ++++++++++++++++++++++++++++++++- + dlls/winedib.drv/dibdrv.h | 27 ++ + dlls/winedib.drv/dibdrvbitmap.c | 124 ++++++++++ + dlls/winedib.drv/graphics.c | 10 + + dlls/winedib.drv/palette.c | 63 +++++ + dlls/winedib.drv/pen_brush.c | 95 ++++++-- + dlls/winedib.drv/primitives_bitblt.c | 18 + + dlls/winedib.drv/primitives_color.c | 71 ++++-- + dlls/winedib.drv/primitives_convert.c | 66 ++++- + dlls/winedib.drv/primitives_pixel.c | 44 ++-- + 13 files changed, 883 insertions(+), 156 deletions(-) + + +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index db66142..97feefd 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -82,7 +82,7 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT* + ys1 = ps->y; + xs2 = xs1 + w; + ys2 = ys1 + h; +- ++ + /* if source clip area is not null, do first clipping on it */ + if(srcClip) + { +@@ -91,7 +91,7 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT* + ysc1 = srcClip->top; + xsc2 = srcClip->right; + ysc2 = srcClip->bottom; +- ++ + /* order clip area rectangle points */ + if(xsc1 > xsc2) intSwap(&xsc1, &xsc2); + if(ysc1 > ysc2) intSwap(&ysc1, &ysc2); +@@ -103,13 +103,12 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT* + /* clip on source clipping end point */ + if(xs2 > xsc2) { dx = xs2 - xsc2; w -= dx; xd2 -= dx; xs2 = xsc2; } + if(ys2 > ysc2) { dy = ys2 - ysc2; h -= dy; yd2 -= dy; ys2 = ysc2; } +- ++ + /* if already zero area, return false */ + if(w <= 0 || h <= 0) + return FALSE; + } + /* now do clipping on destination area */ +- + if(dstClip) + { + /* extract destination clipping area */ +@@ -117,7 +116,7 @@ static BOOL BitBlt_ClipAreas(POINT *ps, POINT *pd, SIZE *sz, RECT*srcClip, RECT* + ydc1 = dstClip->top; + xdc2 = dstClip->right; + ydc2 = dstClip->bottom; +- ++ + /* order clip area rectangle points */ + if(xdc1 > xdc2) intSwap(&xdc1, &xdc2); + if(ydc1 > ydc2) intSwap(&ydc1, &ydc2); +@@ -267,6 +266,13 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + _DIBDRV_Sizes_ws2ds(physDevDst, &widthDst, &heightDst); + _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc); + _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc); ++ ++ /* from tests, it seems that negative coords on phys space are not allowed */ ++ if(xDst < 0 || yDst < 0 || xSrc < 0 || ySrc < 0) ++ { ++ SetLastError(ERROR_INVALID_PARAMETER); ++ return FALSE; ++ } + + /* first clip on physical DC sizes */ + setPoint(&pd, xDst, yDst); +@@ -282,7 +288,7 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + else + res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip); + if(!res) +- return FALSE; ++ return TRUE; + xDst = pd.x; yDst = pd.y; + xSrc = ps.x; ySrc = ps.y; + widthDst = szDst.cx; heightDst = szDst.cy; +@@ -317,9 +323,7 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + BOOL res; + + POINT pd = {xDst, yDst}; +- POINT ps = {xSrc, ySrc}; + SIZE szDst = {widthDst, heightDst}; +- SIZE szSrc = {widthSrc, heightSrc}; + + MAYBE(TRACE("physDevDst:%p(%s%s), xDst:%d, yDst:%d, widthDst:%d, heightDst:%d, physDevSrc:%p(%s%s), xSrc:%d, ySrc:%d, widthSrc:%d, heightSrc:%d\n", + physDevDst, physDevDst->hasDIB ? "DIB-" : "DDB", physDevDst->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevDst->physBitmap) : "", +@@ -327,10 +331,12 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(&physDevSrc->physBitmap) : "", + xSrc, ySrc, widthSrc, heightSrc)); + +- /* if sizes are null or negative, returns false */ +- if(widthSrc <= 0 || heightSrc <= 0 || widthDst <= 0 || heightDst <= 0) ++ /* if sizes are null or negative, or source positions are negatives, returns false */ ++ if(widthSrc <= 0 || heightSrc <= 0 || ++ widthDst <= 0 || heightDst <= 0) + { + res = FALSE; ++ SetLastError(ERROR_INVALID_PARAMETER); + goto fin; + } + +@@ -360,18 +366,25 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + /* DDB selected on dest DC -- must double-convert */ + HBITMAP tmpDIB, stock; + HDC tmpDC; +- RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; + MAYBE(TRACE("Blending DIB->DDB\n")); + +- /* clip blit area */ +- res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0); +- if(!res) ++ /* we should anyways convert dest to physical coordinates here before processing ++ in order to check its consistency -- source coords will be converted/clipped later ++ As we do a conversion to a temporary DIB for destination, we don't care about it */ ++ _DIBDRV_Position_ws2ds(physDevDst, &pd.x, &pd.y); ++ _DIBDRV_Sizes_ws2ds(physDevDst, &szDst.cx, &szDst.cy); ++ ++ /* test shows that negatives origins are not allowed */ ++ if(pd.x < 0 || pd.y < 0) ++ { ++ SetLastError(ERROR_INVALID_PARAMETER); ++ res = FALSE; + goto fin; +- xDst = pd.x; yDst = pd.y; widthDst = szDst.cx; heightDst = szDst.cy; +- xSrc = ps.x; ySrc = ps.y; widthSrc = szSrc.cx; heightSrc = szSrc.cy; ++ } + + /* converts dest DDB onto a temporary DIB -- just the needed part */ +- tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, xDst, yDst, widthDst, heightDst); ++ /* WARNING -- that one could fail if rectangle on dest id out of range */ ++ tmpDIB = _DIBDRV_ConvertDevDDBtoDIB(physDevDst->hdc, physDevSrc->hdc, pd.x, pd.y, szDst.cx, szDst.cy); + if(!tmpDIB) + { + ERR("Couldn't convert dest DDB to DIB\n"); +@@ -399,7 +412,7 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + } + + /* blends source DIB onto temp DIB and re-blits onto dest DC */ +- res = GdiAlphaBlend(tmpDC, 0, 0, widthDst, heightDst, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn); ++ res = GdiAlphaBlend(tmpDC, 0, 0, szDst.cx, szDst.cy, physDevSrc->hdc, xSrc, ySrc, widthSrc, heightSrc, blendfn); + if(!res) + MAYBE(TRACE("AlphaBlend failed\n")); + else +@@ -438,6 +451,7 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setPoint(&ps, xSrc, ySrc); + setSize(&sz, width, height); + setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ + if(physDevSrc) + { + setRect(&srcClip, 0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height); +@@ -446,13 +460,13 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + else + res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip); + if(!res) +- return FALSE; ++ return TRUE; + xDst = pd.x; yDst = pd.y; + xSrc = ps.x; ySrc = ps.y; + width = sz.cx; height = sz.cy; + + /* then, do blitting for each dest clip area (no clipping on source) */ +- res = FALSE; ++ res = TRUE; + for(iRec = 0; iRec < physDevDst->regionRectCount; iRec++) + { + RECT *r = physDevDst->regionRects + iRec; +@@ -462,8 +476,8 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setSize(&sz, width, height); + if(!BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip)) + continue; +- if(physDevDst->physBitmap.funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop)) +- res = TRUE; ++ if(!physDevDst->physBitmap.funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop)) ++ res = FALSE; + } + return res; + } +@@ -503,8 +517,8 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + /* source is a DDB, must convert it to DIB */ + + /* don't clip on source */ +- res = BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip); +- if(!res) ++ res = !BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip); ++ if(res) + goto noBlt2; + xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y; + +@@ -596,11 +610,11 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + if(physDevSrc) + { + RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; +- res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0); ++ res = !BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0); + } + else +- res = TRUE; +- if(!res) ++ res = FALSE; ++ if(res) + goto noBlt3; + xDst = pd.x; yDst = pd.y; width = sz.cx; height = sz.cy; xSrc = ps.x; ySrc = ps.y; + +diff --git a/dlls/winedib.drv/convert.c b/dlls/winedib.drv/convert.c +index dc18e14..2f20ac1 100644 +--- a/dlls/winedib.drv/convert.c ++++ b/dlls/winedib.drv/convert.c +@@ -51,7 +51,7 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca + HDC tmpHdc; + HBITMAP tmpBmp; + int res; +- ++ + /* gets DIBSECTION data from source DIB */ + if(GetObjectW(srcBmp, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION)) + { +@@ -87,13 +87,10 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca + + /* gets the size of DIB palette and bitfields, if any */ + bitFields = 0; +- if(ds.dsBmih.biBitCount > 8) +- { +- colorUsed = 0; +- if(ds.dsBmih.biCompression == BI_BITFIELDS) ++ colorUsed = 0; ++ if(ds.dsBmih.biCompression == BI_BITFIELDS) + bitFields = 3; +- } +- else ++ else if(ds.dsBmih.biBitCount <= 8) + { + colorUsed = ds.dsBmih.biClrUsed; + if(!colorUsed) +@@ -131,9 +128,11 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca + HeapFree(GetProcessHeap(), 0, bmi); + return 0; + } +- GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors); ++ if(!GetDIBColorTable(tmpHdc, 0, colorUsed, bmi->bmiColors)) ++ ERR("GetDIBColorTable failed\n"); + SelectObject(tmpHdc, tmpBmp); + DeleteDC(tmpHdc); ++ + } + + /* fill the bitfields part, if any */ +@@ -165,6 +164,7 @@ HBITMAP _DIBDRV_ConvertDIBtoDDB( HDC hdc, HBITMAP srcBmp, int startScan, int sca + DeleteObject( hBmp ); + return 0; + } ++ + return hBmp; + } + +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +index 9ffceee..f5324b0 100644 +--- a/dlls/winedib.drv/dc.c ++++ b/dlls/winedib.drv/dc.c +@@ -80,6 +80,10 @@ static DWORD get_dpi( void ) + return dpi; + } + ++/* dummy function for pen/brush drawing primitives initializations */ ++static void dummy4(DIBDRVPHYSDEV *physDev, int a, int b, int c) {} ; ++static void dummy5(DIBDRVPHYSDEV *physDev, int a, int b, int c, int d) {} ; ++ + /********************************************************************** + * device_init + * +@@ -120,10 +124,6 @@ static void device_init(void) + device_init_done = TRUE; + } + +-/* dummy null function for pen and brush */ +-static void dummy3(DIBDRVPHYSDEV *p, int a, int b, int c) {} +-static void dummy4(DIBDRVPHYSDEV *p, int a, int b, int c, int d) {} +- + /********************************************************************** + * DIBDRV_CreateDC + */ +@@ -180,22 +180,24 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + physDev->backgroundColor = 0; + _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor); + ++ /* stock pen */ ++ physDev->penStyle = PS_NULL; + physDev->penColor = 0; ++ physDev->penColorref = 0; + _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor); +- +- physDev->penStyle = PS_NULL; +- physDev->penHLine = dummy3; +- physDev->penVLine = dummy3; +- physDev->penLine = dummy4; ++ physDev->penHLine = dummy4; ++ physDev->penVLine = dummy4; ++ physDev->penLine = dummy5; + physDev->penPattern = NULL; + +- physDev->brushColor = 0; +- _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor); ++ /* stock brush */ ++ physDev->brushStyle = BS_NULL; ++ physDev->brushColor = 0x0; ++ physDev->brushColorref = 0x0; ++ _DIBDRV_CalcAndXorMasks(physDev->rop2, 0x0, &physDev->brushAnd, &physDev->brushXor); + physDev->brushAnds = NULL; + physDev->brushXors = NULL; +- +- physDev->brushStyle = BS_NULL; +- physDev->brushHLine = dummy3; ++ physDev->brushHLine = dummy4; + + physDev->isBrushBitmap = FALSE; + _DIBDRVBITMAP_Clear(&physDev->brushBitmap); +@@ -215,7 +217,7 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + + /* sets the result value and returns */ + *pdev = physDev; +- ++ + return TRUE; + } + +diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c +index 653148d..41fb158 100644 +--- a/dlls/winedib.drv/dib.c ++++ b/dlls/winedib.drv/dib.c +@@ -25,6 +25,43 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++/* Default 1 BPP palette */ ++static DWORD pal1[] = ++{ ++ 0x000000, ++ 0xffffff ++}; ++ ++/* Default 4 BPP palette */ ++static DWORD pal4[] = ++{ ++ 0x000000,0x800000,0x008000,0x808000, ++ 0x000080,0x800080,0x008080,0x808080, ++ 0xc0c0c0,0xff0000,0x00ff00,0xffff00, ++ 0x0000ff,0xff00ff,0x00ffff,0xffffff ++}; ++ ++/* Default 8 BPP palette */ ++static DWORD pal8[] = ++{ ++ 0x000000,0x800000,0x008000,0x808000,0x000080,0x800080,0x008080,0xc0c0c0,0xc0dcc0,0xa6caf0,0x000000,0x000033,0x000066,0x000099,0x0000cc,0x0000ff, ++ 0x003300,0x003333,0x003366,0x003399,0x0033cc,0x0033ff,0x006600,0x006633,0x006666,0x006699,0x0066cc,0x0066ff,0x009900,0x009933,0x009966,0x009999, ++ 0x0099cc,0x0099ff,0x00cc00,0x00cc33,0x00cc66,0x00cc99,0x00cccc,0x00ccff,0x00ff00,0x00ff33,0x00ff66,0x00ff99,0x00ffcc,0x00ffff,0x330000,0x330033, ++ 0x330066,0x330099,0x3300cc,0x3300ff,0x333300,0x333333,0x333366,0x333399,0x3333cc,0x3333ff,0x336600,0x336633,0x336666,0x336699,0x3366cc,0x3366ff, ++ 0x339900,0x339933,0x339966,0x339999,0x3399cc,0x3399ff,0x33cc00,0x33cc33,0x33cc66,0x33cc99,0x33cccc,0x33ccff,0x33ff00,0x33ff33,0x33ff66,0x33ff99, ++ 0x33ffcc,0x33ffff,0x660000,0x660033,0x660066,0x660099,0x6600cc,0x6600ff,0x663300,0x663333,0x663366,0x663399,0x6633cc,0x6633ff,0x666600,0x666633, ++ 0x666666,0x666699,0x6666cc,0x6666ff,0x669900,0x669933,0x669966,0x669999,0x6699cc,0x6699ff,0x66cc00,0x66cc33,0x66cc66,0x66cc99,0x66cccc,0x66ccff, ++ 0x66ff00,0x66ff33,0x66ff66,0x66ff99,0x66ffcc,0x66ffff,0x990000,0x990033,0x990066,0x990099,0x9900cc,0x9900ff,0x993300,0x993333,0x993366,0x993399, ++ 0x9933cc,0x9933ff,0x996600,0x996633,0x996666,0x996699,0x9966cc,0x9966ff,0x999900,0x999933,0x999966,0x999999,0x9999cc,0x9999ff,0x99cc00,0x99cc33, ++ 0x99cc66,0x99cc99,0x99cccc,0x99ccff,0x99ff00,0x99ff33,0x99ff66,0x99ff99,0x99ffcc,0x99ffff,0xcc0000,0xcc0033,0xcc0066,0xcc0099,0xcc00cc,0xcc00ff, ++ 0xcc3300,0xcc3333,0xcc3366,0xcc3399,0xcc33cc,0xcc33ff,0xcc6600,0xcc6633,0xcc6666,0xcc6699,0xcc66cc,0xcc66ff,0xcc9900,0xcc9933,0xcc9966,0xcc9999, ++ 0xcc99cc,0xcc99ff,0xcccc00,0xcccc33,0xcccc66,0xcccc99,0xcccccc,0xccccff,0xccff00,0xccff33,0xccff66,0xccff99,0xccffcc,0xccffff,0xff0000,0xff0033, ++ 0xff0066,0xff0099,0xff00cc,0xff00ff,0xff3300,0xff3333,0xff3366,0xff3399,0xff33cc,0xff33ff,0xff6600,0xff6633,0xff6666,0xff6699,0xff66cc,0xff66ff, ++ 0xff9900,0xff9933,0xff9966,0xff9999,0xff99cc,0xff99ff,0xffcc00,0xffcc33,0xffcc66,0xffcc99,0xffcccc,0xffccff,0xffff00,0xffff33,0xffff66,0xffff99, ++ 0xffffcc,0xffffff,0x050500,0x050501,0x050502,0x050503,0x050504,0x050505,0xe8e8e8,0xe9e9e9,0xeaeaea,0xebebeb,0xececec,0xededed,0xeeeeee,0xefefef, ++ 0xf0f0f0,0xf1f1f1,0xf2f2f2,0xf3f3f3,0xf4f4f4,0xf5f5f5,0xfffbf0,0xa0a0a4,0x808080,0xf00000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00ffff,0xffffff ++}; ++ + /*********************************************************************** + * DIBDRV_CreateDIBSection + */ +@@ -46,15 +83,206 @@ HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, + * DIBDRV_GetDIBits + */ + INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, +- UINT lines, LPCVOID bits, const BITMAPINFO *bmi, UINT coloruse ) ++ UINT lines, LPVOID bits, BITMAPINFO *info, UINT coloruse ) + { + INT res; +- +- MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", +- physDev, hbitmap, startscan, lines, bits, bmi, coloruse)); ++ DIBSECTION ds; ++ DIBDRVBITMAP sBmp, dBmp; ++ DWORD *buf; ++ int iLine; ++ int size; ++ BOOL justInfo, justInfoHeader; ++ int requestedBpp; ++ RGBQUAD *colorTable; ++ int colorTableSize; ++ BITMAPINFO *sourceInfo; + +- /* GetDIBits reads bits from a DDB, so we should use the X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, bmi, coloruse); ++ MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", ++ physDev, hbitmap, startscan, lines, bits, info, coloruse)); ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION)) ++ { ++ /* GetDIBits reads bits from a DIB, so we should use the engine driver */ ++ ++ /* for the moment, we don't support startscan != 0 */ ++ if(startscan != 0) ++ { ++ FIXME("startscan != 0 still not supported\n"); ++ return 0; ++ } ++ ++ /* sanity check */ ++ size = info->bmiHeader.biSize; ++ if(size != sizeof(BITMAPINFOHEADER) && size != sizeof(BITMAPCOREHEADER)) ++ { ++ ERR("Unknown header size %d\n", size); ++ return 0; ++ } ++ ++ /* get requested BPP */ ++ requestedBpp = info->bmiHeader.biBitCount; ++ ++ /* check wetrher we wants just the BITMAPINFO data */ ++ justInfo = (bits == NULL); ++ ++ /* check wether we wants just to get BITMAPINFOHEADER data */ ++ justInfoHeader = (requestedBpp == 0); ++ ++ if(!justInfo && justInfoHeader) ++ { ++ ERR("Bad requested BPP\n"); ++ return 0; ++ } ++ ++ /* copy / set missing DIB info */ ++ if(justInfo) ++ { ++ info->bmiHeader.biWidth = ds.dsBmih.biWidth; ++ info->bmiHeader.biHeight = ds.dsBmih.biHeight; ++ } ++ info->bmiHeader.biPlanes = 1; ++ if(justInfoHeader) ++ info->bmiHeader.biBitCount = ds.dsBmih.biBitCount; ++ if(size == sizeof(BITMAPINFOHEADER)) ++ { ++ if(justInfoHeader) ++ { ++ info->bmiHeader.biCompression = ds.dsBmih.biCompression; ++ info->bmiHeader.biXPelsPerMeter = ds.dsBmih.biXPelsPerMeter; ++ info->bmiHeader.biYPelsPerMeter = ds.dsBmih.biYPelsPerMeter; ++ info->bmiHeader.biClrUsed = ds.dsBmih.biClrUsed; ++ info->bmiHeader.biClrImportant = ds.dsBmih.biClrImportant; ++ } ++ info->bmiHeader.biSizeImage = ds.dsBmih.biSizeImage; ++ } ++ ++ /* width and height *must* match source's ones */ ++ if(info->bmiHeader.biWidth != ds.dsBmih.biWidth || ++ abs(info->bmiHeader.biHeight) != abs(ds.dsBmih.biHeight)) ++ { ++ ERR("Size of requested bitmap data don't match source's ones\n"); ++ return 0; ++ } ++ ++ /* if we just wants the BITMAPINFOHEADER data, we're done */ ++ if(justInfoHeader || (justInfo && ds.dsBmih.biBitCount > 8)) ++ return abs(info->bmiHeader.biHeight); ++ ++ /* we now have to get source data -- we need it for palette, for example */ ++ colorTableSize = 0; ++ if(ds.dsBmih.biBitCount <= 8) ++ colorTableSize = (1 << ds.dsBmih.biBitCount); ++ else if(ds.dsBmih.biCompression == BI_BITFIELDS) ++ colorTableSize = 3; ++ sourceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + colorTableSize * sizeof(RGBQUAD)); ++ if(!sourceInfo) ++ { ++ ERR("HeapAlloc failed\n"); ++ return 0; ++ } ++ memcpy(sourceInfo, &ds.dsBmih, sizeof(BITMAPINFOHEADER)); ++ if(ds.dsBmih.biBitCount <= 8) ++ { ++ /* grab palette - well, we should. No way to do it by now.... ++ we should add a list HBITMAP <--> DIBDRVBITMAP and fiddle to many ++ , many parts of the engine. Not worth the effort by now. ++ So, we just synthesize the table */ ++ switch(requestedBpp) ++ { ++ case 1: ++ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal1, 2*sizeof(DWORD)); ++ break; ++ ++ case 4: ++ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal4, 16*sizeof(DWORD)); ++ break; ++ ++ case 8: ++ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal8, 256*sizeof(DWORD)); ++ break; ++ ++ default: ++ ERR("Unknown requested bith depth %d\n", requestedBpp); ++ _DIBDRVBITMAP_Free(&sBmp); ++ return 0; ++ } ++ } ++ else if(ds.dsBmih.biCompression == BI_BITFIELDS) ++ memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), ds.dsBitfields, 3 * sizeof(RGBQUAD)); ++ _DIBDRVBITMAP_Clear(&sBmp); ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, sourceInfo)) ++ { ++ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); ++ HeapFree(GetProcessHeap(), 0, sourceInfo); ++ return 0; ++ } ++ _DIBDRVBITMAP_Set_Bits(&sBmp, ds.dsBm.bmBits, FALSE); ++ HeapFree(GetProcessHeap(), 0, sourceInfo); ++ ++ /* now grab / synthesize the color table if needed */ ++ if(requestedBpp <= 8) ++ { ++ colorTable = (RGBQUAD *)((BYTE *)info + size); ++ if(requestedBpp == ds.dsBmih.biBitCount) ++ { ++ /* same source and dest format - copy color tables */ ++ memcpy(colorTable, sBmp.colorTable, colorTableSize); ++ } ++ else ++ { ++ /* different formats -- synthesize color table */ ++ switch(requestedBpp) ++ { ++ case 1: ++ memcpy(colorTable, pal1, 2*sizeof(DWORD)); ++ break; ++ ++ case 4: ++ memcpy(colorTable, pal4, 16*sizeof(DWORD)); ++ break; ++ ++ case 8: ++ memcpy(colorTable, pal8, 256*sizeof(DWORD)); ++ break; ++ ++ default: ++ ERR("Unknown requested bith depth %d\n", requestedBpp); ++ _DIBDRVBITMAP_Free(&sBmp); ++ return 0; ++ } ++ } ++ } ++ ++ /* if we just wanted DIB info, job is done */ ++ if(justInfo) ++ { ++ _DIBDRVBITMAP_Free(&sBmp); ++ return abs(info->bmiHeader.biHeight); ++ } ++ ++ /* Creates a DIBDRVBITMAP from dest dib */ ++ _DIBDRVBITMAP_Clear(&dBmp); ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&dBmp, info)) ++ { ++ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); ++ _DIBDRVBITMAP_Free(&sBmp); ++ return 0; ++ } ++ _DIBDRVBITMAP_Set_Bits(&dBmp, bits, FALSE); ++ ++ /* now we can do the bit conversion */ ++ buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD)); ++ for(iLine = 0; iLine < lines; iLine++) ++ { ++ sBmp.funcs->GetLine(&sBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ dBmp.funcs->PutLine(&dBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ } ++ _DIBDRVBITMAP_Free(&sBmp); ++ _DIBDRVBITMAP_Free(&dBmp); ++ return lines; ++ } ++ else ++ /* GetDIBits reads bits from a DDB, use X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pGetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse); + + return res; + } +@@ -66,7 +294,10 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + const RGBQUAD *colors ) + { + DIBDRVBITMAP *dib = &physDev->physBitmap; +- ++#if 0 ++ HBITMAP thisDIB; ++#endif ++ + MAYBE(TRACE("physDev:%p, start:%d, count:%d, colors:%p\n", physDev, start, count, colors)); + + /* SetDIBColorTable operates on a DIB, so we use the engine */ +@@ -80,7 +311,7 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + + /* if dib hasn't a color table, or has a small one, we must before + create/extend it */ +- if(!(dib->colorTable)) ++ if(!dib->colorTable) + { + dib->colorTableSize = (1 << dib->bitCount); + dib->colorTable = HeapAlloc(GetProcessHeap(), 0, sizeof(RGBQUAD) * dib->colorTableSize); +@@ -104,6 +335,13 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + memcpy(dib->colorTable + start, colors, sizeof(RGBQUAD) * count); + dib->colorTableGrabbed = TRUE; + ++ /* hack to make GDI32 sense the DIB color table change ++ (fixes a couple of todos in bitmap test suite */ ++#if 0 ++ thisDIB = SelectObject(physDev->hdc, GetStockObject(OBJ_BITMAP)); ++ SelectObject(physDev->hdc, thisDIB); ++#endif ++ + return TRUE; + } + +@@ -114,13 +352,59 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse ) + { + INT res; ++ DIBSECTION ds; ++ DIBDRVBITMAP sBmp, dBmp; ++ DWORD *buf; ++ int iLine; + + MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, bmi:%p, coloruse:%d\n", + physDev, hbitmap, startscan, lines, bits, info, coloruse)); + +- /* SetDIBits writes bits to a DDB, so we should use the X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse); + ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) == sizeof(DIBSECTION)) ++ { ++ /* SetDIBits writes bits to a DIB, so we should use the engine driver */ ++ ++ /* for the moment, we don't support startscan != 0 */ ++ if(startscan != 0) ++ { ++ FIXME("startscan != 0 still not supported\n"); ++ return 0; ++ } ++ ++ /* Creates a DIBDRVBITMAP from source dib */ ++ _DIBDRVBITMAP_Clear(&sBmp); ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, info)) ++ { ++ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); ++ return 0; ++ } ++ _DIBDRVBITMAP_Set_Bits(&sBmp, (LPVOID)bits, FALSE); ++ ++ /* same for destination dib */ ++ if(!_DIBDRVBITMAP_InitFromHBITMAP(&dBmp, hbitmap, FALSE)) ++ { ++ ERR("_DIBDRVBITMAP_InitFromHBITMAP failed\n"); ++ _DIBDRVBITMAP_Free(&sBmp); ++ return 0; ++ } ++ ++ /* now we can do the bit conversion */ ++ buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD)); ++ for(iLine = 0; iLine < lines; iLine++) ++ { ++ sBmp.funcs->GetLine(&sBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ dBmp.funcs->PutLine(&dBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ } ++ _DIBDRVBITMAP_Free(&sBmp); ++ _DIBDRVBITMAP_Free(&dBmp); ++ return lines; ++ } ++ else ++ { ++ /* SetDIBits writes bits to a DDB, so we should use the X11 driver */ ++ res = _DIBDRV_GetDisplayDriver()->pSetDIBits(physDev->X11PhysDev, hbitmap, startscan, lines, bits, info, coloruse); ++ } + return res; + } + +@@ -132,14 +416,105 @@ INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWOR + UINT startscan, UINT lines, LPCVOID bits, + const BITMAPINFO *info, UINT coloruse ) + { +- INT res; ++ BITMAPINFO *bitmapInfo; ++ int bmInfoSize; ++ int dibHeight, dibWidth; ++ DIBDRVBITMAP sBmp; ++ int sLine, dLine, iLine; ++ void *buf; + + MAYBE(TRACE("physDev:%p, xDest:%d, yDest:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", + physDev, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse)); + +- /* SetDIBitsToDevice operates on a physical device, so we should use the X11 driver */ +- res = _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, +- startscan, lines, bits, info, coloruse); ++ if(physDev->hasDIB) ++ { ++ /* DIB section selected in, use DIB Engine */ ++ ++ /* inverts y on source -- FIXME: check if right with some tests, it seems so */ ++ ySrc = abs(info->bmiHeader.biHeight) - ySrc - cy; ++ ++ dibHeight = info->bmiHeader.biHeight; ++ dibWidth = info->bmiHeader.biWidth; + +- return res; ++ /* sanity check and source clipping on physical sizes */ ++ if(startscan >= abs(dibHeight)) ++ return 0; ++ if(startscan + lines > abs(dibHeight)) ++ lines = abs(dibHeight) - startscan; ++ ++ /* adjust height because of startscan */ ++ dibHeight += (dibHeight > 0 ? -startscan : startscan); ++ ++ if(xSrc >= dibWidth) ++ return 0; ++ if(xSrc + cx > dibWidth) ++ cx = dibWidth - xSrc; ++ if(ySrc > abs(dibHeight)) ++ return 0; ++ if(ySrc + cy > abs(dibHeight)) ++ cy = abs(dibHeight) - ySrc; ++ ++ ySrc -= startscan; ++ cy -= startscan; ++ if(cy <= 0) ++ return 0; ++ if(ySrc < 0) ++ { ++ yDest += ySrc; ++ cy += ySrc; ++ ySrc = 0; ++ } ++ if(cy <= 0) ++ return 0; ++ ++ /* grab a copy of BITMAPINFO */ ++ bmInfoSize = sizeof(BITMAPINFOHEADER); ++ if(info->bmiHeader.biCompression == BI_BITFIELDS) ++ bmInfoSize += 3 * sizeof(RGBQUAD); ++ else if (info->bmiHeader.biBitCount <= 8) ++ { ++ if(info->bmiHeader.biClrUsed) ++ bmInfoSize += info->bmiHeader.biClrUsed * sizeof(RGBQUAD); ++ else ++ bmInfoSize += (1 << info->bmiHeader.biBitCount) * sizeof(RGBQUAD); ++ } ++ if(!(bitmapInfo = HeapAlloc(GetProcessHeap(), 0, bmInfoSize))) ++ { ++ ERR("HeapAlloc failed\n"); ++ return 0; ++ } ++ memcpy(bitmapInfo, info, bmInfoSize); ++ bitmapInfo->bmiHeader.biHeight = dibHeight; ++ ++ /* create a DIBDRVBITMAP from BITMAPINFO data */ ++ _DIBDRVBITMAP_Clear(&sBmp); ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, bitmapInfo)) ++ { ++ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); ++ HeapFree(GetProcessHeap, 0, bitmapInfo); ++ return 0; ++ } ++ HeapFree(GetProcessHeap(), 0, bitmapInfo); ++ _DIBDRVBITMAP_Set_Bits(&sBmp, (LPVOID)bits, FALSE); ++ ++ /* transfer lines to dest bitmap */ ++ if(!(buf = HeapAlloc(GetProcessHeap(), 0, cx * sizeof(RGBQUAD)))) ++ { ++ ERR("HeapAlloc failed\n"); ++ return 0; ++ } ++ for(sLine = ySrc, dLine = yDest, iLine = 0; iLine < cy; sLine++, dLine++, iLine++) ++ { ++ sBmp.funcs->GetLine(&sBmp, sLine, xSrc, cx, buf); ++ physDev->physBitmap.funcs->PutLine(&physDev->physBitmap, dLine, xDest, cx, buf); ++ } ++ HeapFree(GetProcessHeap(), 0, buf); ++ ++ return cy; ++ } ++ else ++ { ++ return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, ++ startscan, lines, bits, info, coloruse); ++ } + } +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index 66cc114..8243d4b 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -312,6 +312,11 @@ DWORD _DIBDRV_ROP3(DWORD p, DWORD s, DWORD d, BYTE rop); + /* gets human-readable dib format name */ + const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp); + ++/* sets/gets bits of a DIBDRVBITMAP taking in account if it's a top down ++ or a bottom-up DIB */ ++void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns); ++void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP *dib); ++ + /* initializes dib from a bitmap : + dib dib being initialized + bi source BITMAPINFOHEADER with required DIB format info +@@ -322,7 +327,7 @@ const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp); + BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, const DWORD *bit_fields, + const RGBQUAD *color_table, void *bits); + +-BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi); ++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi); + + /* initializes a DIBRDVBITMAP copying it from a source one + Parameters : +@@ -331,6 +336,13 @@ BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi); + copy TRUE->copy source pixel array FALSE->link to source pixel array */ + BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy); + ++/* initializes a DIBRDVBITMAP from a DIB HBITMAP ++ Parameters : ++ bmp destination DIBDRVBITMAP ++ hbmp source HBITMAP ++ copyPixels TRUE->copy source pixel array FALSE->link to source pixel array */ ++BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL copyPixels); ++ + /* creates a DIBRDVBITMAP copying format info from a source one + Parameters : + dib destination DIBDRVBITMAP +@@ -413,4 +425,17 @@ void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV *physDev, int *w, int *h); + /* converts a rectangle form Word space to Device space */ + void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV *physDev, const RECT *src, RECT *dst); + ++/* ********************************************************************* ++ * COLOR UTILITIES ++ * ********************************************************************/ ++ ++/* maps a colorref to actual color */ ++COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color); ++ ++/* gets nearest color index in DIB palette of a given colorref */ ++DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color); ++ ++/* gets nearest color to DIB palette color */ ++DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color); ++ + #endif +diff --git a/dlls/winedib.drv/dibdrvbitmap.c b/dlls/winedib.drv/dibdrvbitmap.c +index 2c8c367..8e6b653 100644 +--- a/dlls/winedib.drv/dibdrvbitmap.c ++++ b/dlls/winedib.drv/dibdrvbitmap.c +@@ -107,6 +107,41 @@ static void InitBitFields(DIBDRVBITMAP *dib, const DWORD *bit_fields) + CalcShiftAndLen(dib->blueMask, &dib->blueShift, &dib->blueLen); + } + ++/* sets/gets bits of a DIBDRVBITMAP taking in account if it's a top down ++ or a bottom-up DIB */ ++void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns) ++{ ++ /* checks whether dib is top-down or bottom-up one */ ++ if(dib->stride > 0) ++ { ++ /* top-down dib */ ++ dib->bits = bits; ++ } ++ else ++ { ++ /* bottom-up dib */ ++ /* data->bits always points to the top-left corner and the stride is -ve */ ++ dib->bits = (BYTE*)bits - (dib->height - 1) * dib->stride; ++ } ++ dib->ownsBits = owns; ++} ++ ++void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP * dib) ++{ ++ /* checks whether dib is top-down or bottom-up one */ ++ if(dib->stride > 0) ++ { ++ /* top-down dib */ ++ return dib->bits; ++ } ++ else ++ { ++ /* bottom-up dib */ ++ /* data->bits always points to the top-left corner and the stride is -ve */ ++ return (BYTE*)dib->bits + (dib->height - 1) * dib->stride; ++ } ++} ++ + /* initializes dib from a bitmap : + dib dib being initialized + bi source BITMAPINFOHEADER with required DIB format info +@@ -238,7 +273,7 @@ BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, c + return TRUE; + } + +-BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, BITMAPINFO *bmi) ++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi) + { + static const DWORD bit_fields_DIB32_RGB[3] = {0xff0000, 0x00ff00, 0x0000ff}; + static const DWORD bit_fields_DIB16_RGB[3] = {0x7c00, 0x03e0, 0x001f}; +@@ -343,6 +378,93 @@ BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *s + return TRUE; + } + ++/* initializes a DIBRDVBITMAP from a DIB HBITMAP ++ Parameters : ++ bmp destination DIBDRVBITMAP ++ hbmp source HBITMAP ++ copyPixels TRUE->copy source pixel array FALSE->link to source pixel array */ ++BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL copyPixels) ++{ ++ BITMAPINFO *destInfo; ++ DIBSECTION ds; ++ int size; ++ ++ MAYBE(TRACE("bmp=%p, hbmp=%p, copyPixels = %s\n", bmp, hbmp, copyPixels ? "TRUE" : "FALSE")); ++ ++ /* be sure bitmap is empty */ ++ _DIBDRVBITMAP_Clear(bmp); ++ ++ /* gets source bitmap data */ ++ if(!(size = GetObjectW(hbmp, sizeof(DIBSECTION), &ds))) ++ { ++ ERR("Failed getting bitmap object\n"); ++ return FALSE; ++ } ++ if(size != sizeof(DIBSECTION)) ++ { ++ ERR("Bitmap is not a DIB section\n"); ++ return FALSE; ++ } ++ ++ destInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); ++ if(!destInfo) ++ { ++ ERR("HeapAlloc failed\n"); ++ return FALSE; ++ } ++ ++ memcpy(destInfo, &ds.dsBmih, sizeof(BITMAPINFOHEADER)); ++ if(ds.dsBmih.biCompression == BI_BITFIELDS) ++ memcpy((BITMAPINFOHEADER *)destInfo + 1, ds.dsBitfields, 3 * sizeof(RGBQUAD)); ++ else if(ds.dsBmih.biBitCount <= 8) ++ { ++ FIXME("Can't grab color table here.... syslvel lock\n"); ++ return FALSE; ++#if 0 ++ HDC refDC = CreateCompatibleDC(0); ++ if(!refDC) ++ { ++ ERR("CreateCompatibleDC() failed\n"); ++ return FALSE; ++ } ++ if(!GetDIBits(refDC, hbmp, 0, 1, NULL, destInfo, DIB_RGB_COLORS)) ++ { ++ DeleteDC(refDC); ++ HeapFree(GetProcessHeap(), 0, destInfo); ++ ERR("GetDIBits failed\n"); ++ return FALSE; ++ } ++ DeleteDC(refDC); ++#endif ++ } ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(bmp, destInfo)) ++ { ++ HeapFree(GetProcessHeap(), 0, destInfo); ++ ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); ++ return FALSE; ++ } ++ HeapFree(GetProcessHeap(), 0, destInfo); ++ if(copyPixels) ++ { ++ size = abs(bmp->stride) * bmp->height; ++ if(!(bmp->bits = HeapAlloc(GetProcessHeap(), 0, size))) ++ { ++ ERR("HeapAlloc failed\n"); ++ _DIBDRVBITMAP_Free(bmp); ++ return FALSE; ++ } ++ memcpy(bmp->bits, ds.dsBm.bmBits, size); ++ bmp->ownsBits = TRUE; ++ } ++ else ++ bmp->bits = ds.dsBm.bmBits; ++ if(bmp->stride < 0) ++ bmp->bits = (BYTE*)bmp->bits - (bmp->height - 1) * bmp->stride; ++ ++ return TRUE; ++} ++ ++ + /* creates a DIBRDVBITMAP copying format info from a source one + Parameters : + dib destination DIBDRVBITMAP +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +index af264d0..4aebe8e 100644 +--- a/dlls/winedib.drv/graphics.c ++++ b/dlls/winedib.drv/graphics.c +@@ -132,7 +132,7 @@ static inline void SideIntersect(const POINT *p1, const POINT *p2, const RECT *r + break; + case TOP_SIDE: /* top */ + inters->x = MulDiv(p2->x - p1->x, r->top - p1->y, p2->y - p1->y) + p1->x; +- inters->y = r->bottom; ++ inters->y = r->top; + break; + case RIGHT_SIDE: /* right */ + inters->x = r->right - 1; +@@ -698,7 +698,7 @@ BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* ptw, int count ) + { + /* gets polygon bounding box -- for ytop and ybottom */ + PolygonBoundingBox(clipped, clippedCount, &bBox); +- ++ + /* gets all ordered intersections of polygon with + current scanline */ + for(ys = bBox.top; ys < bBox.bottom; ys++) +@@ -972,6 +972,12 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color ) + + if(physDev->hasDIB) + { ++ /* get real colorref */ ++ color = _DIBDRV_MapColor(physDev, color); ++ ++ /* map to pixel color / palette index */ ++ color = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color); ++ + _DIBDRV_Position_ws2ds(physDev, &x, &y); + + /* gets previous pixel */ +diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c +index a1aa648..87016da 100644 +--- a/dlls/winedib.drv/palette.c ++++ b/dlls/winedib.drv/palette.c +@@ -25,6 +25,69 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++/* maps a colorref to actual color */ ++COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color) ++{ ++ WORD index; ++ RGBQUAD *palColor; ++ HPALETTE hPal; ++ PALETTEENTRY paletteEntry; ++ ++ switch(color >> 24) ++ { ++ case 0x10 : /* DIBINDEX */ ++ MAYBE(TRACE("DIBINDEX Color is %08x\n", color)); ++ index = color & 0xffff; ++ if(index >= physDev->physBitmap.colorTableSize) ++ { ++ WARN("DIBINDEX color out of range\n"); ++ return 0; ++ } ++ palColor = physDev->physBitmap.colorTable + index; ++ MAYBE(TRACE("Returning color %08x\n", RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue))); ++ return RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue); ++ ++ case 0x01: /* PALETTEINDEX */ ++ MAYBE(TRACE("PALETTEINDEX Color is %08x\n", color)); ++ index = color & 0xffff; ++ if(!(hPal = GetCurrentObject(physDev->hdc, OBJ_PAL))) ++ { ++ ERR("Couldn't get palette\n"); ++ return 0; ++ } ++ if (!GetPaletteEntries(hPal, index, 1, &paletteEntry)) ++ { ++ WARN("PALETTEINDEX(%x) : index %d is out of bounds, assuming black\n", color, index); ++ return 0; ++ } ++ MAYBE(TRACE("Returning color %08x\n", RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue))); ++ return RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue); ++ ++ case 0x02: /* PALETTERGB */ ++ return _DIBDRV_GetNearestColor(&physDev->physBitmap, color & 0xffffff); ++ ++ default: ++ /* RGB color -- we must process special case for monochrome bitmaps */ ++ if(physDev->physBitmap.bitCount == 1) ++ { ++ RGBQUAD *back = physDev->physBitmap.colorTable; ++ RGBQUAD *fore = back+1; ++ if(fore->rgbRed * fore->rgbRed + fore->rgbGreen * fore->rgbGreen + fore->rgbBlue * fore->rgbBlue < ++ back->rgbRed * back->rgbRed + back->rgbGreen * back->rgbGreen + back->rgbBlue * back->rgbBlue) ++ { ++ fore = back; ++ back = fore + 1; ++ } ++ if ( ((color >> 16) & 0xff) + ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ++ return RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue); ++ else ++ return RGB(back->rgbRed, back->rgbGreen, back->rgbBlue); ++ } ++ else ++ return color; ++ } ++} ++ + /*********************************************************************** + * DIBDRV_RealizePalette + */ +diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c +index 7b15ece..c40bfaf 100644 +--- a/dlls/winedib.drv/pen_brush.c ++++ b/dlls/winedib.drv/pen_brush.c +@@ -51,7 +51,7 @@ static void SolidPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) + physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x1, x2, y, physDev->penAnd, physDev->penXor); + } + +-static void SolidPenVline(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) ++static void SolidPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) + { + OrderEndPoints(&y1, &y2); + physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y1, y2, physDev->penAnd, physDev->penXor); +@@ -65,7 +65,7 @@ static void WINAPI SolidPenLineCallback(int x, int y, LPARAM lparam) + return; + } + +-void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) ++static void SolidPenLine(DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2) + { + LineDDA(x1, y1, x2, y2, SolidPenLineCallback, (LPARAM)physDev); + } +@@ -216,22 +216,29 @@ void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev) + physDev->markSpace = mark; + } + +- ++#if 0 + /* For 1bpp bitmaps, unless the selected foreground color exactly + matches foreground's colortable OR it's the WHITE color, + the background color is used -- tested on WinXP */ + static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color) + { ++ RGBQUAD *back = physDev->physBitmap.colorTable; + RGBQUAD *fore = physDev->physBitmap.colorTable+1; + +- if((color & 0x00ffffff) == 0x00ffffff || +- ( +- fore->rgbRed == GetRValue(color) && +- fore->rgbGreen == GetGValue(color) && +- fore->rgbBlue == GetBValue(color) +- )) +- return 1; +- return 0; ++ if( ++ fore->rgbRed == GetRValue(color) && ++ fore->rgbGreen == GetGValue(color) && ++ fore->rgbBlue == GetBValue(color)) ++ return 1; ++ else if( ++ back->rgbRed == GetRValue(color) && ++ back->rgbGreen == GetGValue(color) && ++ back->rgbBlue == GetBValue(color)) ++ return 0; ++ else if((color & 0x00ffffff) == 0x00ffffff) ++ return 1; ++ else ++ return 0; + } + + static void FixupFgColors1(DIBDRVPHYSDEV *physDev) +@@ -248,6 +255,45 @@ static void FixupFgColors1(DIBDRVPHYSDEV *physDev) + physDev->brushAnds = NULL; + physDev->brushXors = NULL; + } ++#endif ++ ++#if 0 ++/* For 1bpp bitmaps, unless the selected foreground color exactly ++ matches one of the colors in the colortable, then the color that ++ isn't the bkgnd color is used. */ ++static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color) ++{ ++ RGBQUAD rgb; ++ int i; ++ ++ rgb.rgbRed = GetRValue(color); ++ rgb.rgbGreen = GetGValue(color); ++ rgb.rgbBlue = GetBValue(color); ++ ++ for(i = 0; i < physDev->physBitmap.colorTableSize; i++) ++ { ++ RGBQUAD *cur = physDev->physBitmap.colorTable + i; ++ if((rgb.rgbRed == cur->rgbRed) && (rgb.rgbGreen == cur->rgbGreen) && (rgb.rgbBlue == cur->rgbBlue)) ++ return i; ++ } ++ return ~physDev->backgroundColor & 1; ++} ++ ++static void FixupFgColors1(DIBDRVPHYSDEV *physDev) ++{ ++ int rop = GetROP2(physDev->hdc); ++ ++ physDev->penColor = AdjustFgColor(physDev, physDev->penColorref); ++ physDev->brushColor = AdjustFgColor(physDev, physDev->brushColorref); ++ ++ _DIBDRV_CalcAndXorMasks(rop, physDev->penColor, &physDev->penAnd, &physDev->penXor); ++ _DIBDRV_CalcAndXorMasks(rop, physDev->brushColor, &physDev->brushAnd, &physDev->brushXor); ++ HeapFree(GetProcessHeap(), 0, physDev->brushAnds); ++ HeapFree(GetProcessHeap(), 0, physDev->brushXors); ++ physDev->brushAnds = NULL; ++ physDev->brushXors = NULL; ++} ++#endif + + static void SolidBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) + { +@@ -310,23 +356,21 @@ HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) + { + GetObjectW(hpen, sizeof(logpen), &logpen); + +- physDev->penColorref = logpen.lopnColor; +- +- if(physDev->physBitmap.bitCount == 1) +- FixupFgColors1(physDev); +- else +- physDev->penColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, logpen.lopnColor); ++ physDev->penColorref = _DIBDRV_MapColor(physDev, logpen.lopnColor); ++ physDev->penColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->penColorref); + + _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), physDev->penColor, &physDev->penAnd, &physDev->penXor); + ++ physDev->penStyle = logpen.lopnStyle; + switch(logpen.lopnStyle) + { + default: + ONCE(FIXME("Unhandled pen style %d\n", logpen.lopnStyle)); ++ physDev->penStyle = PS_SOLID; + /* fall through */ + case PS_SOLID: + physDev->penHLine = SolidPenHLine; +- physDev->penVLine = SolidPenVline; ++ physDev->penVLine = SolidPenVLine; + physDev->penLine = SolidPenLine; + physDev->penPattern = NULL; + break; +@@ -415,16 +459,13 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + goto solid; + + case BS_SOLID: +- physDev->brushColorref = logbrush.lbColor; ++ physDev->brushColorref = _DIBDRV_MapColor(physDev, logbrush.lbColor); + solid: + MAYBE(TRACE("SOLID Pattern -- color is %x\n", physDev->brushColorref)); + physDev->brushStyle = BS_SOLID; + physDev->brushHLine = SolidBrushHLine; + +- if(physDev->physBitmap.bitCount == 1) +- FixupFgColors1(physDev); +- else +- physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, logbrush.lbColor); ++ physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->brushColorref); + + _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->brushColor, + &physDev->brushAnd, &physDev->brushXor); +@@ -496,8 +537,9 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + { + MAYBE(TRACE("NULL Pattern\n")); + physDev->brushColorref = 0; ++ physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, 0); + physDev->brushHLine = NullBrushHLine; +- goto solid; ++ break; + } + + case BS_PATTERN: +@@ -601,10 +643,9 @@ COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + + if(physDev->hasDIB) + { +- physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color); ++ physDev->backgroundColor = _DIBDRV_MapColor(physDev, color); ++ physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->backgroundColor); + +- if(physDev->physBitmap.bitCount == 1) +- FixupFgColors1(physDev); + _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor); + + res = TRUE; +diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c +index 7feeb49..27d573f 100644 +--- a/dlls/winedib.drv/primitives_bitblt.c ++++ b/dlls/winedib.drv/primitives_bitblt.c +@@ -25,6 +25,12 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + ++static inline COLORREF SwapColors(DWORD c) ++{ ++ return ((c & 0x0000ff) << 16) | (c & 0x00ff00) | ((c & 0xff0000) >> 16); ++ ++} ++ + /* shrinks a line -- srcWidth >= dstWidth */ + static void ShrinkLine(DWORD *dst, int dstWidth, DWORD *src, int srcWidth) + { +@@ -407,9 +413,11 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + srcBmp = NULL; + dstBmp = &physDevDst->physBitmap; + +- /* gets pattern color, in case it's needed */ ++ /* gets pattern color, in case it's needed ++ it's NOT the COLORREF value (colors are swapped ++ NOR the pixel value (it's applied to a 32 BPP BI_RGB */ + if(usePat) +- patColor = physDevDst->brushColor; ++ patColor = SwapColors(physDevDst->brushColorref); + else + patColor = 0; + +@@ -658,9 +666,11 @@ BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + srcBmp = NULL; + dstBmp = &physDevDst->physBitmap; + +- /* gets pattern color, in case it's needed */ ++ /* gets pattern color, in case it's needed ++ it's NOT the COLORREF value (colors are swapped ++ NOR the pixel value (it's applied to a 32 BPP BI_RGB */ + if(usePat) +- patColor = physDevDst->brushColor; ++ patColor = SwapColors(physDevDst->brushColorref); + else + patColor = 0; + +diff --git a/dlls/winedib.drv/primitives_color.c b/dlls/winedib.drv/primitives_color.c +index 3ccc2e0..6c42b44 100644 +--- a/dlls/winedib.drv/primitives_color.c ++++ b/dlls/winedib.drv/primitives_color.c +@@ -94,31 +94,30 @@ DWORD _DIBDRV_ColorToPixel16_BITFIELDS(const DIBDRVBITMAP *dib, COLORREF color) + PutField16(b, dib->blueShift, dib->blueLen); + } + +-DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color) ++/* gets nearest color to DIB palette color */ ++DWORD _DIBDRV_GetNearestColor(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ RGBQUAD *c; ++ ++ if(dib->bitCount > 8) ++ return color; ++ ++ c = dib->colorTable + _DIBDRV_GetNearestColorIndex(dib, color); ++ return RGB(c->rgbRed, c->rgbGreen, c->rgbBlue); ++ ++} ++ ++/* gets nearest color index in DIB palette of a given colorref */ ++DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color) + { +- int i, best_index = 0; + DWORD r, g, b; ++ int i, best_index = 0; + DWORD diff, best_diff = 0xffffffff; +- ++ + r = GetRValue(color); + g = GetGValue(color); + b = GetBValue(color); + +- /* just in case it's being called without color table +- properly initialized */ +- if(!dib->colorTableGrabbed) +- return 0; +- +- /* for monochrome bitmaps, color is background +- if not matching foreground */ +- if(dib->colorTableSize == 2) +- { +- RGBQUAD *fore = dib->colorTable + 1; +- if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue) +- return 1; +- return 0; +- } +- + for(i = 0; i < dib->colorTableSize; i++) + { + RGBQUAD *cur = dib->colorTable + i; +@@ -140,3 +139,39 @@ DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color) + } + return best_index; + } ++ ++DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color) ++{ ++ DWORD r, g, b; ++ ++ r = GetRValue(color); ++ g = GetGValue(color); ++ b = GetBValue(color); ++ ++ /* just in case it's being called without color table ++ properly initialized */ ++ if(!dib->colorTableGrabbed) ++ return 0; ++ ++ /* for monochrome bitmaps, color is : ++ foreground if matching foreground ctable ++ else background if matching background ctable ++ else foreground ix 0xffffff ++ else background */ ++ if(dib->colorTableSize == 2) ++ { ++ RGBQUAD *back = dib->colorTable; ++ RGBQUAD *fore = dib->colorTable + 1; ++ if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue) ++ return 1; ++ else if(r == back->rgbRed && g == back->rgbGreen && b == back->rgbBlue) ++ return 0; ++ if((color & 0xffffff) == 0xffffff) ++ return 1; ++ else ++ return 0; ++ } ++ ++ /* otherwise looks for nearest color in palette */ ++ return _DIBDRV_GetNearestColorIndex(dib, color); ++} +diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c +index f8f87ce..24a5e77 100644 +--- a/dlls/winedib.drv/primitives_convert.c ++++ b/dlls/winedib.drv/primitives_convert.c +@@ -31,6 +31,33 @@ static inline COLORREF SwapColors(DWORD c) + + } + ++static inline DWORD PlaceField32(BYTE c, int shift, int len) ++{ ++ DWORD res = c; ++ if(len < 8) ++ res >>= (8 - len); ++ else ++ res <<= (len - 8); ++ return res << shift; ++} ++ ++static inline WORD PlaceField16(BYTE c, int shift, int len) ++{ ++ WORD res = c; ++ if(len < 8) ++ res >>= (8 - len); ++ else ++ res <<= (len - 8); ++ return res << shift; ++} ++ ++static inline BYTE GetField32(DWORD dwColor, int shift, int len) ++{ ++ dwColor = dwColor & (((1 << (len)) - 1) << shift); ++ dwColor = dwColor << (32 - (shift + len)) >> 24; ++ return dwColor; ++} ++ + /* ----------------------------------------------------------------*/ + /* CONVERT PRIMITIVES */ + /* converts (part of) line of any DIB format from/to DIB32_RGB one */ +@@ -63,7 +90,7 @@ BOOL _DIBDRV_GetLine32_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int wi + + BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, void *buf) + { +- BYTE *bBuf = (BYTE *)buf; ++ DWORD *dwBuf = (DWORD *)buf; + DWORD *src; + + #ifdef DIBDRV_CHECK_RANGES +@@ -85,10 +112,10 @@ BOOL _DIBDRV_GetLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, + src = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx); + for(; width ; width--) + { +- *bBuf++ = (*src & bmp->blueMask ) >> bmp->blueShift; +- *bBuf++ = (*src & bmp->greenMask) >> bmp->greenShift; +- *bBuf++ = (*src & bmp->redMask ) >> bmp->redShift; +- *bBuf++ = 0x0; ++ *dwBuf++ = ++ GetField32(*src, bmp->redShift , bmp->redLen ) << 16 | ++ GetField32(*src, bmp->greenShift, bmp->greenLen) << 8 | ++ GetField32(*src, bmp->blueShift , bmp->blueLen ); + src++; + } + return TRUE; +@@ -184,6 +211,7 @@ BOOL _DIBDRV_GetLine16_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, + for(; width ; width--) + { + b = *src++; ++ + *dwBuf++ =((( b & bmp->blueMask) >> bmp->blueShift ) << ( 8 - bmp->blueLen )) | + (((b & bmp->greenMask) >> bmp->greenShift) << (16 - bmp->greenLen)) | + (((b & bmp->redMask ) >> bmp->redShift ) << (24 - bmp->redLen )); +@@ -350,14 +378,14 @@ BOOL _DIBDRV_PutLine32_BITFIELDS(const DIBDRVBITMAP *bmp, INT line, INT startx, + { + DWORD *dwBuf = (DWORD *)buf; + DWORD *dst = (DWORD *)((BYTE *)bmp->bits + line * bmp->stride + 4 * startx); +- DWORD c; ++ RGBQUAD *c; + for(; width; width--) + { +- c = *dwBuf++; ++ c = (RGBQUAD *)dwBuf++; + *dst++ = +- ((( c & 0x000000ff) << bmp->blueShift) & bmp->blueMask) | +- ((((c & 0x0000ff00) >> 8) << bmp->greenShift) & bmp->greenMask) | +- ((((c & 0x00ff0000) >> 16) << bmp->redShift) & bmp->redMask); ++ PlaceField32(c->rgbRed , bmp->redShift , bmp->redLen ) | ++ PlaceField32(c->rgbGreen, bmp->greenShift, bmp->greenLen) | ++ PlaceField32(c->rgbBlue , bmp->blueShift , bmp->blueLen ); + } + return TRUE; + } +@@ -386,6 +414,7 @@ BOOL _DIBDRV_PutLine16_RGB(const DIBDRVBITMAP *bmp, INT line, INT startx, int wi + { + c = *dwBuf++; + *dst++ = ++ /* 0RRR|RRGG|GGGB|BBBB */ + ((c & 0x000000f8) >> 3) | + ((c & 0x0000f800) >> 6) | + ((c & 0x00f80000) >> 9); +@@ -506,8 +535,9 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + DWORD c; + + /* get foreground color */ ++ DWORD back = *(DWORD *)bmp->colorTable & 0x00ffffff; + DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff; +- ++ + /* put first partial byte, if any */ + startx &= 0x07; + mask = 0x80 >> startx; +@@ -519,7 +549,11 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + while(startx--) + { + c = *dwBuf++ & 0x00ffffff; +- if(c == 0x00ffffff || c == fore) ++ if(c == fore) ++ b |= mask; ++ else if(c == back) ++ b &= !mask; ++ else if(c == 0x00ffffff) + b |= mask; + else + b &= !mask; +@@ -536,7 +570,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + for(i = 0 ; i < 8 ; i++) + { + c = *dwBuf++ & 0x00ffffff; +- if(c == 0x00ffffff || c == fore) ++ if(c == fore || (c == 0x00ffffff && c != back)) + b |= mask; + mask >>= 1; + } +@@ -551,7 +585,11 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + while(width--) + { + c = *dwBuf++ & 0x00ffffff; +- if(c == 0x00ffffff || c == fore) ++ if(c == fore) ++ b |= mask; ++ else if(c == back) ++ b &= !mask; ++ else if(c == 0x00ffffff) + b |= mask; + else + b &= !mask; +diff --git a/dlls/winedib.drv/primitives_pixel.c b/dlls/winedib.drv/primitives_pixel.c +index ca68cf1..78e68c7 100644 +--- a/dlls/winedib.drv/primitives_pixel.c ++++ b/dlls/winedib.drv/primitives_pixel.c +@@ -25,24 +25,15 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); + +- + /* ------------------------------------------------------------*/ + /* BITFIELD HELPERS */ +-static DWORD GetField32 (DWORD pixel, int shift, int len) ++static inline DWORD GetField32 (DWORD pixel, int shift, int len) + { + pixel = pixel & (((1 << (len)) - 1) << shift); + pixel = pixel << (32 - (shift + len)) >> 24; + return pixel; + } + +-static WORD GetField16 (WORD pixel, int shift, int len) +-{ +- FIXME("TODO\n"); +- return 0; +-} +- +- +- + /* ------------------------------------------------------------*/ + /* PIXEL POINTER READING */ + void *_DIBDRV_GetPixelPointer32(const DIBDRVBITMAP *dib, int x, int y) +@@ -174,45 +165,50 @@ void _DIBDRV_SetPixel1(DIBDRVBITMAP *dib, int x, int y, DWORD and, DWORD xor) + /* PIXEL READING */ + DWORD _DIBDRV_GetPixel32_RGB(const DIBDRVBITMAP *dib, int x, int y) + { +- DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); +- return *ptr; ++ DWORD c = *(DWORD *)dib->funcs->GetPixelPointer(dib, x, y); ++ return ++ ((c & 0x000000ff) << 16) | ++ ((c & 0x0000ff00) ) | ++ ((c & 0x00ff0000) >> 16) | ++ ( c & 0xff000000 ); /* last one for alpha channel */ + } + + DWORD _DIBDRV_GetPixel32_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y) + { + DWORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); + +- return GetField32(*ptr, dib->redShift, dib->redLen) << 16 | ++ return GetField32(*ptr, dib->redShift, dib->redLen) | + GetField32(*ptr, dib->greenShift, dib->greenLen) << 8 | +- GetField32(*ptr, dib->blueShift, dib->blueLen); ++ GetField32(*ptr, dib->blueShift, dib->blueLen) << 16; + } + + DWORD _DIBDRV_GetPixel24(const DIBDRVBITMAP *dib, int x, int y) + { + BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); +- return (ptr[0] << 16) | (ptr[1] << 8) | ptr[2]; ++ return ((WORD)ptr[0] << 16) | ((WORD)ptr[1] << 8) | (WORD)ptr[2]; + } + + DWORD _DIBDRV_GetPixel16_RGB(const DIBDRVBITMAP *dib, int x, int y) + { +- WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); +- return ((*ptr & 0x7c00) << 9) | ((*ptr & 0x03e0) << 6) | ((*ptr & 0x001f) << 3); ++ WORD c = *(WORD *)dib->funcs->GetPixelPointer(dib, x, y); ++ /* 0RRR|RRGG|GGGB|BBBB */ ++ return ((c & 0x7c00) >> 7) | ((c & 0x03e0) << 6) | ((c & 0x001f) << 19); + } + + DWORD _DIBDRV_GetPixel16_BITFIELDS(const DIBDRVBITMAP *dib, int x, int y) + { +- WORD *ptr = dib->funcs->GetPixelPointer(dib, x, y); ++ WORD c = *(WORD *)dib->funcs->GetPixelPointer(dib, x, y); + +- return GetField16(*ptr, dib->redShift, dib->redLen) << 16 | +- GetField16(*ptr, dib->greenShift, dib->greenLen) << 8 | +- GetField16(*ptr, dib->blueShift, dib->blueLen); ++ return (((c & dib->blueMask ) >> dib->blueShift ) << (24 - dib->blueLen )) | ++ (((c & dib->greenMask) >> dib->greenShift) << (16 - dib->greenLen)) | ++ (((c & dib->redMask ) >> dib->redShift ) << ( 8 - dib->redLen )); + } + + DWORD _DIBDRV_GetPixel8(const DIBDRVBITMAP *dib, int x, int y) + { + BYTE *ptr = dib->funcs->GetPixelPointer(dib, x, y); + RGBQUAD *color = dib->colorTable + *ptr; +- return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue; ++ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16); + } + + DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y) +@@ -226,7 +222,7 @@ DWORD _DIBDRV_GetPixel4(const DIBDRVBITMAP *dib, int x, int y) + pix = *ptr >> 4; + + color = dib->colorTable + pix; +- return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue; ++ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16); + } + + DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y) +@@ -240,5 +236,5 @@ DWORD _DIBDRV_GetPixel1(const DIBDRVBITMAP *dib, int x, int y) + pix &= 1; + + color = dib->colorTable + pix; +- return (color->rgbRed << 16) | (color->rgbGreen << 8) | color->rgbBlue; ++ return (color->rgbRed) | (color->rgbGreen << 8) | (color->rgbBlue << 16); + } diff --git a/app-emulation/wine/files/0010-dib-engine-introduction-of-bit.patch b/app-emulation/wine/files/0010-dib-engine-introduction-of-bit.patch new file mode 100644 index 00000000..733d6030 --- /dev/null +++ b/app-emulation/wine/files/0010-dib-engine-introduction-of-bit.patch @@ -0,0 +1,2103 @@ +DIB Engine: introduction of bitmaplist structure + +From: Massimo Del Fedele + + +--- + + dlls/winedib.drv/Makefile.in | 3 + dlls/winedib.drv/bitblt.c | 44 ++-- + dlls/winedib.drv/bitmap.c | 54 +++--- + dlls/winedib.drv/bitmaplist.c | 168 +++++++++++++++++ + dlls/winedib.drv/dc.c | 20 +- + dlls/winedib.drv/dib.c | 323 +++++++++++++-------------------- + dlls/winedib.drv/dibdrv.h | 55 ++++-- + dlls/winedib.drv/dibdrv_main.c | 6 + + dlls/winedib.drv/dibdrvbitmap.c | 211 ++++++++++++---------- + dlls/winedib.drv/font.c | 4 + dlls/winedib.drv/graphics.c | 8 - + dlls/winedib.drv/palette.c | 56 ++++-- + dlls/winedib.drv/pen_brush.c | 66 ++++--- + dlls/winedib.drv/primitives_bitblt.c | 16 +- + dlls/winedib.drv/primitives_color.c | 20 +- + dlls/winedib.drv/primitives_convert.c | 9 + + dlls/winedib.drv/primitives_font.c | 18 +- + dlls/winedib.drv/text.c | 6 - + 18 files changed, 639 insertions(+), 448 deletions(-) + create mode 100644 dlls/winedib.drv/bitmaplist.c + + +diff --git a/dlls/winedib.drv/Makefile.in b/dlls/winedib.drv/Makefile.in +index 722785e..a29edf0 100644 +--- a/dlls/winedib.drv/Makefile.in ++++ b/dlls/winedib.drv/Makefile.in +@@ -3,13 +3,14 @@ TOPOBJDIR = ../.. + SRCDIR = @srcdir@ + VPATH = @srcdir@ + EXTRAINCL = @FREETYPEINCL@ @FONTCONFIGINCL@ +-EXTRALIBS = @XLIB@ ++EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ + MODULE = winedib.drv + IMPORTS = user32 gdi32 advapi32 kernel32 ntdll + + C_SRCS = \ + bitblt.c \ + bitmap.c \ ++ bitmaplist.c \ + clipping.c \ + convert.c \ + dc.c \ +diff --git a/dlls/winedib.drv/bitblt.c b/dlls/winedib.drv/bitblt.c +index 97feefd..3a987bd 100644 +--- a/dlls/winedib.drv/bitblt.c ++++ b/dlls/winedib.drv/bitblt.c +@@ -267,8 +267,12 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + _DIBDRV_Position_ws2ds(physDevSrc, &xSrc, &ySrc); + _DIBDRV_Sizes_ws2ds(physDevSrc, &widthSrc, &heightSrc); + +- /* from tests, it seems that negative coords on phys space are not allowed */ +- if(xDst < 0 || yDst < 0 || xSrc < 0 || ySrc < 0) ++ /* from tests, it seems that coords out of phys spaces are not allowed */ ++ if(xDst < 0 || yDst < 0 || xSrc < 0 || ySrc < 0 || ++ xDst + widthDst > physDevDst->physBitmap->width || ++ yDst + heightDst > physDevDst->physBitmap->height || ++ xSrc + widthSrc > physDevSrc->physBitmap->width || ++ ySrc + heightSrc > physDevSrc->physBitmap->height) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; +@@ -279,10 +283,10 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setPoint(&ps, xSrc, ySrc); + setSize(&szDst, widthDst, heightDst); + setSize(&szSrc, widthSrc, heightSrc); +- setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ setRect(&dstClip, 0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height); + if(physDevSrc) + { +- setRect(&srcClip, 0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height); ++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height); + res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip); + } + else +@@ -306,7 +310,7 @@ BOOL _DIBDRV_InternalAlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setSize(&szSrc, widthSrc, heightSrc); + if(!StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip)) + continue; +- if(physDevDst->physBitmap.funcs->AlphaBlend(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy, ++ if(physDevDst->physBitmap->funcs->AlphaBlend(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy, + physDevSrc, ps.x, ps.y, szSrc.cx, szSrc.cy, blendfn)) + res = TRUE; + } +@@ -326,9 +330,9 @@ BOOL DIBDRV_AlphaBlend( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, INT width + SIZE szDst = {widthDst, heightDst}; + + 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) : "", ++ 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) : "", ++ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevSrc->physBitmap) : "", + xSrc, ySrc, widthSrc, heightSrc)); + + /* if sizes are null or negative, or source positions are negatives, returns false */ +@@ -450,11 +454,11 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setPoint(&pd, xDst, yDst); + setPoint(&ps, xSrc, ySrc); + setSize(&sz, width, height); +- setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ setRect(&dstClip, 0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height); + + if(physDevSrc) + { +- setRect(&srcClip, 0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height); ++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height); + res = BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, &dstClip); + } + else +@@ -476,7 +480,7 @@ BOOL _DIBDRV_InternalBitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setSize(&sz, width, height); + if(!BitBlt_ClipAreas(&ps, &pd, &sz, 0, &dstClip)) + continue; +- if(!physDevDst->physBitmap.funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop)) ++ if(!physDevDst->physBitmap->funcs->BitBlt(physDevDst, pd.x, pd.y, sz.cx, sz.cy, physDevSrc, ps.x, ps.y, rop)) + res = FALSE; + } + return res; +@@ -496,16 +500,16 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + SIZE sz = {width, height}; + + 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) : "", ++ 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) : "", ++ physDevSrc, physDevSrc ? (physDevSrc->hasDIB ? "DIB-" : "DDB"): "---", physDevSrc && physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevSrc->physBitmap) : "", + xSrc, ySrc, rop)); + + if(physDevDst->hasDIB) + { + /* DIB section selected in dest DC, use DIB Engine */ + /* clip blit area */ +- RECT dstClip = {0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height}; ++ RECT dstClip = {0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height}; + + if(!physDevSrc || physDevSrc->hasDIB) + { +@@ -609,7 +613,7 @@ BOOL DIBDRV_BitBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + /* clip blit area */ + if(physDevSrc) + { +- RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; ++ RECT srcClip = {0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height}; + res = !BitBlt_ClipAreas(&ps, &pd, &sz, &srcClip, 0); + } + else +@@ -672,10 +676,10 @@ BOOL _DIBDRV_InternalStretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setPoint(&ps, xSrc, ySrc); + setSize(&szDst, widthDst, heightDst); + setSize(&szSrc, widthSrc, heightSrc); +- setRect(&dstClip, 0, 0, physDevDst->physBitmap.width, physDevDst->physBitmap.height); ++ setRect(&dstClip, 0, 0, physDevDst->physBitmap->width, physDevDst->physBitmap->height); + if(physDevSrc) + { +- setRect(&srcClip, 0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height); ++ setRect(&srcClip, 0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height); + res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, &dstClip); + } + else +@@ -699,7 +703,7 @@ BOOL _DIBDRV_InternalStretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + setSize(&szSrc, widthSrc, heightSrc); + if(!StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, 0, &dstClip)) + continue; +- if(physDevDst->physBitmap.funcs->StretchBlt(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy, ++ if(physDevDst->physBitmap->funcs->StretchBlt(physDevDst, pd.x, pd.y, szDst.cx, szDst.cy, + physDevSrc, ps.x, ps.y, szSrc.cx, szSrc.cy, rop)) + res = TRUE; + } +@@ -727,9 +731,9 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + 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) : "", ++ 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) : "", ++ physDevSrc, physDevSrc->hasDIB ? "DIB-" : "DDB", physDevSrc->hasDIB ? _DIBDRVBITMAP_GetFormatName(physDevSrc->physBitmap) : "", + xSrc, ySrc, widthSrc, heightSrc, rop)); + + if(physDevDst->hasDIB) +@@ -833,7 +837,7 @@ BOOL DIBDRV_StretchBlt( DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + /* clip blit area */ + if(physDevSrc) + { +- RECT srcClip = {0, 0, physDevSrc->physBitmap.width, physDevSrc->physBitmap.height}; ++ RECT srcClip = {0, 0, physDevSrc->physBitmap->width, physDevSrc->physBitmap->height}; + res = StretchBlt_ClipAreas(&ps, &pd, &szSrc, &szDst, &srcClip, 0); + } + else +diff --git a/dlls/winedib.drv/bitmap.c b/dlls/winedib.drv/bitmap.c +index f3d3b9c..1562137 100644 +--- a/dlls/winedib.drv/bitmap.c ++++ b/dlls/winedib.drv/bitmap.c +@@ -34,13 +34,15 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) + DIBSECTION dibSection; + HBITMAP res; + ++ MAYBE(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)) ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) != sizeof(DIBSECTION)) + { + /* not a DIB section, sets it on physDev and use X11 behaviour */ + +- MAYBE(TRACE("physDev:%p, hbitmap:%p\n", physDev, hbitmap)); + physDev->hasDIB = FALSE; ++ physDev->physBitmap = NULL; + res = _DIBDRV_GetDisplayDriver()->pSelectBitmap(physDev->X11PhysDev, hbitmap); + if(res) + physDev->hbitmap = hbitmap; +@@ -49,32 +51,23 @@ HBITMAP DIBDRV_SelectBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap ) + { + /* it's a DIB section, sets it on physDev and use DIB Engine behaviour */ + +- 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)) ++ /* sets the physical bitmap */ ++ if((physDev->physBitmap = _BITMAPLIST_Get(hbitmap)) != NULL) + { +- /* stores the active bitmap */ +- res = physDev->hbitmap; +- physDev->hbitmap = hbitmap; +- +- /* remember there's a DIB selected in */ + physDev->hasDIB = TRUE; ++ physDev->hbitmap = hbitmap; ++ MAYBE(TRACE("physDev->physBitmap:%p(%s)\n", physDev->physBitmap, _DIBDRVBITMAP_GetFormatName(physDev->physBitmap))); ++ res = hbitmap; + } + else + { +- ERR("Failed to initialize physical bitmap\n"); ++ ERR("Physical bitmap %p not found in internal list\n", hbitmap); ++ physDev->hbitmap = GetStockObject(DEFAULT_BITMAP); ++ physDev->hasDIB = FALSE; + res = 0; + } + } + return res; +- + } + + /**************************************************************************** +@@ -96,7 +89,7 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits + else + { + /* 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")); ++ ERR("CreateBitmap() called for a DIB section - shouldn't happen\n"); + res = TRUE; + } + return res; +@@ -108,12 +101,13 @@ BOOL DIBDRV_CreateBitmap( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, LPVOID bmBits + BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) + { + DIBSECTION dibSection; ++ DIBDRVBITMAP *bmp; + BOOL res; + + MAYBE(TRACE("hbitmap:%p\n", hbitmap)); + + /* try to get the DIBSECTION data from the bitmap */ +- if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) == sizeof(BITMAP)) ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &dibSection) != sizeof(DIBSECTION)) + { + /* not a DIB section, use X11 behaviour */ + res = _DIBDRV_GetDisplayDriver()->pDeleteBitmap(hbitmap); +@@ -121,8 +115,22 @@ BOOL DIBDRV_DeleteBitmap( HBITMAP hbitmap ) + else + { + /* it's a DIB section, use DIB Engine behaviour */ +- ONCE(FIXME("STUB\n")); +- res = TRUE; ++ ++ /* do not try to delete stock objects */ ++ if(hbitmap == GetStockObject(DEFAULT_BITMAP)) ++ res = TRUE; ++ ++ /* locates and frees the physical bitmap */ ++ else if((bmp = _BITMAPLIST_Remove(hbitmap)) != NULL) ++ { ++ _DIBDRVBITMAP_Free(bmp); ++ res = TRUE; ++ } ++ else ++ { ++ ERR("Physical bitmap %p not found in internal list\n", hbitmap); ++ res = FALSE; ++ } + } + return res; + } +diff --git a/dlls/winedib.drv/bitmaplist.c b/dlls/winedib.drv/bitmaplist.c +new file mode 100644 +index 0000000..455f36a +--- /dev/null ++++ b/dlls/winedib.drv/bitmaplist.c +@@ -0,0 +1,168 @@ ++/* ++ * DIBDRV in-memory bitmap list ++ * ++ * 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 ++ */ ++ ++/* this modules manages association between HBITMAP handles and DIBDRVBITMAP ++ * physical bitmap objects. Needed mostly to get palettes from DIBs without ++ * resorting to GetDIBColorTable() or GETDIBits(), which are DC dependent. ++ * It makes also much easier (and faster) many bitmap operations */ ++ ++#include "config.h" ++#include "wine/port.h" ++ ++#include "dibdrv.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(dibdrv); ++ ++static CRITICAL_SECTION BITMAPLIST_CritSection; ++static CRITICAL_SECTION_DEBUG critsect_debug = ++{ ++ 0, 0, &BITMAPLIST_CritSection, ++ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, ++ 0, 0, { (DWORD_PTR)(__FILE__ ": BITMAPLIST_CritSection") } ++}; ++static CRITICAL_SECTION BITMAPLIST_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 }; ++ ++typedef struct _BITMAPLIST_NODE ++{ ++ HBITMAP hbmp; ++ DIBDRVBITMAP *bmp; ++ UINT refCount; ++ struct _BITMAPLIST_NODE *prev, *next; ++ ++} BITMAPLIST_NODE; ++ ++/* the list */ ++static BITMAPLIST_NODE *DIBDRV_BITMAPLIST; ++ ++/* initializes bitmap list -- to be called at process attach */ ++void _BITMAPLIST_Init(void) ++{ ++ DIBDRV_BITMAPLIST = NULL; ++} ++ ++/* terminates bitmap list -- to be called at process detach */ ++void _BITMAPLIST_Terminate(void) ++{ ++ BITMAPLIST_NODE *curNode, *nextNode; ++ ++ EnterCriticalSection(&BITMAPLIST_CritSection); ++ ++ /* frees all stored bitmaps, if any left */ ++ curNode = DIBDRV_BITMAPLIST; ++ while(curNode) ++ { ++ nextNode = curNode->next; ++ ERR("Unfreed DIB found, handle is %p\n", curNode->hbmp); ++ HeapFree(GetProcessHeap(), 0, curNode); ++ curNode = nextNode; ++ } ++ DIBDRV_BITMAPLIST = NULL; ++ LeaveCriticalSection(&BITMAPLIST_CritSection); ++ DeleteCriticalSection(&BITMAPLIST_CritSection); ++} ++ ++/* scan list for a DIB -- returns node containing it */ ++static BITMAPLIST_NODE *GetNode(HBITMAP hbmp) ++{ ++ BITMAPLIST_NODE *node = DIBDRV_BITMAPLIST; ++ while(node) ++ { ++ if(node->hbmp == hbmp) ++ return node; ++ node = node->next; ++ } ++ return NULL; ++} ++ ++/* adds a DIB to the list - it adds it on top, as ++ usually most recently created DIBs are used first */ ++BOOL _BITMAPLIST_Add(HBITMAP hbmp, DIBDRVBITMAP *bmp) ++{ ++ BITMAPLIST_NODE *existNode, *node; ++ ++ EnterCriticalSection(&BITMAPLIST_CritSection); ++ ++ /* checks if already there */ ++ node = NULL; ++ existNode = GetNode(hbmp); ++ if(!existNode) ++ { ++ node = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPLIST_NODE)); ++ if(!node) ++ ERR("HeapAlloc failed\n"); ++ else ++ { ++ node->next = DIBDRV_BITMAPLIST; ++ node->prev = NULL; ++ DIBDRV_BITMAPLIST = node; ++ if(node->next) ++ node->next->prev = node; ++ node->hbmp = hbmp; ++ node->bmp = bmp; ++ } ++ } ++ LeaveCriticalSection(&BITMAPLIST_CritSection); ++ return !existNode && node; ++} ++ ++/* removes a DIB from the list */ ++DIBDRVBITMAP *_BITMAPLIST_Remove(HBITMAP hbmp) ++{ ++ BITMAPLIST_NODE *node; ++ DIBDRVBITMAP *bmp; ++ ++ /* checks if already there */ ++ EnterCriticalSection(&BITMAPLIST_CritSection); ++ node = GetNode(hbmp); ++ if(node) ++ { ++ if(node->prev) ++ node->prev->next = node->next; ++ else ++ DIBDRV_BITMAPLIST = node->next; ++ if(node->next) ++ node->next->prev = node->prev; ++ } ++ LeaveCriticalSection(&BITMAPLIST_CritSection); ++ if(node) ++ { ++ bmp = node->bmp; ++ HeapFree(GetProcessHeap(), 0, node); ++ } ++ else ++ bmp = NULL; ++ return bmp; ++} ++ ++/* scans list for a DIB */ ++DIBDRVBITMAP *_BITMAPLIST_Get(HBITMAP hbmp) ++{ ++ BITMAPLIST_NODE *node; ++ DIBDRVBITMAP *bmp; ++ ++ EnterCriticalSection(&BITMAPLIST_CritSection); ++ node = GetNode(hbmp); ++ if(!node) ++ bmp = NULL; ++ else ++ bmp = node->bmp; ++ LeaveCriticalSection(&BITMAPLIST_CritSection); ++ return bmp; ++} +diff --git a/dlls/winedib.drv/dc.c b/dlls/winedib.drv/dc.c +index f5324b0..d2dae5f 100644 +--- a/dlls/winedib.drv/dc.c ++++ b/dlls/winedib.drv/dc.c +@@ -165,8 +165,8 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + /* no DIB selected into DC on creation */ + physDev->hasDIB = FALSE; + +- /* clear physical bitmap */ +- _DIBDRVBITMAP_Clear(&physDev->physBitmap); ++ /* initializes the physical bitmap */ ++ physDev->physBitmap = NULL; + + /* clears pen and brush */ + physDev->rop2 = R2_COPYPEN; +@@ -200,8 +200,8 @@ BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR dev + physDev->brushHLine = dummy4; + + physDev->isBrushBitmap = FALSE; +- _DIBDRVBITMAP_Clear(&physDev->brushBitmap); +- _DIBDRVBITMAP_Clear(&physDev->brushBmpCache); ++ physDev->brushBitmap = NULL; ++ physDev->brushBmpCache = NULL; + + /* text color */ + physDev->textColor = 0; +@@ -234,12 +234,14 @@ BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev ) + res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev); + physDev->X11PhysDev = NULL; + +- /* frees physical bitmap */ +- _DIBDRVBITMAP_Free(&physDev->physBitmap); ++ /* resets physical bitmap */ ++ physDev->physBitmap = NULL; + +- /* frees brush bitmap */ +- _DIBDRVBITMAP_Free(&physDev->brushBitmap); +- _DIBDRVBITMAP_Free(&physDev->brushBmpCache); ++ /* reset brush bitmap */ ++ _DIBDRVBITMAP_Free(physDev->brushBitmap); ++ physDev->brushBitmap = NULL; ++ _DIBDRVBITMAP_Free(physDev->brushBmpCache); ++ physDev->brushBmpCache = NULL; + + /* free brush ands and xors */ + if(physDev->brushAnds) +diff --git a/dlls/winedib.drv/dib.c b/dlls/winedib.drv/dib.c +index 41fb158..ae6a5cf 100644 +--- a/dlls/winedib.drv/dib.c ++++ b/dlls/winedib.drv/dib.c +@@ -68,15 +68,44 @@ static DWORD pal8[] = + HBITMAP DIBDRV_CreateDIBSection( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, + const BITMAPINFO *bmi, UINT usage ) + { +- HBITMAP res; ++ DIBDRVBITMAP *bmp; ++ DIBSECTION ds; + + 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("STUB\n")); +- res = hbitmap; + +- return res; ++ /* we need bitmap bits */ ++ if(GetObjectW(hbitmap, sizeof(DIBSECTION), &ds) != sizeof(DIBSECTION)) ++ { ++ ERR("Bitmap is not a DIB Section\n"); ++ return NULL; ++ } ++ ++ /* creates the physical bitmap */ ++ if(!(bmp = _DIBDRVBITMAP_CreateFromBitmapinfo(bmi, ds.dsBm.bmBits))) ++ { ++ ERR("_DIBDRVBITMAP_CreateFromBitmapinfo failed\n"); ++ return NULL; ++ } ++ ++ /* TEMPORARY -- if usage is DIB_PAL_COLOR, sets the palette ++ as ungrabbed, so next call to RealizeDefaultPalette will ++ do it */ ++ if(usage == DIB_PAL_COLORS) ++ { ++ FIXME("Do color table grabbing here instead of RealizeDefaultPalette\n"); ++ bmp->colorTableGrabbed = FALSE; ++ } ++ ++ /* adds it to the internal list */ ++ if(!_BITMAPLIST_Add(hbitmap, bmp)) ++ { ++ ERR("Couldn't add physical bitmap to list\n"); ++ _DIBDRVBITMAP_Free(bmp); ++ return NULL; ++ } ++ return hbitmap; + } + + /*********************************************************************** +@@ -87,15 +116,12 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + { + INT res; + DIBSECTION ds; +- DIBDRVBITMAP sBmp, dBmp; ++ DIBDRVBITMAP *sBmp, *dBmp; + DWORD *buf; + int iLine; + int size; +- BOOL justInfo, justInfoHeader; + int requestedBpp; +- RGBQUAD *colorTable; +- int colorTableSize; +- BITMAPINFO *sourceInfo; ++ RGBQUAD *colorTable = NULL; + + MAYBE(TRACE("physDev:%p, hbitmap:%p, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", + physDev, hbitmap, startscan, lines, bits, info, coloruse)); +@@ -118,118 +144,46 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + return 0; + } + +- /* get requested BPP */ +- requestedBpp = info->bmiHeader.biBitCount; +- +- /* check wetrher we wants just the BITMAPINFO data */ +- justInfo = (bits == NULL); +- +- /* check wether we wants just to get BITMAPINFOHEADER data */ +- justInfoHeader = (requestedBpp == 0); +- +- if(!justInfo && justInfoHeader) ++ /* if we wants just the BITMAPINFOHEADER data, do it */ ++ if(bits == NULL && info->bmiHeader.biBitCount == 0) + { +- ERR("Bad requested BPP\n"); +- return 0; ++ memcpy(&info->bmiHeader, &ds.dsBmih, size); ++ return abs(ds.dsBmih.biHeight); + } +- +- /* copy / set missing DIB info */ +- if(justInfo) +- { +- info->bmiHeader.biWidth = ds.dsBmih.biWidth; +- info->bmiHeader.biHeight = ds.dsBmih.biHeight; +- } +- info->bmiHeader.biPlanes = 1; +- if(justInfoHeader) +- info->bmiHeader.biBitCount = ds.dsBmih.biBitCount; +- if(size == sizeof(BITMAPINFOHEADER)) +- { +- if(justInfoHeader) +- { +- info->bmiHeader.biCompression = ds.dsBmih.biCompression; +- info->bmiHeader.biXPelsPerMeter = ds.dsBmih.biXPelsPerMeter; +- info->bmiHeader.biYPelsPerMeter = ds.dsBmih.biYPelsPerMeter; +- info->bmiHeader.biClrUsed = ds.dsBmih.biClrUsed; +- info->bmiHeader.biClrImportant = ds.dsBmih.biClrImportant; +- } +- info->bmiHeader.biSizeImage = ds.dsBmih.biSizeImage; +- } +- +- /* width and height *must* match source's ones */ +- if(info->bmiHeader.biWidth != ds.dsBmih.biWidth || +- abs(info->bmiHeader.biHeight) != abs(ds.dsBmih.biHeight)) ++ ++ /* source and dest sizes must match */ ++ if(info->bmiHeader.biWidth != ds.dsBmih.biWidth || abs(info->bmiHeader.biHeight) != abs(ds.dsBmih.biHeight)) + { +- ERR("Size of requested bitmap data don't match source's ones\n"); ++ WARN("Source and dest DIBs sizes don't match\n"); + return 0; + } +- +- /* if we just wants the BITMAPINFOHEADER data, we're done */ +- if(justInfoHeader || (justInfo && ds.dsBmih.biBitCount > 8)) +- return abs(info->bmiHeader.biHeight); +- +- /* we now have to get source data -- we need it for palette, for example */ +- colorTableSize = 0; +- if(ds.dsBmih.biBitCount <= 8) +- colorTableSize = (1 << ds.dsBmih.biBitCount); +- else if(ds.dsBmih.biCompression == BI_BITFIELDS) +- colorTableSize = 3; +- sourceInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + colorTableSize * sizeof(RGBQUAD)); +- if(!sourceInfo) ++ ++ /* get requested BPP and check it */ ++ requestedBpp = info->bmiHeader.biBitCount; ++ if(requestedBpp != 1 && requestedBpp != 4 && ++ requestedBpp != 8 && requestedBpp != 16 && ++ requestedBpp != 24 && requestedBpp != 32) + { +- ERR("HeapAlloc failed\n"); ++ ERR("Unknown BitCount %d\n", requestedBpp); + return 0; + } +- memcpy(sourceInfo, &ds.dsBmih, sizeof(BITMAPINFOHEADER)); +- if(ds.dsBmih.biBitCount <= 8) +- { +- /* grab palette - well, we should. No way to do it by now.... +- we should add a list HBITMAP <--> DIBDRVBITMAP and fiddle to many +- , many parts of the engine. Not worth the effort by now. +- So, we just synthesize the table */ +- switch(requestedBpp) +- { +- case 1: +- memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal1, 2*sizeof(DWORD)); +- break; +- +- case 4: +- memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal4, 16*sizeof(DWORD)); +- break; +- +- case 8: +- memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), pal8, 256*sizeof(DWORD)); +- break; +- +- default: +- ERR("Unknown requested bith depth %d\n", requestedBpp); +- _DIBDRVBITMAP_Free(&sBmp); +- return 0; +- } +- } +- else if(ds.dsBmih.biCompression == BI_BITFIELDS) +- memcpy((BYTE *)sourceInfo + sizeof(BITMAPINFOHEADER), ds.dsBitfields, 3 * sizeof(RGBQUAD)); +- _DIBDRVBITMAP_Clear(&sBmp); +- if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, sourceInfo)) ++ ++ /* now we must get (if needed) the color table */ ++ if(!(sBmp = _BITMAPLIST_Get(hbitmap))) + { +- ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); +- HeapFree(GetProcessHeap(), 0, sourceInfo); ++ ERR("Couldn't retrieve source DIB data\n"); + return 0; + } +- _DIBDRVBITMAP_Set_Bits(&sBmp, ds.dsBm.bmBits, FALSE); +- HeapFree(GetProcessHeap(), 0, sourceInfo); +- +- /* now grab / synthesize the color table if needed */ + if(requestedBpp <= 8) + { + colorTable = (RGBQUAD *)((BYTE *)info + size); +- if(requestedBpp == ds.dsBmih.biBitCount) +- { +- /* same source and dest format - copy color tables */ +- memcpy(colorTable, sBmp.colorTable, colorTableSize); +- } ++ ++ /* if same color format, just grab the color table */ ++ if(requestedBpp == sBmp->bitCount) ++ memcpy(colorTable, sBmp->colorTable, sBmp->colorTableSize); ++ /* otherwise synthesize a new color table */ + else + { +- /* different formats -- synthesize color table */ + switch(requestedBpp) + { + case 1: +@@ -246,38 +200,33 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + + default: + ERR("Unknown requested bith depth %d\n", requestedBpp); +- _DIBDRVBITMAP_Free(&sBmp); + return 0; + } + } + } + +- /* if we just wanted DIB info, job is done */ +- if(justInfo) +- { +- _DIBDRVBITMAP_Free(&sBmp); +- return abs(info->bmiHeader.biHeight); +- } +- +- /* Creates a DIBDRVBITMAP from dest dib */ +- _DIBDRVBITMAP_Clear(&dBmp); +- if(!_DIBDRVBITMAP_InitFromBitmapinfo(&dBmp, info)) ++ /* If we wanted just BITMAPINFO data, we're done */ ++ if(!bits) ++ return abs(ds.dsBmih.biHeight); ++ ++ /* now it's time to transfer image bits; for this we should create ++ a DIBDRVBITMAP from dest BITMAPINFO data */ ++ /* FIXME -- HERE is the place to add support for 'startscan' stuffs */ ++ if(!(dBmp = _DIBDRVBITMAP_CreateFromBMIH((BITMAPINFOHEADER *)info, ds.dsBitfields, colorTable, bits))) + { +- ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); +- _DIBDRVBITMAP_Free(&sBmp); ++ ERR("Couldn't create dest DIB\n"); + return 0; + } +- _DIBDRVBITMAP_Set_Bits(&dBmp, bits, FALSE); + + /* now we can do the bit conversion */ + buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD)); + for(iLine = 0; iLine < lines; iLine++) + { +- sBmp.funcs->GetLine(&sBmp, iLine, 0, ds.dsBmih.biWidth, buf); +- dBmp.funcs->PutLine(&dBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ sBmp->funcs->GetLine(sBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ dBmp->funcs->PutLine(dBmp, iLine, 0, ds.dsBmih.biWidth, buf); + } +- _DIBDRVBITMAP_Free(&sBmp); +- _DIBDRVBITMAP_Free(&dBmp); ++ HeapFree(GetProcessHeap(), 0, buf); ++ _DIBDRVBITMAP_Free(dBmp); + return lines; + } + else +@@ -293,13 +242,11 @@ INT DIBDRV_GetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + const RGBQUAD *colors ) + { +- DIBDRVBITMAP *dib = &physDev->physBitmap; +-#if 0 +- HBITMAP thisDIB; +-#endif ++ DIBDRVBITMAP *dib = physDev->physBitmap; ++ HBRUSH thisBrush; ++ HPEN thisPen; + + 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 */ + + /* if bpp > 8, some error occurred... */ +@@ -334,13 +281,16 @@ UINT DIBDRV_SetDIBColorTable( DIBDRVPHYSDEV *physDev, UINT start, UINT count, + } + memcpy(dib->colorTable + start, colors, sizeof(RGBQUAD) * count); + dib->colorTableGrabbed = TRUE; +- +- /* hack to make GDI32 sense the DIB color table change +- (fixes a couple of todos in bitmap test suite */ +-#if 0 +- thisDIB = SelectObject(physDev->hdc, GetStockObject(OBJ_BITMAP)); +- SelectObject(physDev->hdc, thisDIB); +-#endif ++ ++ /* for monochrome bitmaps, we need the 'lightest' color */ ++ _DIBDRVBITMAP_GetLightestColorIndex(dib); ++ ++ /* we should re-select both current pen and brush ++ in order to update colormap-dependent colors */ ++ thisBrush = SelectObject(physDev->hdc, GetStockObject(NULL_BRUSH)); ++ thisPen = SelectObject(physDev->hdc, GetStockObject(NULL_PEN)); ++ SelectObject(physDev->hdc, thisBrush); ++ SelectObject(physDev->hdc, thisPen); + + return TRUE; + } +@@ -353,7 +303,7 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + { + INT res; + DIBSECTION ds; +- DIBDRVBITMAP sBmp, dBmp; ++ DIBDRVBITMAP *sBmp, *dBmp; + DWORD *buf; + int iLine; + +@@ -373,31 +323,29 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + } + + /* Creates a DIBDRVBITMAP from source dib */ +- _DIBDRVBITMAP_Clear(&sBmp); +- if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, info)) ++ if(!(sBmp = _DIBDRVBITMAP_CreateFromBitmapinfo(info, (LPVOID)bits))) + { +- ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); ++ ERR("_DIBDRVBITMAP_CreateFromBitmapinfo failed\n"); + return 0; + } +- _DIBDRVBITMAP_Set_Bits(&sBmp, (LPVOID)bits, FALSE); + +- /* same for destination dib */ +- if(!_DIBDRVBITMAP_InitFromHBITMAP(&dBmp, hbitmap, FALSE)) ++ /* get destination physical bitmap */ ++ if(!(dBmp = _BITMAPLIST_Get(hbitmap))) + { +- ERR("_DIBDRVBITMAP_InitFromHBITMAP failed\n"); +- _DIBDRVBITMAP_Free(&sBmp); ++ ERR("Couldn't retrieve dest physical bitmap\n"); ++ _DIBDRVBITMAP_Free(sBmp); + return 0; + } +- ++ + /* now we can do the bit conversion */ + buf = HeapAlloc(GetProcessHeap(), 0, ds.dsBmih.biWidth * sizeof(RGBQUAD)); + for(iLine = 0; iLine < lines; iLine++) + { +- sBmp.funcs->GetLine(&sBmp, iLine, 0, ds.dsBmih.biWidth, buf); +- dBmp.funcs->PutLine(&dBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ sBmp->funcs->GetLine(sBmp, iLine, 0, ds.dsBmih.biWidth, buf); ++ dBmp->funcs->PutLine(dBmp, iLine, 0, ds.dsBmih.biWidth, buf); + } +- _DIBDRVBITMAP_Free(&sBmp); +- _DIBDRVBITMAP_Free(&dBmp); ++ HeapFree(GetProcessHeap(), 0, buf); ++ _DIBDRVBITMAP_Free(sBmp); + return lines; + } + else +@@ -411,34 +359,35 @@ INT DIBDRV_SetDIBits( DIBDRVPHYSDEV *physDev, HBITMAP hbitmap, UINT startscan, + /************************************************************************* + * DIBDRV_SetDIBitsToDevice + */ +-INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWORD cx, ++INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDst, INT yDst, DWORD cx, + DWORD cy, INT xSrc, INT ySrc, + UINT startscan, UINT lines, LPCVOID bits, + const BITMAPINFO *info, UINT coloruse ) + { +- BITMAPINFO *bitmapInfo; +- int bmInfoSize; + int dibHeight, dibWidth; +- DIBDRVBITMAP sBmp; +- int sLine, dLine, iLine; ++ DIBDRVBITMAP *sBmp, *dBmp; ++ int iLine; + void *buf; + +- MAYBE(TRACE("physDev:%p, xDest:%d, yDest:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", +- physDev, xDest, yDest, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse)); ++ MAYBE(TRACE("physDev:%p, xDst:%d, yDst:%d, cx:%x, cy:%x, xSrc:%d, ySrc:%d, startscan:%d, lines:%d, bits:%p, info:%p, coloruse:%d\n", ++ physDev, xDst, yDst, cx, cy, xSrc, ySrc, startscan, lines, bits, info, coloruse)); + + if(physDev->hasDIB) + { + /* DIB section selected in, use DIB Engine */ + + /* inverts y on source -- FIXME: check if right with some tests, it seems so */ +- ySrc = abs(info->bmiHeader.biHeight) - ySrc - cy; ++// ySrc = abs(info->bmiHeader.biHeight) - ySrc - cy; + + dibHeight = info->bmiHeader.biHeight; + dibWidth = info->bmiHeader.biWidth; + + /* sanity check and source clipping on physical sizes */ + if(startscan >= abs(dibHeight)) ++ { ++ ERR("startscan out of range\n"); + return 0; ++ } + if(startscan + lines > abs(dibHeight)) + lines = abs(dibHeight) - startscan; + +@@ -446,75 +395,63 @@ INT DIBDRV_SetDIBitsToDevice( DIBDRVPHYSDEV *physDev, INT xDest, INT yDest, DWOR + dibHeight += (dibHeight > 0 ? -startscan : startscan); + + if(xSrc >= dibWidth) ++ { ++ ERR("xSrc out of range\n"); + return 0; ++ } + if(xSrc + cx > dibWidth) + cx = dibWidth - xSrc; + if(ySrc > abs(dibHeight)) ++ { ++ ERR("ySrc out of range\n"); + return 0; ++ } + if(ySrc + cy > abs(dibHeight)) + cy = abs(dibHeight) - ySrc; + + ySrc -= startscan; + cy -= startscan; + if(cy <= 0) ++ { ++ ERR("Null or negative vertical size\n"); + return 0; ++ } + if(ySrc < 0) + { +- yDest += ySrc; ++ yDst += ySrc; + cy += ySrc; + ySrc = 0; + } + if(cy <= 0) +- return 0; +- +- /* grab a copy of BITMAPINFO */ +- bmInfoSize = sizeof(BITMAPINFOHEADER); +- if(info->bmiHeader.biCompression == BI_BITFIELDS) +- bmInfoSize += 3 * sizeof(RGBQUAD); +- else if (info->bmiHeader.biBitCount <= 8) +- { +- if(info->bmiHeader.biClrUsed) +- bmInfoSize += info->bmiHeader.biClrUsed * sizeof(RGBQUAD); +- else +- bmInfoSize += (1 << info->bmiHeader.biBitCount) * sizeof(RGBQUAD); +- } +- if(!(bitmapInfo = HeapAlloc(GetProcessHeap(), 0, bmInfoSize))) + { +- ERR("HeapAlloc failed\n"); ++ ERR("Null or negative vertical size\n"); + return 0; + } +- memcpy(bitmapInfo, info, bmInfoSize); +- bitmapInfo->bmiHeader.biHeight = dibHeight; + +- /* create a DIBDRVBITMAP from BITMAPINFO data */ +- _DIBDRVBITMAP_Clear(&sBmp); +- if(!_DIBDRVBITMAP_InitFromBitmapinfo(&sBmp, bitmapInfo)) ++ /* Creates a DIBDRVBITMAP from source dib */ ++ if(!(sBmp = _DIBDRVBITMAP_CreateFromBitmapinfo(info, (LPVOID)bits))) + { +- ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); +- HeapFree(GetProcessHeap, 0, bitmapInfo); ++ ERR("_DIBDRVBITMAP_CreateFromBitmapinfo failed\n"); + return 0; + } +- HeapFree(GetProcessHeap(), 0, bitmapInfo); +- _DIBDRVBITMAP_Set_Bits(&sBmp, (LPVOID)bits, FALSE); + +- /* transfer lines to dest bitmap */ +- if(!(buf = HeapAlloc(GetProcessHeap(), 0, cx * sizeof(RGBQUAD)))) +- { +- ERR("HeapAlloc failed\n"); +- return 0; +- } +- for(sLine = ySrc, dLine = yDest, iLine = 0; iLine < cy; sLine++, dLine++, iLine++) ++ /* get destination physical bitmap */ ++ dBmp = physDev->physBitmap; ++ ++ /* now we can do the bit conversion */ ++ buf = HeapAlloc(GetProcessHeap(), 0, cx * sizeof(RGBQUAD)); ++ for(iLine = 0; iLine < cy; iLine++) + { +- sBmp.funcs->GetLine(&sBmp, sLine, xSrc, cx, buf); +- physDev->physBitmap.funcs->PutLine(&physDev->physBitmap, dLine, xDest, cx, buf); ++ sBmp->funcs->GetLine(sBmp, ySrc++, xSrc, cx, buf); ++ dBmp->funcs->PutLine(dBmp, yDst++, xDst, cx, buf); + } + HeapFree(GetProcessHeap(), 0, buf); +- ++ _DIBDRVBITMAP_Free(sBmp); + return cy; + } + else + { +- return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDest, yDest, cx, cy, xSrc, ySrc, ++ return _DIBDRV_GetDisplayDriver()->pSetDIBitsToDevice(physDev->X11PhysDev, xDst, yDst, cx, cy, xSrc, ySrc, + startscan, lines, bits, info, coloruse); + } + } +diff --git a/dlls/winedib.drv/dibdrv.h b/dlls/winedib.drv/dibdrv.h +index 8243d4b..4266703 100644 +--- a/dlls/winedib.drv/dibdrv.h ++++ b/dlls/winedib.drv/dibdrv.h +@@ -171,6 +171,9 @@ typedef struct _DIBDRVBITMAP + RGBQUAD *colorTable; + DWORD colorTableSize; + ++ /* lightest color index, for monochrome bitmaps */ ++ int lightColor; ++ + /* flag indicating that color table has been grabbed */ + BOOL colorTableGrabbed; + +@@ -203,7 +206,7 @@ typedef struct _DIBDRVPHYSDEV + HBITMAP hbitmap; + + /* physical bitmap */ +- DIBDRVBITMAP physBitmap; ++ DIBDRVBITMAP *physBitmap; + + /* active ROP2 */ + INT rop2; +@@ -249,8 +252,8 @@ typedef struct _DIBDRVPHYSDEV + + /* brush bitmap, if needed, and its converted/resized cache copy */ + BOOL isBrushBitmap; +- DIBDRVBITMAP brushBitmap; +- DIBDRVBITMAP brushBmpCache; ++ DIBDRVBITMAP *brushBitmap; ++ DIBDRVBITMAP *brushBmpCache; + + /* text color */ + COLORREF textColor; +@@ -317,7 +320,10 @@ const char *_DIBDRVBITMAP_GetFormatName(DIBDRVBITMAP const *bmp); + void _DIBDRVBITMAP_Set_Bits(DIBDRVBITMAP *dib, void *bits, BOOL owns); + void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP *dib); + +-/* initializes dib from a bitmap : ++/* calculates and sets the lightest color for monochrome bitmaps */ ++int _DIBDRVBITMAP_GetLightestColorIndex(DIBDRVBITMAP *dib); ++ ++/* initialize or create dib from a bitmap : + dib dib being initialized + bi source BITMAPINFOHEADER with required DIB format info + bit_fields color masks +@@ -326,8 +332,11 @@ void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP *dib); + 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); ++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBMIH(const BITMAPINFOHEADER *bi, const DWORD *bit_fields, ++ const RGBQUAD *colorTable, void *bits); + +-BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi); ++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi, void *bits); ++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBitmapinfo(const BITMAPINFO *bmi, void *bits); + + /* initializes a DIBRDVBITMAP copying it from a source one + Parameters : +@@ -336,13 +345,6 @@ BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi); + copy TRUE->copy source pixel array FALSE->link to source pixel array */ + BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, BOOL copy); + +-/* initializes a DIBRDVBITMAP from a DIB HBITMAP +- Parameters : +- bmp destination DIBDRVBITMAP +- hbmp source HBITMAP +- copyPixels TRUE->copy source pixel array FALSE->link to source pixel array */ +-BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL copyPixels); +- + /* creates a DIBRDVBITMAP copying format info from a source one + Parameters : + dib destination DIBDRVBITMAP +@@ -350,13 +352,16 @@ BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL c + widht, height sizes of newly created bitmap */ + BOOL _DIBDRVBITMAP_CreateFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *src, int width, int height); + ++/* allocates a new DIBDTVBITMAP */ ++DIBDRVBITMAP *_DIBDRVBITMAP_New(void); ++ ++/* Frees and de-allocates a DIBDRVBITMAP structure data */ ++void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp); ++ + /* 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 */ +@@ -375,6 +380,26 @@ BOOL _DIBDRVBITMAP_CreateSolid(DIBDRVBITMAP *bmp, DIBDRVBITMAP *format, int widt + BOOL _DIBDRVBITMAP_ExpandHoriz(DIBDRVBITMAP *dib, int baseWidth, int minWidth); + + /* ********************************************************************* ++ * BITMAP LIST MANAGEMENT FUNCTIONS ++ * ********************************************************************/ ++ ++/* initializes bitmap list -- to be called at process attach */ ++void _BITMAPLIST_Init(void); ++ ++/* terminates bitmap list -- to be called at process detach */ ++void _BITMAPLIST_Terminate(void); ++ ++/* adds a DIB to the list - it adds it on top, as ++ usually most recently created DIBs are used first */ ++BOOL _BITMAPLIST_Add(HBITMAP hbmp, DIBDRVBITMAP *bmp); ++ ++/* removes a DIB from the list */ ++DIBDRVBITMAP *_BITMAPLIST_Remove(HBITMAP hbmp); ++ ++/* scans list for a DIB */ ++DIBDRVBITMAP *_BITMAPLIST_Get(HBITMAP hbmp); ++ ++/* ********************************************************************* + * DIB <--> DDB CONVERSION ROUTINES + * ********************************************************************/ + +diff --git a/dlls/winedib.drv/dibdrv_main.c b/dlls/winedib.drv/dibdrv_main.c +index e436440..119a294 100644 +--- a/dlls/winedib.drv/dibdrv_main.c ++++ b/dlls/winedib.drv/dibdrv_main.c +@@ -42,6 +42,9 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) + /* initializes freetype library */ + if(!_DIBDRV_FreeType_Init()) + ERR("Couldn't initialize freetype library.\n"); ++ ++ /* initializes internal bitmap list */ ++ _BITMAPLIST_Init(); + + break; + case DLL_THREAD_DETACH: +@@ -55,6 +58,9 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) + /* unloads display driver */ + _DIBDRV_FreeDisplayDriver(); + ++ /* terminates internal bitmap list */ ++ _BITMAPLIST_Terminate(); ++ + break; + } + return ret; +diff --git a/dlls/winedib.drv/dibdrvbitmap.c b/dlls/winedib.drv/dibdrvbitmap.c +index 8e6b653..eb7d1e2 100644 +--- a/dlls/winedib.drv/dibdrvbitmap.c ++++ b/dlls/winedib.drv/dibdrvbitmap.c +@@ -142,6 +142,33 @@ void *_DIBDRVBITMAP_Get_Bits(DIBDRVBITMAP * dib) + } + } + ++/* calculates and sets the lightest color for monochrome bitmaps */ ++int _DIBDRVBITMAP_GetLightestColorIndex(DIBDRVBITMAP *dib) ++{ ++ DWORD foreRed, foreGreen, foreBlue; ++ DWORD backRed, backGreen, backBlue; ++ RGBQUAD *fore, *back; ++ ++ /* zero for non-monochrome bitmaps */ ++ if(dib->bitCount != 1) ++ return 0; ++ /* just in case color table hasn't been grabbed yet */ ++ if(!dib->colorTableGrabbed) ++ return 1; ++ back = dib->colorTable; ++ fore = back + 1; ++ foreRed = fore->rgbRed; foreGreen = fore->rgbGreen; foreBlue = fore->rgbBlue; ++ backRed = back->rgbRed; backGreen = back->rgbGreen; backBlue = back->rgbBlue; ++ if(foreRed*foreRed + foreGreen*foreGreen + foreBlue*foreBlue > ++ backRed*backRed + backGreen*backGreen + backBlue*backBlue) ++ { ++ dib->lightColor = 1; ++ return 1; ++ } ++ dib->lightColor = 0; ++ return 0; ++} ++ + /* initializes dib from a bitmap : + dib dib being initialized + bi source BITMAPINFOHEADER with required DIB format info +@@ -264,6 +291,9 @@ BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, c + memcpy(dib->colorTable, colorTable, + dib->colorTableSize * sizeof(dib->colorTable[0])); + dib->colorTableGrabbed = TRUE; ++ ++ /* for monochrome bitmaps, we need the 'lightest' color */ ++ _DIBDRVBITMAP_GetLightestColorIndex(dib); + } + else if(!dib->colorTableSize) + /* no color table on more than 8 bits/pixel */ +@@ -273,16 +303,64 @@ BOOL _DIBDRVBITMAP_InitFromBMIH(DIBDRVBITMAP *dib, const BITMAPINFOHEADER *bi, c + return TRUE; + } + +-BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi) ++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBMIH(const BITMAPINFOHEADER *bi, const DWORD *bit_fields, ++ const RGBQUAD *colorTable, void *bits) ++{ ++ DIBDRVBITMAP *bmp = _DIBDRVBITMAP_New(); ++ if(bmp && !_DIBDRVBITMAP_InitFromBMIH(bmp, bi, bit_fields, colorTable, bits)) ++ { ++ _DIBDRVBITMAP_Free(bmp); ++ bmp = NULL; ++ } ++ return bmp; ++} ++ ++/* gets a BITMAPINFOHEADER from a soure BITMAPINFO- or BITMAPCORE-header */ ++static BITMAPINFOHEADER *GetBitmapInfoHeader(BITMAPINFO const *bmi) ++{ ++ BITMAPINFOHEADER *res = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER)); ++ ++ int size = bmi->bmiHeader.biSize; ++ if(size >= sizeof(BITMAPINFOHEADER)) ++ { ++ memcpy(res, bmi, sizeof(BITMAPINFOHEADER)); ++ res->biSize = sizeof(BITMAPINFOHEADER); ++ } ++ else if(size == sizeof(BITMAPCOREHEADER)) ++ { ++ BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)bmi; ++ res->biSize = sizeof(BITMAPINFOHEADER); ++ res->biWidth = core->bcWidth; ++ res->biHeight = core->bcHeight; ++ res->biPlanes = core->bcPlanes; ++ res->biBitCount = core->bcBitCount; ++ } ++ else ++ { ++ HeapFree(GetProcessHeap(), 0, res); ++ ERR("Bad/unknown header size %d\n", size); ++ res = NULL; ++ } ++ return res; ++} ++ ++BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi, void *bits) + { + 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; ++ BITMAPINFOHEADER *bi; ++ BYTE *ptr; ++ int num_colors; + BOOL res; ++ ++ /* gets info header */ ++ if(!(bi = GetBitmapInfoHeader(bmi))) ++ return FALSE; ++ ++ ptr = (BYTE*)bmi + bmi->bmiHeader.biSize; ++ num_colors = bi->biClrUsed; + + MAYBE(TRACE("dib=%p, bmi=%p\n", dib, bmi)); + +@@ -302,11 +380,23 @@ BOOL _DIBDRVBITMAP_InitFromBitmapinfo(DIBDRVBITMAP *dib, const BITMAPINFO *bmi) + colorTable = (RGBQUAD*)ptr; + ptr += num_colors * sizeof(*colorTable); + +- res = _DIBDRVBITMAP_InitFromBMIH(dib, bi, masks, colorTable, ptr); ++ res = _DIBDRVBITMAP_InitFromBMIH(dib, bi, masks, colorTable, bits ? bits : ptr); ++ HeapFree(GetProcessHeap(), 0, bi); + MAYBE(TRACE("END\n")); + return res; + } + ++DIBDRVBITMAP *_DIBDRVBITMAP_CreateFromBitmapinfo(const BITMAPINFO *bmi, void *bits) ++{ ++ DIBDRVBITMAP *bmp = _DIBDRVBITMAP_New(); ++ if(bmp && !_DIBDRVBITMAP_InitFromBitmapinfo(bmp, bmi, bits)) ++ { ++ _DIBDRVBITMAP_Free(bmp); ++ bmp = NULL; ++ } ++ return bmp; ++} ++ + /* initializes a DIBRDVBITMAP copying it from a source one + Parameters : + dib destination DIBDRVBITMAP +@@ -335,6 +425,8 @@ BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *s + + dib->funcs = src->funcs; + ++ dib->lightColor = src->lightColor; ++ + if(copy) + { + int size = dib->height*abs(dib->stride); +@@ -378,92 +470,6 @@ BOOL _DIBDRVBITMAP_InitFromDibdrvbitmap(DIBDRVBITMAP *dib, const DIBDRVBITMAP *s + return TRUE; + } + +-/* initializes a DIBRDVBITMAP from a DIB HBITMAP +- Parameters : +- bmp destination DIBDRVBITMAP +- hbmp source HBITMAP +- copyPixels TRUE->copy source pixel array FALSE->link to source pixel array */ +-BOOL _DIBDRVBITMAP_InitFromHBITMAP(DIBDRVBITMAP *bmp, const HBITMAP hbmp, BOOL copyPixels) +-{ +- BITMAPINFO *destInfo; +- DIBSECTION ds; +- int size; +- +- MAYBE(TRACE("bmp=%p, hbmp=%p, copyPixels = %s\n", bmp, hbmp, copyPixels ? "TRUE" : "FALSE")); +- +- /* be sure bitmap is empty */ +- _DIBDRVBITMAP_Clear(bmp); +- +- /* gets source bitmap data */ +- if(!(size = GetObjectW(hbmp, sizeof(DIBSECTION), &ds))) +- { +- ERR("Failed getting bitmap object\n"); +- return FALSE; +- } +- if(size != sizeof(DIBSECTION)) +- { +- ERR("Bitmap is not a DIB section\n"); +- return FALSE; +- } +- +- destInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); +- if(!destInfo) +- { +- ERR("HeapAlloc failed\n"); +- return FALSE; +- } +- +- memcpy(destInfo, &ds.dsBmih, sizeof(BITMAPINFOHEADER)); +- if(ds.dsBmih.biCompression == BI_BITFIELDS) +- memcpy((BITMAPINFOHEADER *)destInfo + 1, ds.dsBitfields, 3 * sizeof(RGBQUAD)); +- else if(ds.dsBmih.biBitCount <= 8) +- { +- FIXME("Can't grab color table here.... syslvel lock\n"); +- return FALSE; +-#if 0 +- HDC refDC = CreateCompatibleDC(0); +- if(!refDC) +- { +- ERR("CreateCompatibleDC() failed\n"); +- return FALSE; +- } +- if(!GetDIBits(refDC, hbmp, 0, 1, NULL, destInfo, DIB_RGB_COLORS)) +- { +- DeleteDC(refDC); +- HeapFree(GetProcessHeap(), 0, destInfo); +- ERR("GetDIBits failed\n"); +- return FALSE; +- } +- DeleteDC(refDC); +-#endif +- } +- if(!_DIBDRVBITMAP_InitFromBitmapinfo(bmp, destInfo)) +- { +- HeapFree(GetProcessHeap(), 0, destInfo); +- ERR("_DIBDRVBITMAP_InitFromBitmapinfo failed\n"); +- return FALSE; +- } +- HeapFree(GetProcessHeap(), 0, destInfo); +- if(copyPixels) +- { +- size = abs(bmp->stride) * bmp->height; +- if(!(bmp->bits = HeapAlloc(GetProcessHeap(), 0, size))) +- { +- ERR("HeapAlloc failed\n"); +- _DIBDRVBITMAP_Free(bmp); +- return FALSE; +- } +- memcpy(bmp->bits, ds.dsBm.bmBits, size); +- bmp->ownsBits = TRUE; +- } +- else +- bmp->bits = ds.dsBm.bmBits; +- if(bmp->stride < 0) +- bmp->bits = (BYTE*)bmp->bits - (bmp->height - 1) * bmp->stride; +- +- return TRUE; +-} +- + + /* creates a DIBRDVBITMAP copying format info from a source one + Parameters : +@@ -512,6 +518,8 @@ void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp) + { + MAYBE(TRACE("bmp=%p\n", bmp)); + ++ if(!bmp) ++ return; + bmp->bits = NULL; + bmp->ownsBits = FALSE; + bmp->colorTable = NULL; +@@ -521,11 +529,23 @@ void _DIBDRVBITMAP_Clear(DIBDRVBITMAP *bmp) + MAYBE(TRACE("END\n")); + } + ++/* allocates a new DIBDTVBITMAP */ ++DIBDRVBITMAP *_DIBDRVBITMAP_New(void) ++{ ++ DIBDRVBITMAP *bmp = HeapAlloc(GetProcessHeap(), 0, sizeof(DIBDRVBITMAP)); ++ if(!bmp) ++ return NULL; ++ _DIBDRVBITMAP_Clear(bmp); ++ return bmp; ++} ++ + /* Frees a DIBDRVBITMAP structure data */ + void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp) + { + MAYBE(TRACE("bmp=%p\n", bmp)); + ++ if(!bmp) ++ return; + /* frees bits, if needed */ + if(bmp->bits && bmp->ownsBits) + { +@@ -535,17 +555,12 @@ void _DIBDRVBITMAP_Free(DIBDRVBITMAP *bmp) + 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; ++ ++ HeapFree(GetProcessHeap(), 0, bmp); + +- MAYBE(TRACE("END\n")); + } + + +diff --git a/dlls/winedib.drv/font.c b/dlls/winedib.drv/font.c +index f7ea8dc..bcfbaba 100644 +--- a/dlls/winedib.drv/font.c ++++ b/dlls/winedib.drv/font.c +@@ -93,7 +93,7 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + + #ifdef DIBDRV_ANTIALIASED_FONTS + /* fills the text color table used on antialiased font display */ +- if(physDev->physBitmap.funcs) ++ if(physDev->physBitmap->funcs) + { + BYTE r, g, b; + INT i; +@@ -103,7 +103,7 @@ COLORREF DIBDRV_SetTextColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + b = GetBValue(color); + for(i = 0; i < 256; i++) + { +- physDev->textColorTable[i] = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, RGB( ++ physDev->textColorTable[i] = physDev->physBitmap->funcs->ColorToPixel(physDev->physBitmap, RGB( + MulDiv(r, i, 255), + MulDiv(g, i, 255), + MulDiv(b, i, 255) +diff --git a/dlls/winedib.drv/graphics.c b/dlls/winedib.drv/graphics.c +index 4aebe8e..1fd155d 100644 +--- a/dlls/winedib.drv/graphics.c ++++ b/dlls/winedib.drv/graphics.c +@@ -517,7 +517,7 @@ COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y ) + if(physDev->hasDIB) + { + _DIBDRV_Position_ws2ds(physDev, &x, &y); +- res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y); ++ res = physDev->physBitmap->funcs->GetPixel(physDev->physBitmap, x, y); + } + else + { +@@ -976,18 +976,18 @@ COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color ) + color = _DIBDRV_MapColor(physDev, color); + + /* map to pixel color / palette index */ +- color = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, color); ++ color = physDev->physBitmap->funcs->ColorToPixel(physDev->physBitmap, color); + + _DIBDRV_Position_ws2ds(physDev, &x, &y); + + /* gets previous pixel */ +- res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y); ++ 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); ++ physDev->physBitmap->funcs->SetPixel(physDev->physBitmap, x, y, and, xor); + } + else + { +diff --git a/dlls/winedib.drv/palette.c b/dlls/winedib.drv/palette.c +index 87016da..301cf1d 100644 +--- a/dlls/winedib.drv/palette.c ++++ b/dlls/winedib.drv/palette.c +@@ -38,12 +38,12 @@ COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color) + case 0x10 : /* DIBINDEX */ + MAYBE(TRACE("DIBINDEX Color is %08x\n", color)); + index = color & 0xffff; +- if(index >= physDev->physBitmap.colorTableSize) ++ if(index >= physDev->physBitmap->colorTableSize) + { +- WARN("DIBINDEX color out of range\n"); ++ WARN("DIBINDEX color %d out of range, color table size is %d\n", index, physDev->physBitmap->colorTableSize); + return 0; + } +- palColor = physDev->physBitmap.colorTable + index; ++ palColor = physDev->physBitmap->colorTable + index; + MAYBE(TRACE("Returning color %08x\n", RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue))); + return RGB(palColor->rgbRed, palColor->rgbGreen, palColor->rgbBlue); + +@@ -64,24 +64,36 @@ COLORREF _DIBDRV_MapColor(DIBDRVPHYSDEV *physDev, COLORREF color) + return RGB(paletteEntry.peRed, paletteEntry.peGreen, paletteEntry.peBlue); + + case 0x02: /* PALETTERGB */ +- return _DIBDRV_GetNearestColor(&physDev->physBitmap, color & 0xffffff); ++ return _DIBDRV_GetNearestColor(physDev->physBitmap, color & 0xffffff); + + default: + /* RGB color -- we must process special case for monochrome bitmaps */ +- if(physDev->physBitmap.bitCount == 1) ++ if(physDev->physBitmap->bitCount == 1) + { +- RGBQUAD *back = physDev->physBitmap.colorTable; ++ RGBQUAD *back = physDev->physBitmap->colorTable; + RGBQUAD *fore = back+1; +- if(fore->rgbRed * fore->rgbRed + fore->rgbGreen * fore->rgbGreen + fore->rgbBlue * fore->rgbBlue < +- back->rgbRed * back->rgbRed + back->rgbGreen * back->rgbGreen + back->rgbBlue * back->rgbBlue) ++ COLORREF lightColorref, darkColorref; ++ ++ /* lightest color is considered to be 'foreground' one, i.e. associated to white color */ ++ if(physDev->physBitmap->lightColor == 1) + { +- fore = back; +- back = fore + 1; ++ darkColorref = RGB(back->rgbRed, back->rgbGreen, back->rgbBlue); ++ lightColorref = RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue); + } +- if ( ((color >> 16) & 0xff) + ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) +- return RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue); + else +- return RGB(back->rgbRed, back->rgbGreen, back->rgbBlue); ++ { ++ darkColorref = RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue); ++ lightColorref = RGB(back->rgbRed, back->rgbGreen, back->rgbBlue); ++ } ++ ++ /* tested on Windows XP -- if present in colortable, maps to corresponding color ++ if not, if white maps to the lightest color, otherwise darkest one. */ ++ if(color == lightColorref || color == darkColorref) ++ return color; ++ else if (color == 0x00ffffff) ++ return lightColorref; ++ else ++ return darkColorref; + } + else + return color; +@@ -200,20 +212,24 @@ UINT DIBDRV_RealizeDefaultPalette( DIBDRVPHYSDEV *physDev ) + /* 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("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); ++ 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++) ++ for(i = 0; i < physDev->physBitmap->colorTableSize; i++) + { +- q = physDev->physBitmap.colorTable + 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; ++ physDev->physBitmap->colorTableGrabbed = TRUE; ++ ++ /* for monochrome bitmaps, we need the 'lightest' color */ ++ _DIBDRVBITMAP_GetLightestColorIndex(physDev->physBitmap); ++ + } + res = 0; + } +diff --git a/dlls/winedib.drv/pen_brush.c b/dlls/winedib.drv/pen_brush.c +index c40bfaf..32d50fb 100644 +--- a/dlls/winedib.drv/pen_brush.c ++++ b/dlls/winedib.drv/pen_brush.c +@@ -48,20 +48,20 @@ static inline void OrderEndPoints(int *s, int *e) + 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); ++ 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); ++ 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); ++ physDev->physBitmap->funcs->SetPixel(physDev->physBitmap, x, y, physDev->penAnd, physDev->penXor); + return; + } + +@@ -120,7 +120,7 @@ static void DashedPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) + if(x + dashLen > x2) + dashLen = x2 - x; + +- physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x, x + dashLen, y, and, xor); ++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x, x + dashLen, y, and, xor); + x += dashLen; + + physDev->leftInDash -= dashLen; +@@ -137,7 +137,7 @@ static void DashedPenHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) + if(x - (int)dashLen < x2) + dashLen = x - x2; + +- physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, x - dashLen + 1, x + 1, y, and, xor); ++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x - dashLen + 1, x + 1, y, and, xor); + x -= dashLen; + + physDev->leftInDash -= dashLen; +@@ -162,7 +162,7 @@ static void DashedPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) + if(y + dashLen > y2) + dashLen = y2 - y; + +- physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y, y + dashLen, and, xor); ++ physDev->physBitmap->funcs->SolidVLine(physDev->physBitmap, x, y, y + dashLen, and, xor); + y += dashLen; + + physDev->leftInDash -= dashLen; +@@ -179,7 +179,7 @@ static void DashedPenVLine(DIBDRVPHYSDEV *physDev, int x, int y1, int y2) + if(y - (int)dashLen < y2) + dashLen = y - y2; + +- physDev->physBitmap.funcs->SolidVLine(&physDev->physBitmap, x, y - dashLen + 1, y + 1, and, xor); ++ physDev->physBitmap->funcs->SolidVLine(physDev->physBitmap, x, y - dashLen + 1, y + 1, and, xor); + y -= dashLen; + + physDev->leftInDash -= dashLen; +@@ -195,7 +195,7 @@ static void WINAPI DashedPenLineCallback(int x, int y, LPARAM lparam) + + GetDashColors(physDev, &and, &xor); + +- physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, and, xor); ++ physDev->physBitmap->funcs->SetPixel(physDev->physBitmap, x, y, and, xor); + + physDev->leftInDash--; + NextDash(physDev); +@@ -222,8 +222,8 @@ void _DIBDRV_ResetDashOrigin(DIBDRVPHYSDEV *physDev) + the background color is used -- tested on WinXP */ + static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color) + { +- RGBQUAD *back = physDev->physBitmap.colorTable; +- RGBQUAD *fore = physDev->physBitmap.colorTable+1; ++ RGBQUAD *back = physDev->physBitmap->colorTable; ++ RGBQUAD *fore = physDev->physBitmap->colorTable+1; + + if( + fore->rgbRed == GetRValue(color) && +@@ -270,9 +270,9 @@ static DWORD AdjustFgColor(DIBDRVPHYSDEV *physDev, COLORREF color) + rgb.rgbGreen = GetGValue(color); + rgb.rgbBlue = GetBValue(color); + +- for(i = 0; i < physDev->physBitmap.colorTableSize; i++) ++ for(i = 0; i < physDev->physBitmap->colorTableSize; i++) + { +- RGBQUAD *cur = physDev->physBitmap.colorTable + i; ++ RGBQUAD *cur = physDev->physBitmap->colorTable + i; + if((rgb.rgbRed == cur->rgbRed) && (rgb.rgbGreen == cur->rgbGreen) && (rgb.rgbBlue == cur->rgbBlue)) + return i; + } +@@ -298,7 +298,7 @@ static void FixupFgColors1(DIBDRVPHYSDEV *physDev) + 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); ++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, x1, x2, y, physDev->brushAnd, physDev->brushXor); + } + + +@@ -324,16 +324,16 @@ static void GenerateMasks(DIBDRVPHYSDEV *physDev, DIBDRVBITMAP *bmp, DWORD **and + + static void PatternBrushHLine(DIBDRVPHYSDEV *physDev, int x1, int x2, int y) + { +- DWORD *and, *xor, brushY = y % physDev->brushBitmap.height; ++ DWORD *and, *xor, brushY = y % physDev->brushBitmap->height; + + if(!physDev->brushAnds) +- GenerateMasks(physDev, &physDev->brushBitmap, &physDev->brushAnds, &physDev->brushXors); ++ 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); ++ 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); ++ physDev->physBitmap->funcs->PatternHLine(physDev->physBitmap, x1, x2, y, and, xor, physDev->brushBitmap->width, x1 % physDev->brushBitmap->width); + } + + /* null function for PS_NULL and BS_NULL pen and brush styles */ +@@ -356,8 +356,10 @@ HPEN DIBDRV_SelectPen( DIBDRVPHYSDEV *physDev, HPEN hpen ) + { + GetObjectW(hpen, sizeof(logpen), &logpen); + +- physDev->penColorref = _DIBDRV_MapColor(physDev, logpen.lopnColor); +- physDev->penColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->penColorref); ++ physDev->penColorref = logpen.lopnColor; ++ physDev->penColor = physDev->physBitmap->funcs->ColorToPixel( ++ physDev->physBitmap, ++ _DIBDRV_MapColor(physDev, physDev->penColorref)); + + _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), physDev->penColor, &physDev->penAnd, &physDev->penXor); + +@@ -441,8 +443,10 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + GetObjectW(hbrush, sizeof(logbrush), &logbrush); + + /* frees any currently selected DIB brush and cache */ +- _DIBDRVBITMAP_Free(&physDev->brushBitmap); +- _DIBDRVBITMAP_Free(&physDev->brushBmpCache); ++ _DIBDRVBITMAP_Free(physDev->brushBitmap); ++ physDev->brushBitmap = NULL; ++ _DIBDRVBITMAP_Free(physDev->brushBmpCache); ++ physDev->brushBmpCache = NULL; + if(physDev->brushAnds) + { + HeapFree(GetProcessHeap(), 0, physDev->brushAnds); +@@ -459,13 +463,15 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + goto solid; + + case BS_SOLID: +- physDev->brushColorref = _DIBDRV_MapColor(physDev, logbrush.lbColor); ++ physDev->brushColorref = logbrush.lbColor; + solid: + MAYBE(TRACE("SOLID Pattern -- color is %x\n", physDev->brushColorref)); + physDev->brushStyle = BS_SOLID; + physDev->brushHLine = SolidBrushHLine; + +- physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->brushColorref); ++ physDev->brushColor = physDev->physBitmap->funcs->ColorToPixel( ++ physDev->physBitmap, ++ _DIBDRV_MapColor(physDev, physDev->brushColorref)); + + _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->brushColor, + &physDev->brushAnd, &physDev->brushXor); +@@ -485,7 +491,7 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + FIXME("DIB Pattern\n"); + + /* if no DIB selected in, fallback to null brush */ +- if(!physDev->physBitmap.bits) ++ if(!physDev->physBitmap->bits) + { + physDev->brushColorref = 0; + goto solid; +@@ -495,7 +501,7 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + bmi = GlobalLock16(logbrush.lbHatch); + + /* initializes a temporary DIB with brush's one */ +- if(!_DIBDRVBITMAP_InitFromBitmapinfo(&src, bmi)) ++ if(!_DIBDRVBITMAP_InitFromBitmapinfo(&src, bmi, NULL)) + { + ERR("Failed to initialize brush DIB\n"); + res = 0; +@@ -503,7 +509,7 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + } + + /* converts brush bitmap to match currently selected one's format */ +- if(!_DIBDRVBITMAP_Convert(&physDev->brushBitmap, &src, &physDev->physBitmap)) ++ if(!_DIBDRVBITMAP_Convert(physDev->brushBitmap, &src, physDev->physBitmap)) + { + ERR("Failed to convert brush DIB\n"); + _DIBDRVBITMAP_Free(&src); +@@ -537,7 +543,9 @@ HBRUSH DIBDRV_SelectBrush( DIBDRVPHYSDEV *physDev, HBRUSH hbrush ) + { + MAYBE(TRACE("NULL Pattern\n")); + physDev->brushColorref = 0; +- physDev->brushColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, 0); ++ physDev->brushColor = physDev->physBitmap->funcs->ColorToPixel( ++ physDev->physBitmap, ++ _DIBDRV_MapColor(physDev, 0)); + physDev->brushHLine = NullBrushHLine; + break; + } +@@ -644,7 +652,7 @@ COLORREF DIBDRV_SetBkColor( DIBDRVPHYSDEV *physDev, COLORREF color ) + if(physDev->hasDIB) + { + physDev->backgroundColor = _DIBDRV_MapColor(physDev, color); +- physDev->backgroundColor = physDev->physBitmap.funcs->ColorToPixel(&physDev->physBitmap, physDev->backgroundColor); ++ physDev->backgroundColor = physDev->physBitmap->funcs->ColorToPixel(physDev->physBitmap, physDev->backgroundColor); + + _DIBDRV_CalcAndXorMasks(physDev->rop2, physDev->backgroundColor, &physDev->backgroundAnd, &physDev->backgroundXor); + +diff --git a/dlls/winedib.drv/primitives_bitblt.c b/dlls/winedib.drv/primitives_bitblt.c +index 27d573f..3505277 100644 +--- a/dlls/winedib.drv/primitives_bitblt.c ++++ b/dlls/winedib.drv/primitives_bitblt.c +@@ -169,8 +169,8 @@ BOOL _DIBDRV_AlphaBlend_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + BYTE constAlpha = blendFn.SourceConstantAlpha; + + /* source and dest bitmaps */ +- const DIBDRVBITMAP *srcBmp = &physDevSrc->physBitmap; +- DIBDRVBITMAP *dstBmp = &physDevDst->physBitmap; ++ const DIBDRVBITMAP *srcBmp = physDevSrc->physBitmap; ++ DIBDRVBITMAP *dstBmp = physDevDst->physBitmap; + + /* source and destination line buffers */ + DWORD *sBuf = HeapAlloc(GetProcessHeap(), 0, abs(srcBmp->stride)); +@@ -403,15 +403,15 @@ BOOL _DIBDRV_BitBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + + /* gets source, dest and pattern bitmaps, if available */ + if(usePat && physDevDst->isBrushBitmap) +- patBmp = &physDevDst->brushBmpCache; ++ patBmp = physDevDst->brushBmpCache; + else + patBmp = NULL; + + if(useSrc) +- srcBmp = &physDevSrc->physBitmap; ++ srcBmp = physDevSrc->physBitmap; + else + srcBmp = NULL; +- dstBmp = &physDevDst->physBitmap; ++ dstBmp = physDevDst->physBitmap; + + /* gets pattern color, in case it's needed + it's NOT the COLORREF value (colors are swapped +@@ -656,15 +656,15 @@ BOOL _DIBDRV_StretchBlt_generic(DIBDRVPHYSDEV *physDevDst, INT xDst, INT yDst, + + /* gets source, dest and pattern bitmaps, if available */ + if(usePat && physDevDst->isBrushBitmap) +- patBmp = &physDevDst->brushBmpCache; ++ patBmp = physDevDst->brushBmpCache; + else + patBmp = NULL; + + if(useSrc) +- srcBmp = &physDevSrc->physBitmap; ++ srcBmp = physDevSrc->physBitmap; + else + srcBmp = NULL; +- dstBmp = &physDevDst->physBitmap; ++ dstBmp = physDevDst->physBitmap; + + /* gets pattern color, in case it's needed + it's NOT the COLORREF value (colors are swapped +diff --git a/dlls/winedib.drv/primitives_color.c b/dlls/winedib.drv/primitives_color.c +index 6c42b44..93baf43 100644 +--- a/dlls/winedib.drv/primitives_color.c ++++ b/dlls/winedib.drv/primitives_color.c +@@ -142,32 +142,30 @@ DWORD _DIBDRV_GetNearestColorIndex(const DIBDRVBITMAP *dib, COLORREF color) + + DWORD _DIBDRV_ColorToPixelColortable(const DIBDRVBITMAP *dib, COLORREF color) + { +- DWORD r, g, b; +- +- r = GetRValue(color); +- g = GetGValue(color); +- b = GetBValue(color); +- + /* just in case it's being called without color table + properly initialized */ + if(!dib->colorTableGrabbed) + return 0; + ++ color &= 0xffffff; ++ + /* for monochrome bitmaps, color is : + foreground if matching foreground ctable + else background if matching background ctable +- else foreground ix 0xffffff ++ else foreground if 0xffffff + else background */ + if(dib->colorTableSize == 2) + { + RGBQUAD *back = dib->colorTable; + RGBQUAD *fore = dib->colorTable + 1; +- if(r == fore->rgbRed && g == fore->rgbGreen && b == fore->rgbBlue) ++ COLORREF backColorref = RGB(back->rgbRed, back->rgbGreen, back->rgbBlue); ++ COLORREF foreColorref = RGB(fore->rgbRed, fore->rgbGreen, fore->rgbBlue); ++ if(color == foreColorref) + return 1; +- else if(r == back->rgbRed && g == back->rgbGreen && b == back->rgbBlue) ++ else if(color == backColorref) + return 0; +- if((color & 0xffffff) == 0xffffff) +- return 1; ++ else if(color == 0xffffff) ++ return dib->lightColor; + else + return 0; + } +diff --git a/dlls/winedib.drv/primitives_convert.c b/dlls/winedib.drv/primitives_convert.c +index 24a5e77..7c4da14 100644 +--- a/dlls/winedib.drv/primitives_convert.c ++++ b/dlls/winedib.drv/primitives_convert.c +@@ -537,6 +537,9 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + /* get foreground color */ + DWORD back = *(DWORD *)bmp->colorTable & 0x00ffffff; + DWORD fore = *((DWORD *)bmp->colorTable + 1) & 0x00ffffff; ++ ++ /* get 'light' color */ ++ int lightColor = bmp->lightColor; + + /* put first partial byte, if any */ + startx &= 0x07; +@@ -553,7 +556,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + b |= mask; + else if(c == back) + b &= !mask; +- else if(c == 0x00ffffff) ++ else if((c == 0x00ffffff && lightColor) || (c == 0 && !lightColor)) + b |= mask; + else + b &= !mask; +@@ -570,7 +573,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + for(i = 0 ; i < 8 ; i++) + { + c = *dwBuf++ & 0x00ffffff; +- if(c == fore || (c == 0x00ffffff && c != back)) ++ if(c == fore || (c == 0x00ffffff && c != back && lightColor) || (c == 0 && !lightColor)) + b |= mask; + mask >>= 1; + } +@@ -589,7 +592,7 @@ BOOL _DIBDRV_PutLine1(const DIBDRVBITMAP *bmp, INT line, INT startx, int width, + b |= mask; + else if(c == back) + b &= !mask; +- else if(c == 0x00ffffff) ++ else if((c == 0x00ffffff && lightColor) || (c == 0 && !lightColor)) + b |= mask; + else + b &= !mask; +diff --git a/dlls/winedib.drv/primitives_font.c b/dlls/winedib.drv/primitives_font.c +index e604a39..a2824a5 100644 +--- a/dlls/winedib.drv/primitives_font.c ++++ b/dlls/winedib.drv/primitives_font.c +@@ -31,7 +31,7 @@ void _DIBDRV_freetype_blit_8888(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clip + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -84,7 +84,7 @@ void _DIBDRV_freetype_blit_32_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *cl + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -137,7 +137,7 @@ void _DIBDRV_freetype_blit_32_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RE + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -189,7 +189,7 @@ void _DIBDRV_freetype_blit_24(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRe + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -241,7 +241,7 @@ void _DIBDRV_freetype_blit_16_RGB(DIBDRVPHYSDEV *physDev, int x, int y, RECT *cl + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -293,7 +293,7 @@ void _DIBDRV_freetype_blit_16_BITFIELDS(DIBDRVPHYSDEV *physDev, int x, int y, RE + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -345,7 +345,7 @@ void _DIBDRV_freetype_blit_8(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -375,7 +375,7 @@ void _DIBDRV_freetype_blit_4(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +@@ -405,7 +405,7 @@ void _DIBDRV_freetype_blit_1(DIBDRVPHYSDEV *physDev, int x, int y, RECT *clipRec + { + /* FIXME : MUST BE OPTIMIZED !!! */ + +- DIBDRVBITMAP *dib = &physDev->physBitmap; ++ DIBDRVBITMAP *dib = physDev->physBitmap; + int bmpX, bmpY; + BYTE *buf; + int dibX, dibY; +diff --git a/dlls/winedib.drv/text.c b/dlls/winedib.drv/text.c +index 0ae3575..94c7992 100644 +--- a/dlls/winedib.drv/text.c ++++ b/dlls/winedib.drv/text.c +@@ -120,7 +120,7 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + { + /* paints the backgound */ + for(iLine = tr.top; iLine < tr.bottom; iLine++) +- physDev->physBitmap.funcs->SolidHLine(&physDev->physBitmap, ++ physDev->physBitmap->funcs->SolidHLine(physDev->physBitmap, + tr.left, tr.right-1, iLine, 0, backPixel); + } + } +@@ -187,7 +187,7 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + error = pFT_Glyph_To_Bitmap( + &glyph, + #ifdef DIBDRV_ANTIALIASED_FONTS +- physDev->physBitmap.bitCount > 8 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, ++ physDev->physBitmap->bitCount > 8 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, + #else + FT_RENDER_MODE_MONO, + #endif +@@ -220,7 +220,7 @@ BOOL DIBDRV_ExtTextOut( DIBDRVPHYSDEV *physDev, INT x, INT y, UINT flags, + } + + /* now, draw to our target surface */ +- physDev->physBitmap.funcs->FreetypeBlit(physDev, x+bitmapGlyph->left, y-bitmapGlyph->top, &clipRec, bitmap); ++ physDev->physBitmap->funcs->FreetypeBlit(physDev, x+bitmapGlyph->left, y-bitmapGlyph->top, &clipRec, bitmap); + + /* frees converted bitmap, if any */ + if(bitmap != &bitmapGlyph->bitmap) diff --git a/app-emulation/wine/files/ddraw-1.1.24.diff b/app-emulation/wine/files/ddraw-1.1.24.diff new file mode 100644 index 00000000..5aff1176 --- /dev/null +++ b/app-emulation/wine/files/ddraw-1.1.24.diff @@ -0,0 +1,42 @@ +diff -urN wine-1.1.24.orig/dlls/ddraw/ddraw.c wine-1.1.24/dlls/ddraw/ddraw.c +--- wine-1.1.24.orig/dlls/ddraw/ddraw.c 2009-03-27 18:31:22.000000000 +0000 ++++ wine-1.1.24/dlls/ddraw/ddraw.c 2009-04-05 19:06:28.000000000 +0100 +@@ -35,6 +35,7 @@ + #include "winbase.h" + #include "winerror.h" + #include "wingdi.h" ++#include "winreg.h" + #include "wine/exception.h" + + #include "ddraw.h" +@@ -45,6 +46,8 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + ++#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1') ++ + static BOOL IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, const DDSURFACEDESC2* provided); + static HRESULT IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary); + static HRESULT IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD, IDirectDrawSurfaceImpl **ppSurf, UINT level); +@@ -476,7 +479,20 @@ + !(This->devicewindow) && + (hwnd != window) ) + { +- This->dest_window = hwnd; ++ BYTE buffer[32]; ++ DWORD size = sizeof(buffer); ++ HKEY hkey = 0; ++ HWND drawwin = hwnd; ++ /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */ ++ if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey)) { ++ if (!RegQueryValueExA( hkey, "DirectDrawDesktopHack", 0, NULL, buffer, &size)) { ++ if ( IS_OPTION_TRUE( buffer[0] ) ) { ++ TRACE("Enabling DirectDrawDesktopHack hack\n"); ++ drawwin = GetDesktopWindow(); ++ } ++ } ++ } ++ This->dest_window = drawwin; + } + } + else if(cooplevel & DDSCL_EXCLUSIVE) diff --git a/app-emulation/wine/files/hack.reg b/app-emulation/wine/files/hack.reg new file mode 100644 index 00000000..2ce9b23f --- /dev/null +++ b/app-emulation/wine/files/hack.reg @@ -0,0 +1,5 @@ +REGEDIT4 + +[HKEY_CURRENT_USER\Software\Wine\Direct3D] +"DirectDrawDesktopHack"="true" + diff --git a/app-emulation/wine/wine-1.1.26.ebuild b/app-emulation/wine/wine-1.1.26.ebuild index d1835dd9..7cff849f 100644 --- a/app-emulation/wine/wine-1.1.26.ebuild +++ b/app-emulation/wine/wine-1.1.26.ebuild @@ -91,6 +91,17 @@ src_prepare() { epatch "${FILESDIR}"/dinput.patch epatch "${FILESDIR}"/schannel.patch epatch "${FILESDIR}"/revert-ntdll.patch + epatch "${FILESDIR}"/ddraw-1.1.24.diff + epatch "${FILESDIR}"/0001-dib-engine-hook-the-engine-bet.patch + epatch "${FILESDIR}"/0002-dib-engine-initial-pass-throug.patch + epatch "${FILESDIR}"/0003-dib-engine-fork-ddb-dib-behavi.patch + epatch "${FILESDIR}"/0004-dib-engine-implement-most-engi.patch + epatch "${FILESDIR}"/0005-dib-engine-implement-alphablen.patch + epatch "${FILESDIR}"/0006-dib-engine-add-clipping-on-xxx.patch + epatch "${FILESDIR}"/0007-dib-engine-implement-polygon.patch + epatch "${FILESDIR}"/0008-dib-engine-fixes-clipping-text.patch + epatch "${FILESDIR}"/0009-dib-engine-fixes-against-wine-.patch + epatch "${FILESDIR}"/0010-dib-engine-introduction-of-bit.patch sed -i '/^UPDATE_DESKTOP_DATABASE/s:=.*:=true:' tools/Makefile.in || die sed -i '/^MimeType/d' tools/wine.desktop || die #117785 }