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.
Offscreen Region.c
/* |
File: Offscreen Region.c |
Contains: Print clipped offscreen: Takes a text string, turns it into a region and |
copies a clipped bitmap (just a pattern in this case, but it could be |
anything) to the printing grafPort. The effect is patterned text here, |
but any image could be showing through the text. |
You can also see the clipped image on the screen by turning on DrawStuffToScreen. |
Do this with qdToScreen below. |
This sample is a rewrite of the 'Offscreen region MaskRgn' sample. |
Written by: Tim Carroll and Ingrid Kelly |
Copyright: Copyright © 1994-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): |
7/26/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
11/96 Rewritten as 'Print clipped offscreen' to fix |
problems printing to PostScript printers (changed |
maskRgn to clipping the region before sending to the |
printing port since PS printers don't support maskRgn) |
*/ |
/************************************************************************************* |
# |
# CONDITIONALS |
# |
# There are a number of conditionals used to control exactly how the code runs. |
# |
# |
# qDebugging -- Whether or not additional debugging code should be inserted. With this |
# turned on, most errors will DebugStr almost immediately and return errors as the error |
# propagates up the calling chain. This is slower, but if you've found a weird bug, |
# this is the fastest way to replicate it. |
# |
# qdToScreen -- if this is set to 1, we draw to the screen instead of to the printer. |
# |
*************************************************************************************/ |
#define qDebugging 1 |
#define qdToScreen 0 |
/********************************************************************************* |
# ERROR HANDLING MACROS |
# |
# These macros can be used to implement nice error handling within a function. |
# Essentially, all errors jump to an error handler at the end of the function, which |
# should cleanup any leftovers and return the appropriate error result. |
# |
# Note that the error handlers take a message string. This should be a good |
# indication of the actual error, and it will appear when debugging is turned on. |
# |
# Note that any additional sanity checking code can be added to any function by using |
# |
#if qDebugging |
// do additional sanity checking here. |
#endif |
# |
# For example, this could be used to check the internal validity of an object before |
# taking an action. |
# |
*********************************************************************************/ |
#ifndef qDebugging |
#define qDebugging 0 |
#endif |
#if qDebugging |
#define SIGNAL_ERROR(msg) {DebugStr(msg); goto error;} |
#else |
#define SIGNAL_ERROR(msg) {goto error;} |
#endif |
#define FAIL_NIL(y,msg) if (y == NULL) SIGNAL_ERROR(msg) |
#define FAIL_OSERR(y,msg) if (y != noErr) SIGNAL_ERROR(msg) |
#define FAIL_FALSE(y,msg) if (!y) SIGNAL_ERROR(msg) |
#include <Printing.h> |
#include <QDOffscreen.h> |
#include <Fonts.h> |
void main (void); |
OSStatus PrintStuff (void); |
OSStatus DrawStuff (Rect theWorld); |
OSStatus PrepareOffScreens(void); |
OSStatus KillOffscreens(void); |
OSStatus DrawStuffToScreen(void); |
/*------ globals --------------------------------------------------------------------------*/ |
GWorldPtr gMaskOffscreen = NULL, gImageOffscreen = NULL; |
RgnHandle gMaskRegion = NULL; |
Rect gBoundsRect; |
/*------ main ----------------------------------------------------------------------------*/ |
// All main does is the standard mac init, followed by initializing the offscreens |
// and printing. |
/*----------------------------------------------------------------------------------------*/ |
void main(void) |
{ |
OSStatus theErr = noErr; |
InitGraf(&qd.thePort); |
InitFonts(); |
InitWindows(); |
InitMenus(); |
TEInit(); |
InitDialogs(nil); |
InitCursor(); |
theErr = PrepareOffScreens(); |
FAIL_OSERR (theErr, "\pError: Failed to prepare the offscreen environment") |
#if qdToScreen |
DrawStuffToScreen(); |
while (!Button()); |
#else |
PrintStuff (); |
#endif |
error: |
theErr = KillOffscreens(); |
} /* main */ |
/*------ PrepareOffScreens ---------------------------------------------------------------*/ |
// PrepareOffScreens sets up the GWorlds and does the actual text clipping. |
/*----------------------------------------------------------------------------------------*/ |
OSStatus PrepareOffScreens() |
{ |
OSStatus theErr = noErr; |
CGrafPtr savePort; |
GDHandle saveDevice; |
short fontNum; |
PixPatHandle image = NULL; |
PixMapHandle thePix = NULL; |
SetRect(&gBoundsRect,0,0,700,700); |
GetGWorld(&savePort,&saveDevice); |
/* Create the offscreen mask */ |
theErr = NewGWorld(&gMaskOffscreen, 1, &gBoundsRect, NULL, NULL, 0); |
FAIL_OSERR (theErr, "\pError: Failed to create mask GWorld") |
FAIL_NIL (gMaskOffscreen, "\pError: Failed to create mask GWorld") |
thePix = GetGWorldPixMap (gMaskOffscreen); |
FAIL_NIL (thePix, "\pError: Failed to retrieve mask pixmap") |
FAIL_FALSE (LockPixels(thePix), "\pError: Failed to lock the mask pixmap") |
SetGWorld(gMaskOffscreen,NULL); |
ClipRect(&gBoundsRect); |
ForeColor(blackColor); |
EraseRect(&gBoundsRect); |
GetFNum("\pTimes",&fontNum); |
TextFont(fontNum); |
TextFace(bold); |
TextSize(60); |
MoveTo(10,100); |
DrawString("\pHereÕs our string test"); |
SetGWorld (savePort,saveDevice); |
/* OK, the mask pixmap now has our string in it. Let's make a region from it. */ |
gMaskRegion = NewRgn(); |
theErr = QDError(); |
FAIL_OSERR (theErr, "\pError: Failed to create the mask region") |
FAIL_NIL (gMaskRegion,"\pError: Failed to create the mask region") |
theErr = BitMapToRegion(gMaskRegion,&((GrafPtr)gMaskOffscreen)->portBits); |
FAIL_OSERR (theErr, "\pError: Failed to convert the mask to a region") |
UnlockPixels (thePix); |
/* Build the offscreen pixmap that we'll draw to the printer */ |
theErr = NewGWorld(&gImageOffscreen, 8, &gBoundsRect, NULL, NULL, 0); |
FAIL_OSERR (theErr, "\pError: Failed to create image GWorld") |
FAIL_NIL (gImageOffscreen, "\pError: Failed to create image GWorld") |
thePix = GetGWorldPixMap (gImageOffscreen); |
FAIL_NIL (thePix, "\pError: Failed to retrieve image pixmap") |
FAIL_FALSE (LockPixels(thePix), "\pError: Failed to lock the image pixmap") |
/* We erase the image, then we use the mask clipping region and draw a color |
pattern to the pixmap */ |
image = GetPixPat(16); |
FAIL_NIL (image, "\pError: Failed to load the pixel pat") |
SetGWorld(gImageOffscreen,NULL); |
ClipRect (&gBoundsRect); |
EraseRect (&gBoundsRect); |
SetClip(gMaskRegion); |
FillCRect(&gBoundsRect, image); |
// restore the clip rect |
ClipRect (&gBoundsRect); |
UnlockPixels(thePix); |
// Cleanup and return noErr; |
goto cleanup; |
error: |
if (theErr == noErr) |
theErr = paramErr; |
cleanup: |
SetGWorld (savePort, saveDevice); |
if (image != NULL) |
DisposePixPat(image); |
return theErr; |
} |
/*------ DrawStuff -----------------------------------------------------------------------*/ |
// DrawStuff CopyBits from the offscreen into the printer/window port. |
/*----------------------------------------------------------------------------------------*/ |
OSStatus DrawStuff (Rect theRect) |
{ |
#pragma unused(theRect) |
OSStatus theErr = noErr; |
GrafPtr currentPort; |
PixMapHandle offscreenPix; |
/* Here's where we use CopyBits to copy from gImageOffscreen to the printer/window port */ |
GetPort(¤tPort); |
offscreenPix = GetGWorldPixMap(gImageOffscreen); |
FAIL_NIL (offscreenPix, "\pError: Failed to retrieve image pixmap") |
FAIL_FALSE (LockPixels(offscreenPix), "\pError: Failed to lock the image pixmap") |
CopyBits((BitMap*)*offscreenPix, |
&(currentPort)->portBits, |
&gBoundsRect, &gBoundsRect, srcCopy, NULL); |
UnlockPixels(offscreenPix); |
goto cleanup; |
error: |
if (theErr == noErr) |
theErr = paramErr; |
cleanup: |
return theErr; |
} /* DrawStuff */ |
/*------ PrintStuff ----------------------------------------------------------------------*/ |
// PrintStuff performs the generic printing calls for printing to the Macintosh Printing |
// Manager. |
// Sets the current port to the printer port. |
/*----------------------------------------------------------------------------------------*/ |
OSStatus PrintStuff () |
{ |
OSStatus theErr = noErr; |
GrafPtr oldPort; |
THPrint thePrRecHdl; |
TPPrPort thePrPort; |
TPrStatus theStatus; |
GetPort(&oldPort); |
thePrRecHdl = (THPrint) NewHandle (sizeof (TPrint)); |
theErr = MemError(); |
FAIL_OSERR( theErr, "\pError: Failed to allocate a TPrint record") |
FAIL_NIL (thePrRecHdl, "\pError: Failed to allocate a TPrint record") |
PrOpen(); //The PrOpen procedure prepares the current printer driver for use. |
theErr = PrError(); |
FAIL_OSERR (theErr, "\pError: Failed to open the printer driver") |
PrintDefault(thePrRecHdl); |
PrValidate(thePrRecHdl); |
theErr = PrError(); |
FAIL_OSERR (theErr, "\pError: Failed to create a valid print record") |
if (! PrStlDialog(thePrRecHdl)) |
goto cleanup; // user cancelled |
if (! PrJobDialog(thePrRecHdl)) |
goto cleanup; // user cancelled |
thePrPort = PrOpenDoc(thePrRecHdl, nil, nil); |
theErr = PrError(); |
if (theErr == noErr) |
{ |
PrOpenPage(thePrPort, nil); |
theErr = PrError(); |
if (theErr == noErr) |
{ |
// Finally, we're ready to draw! |
DrawStuff ((**thePrRecHdl).prInfo.rPage); |
PrClosePage(thePrPort); |
} |
PrCloseDoc(thePrPort); |
} |
theErr = PrError(); |
FAIL_OSERR (theErr, "\pError: Document failed to print") |
if ((((TPPrint)*thePrRecHdl)->prJob.bJDocLoop == bSpoolLoop)) |
PrPicFile(thePrRecHdl, nil, nil, nil, &theStatus); |
goto cleanup; |
error: |
if (theErr == noErr) |
theErr = paramErr; |
cleanup: |
SetPort(oldPort); |
PrClose(); |
if (thePrRecHdl) |
DisposeHandle ((Handle) thePrRecHdl); |
return theErr; |
} /* PrintStuff */ |
/*------ KillOffscreens ------------------------------------------------------------------*/ |
// KillOffscreens cleans up the offscreens. |
/*----------------------------------------------------------------------------------------*/ |
OSStatus KillOffscreens() |
{ |
if (gMaskOffscreen) |
DisposeGWorld(gMaskOffscreen); |
if (gImageOffscreen) |
DisposeGWorld(gImageOffscreen); |
if (gMaskRegion) |
DisposeRgn(gMaskRegion); |
return noErr; |
} /* KillOffscreens */ |
/*------ DrawStuffToScreen ------------------------------------------------------------------*/ |
// DrawStuffToScreen sets up the window port. |
// Sets the current port to the window port. |
/*----------------------------------------------------------------------------------------*/ |
OSStatus DrawStuffToScreen(void) |
{ |
WindowRef theWindow = NULL; |
Rect bounds = gBoundsRect; |
OSStatus theErr = noErr; |
GrafPtr savePort; |
GetPort (&savePort); |
OffsetRect (&bounds, 30,30); |
theWindow = NewCWindow(NULL, &bounds, "\pFoo", true, 0, (WindowRef)-1, false, 0); |
FAIL_NIL (theWindow, "\pError: Failed to create the window") |
SetPortWindowPort (theWindow); |
theErr = DrawStuff(gBoundsRect); |
goto cleanup; |
error: |
if (theErr == noErr) |
theErr = paramErr; |
cleanup: |
SetPort (savePort); |
return theErr; |
} /* DrawStuffToScreen */ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-26