Merged 47838 from trunk:
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/branches/WX_2_8_BRANCH@47860 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -78,6 +78,12 @@ void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
|
|||||||
{
|
{
|
||||||
CocoaTakeFocus();
|
CocoaTakeFocus();
|
||||||
wxASSERT(m_cocoaNSImage);
|
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(
|
m_selectedBitmap.SetNSBitmapImageRep(
|
||||||
[[NSBitmapImageRep alloc]
|
[[NSBitmapImageRep alloc]
|
||||||
initWithFocusedViewRect:NSMakeRect(0.0,0.0,
|
initWithFocusedViewRect:NSMakeRect(0.0,0.0,
|
||||||
@@ -96,6 +102,16 @@ void wxMemoryDC::DoSelect( const wxBitmap& bitmap )
|
|||||||
m_selectedBitmap.GetHeight())];
|
m_selectedBitmap.GetHeight())];
|
||||||
|
|
||||||
// Now copy the data
|
// 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];
|
NSImage *nsimage = [m_selectedBitmap.GetNSImage(false) retain];
|
||||||
[m_cocoaNSImage lockFocus];
|
[m_cocoaNSImage lockFocus];
|
||||||
[nsimage drawAtPoint: NSMakePoint(0,0)
|
[nsimage drawAtPoint: NSMakePoint(0,0)
|
||||||
@@ -142,14 +158,48 @@ bool wxMemoryDC::CocoaDoBlitOnFocusedDC(wxCoord xdest, wxCoord ydest,
|
|||||||
[transform concat];
|
[transform concat];
|
||||||
[flipTransform 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]);
|
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,
|
fromRect: NSMakeRect(xsrc,
|
||||||
m_selectedBitmap.GetHeight()-height-ysrc,
|
m_selectedBitmap.GetHeight()-height-ysrc,
|
||||||
width, height)
|
width, height)
|
||||||
operation: NSCompositeCopy // FIXME: raster ops
|
operation: drawingOp
|
||||||
fraction: 1.0];
|
fraction: 1.0];
|
||||||
|
|
||||||
|
[sourceImage release]; // It was either retained, copied, or allocated.
|
||||||
[context restoreGraphicsState];
|
[context restoreGraphicsState];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user