diff options
Diffstat (limited to 'win32/PlatWin.cxx')
| -rw-r--r-- | win32/PlatWin.cxx | 74 | 
1 files changed, 63 insertions, 11 deletions
| diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 7ef0e7b2c..35d66030f 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -13,6 +13,13 @@  #include <time.h>  #include <limits.h> +#ifdef _MSC_VER +#pragma warning(disable: 4786) +#endif + +#include <vector> +#include <map> +  #undef _WIN32_WINNT  #define _WIN32_WINNT  0x0500  #include <windows.h> @@ -404,6 +411,7 @@ public:  	void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);  	void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,  		ColourAllocated outline, int alphaOutline, int flags); +	void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage);  	void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);  	void Copy(PRectangle rc, Point from, Surface &surfaceSource); @@ -696,6 +704,45 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated  	}  } +void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) { +	if (AlphaBlendFn && rc.Width() > 0) { +		HDC hMemDC = ::CreateCompatibleDC(reinterpret_cast<HDC>(hdc)); +		if (rc.Width() > width) +			rc.left += (rc.Width() - width) / 2; +		rc.right = rc.left + width; +		if (rc.Height() > height) +			rc.top += (rc.Height() - height) / 2; +		rc.bottom = rc.top + height; + +		BITMAPINFO bpih = {sizeof(BITMAPINFOHEADER), width, height, 1, 32, BI_RGB, 0, 0, 0, 0, 0}; +		unsigned char *image = 0; +		HBITMAP hbmMem = CreateDIBSection(reinterpret_cast<HDC>(hMemDC), &bpih, +			DIB_RGB_COLORS, reinterpret_cast<void **>(&image), NULL, 0); +		HBITMAP hbmOld = SelectBitmap(hMemDC, hbmMem); +		 +		for (int y=height-1; y>=0; y--) { +			for (int x=0; x<width; x++) { +				unsigned char *pixel = image + (y*width+x) * 4; +				unsigned char alpha = pixelsImage[3]; +				// Input is RGBA, output is BGRA with premultiplied alpha +				pixel[2] = (*pixelsImage++) * alpha / 255; +				pixel[1] = (*pixelsImage++) * alpha / 255; +				pixel[0] = (*pixelsImage++) * alpha / 255; +				pixel[3] = *pixelsImage++; +			} +		} +		 +		BLENDFUNCTION merge = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; + +		AlphaBlendFn(reinterpret_cast<HDC>(hdc), rc.left, rc.top, rc.Width(), rc.Height(), hMemDC, 0, 0, width, height, merge); + +		SelectBitmap(hMemDC, hbmOld); +		::DeleteObject(hbmMem); +		::DeleteDC(hMemDC); + +	} +} +  void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {  	PenColour(fore);  	BrushColor(back); @@ -1318,7 +1365,7 @@ ListBox::~ListBox() {  class ListBoxX : public ListBox {  	int lineHeight;  	FontID fontCopy; -	XPMSet xset; +	RGBAImageSet images;  	LineToItem lti;  	HWND lb;  	bool unicodeMode; @@ -1385,6 +1432,7 @@ public:  	virtual int Find(const char *prefix);  	virtual void GetValue(int n, char *value, int len);  	virtual void RegisterImage(int type, const char *xpm_data); +	virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage);  	virtual void ClearRegisteredImages();  	virtual void SetDoubleClickAction(CallBackAction action, void *data) {  		doubleClickAction = action; @@ -1491,7 +1539,7 @@ PRectangle ListBoxX::GetDesiredRect() {  }  int ListBoxX::TextOffset() const { -	int pixWidth = const_cast<XPMSet*>(&xset)->GetWidth(); +	int pixWidth = images.GetWidth();  	return pixWidth == 0 ? ItemInset.x : ItemInset.x + pixWidth + (ImageInset.x * 2);  } @@ -1550,11 +1598,16 @@ void ListBoxX::GetValue(int n, char *value, int len) {  }  void ListBoxX::RegisterImage(int type, const char *xpm_data) { -	xset.Add(type, xpm_data); +	XPM xpmImage(xpm_data); +	images.Add(type, new RGBAImage(xpmImage)); +} + +void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) { +	images.Add(type, new RGBAImage(width, height, pixelsImage));  }  void ListBoxX::ClearRegisteredImages() { -	xset.Clear(); +	images.Clear();  }  void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) { @@ -1594,17 +1647,16 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) {  		}  		// Draw the image, if any -		XPM *pxpm = xset.Get(pixId); -		if (pxpm) { +		RGBAImage *pimage = images.Get(pixId); +		if (pimage) {  			Surface *surfaceItem = Surface::Allocate();  			if (surfaceItem) {  				surfaceItem->Init(pDrawItem->hDC, pDrawItem->hwndItem); -				//surfaceItem->SetUnicodeMode(unicodeMode); -				//surfaceItem->SetDBCSMode(codePage);  				int left = pDrawItem->rcItem.left + ItemInset.x + ImageInset.x;  				PRectangle rcImage(left, pDrawItem->rcItem.top, -					left + xset.GetWidth(), pDrawItem->rcItem.bottom); -				pxpm->Draw(surfaceItem, rcImage); +					left + images.GetWidth(), pDrawItem->rcItem.bottom); +				surfaceItem->DrawRGBAImage(rcImage, +					pimage->GetWidth(), pimage->GetHeight(), pimage->Pixels());  				delete surfaceItem;  				::SetTextAlign(pDrawItem->hDC, TA_TOP);  			} @@ -1678,7 +1730,7 @@ void ListBoxX::AdjustWindowRect(PRectangle *rc) const {  int ListBoxX::ItemHeight() const {  	int itemHeight = lineHeight + (TextInset.y * 2); -	int pixHeight = const_cast<XPMSet*>(&xset)->GetHeight() + (ImageInset.y * 2); +	int pixHeight = images.GetHeight() + (ImageInset.y * 2);  	if (itemHeight < pixHeight) {  		itemHeight = pixHeight;  	} | 
