[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

[XaraXtreme-commits] Commit Complete



Commit by  : alex
Repository : xara
Revision   : 923
Date       : Sat Apr 29 20:13:20 BST 2006

Changed paths:
   M /Trunk/XaraLX/Kernel/cxfile.cpp
   M /Trunk/XaraLX/Kernel/draginfo.h
   M /Trunk/XaraLX/wxOil/dibutil.cpp
   M /Trunk/XaraLX/wxOil/dibutil.h
   M /Trunk/XaraLX/wxOil/dragbmp.cpp
   M /Trunk/XaraLX/wxOil/dragbmp.h
   M /Trunk/XaraLX/wxOil/dragmgr.cpp

Make dragging of a bitmap with transparency in it take account of the transparency in the bitmap, as well as the transparency of the drag.


Diff:
Index: Trunk/XaraLX/Kernel/cxfile.cpp
===================================================================
--- Trunk/XaraLX/Kernel/cxfile.cpp	(revision 922)
+++ Trunk/XaraLX/Kernel/cxfile.cpp	(revision 923)
@@ -1125,8 +1125,6 @@
 	if (pStr == NULL)
 		return FALSE;
 
-	size_t len = camStrlen(pStr);
-
 #ifdef UNICODE
 	// pStr points to a Unicode string, so just write it out
 	//
@@ -1152,6 +1150,8 @@
 	// pStr points to an ASCII string, and we want it written as a Unicode string
 	// Write out each char, followed by a 0 byte
 
+	size_t len = camStrlen(pStr);
+
 	BOOL ok= TRUE;
 	for (unsigned i=0;ok && i<=len;i++)
 		ok = Write(BYTE(pStr[i])) && Write(BYTE(0));
Index: Trunk/XaraLX/Kernel/draginfo.h
===================================================================
--- Trunk/XaraLX/Kernel/draginfo.h	(revision 922)
+++ Trunk/XaraLX/Kernel/draginfo.h	(revision 923)
@@ -147,12 +147,12 @@
 
 	BOOL IsAnAdjustDrag()						{ return IsAdjustDrag; }
 
-
 public:		// Solid-dragging support
 	virtual INT32 GetDragTransparency()			{ return 0; }		// Not transparent
 	virtual KernelBitmap *GetSolidDragMask()	{ return NULL; }	// Not masked
+	virtual BOOL HasTransparentMask()			{ return FALSE; }
+	virtual wxBitmap * GetTransparentMask()		{ return NULL; }
 
-
 public:		// Special dropping functions called for drop-on-page (called by ViewDragTarget)
 	virtual BOOL CanDropOnPage()				{ return FALSE; }
 	virtual BOOL OnPageDrop(ViewDragTarget*)	{ return FALSE; }
Index: Trunk/XaraLX/wxOil/dibutil.h
===================================================================
--- Trunk/XaraLX/wxOil/dibutil.h	(revision 922)
+++ Trunk/XaraLX/wxOil/dibutil.h	(revision 923)
@@ -285,6 +285,7 @@
 #ifdef _DEBUG
 	static void FillColour24(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits);
 #endif
+	static void MakeAlphaIntoGreyscale(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits);
 };
 
 
Index: Trunk/XaraLX/wxOil/dragbmp.cpp
===================================================================
--- Trunk/XaraLX/wxOil/dragbmp.cpp	(revision 922)
+++ Trunk/XaraLX/wxOil/dragbmp.cpp	(revision 923)
@@ -195,6 +195,7 @@
 	MemDC = NULL;
 	Bitmap = NULL;
 	DragMask = NULL;
+	MaskBitmap = NULL;
 
 	// Set up a few things about this drag
 	DoesSolidDrag = TRUE;
@@ -273,6 +274,11 @@
 		delete Bitmap;
 	}
 
+	if (MaskBitmap)
+	{
+		delete MaskBitmap;
+	}
+
 	if (DragMask)
 	{
 //		DragMask->ActualBitmap->IsTemp = TRUE;
@@ -639,6 +645,23 @@
 			return FALSE;
 		}
 
+		INT32 bpp = wxBM->GetBPP();
+
+		if (MaskBitmap)
+		{
+			delete MaskBitmap;
+			MaskBitmap = NULL;
+		}
+
+		// For now, only do the mask bitmap where we have a 32bpp representation
+		// as I haven't tested whether Gavin works OK with (say) a palette with
+		// transparency in it
+		if ((bpp==32) && TheBitmap->IsTransparent())
+		{
+			// If this fails, we simply treat it as non-transparent. Hey ho
+			MaskBitmap = new wxBitmap(DestWidth, DestHeight);
+		}
+
 		MemDC.SelectObject(*Bitmap);
 
 PORTNOTE("other", "disabled palettes in dragbmp")
