[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
[XaraXtreme-commits] Commit Complete
Commit by : alex
Repository : xara
Revision : 919
Date : Fri Apr 28 21:05:12 BST 2006
Changed paths:
M /Trunk/XaraLX/wxOil/dragmgr.cpp
Fixed pseudotransparent dragging of bitmaps
Diff:
Index: Trunk/XaraLX/wxOil/dragmgr.cpp
===================================================================
--- Trunk/XaraLX/wxOil/dragmgr.cpp (revision 918)
+++ Trunk/XaraLX/wxOil/dragmgr.cpp (revision 919)
@@ -114,6 +114,7 @@
#include "cursor.h"
//#include "resource.h"
#include "gbrush.h"
+#include "grndrgn.h"
#include "oilbitmap.h"
#include "osrndrgn.h"
@@ -323,81 +324,86 @@
// which will be used to 'knock' pixels out of the
// drag bitmap.
- wxMemoryDC MaskDC;
- MaskBitmap = new wxBitmap(DSize.x, DSize.y, 1);
+ // Sadly, the world has conspired against us in terms of producing this
+ // in any rational manner. 1bpp wxBitmaps do not work as brushes (random
+ // memory). 24bpp wxBitmaps do not work as brushes into wxMemoryDCs backed
+ // by 1bpp brushes. Conversion of 24bpp bitmaps to 1bpp does not dither.
+ // making 1bpp brushes with a stipple does not dither. So we just manually
+ // implement they bayer dithering algorithm.
- if (MaskBitmap == NULL)
- {
- return FALSE;
- }
+ // Create a wxImage, don't initalize it
+ wxImage MaskImage(DSize.x, DSize.y, false);
- MaskDC.SelectObject(*MaskBitmap);
-
- // get a grey level hatched brush
-
// DragTransparency is between 0 and 100,
// and we need a grey level between 0 and 255.
INT32 GreyLevel = (DragTransparency * 255) / 100;
- // create the Brush and Pen
- wxBrush DragBrush(wxColour(GreyLevel, GreyLevel, GreyLevel), wxSOLID);
- wxPen MyPen(wxColour(0, 0, 0), 1, wxTRANSPARENT);
-
- // the rectangle to draw into
- wxRect DrawRect(0, 0, DSize.x, DSize.y);
+ // for (i=0; i<4*4*3; i++) ImageData[i]=GreyLevel;
+ // The above would be far too easy. wxWidgets doesn't seem to want to dither. Sigh
+ // write our own ordered dither! And neither do 1bpp wxBitmaps work as brushes
+ // sigh... And painting a 24bpp brush into a 1bpp bitmap dies horribly. Aaarrggghh
+ // Bayer table
+ INT32 OrderedDither[4*4]={1,9,3,11,13,5,15,7,4,12,2,10,16,8,14,6};
+ INT32 x, y;
- // select brushes and pens ..
- MaskDC.SetBrush(DragBrush);
- MaskDC.SetPen(MyPen);
+ unsigned char * pix=MaskImage.GetData();
- MaskDC.DrawRectangle(DrawRect);
+ 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;
+ // write three pixels
+ *pix++=thresh;
+ *pix++=thresh;
+ *pix++=thresh;
+ }
-PORTNOTE("other","Removed bitmap masking in drags")
-#ifndef EXCLUDE_FROM_XARALX
- // Now combine the DragMask with the transparency mask.
- if (DragMask)
+ MaskBitmap=new wxBitmap(MaskImage, 1);
+ if (MaskBitmap)
{
- // This needs to create a wxBitmap from DragMask
- // and OR it into the MaskDC
-
- WinBitmap* pMaskBmp = (WinBitmap*)DragMask->ActualBitmap;
- RGBQUAD* Palette = (RGBQUAD *) (pMaskBmp->BMInfo->bmiColors);
-
- // set the first colours to black and white
- Palette[0].rgbRed = Palette[0].rgbBlue = Palette[0].rgbGreen = 0;
- Palette[1].rgbRed = Palette[1].rgbBlue = Palette[1].rgbGreen = 255;
+ // Now combine the DragMask with the transparency mask.
+ if (DragMask)
+ {
- // set the reserved bytes to zero
- Palette[0].rgbReserved = Palette[1].rgbReserved = 0;
-
- wxMemoryDC MemDC;
- MemDC.CreateCompatibleDC(pMaskDC);
-
- // Make a Windows DDB from the Kernel Mask Bitmap
- HBITMAP hBmp = CreateDIBitmap(MemDC.m_hDC,
- (BITMAPINFOHEADER*)pMaskBmp->BMInfo,
- CBM_INIT,
- pMaskBmp->BMBytes,
- pMaskBmp->BMInfo,
- DIB_RGB_COLORS
- );
-
- // Get a CBitmap version to select into the MemoryDC
- CBitmap* WinMaskBmp = CBitmap::FromHandle(hBmp);
- CBitmap* OldBmp = MemDC.SelectObject(WinMaskBmp);
-
- // Now OR the Mask Bitmap into the MaskDC, so that
- // it 'masks' the transparency mask.
- MaskDC.Blit(DrawRect.x, DrawRect.y, DrawRect.width, DrawRect.height, &MemDC, 0, 0, wxOR);
-
- MemDC.SelectObject(OldBmp);
- WinMaskBmp->DeleteObject();
+ wxMemoryDC MaskDC;
+ MaskDC.SelectObject(*MaskBitmap);
+
+ // This needs to create a wxBitmap from DragMask
+ // and OR it into the MaskDC
+
+ CWxBitmap* pMaskBmp = (CWxBitmap*)DragMask->ActualBitmap;
+ RGBQUAD* Palette = (RGBQUAD *) (pMaskBmp->BMInfo->bmiColors);
+
+ // set the first colours to black and white
+ Palette[0].rgbRed = Palette[0].rgbBlue = Palette[0].rgbGreen = 0;
+ Palette[1].rgbRed = Palette[1].rgbBlue = Palette[1].rgbGreen = 255;
+
+ // set the reserved bytes to zero
+ Palette[0].rgbReserved = Palette[1].rgbReserved = 0;
+
+ UINT32 bpp=pMaskBmp->GetBPP();
+
+ wxMemoryDC MemDC;
+ wxBitmap MemBitmap(DSize.x, DSize.y, bpp);
+ MemDC.SelectObject(MemBitmap);
+
+ if (bpp>8)
+ bpp=32;
+
+ LPBYTE MemBBits;
+ LPBITMAPINFO MemBInfo = AllocDIB(DSize.x, DSize.y, bpp, &MemBBits);
+
+ GRenderRegion::StaticPlotBitmap(&MemDC, DIB_RGB_COLORS, MemBInfo, MemBBits, 0, 0, DSize.x, DSize.y, MaskBitmap->GetPalette(), 0, 0);
+
+ // Now OR the Mask Bitmap into the MaskDC, so that
+ // it 'masks' the transparency mask.
+ MaskDC.Blit(0, 0, DSize.x, DSize.y, &MemDC, 0, 0, wxOR);
+
+ // clean up the dc
+ MaskDC.SetBrush(*wxTRANSPARENT_BRUSH);
+ MaskDC.SetPen(*wxTRANSPARENT_PEN);
+ MaskDC.SelectObject(wxNullBitmap);
+ }
}
-#endif
- // clean up the dc
- MaskDC.SetBrush(*wxTRANSPARENT_BRUSH);
- MaskDC.SetPen(*wxTRANSPARENT_PEN);
- MaskDC.SelectObject(wxNullBitmap);
}
else
MaskBitmap = NULL;
@@ -598,7 +604,7 @@
if(!DragManagerOp::CurrentManager->CurrentDragInfo->DoesSolidDrag)
return TRUE;
-#ifndef __WXGTK__
+//#ifndef __WXGTK__
INT32 DragTransparency = DragManagerOp::CurrentManager->CurrentDragInfo->
GetDragTransparency();
// If the Drag Info says it wants to be transparent,
@@ -611,7 +617,7 @@
// If the Transparency Drag fails (eg. not enough resources under Win32s !!)
// then just fall though, and try a normal solid drag .....
}
-#endif
+//#endif
// offset mouse pos by drag offset
point += DragManagerOp::CurrentManager->CurrentDragInfo->SolidDragOffset;
@@ -744,7 +750,7 @@
MaskDC.SelectObject(*MaskBitmap);
- TempDC.Blit(0, 0, DSize.x, DSize.y, &MaskDC, 0, 0, wxAND);
+ TempDC.Blit(0, 0, DSize.x, DSize.y, &MaskDC, 0, 0, wxAND_INVERT);
wxBitmap OffScreenBmp(DSize.x, DSize.y);
wxMemoryDC OffScreenDC;
Xara