Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
CopyDeepMask.c
/* |
File: CopyDeepMask.c |
Contains: This snippet demonstrates the use of CopyDeepMask using 2 PICTS; |
one a photograph and the other a triangular mask. It uses 2 offscreen |
gworlds to hold the source and mask pixmaps. CopyDeepMask is then used |
to create the masked image and display it in the application window. The |
source, mask, and destination rectangles are all the same size in order |
avoid altering pixel sizes. |
Written by: KM |
Copyright: Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
08/2000 JM Carbonized, non-Carbon code is commented out |
for demonstration purposes. |
7/9/1999 KG Updated for Metrowerks Codewarror Pro 2.1 |
12/14/94 KM Fixed a bug in doEventLoop that was causing a bus error using |
EvenBetterBusError (bad things happen when you attempt to use an |
unitialized EventRecord!) |
11/22/93 KM Created |
*/ |
#ifdef __MWERKS__ |
// includes for MetroWerks CodeWarrior |
#include "CarbonPrefix.h" |
#include <Quickdraw.h> |
#include <QDOffscreen.h> |
#include <Windows.h> |
#include <Dialogs.h> |
#include <Menus.h> |
#include <Types.h> |
#include <Memory.h> |
#include <Fonts.h> |
//#include <OSEvents.h> |
#include <Events.h> |
#include <ToolUtils.h> |
#else |
#ifdef __APPLE_CC__ |
// includes for ProjectBuilder |
#include <Carbon/Carbon.h> |
#else |
// includes for MPW |
#include <Carbon.h> |
#endif |
#endif |
#define windID 128 |
#define inFront -1 |
#define sleepTime 30 |
#define srcPicID 130 |
#define maskPicID 131 |
Boolean continueThis; |
WindowPtr mainWindow; |
void InitToolbox(void); |
void doEventLoop(void); |
void doDrag (WindowPtr winPtr,Point mouseLoc); |
void doUpdateEvent(EventRecord *event); |
void main(void) |
{ |
InitToolbox(); |
mainWindow = GetNewCWindow(windID,nil,(WindowPtr)inFront); |
continueThis = true; |
doEventLoop(); |
} |
void InitToolbox(void) |
{ |
/*MoreMasters(); |
MoreMasters(); |
MoreMasters(); |
MaxApplZone(); |
InitGraf((Ptr)&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
//InitDialogs((long)nil); |
TEInit();*/ |
MoreMasterPointers(3); |
InitCursor(); |
FlushEvents(everyEvent, 0); |
} |
void doEventLoop(void) |
{ |
EventRecord event; |
WindowPtr window; |
short hitArea; |
while (continueThis) |
{ |
if (WaitNextEvent(everyEvent,&event,sleepTime,nil)) |
if (event.what == updateEvt) |
doUpdateEvent(&event); |
else if (event.what == mouseDown) |
{ |
hitArea = FindWindow(event.where,&window); |
if (hitArea == inDrag) |
doDrag(window,event.where); |
else if (hitArea == inGoAway) |
if (TrackGoAway (window,event.where)) |
return; |
} |
} |
} |
void doDrag (WindowPtr winPtr,Point mouseLoc) |
{ |
Rect dragRect; |
Rect bndsRect; |
BitMap bitMap; |
//bndsRect = qd.screenBits.bounds; /*screenBits is a QuickDraw global variable with the same structure as portBits (BitMap)*/ |
bndsRect = GetQDGlobalsScreenBits(&bitMap)->bounds; //must use accessor functions to get at the global Quickdraw variable in Carbon |
InsetRect(&dragRect,10,10); |
DragWindow(winPtr,mouseLoc,&bndsRect); |
} |
void doUpdateEvent(EventRecord *event) |
{ |
#pragma unused (event) |
Rect bndsRectSrc,bndsRectMask,srcRect,maskRect,destRect; |
QDErr gWorldErr; |
GWorldPtr offscreenGWorldSource; |
GWorldPtr offscreenGWorldMask; |
short pixelDepthSource = 32; |
short pixelDepthMask = 1; |
GWorldFlags flags = 0; |
GDHandle currGDevice; |
GWorldPtr currGWorldPort; |
PicHandle srcPicHdl; |
PicHandle maskPicHdl; |
PixMapHandle srcPMHdl; |
PixMapHandle maskPMHdl; |
Boolean pmLock= false; |
GrafPtr oldPort; |
GetPort(&oldPort); |
//Set up the bounds rectangle for the source and mask gWorlds |
bndsRectSrc.top = 32; |
bndsRectSrc.left = 64; |
bndsRectSrc.bottom = 160; |
bndsRectSrc.right = 192; |
bndsRectMask = bndsRectSrc; |
//Make the source,mask and destination rectangles the same |
// size as the associated gWorlds |
srcRect = bndsRectSrc; |
maskRect = bndsRectSrc; |
destRect = bndsRectSrc; |
//Fetch the current port and gdevice and save them for later |
GetGWorld(&currGWorldPort,&currGDevice); |
//Set up our source and mask gWorlds |
gWorldErr = NewGWorld(&offscreenGWorldSource,pixelDepthSource,&bndsRectSrc,0,nil,flags); |
if(gWorldErr != noErr) |
DebugStr("\pthe first NewGWorld call failed"); |
else |
{ |
//lock the offscreen buffer |
srcPMHdl = GetGWorldPixMap(offscreenGWorldSource); |
pmLock = LockPixels(srcPMHdl); |
if (!pmLock) |
DebugStr("\pthe first LockPixels call failed"); |
} |
gWorldErr = NewGWorld(&offscreenGWorldMask,pixelDepthMask,&bndsRectMask,0,nil,flags); |
if(gWorldErr != noErr) |
DebugStr("\pthe second NewGWorld call failed"); |
else |
{ |
//lock the offscreen buffer |
maskPMHdl = GetGWorldPixMap(offscreenGWorldMask); |
pmLock = LockPixels(maskPMHdl); |
if (!pmLock) |
DebugStr("\pthe second LockPixels call failed"); |
} |
//Set the current graphics world to my offscreen source and draw into it |
SetGWorld((CGrafPtr) offscreenGWorldSource,nil); |
srcPicHdl = GetPicture(srcPicID); |
if (srcPicHdl==nil) |
DebugStr("\pthe first call to GetPicture failed"); |
EraseRect(&srcRect); |
HLock((Handle)srcPicHdl); |
DrawPicture(srcPicHdl,&srcRect); |
HUnlock((Handle) srcPicHdl); |
//Set the current graphics world to my offscreen mask and draw into it |
SetGWorld((CGrafPtr)offscreenGWorldMask,nil); |
GetPicture(maskPicID); |
maskPicHdl = GetPicture(maskPicID); |
if (maskPicHdl==nil) |
DebugStr("\pthe second call to GetPicture failed"); |
EraseRect(&maskRect); |
HLock((Handle)maskPicHdl); |
DrawPicture(maskPicHdl,&maskRect); |
HUnlock((Handle)maskPicHdl); |
//Set the current graphics port to my application window for drawing into |
SetGWorld(GetWindowPort(mainWindow),nil); |
BeginUpdate(mainWindow); |
//Now for the whole point of this. . .call CopyDeepMask |
/*CopyDeepMask( |
(BitMap *) &(offscreenGWorldSource->portPixMap), |
(BitMap *) &(offscreenGWorldMask->portPixMap), |
&(mainWindow->portBits), |
&srcRect, |
&maskRect, |
&destRect, |
srcCopy, |
nil);*/ |
CopyDeepMask( |
(BitMap *) *(GetPortPixMap(offscreenGWorldSource)), |
(BitMap *) *(GetPortPixMap(offscreenGWorldMask)), |
GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), |
&srcRect, |
&maskRect, |
&destRect, |
srcCopy, |
nil); |
EndUpdate(mainWindow); |
//Unlock the offscreen buffer |
UnlockPixels(srcPMHdl); |
UnlockPixels(maskPMHdl); |
//Restore the saved port and gdevice |
SetGWorld(currGWorldPort,currGDevice); |
//Dispose of the gWorlds |
DisposeGWorld(offscreenGWorldSource); |
DisposeGWorld(offscreenGWorldMask); |
SetPort(oldPort); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-10