@@ -714,7 +737,6 @@
 		RGBQUAD TempPalette[256];
 		RGBQUAD* Palette = wxBM->BMInfo->bmiColors;
 	
-		INT32 bpp = wxBM->GetBPP();
 		if (bpp <= 8)
 		{
 			INT32 NumCols;
@@ -790,16 +812,39 @@
 		// Now we use GRenderRegion to plot it (far easier than farting about
 		// with conversion which was the previous technique...)
 
-
 		GRenderRegion::StaticPlotBitmap(&MemDC, DIBPal, TempInfo, TempBits, 0, 0, DestWidth, DestHeight, pPal, 0, 0);
 
-//		Bitmap->SaveFile(_T("/tmp/test.png"), wxBITMAP_TYPE_PNG);
+		if (MaskBitmap)
+		{
+			// Make the rectangle black
+			MemDC.SelectObject(*MaskBitmap);
+			GD->SetColour(0);
+			GD->FillRectangle(&BmpRect);
 
+			// Contone between white and white, but use the transparency values
+			GD->SetColour(0xFFFFFF);
+			GD->SetContone(1, 0xFFFFFF, 0xFFFFFF);
+			GD->SetBitmapFill(	&(wxBM->BMInfo->bmiHeader),
+								wxBM->BMBytes,
+								0x4000,
+								PGram,
+								DefaultColour,
+								Palette,
+								NULL, NULL, NULL,
+								NULL,
+								0
+								);
+			GD->FillRectangle(&BmpRect);
+
+			GRenderRegion::StaticPlotBitmap(&MemDC, DIBPal, TempInfo, TempBits, 0, 0, DestWidth, DestHeight, pPal, 0, 0);
+		}
+
 		FreeDIB(TempInfo, TempBits);
 
 	}
 	// Finally plot the Bitmap onto the output RenderDC
-	RenderDC->DrawBitmap(*Bitmap, TopLeft.x, TopLeft.y, true);
+	if (RenderDC)
+		RenderDC->DrawBitmap(*Bitmap, TopLeft.x, TopLeft.y, true);
 
 	// Yipeee !! We done it
    	return TRUE;
@@ -815,10 +860,21 @@
 	Purpose:	Get a 1 bpp mask to use for the solid drag.
 	SeeAlso:	-
 
+We (ab)use this call to ensure an initial plot is done, which in turn sets up the mask,
+which has to be done before the first plot (on setup)
+
 ********************************************************************************************/
 
 KernelBitmap* BitmapDragInformation::GetSolidDragMask()
 {
+	if (TheBitmap != NULL && TheBitmap->ActualBitmap != NULL)
+	{	
+		wxBitmap bitmap(1,1);
+		wxMemoryDC DC;
+		DC.SelectObject(bitmap);
+		PlotBitmap((CWxBitmap*)TheBitmap->ActualBitmap, wxPoint(0,0), DragRect, &DC);
+	}
+	
 	return DragMask;
 }
 
@@ -864,3 +920,4 @@
 
 	return TRUE;
 }
+
Index: Trunk/XaraLX/wxOil/dibutil.cpp
===================================================================
--- Trunk/XaraLX/wxOil/dibutil.cpp	(revision 922)
+++ Trunk/XaraLX/wxOil/dibutil.cpp	(revision 923)
@@ -4863,7 +4863,40 @@
 	}
 }
 
