Make masks and alpha work for wxCOPY when blitting a selected bitmap from a
wxMemoryDC with an eye towards possibly doing more in the future. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47838 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -78,6 +78,12 @@ void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
|
||||
{
|
||||
CocoaTakeFocus();
|
||||
wxASSERT(m_cocoaNSImage);
|
||||
// Replace the bitmap's native data with a newly created one based on the
|
||||
// NSImage that has been (potentially) drawn upon. Note that this may and
|
||||
// probably will in many cases change the bitmap's format.
|
||||
// There is nothing we can do about this using pure Cocoa code. Even using
|
||||
// CGBitmapContext is not an option because it only supports a limited
|
||||
// number of bitmap formats. Specifically, 24-bpp is not supported.
|
||||
m_selectedBitmap.SetNSBitmapImageRep(
|
||||
[[NSBitmapImageRep alloc]
|
||||
initWithFocusedViewRect:NSMakeRect(0.0,0.0,
|
||||
@@ -96,6 +102,16 @@ void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
|
||||
m_selectedBitmap.GetHeight())];
|
||||
|
||||
// Now copy the data
|
||||
// Pass false to GetNSImage so the mask is not applied as an alpha channel.
|
||||
// Cocoa uses premultiplied alpha so applying the mask would cause all
|
||||
// color information masked out to be turned black which is undesirable.
|
||||
// FIXME: Currently, the mask will not be updated if any drawing occurs.
|
||||
// My only suggestion is for wxCocoa users to eschew the mask in favor
|
||||
// of an alpha channel or to recreate the mask after drawing.
|
||||
// The only way to fix this is to draw twice, once as normal and again
|
||||
// onto the mask to update it. That would require overriding every
|
||||
// single drawing primitive (e.g. DoDrawLine, DoDrawRectangle, etc.)
|
||||
// and would be a major undertaking.
|
||||
NSImage *nsimage = [m_selectedBitmap.GetNSImage(false) retain];
|
||||
[m_cocoaNSImage lockFocus];
|
||||
[nsimage drawAtPoint: NSMakePoint(0,0)
|
||||
@@ -142,14 +158,48 @@ bool wxMemoryDC::CocoaDoBlitOnFocusedDC(wxCoord xdest, wxCoord ydest,
|
||||
[transform concat];
|
||||
[flipTransform concat];
|
||||
|
||||
NSImage *sourceImage;
|
||||
if(useMask)
|
||||
{
|
||||
sourceImage = [m_cocoaNSImage copy];
|
||||
// Apply the mask to the copied image
|
||||
NSBitmapImageRep *maskRep = m_selectedBitmap.GetMask()->GetNSBitmapImageRep();
|
||||
NSImage *maskImage = [[NSImage alloc] initWithSize:[maskRep size]];
|
||||
[maskImage addRepresentation:maskRep];
|
||||
[sourceImage lockFocus];
|
||||
[maskImage compositeToPoint:NSZeroPoint operation:NSCompositeDestinationIn];
|
||||
[sourceImage unlockFocus];
|
||||
[maskImage release];
|
||||
}
|
||||
else
|
||||
{ // retain the m_cocoaNSImage so it has the same ownership as the copy done in the other case.
|
||||
sourceImage = [m_cocoaNSImage retain];
|
||||
}
|
||||
NSCompositingOperation drawingOp;
|
||||
switch(logicalFunc)
|
||||
{
|
||||
case wxCOPY:
|
||||
// Even if not using the mask, the image might have an alpha channel
|
||||
// so always use NSCompositeSourceOver. If the image is fully opaque
|
||||
// it works out the same as NSCompositeCopy.
|
||||
drawingOp = NSCompositeSourceOver;
|
||||
break;
|
||||
// FIXME: implement more raster ops
|
||||
default:
|
||||
wxLogDebug(wxT("wxCocoa does not support blitting with raster operation %d."), logicalFunc);
|
||||
// Just use the default operation.
|
||||
drawingOp = NSCompositeCopy;
|
||||
}
|
||||
|
||||
wxLogTrace(wxTRACE_COCOA,wxT("[m_cocoaNSImage isFlipped]=%d"), [m_cocoaNSImage isFlipped]);
|
||||
[m_cocoaNSImage drawAtPoint: NSMakePoint(0,0)
|
||||
[sourceImage drawAtPoint: NSMakePoint(0,0)
|
||||
fromRect: NSMakeRect(xsrc,
|
||||
m_selectedBitmap.GetHeight()-height-ysrc,
|
||||
width, height)
|
||||
operation: NSCompositeCopy // FIXME: raster ops
|
||||
operation: drawingOp
|
||||
fraction: 1.0];
|
||||
|
||||
[sourceImage release]; // It was either retained, copied, or allocated.
|
||||
[context restoreGraphicsState];
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user