+/********************************************************************************************
 
+>	static void DIBUtil::MakeAlphaIntoGreyscale ( LPBITMAPINFO	lpBitmapInfo,
+										  LPBYTE		lpBits )
+
+	Author:		Graeme_Sutherland (Xara Group Ltd) <camelotdev@xxxxxxxx>
+	Created:	27/6/00 (moved here by Phil 06/02/2004)
+	Purpose:	Camelot uses a different transparency scheme to the rest of the world, in
+				that 255 is clear, and 0 is opaque. Until the rest of the world catches up,
+				it's necessary to invert the alpha channel to make exported files compatible
+				with other programs.
+
+********************************************************************************************/
+
+void DIBUtil::MakeAlphaIntoGreyscale(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits)
+{
+	// Only 32 bpp bitmaps have an alpha channel.
+	if ( lpBitmapInfo->bmiHeader.biBitCount == 32 )
+	{
+		// Cast the pointer into a DWORD.
+		DWORD *lpRGBA = reinterpret_cast<DWORD*> ( lpBits );
+
+		// If we`re exporting a 32Bit BMP then we need to make sure that we convert the
+		// Alpha channel to Transparency! i.e. invert it!
+		for ( UINT32 i = 0; i < lpBitmapInfo->bmiHeader.biSizeImage; i+=4 )
+		{
+			// Multiply the alpha value by 0x010101 puts it in each of R, G and B
+			*lpRGBA = 0x010101 * (*lpRGBA>>24);
+			lpRGBA ++;
+		}
+	}
+}
+
+
 #ifdef _DEBUG
 void DIBUtil::FillColour24(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits)
 {
Index: Trunk/XaraLX/wxOil/dragmgr.cpp
===================================================================
--- Trunk/XaraLX/wxOil/dragmgr.cpp	(revision 922)
+++ Trunk/XaraLX/wxOil/dragmgr.cpp	(revision 923)
@@ -316,7 +316,9 @@
 	KernelBitmap* DragMask = 
 		DragManagerOp::CurrentManager->CurrentDragInfo->GetSolidDragMask();
 	
-	if (DragTransparency > 0 || DragMask != NULL)
+	BOOL TransparentMask = DragManagerOp::CurrentManager->CurrentDragInfo->HasTransparentMask();
+
+	if (DragTransparency > 0 || TransparentMask ||  DragMask != NULL)
  	{
 		// If we're doing a transparency drag, then we'll need
 		// a monochome mask bitmap.
@@ -333,7 +335,24 @@
 
 		// Create a wxImage, don't initalize it
 		wxImage MaskImage(DSize.x, DSize.y, false);
+		unsigned char * pix=MaskImage.GetData();
+		unsigned char * tpix = NULL;
 
+		wxImage * pTransparentMask = NULL;
+		if (TransparentMask)
+		{
+			wxBitmap *pTMbitmap=DragManagerOp::CurrentManager->CurrentDragInfo->GetTransparentMask();
+			if (pTMbitmap)
+				pTransparentMask = new wxImage();
+			if (!pTransparentMask)
+				TransparentMask=FALSE;
+			else
+			{
+				*pTransparentMask=pTMbitmap->ConvertToImage();
+				tpix=pTransparentMask->GetData();
+			}
+		}
+
 		// DragTransparency is between 0 and 100,
 		// and we need a grey level between 0 and 255.
 		INT32 GreyLevel = (DragTransparency * 255) / 100;
@@ -349,17 +368,29 @@
 								  16, 8,14, 6};
 		INT32 x, y;
 
-		unsigned char * pix=MaskImage.GetData();
-
 		for (y=0; y<DSize.y; y++) for (x=0; x<DSize.x; x++)
 		{
-			BYTE thresh = (GreyLevel>(OrderedDither[(x&3)|((y&3)<<2)]*16-8))?0xff:0x00;
+			INT32 tlevel=GreyLevel;
+			if (TransparentMask)
+			{
+				// Combine the transparency level with the transparency of the mask
+				// Note if EITHER are 255 we want full transparency. The appropriate
+				// operation is thus 1-((1-x)(1-y)), except of course they are 0..255
+				tlevel=((255*255+(255/2)) - // that's the maximum value (as we invert), but also add 255/2 for rounding when we divide by 255
+						((255-GreyLevel)*(*tpix))
+						)/255;
+				tpix +=3;
+			}
+			BYTE thresh = (tlevel>(OrderedDither[(x&3)|((y&3)<<2)]*16-8))?0xff:0x00;
 			// write three bytes (R, G, B)
 			*pix++=thresh;
 			*pix++=thresh;
 			*pix++=thresh;
 		}
 
+		if (pTransparentMask)
+			delete pTransparentMask;
+
 		MaskBitmap=new wxBitmap(MaskImage, 1);
 		if (MaskBitmap)
 		{
Index: Trunk/XaraLX/wxOil/dragbmp.h
===================================================================
--- Trunk/XaraLX/wxOil/dragbmp.h	(revision 922)
+++ Trunk/XaraLX/wxOil/dragbmp.h	(revision 923)
@@ -147,6 +147,9 @@
 	virtual BOOL GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget);
 	virtual BOOL OnDrawSolidDrag(wxPoint Origin,wxDC * TheDC, DragTarget* pDragTarget);
 
+	virtual BOOL HasTransparentMask()	{ return (MaskBitmap != NULL); }
+	virtual wxBitmap* GetTransparentMask() { return (MaskBitmap); }
+
 	virtual KernelBitmap* GetSolidDragMask();
 
 	KernelBitmap *GetTheBitmap(void)	{ return TheBitmap; }
@@ -176,6 +179,7 @@
 	wxDC* MemDC;
 	wxBitmap* Bitmap;
 	wxBitmap* OldBmp;
+	wxBitmap* MaskBitmap;
 
 	static INT32 DragTransparency;
 };


Xara