Important: The information in this document is obsolete and should not be used for new development.
Using Palettes With Offscreen Graphics Worlds
You can attach a palette to an offscreen graphics world; however, the only Palette Manager color usage categories that you can use to specify the types of colors in such a case arepmCourteous
andpmBlack
andpmWhite
. The other three color usage categories,pmTolerant
,pmAnimated
, andpmExplicit
, are interpreted in an offscreen graphics world aspmCourteous
, so they are of no use in this environment.This section first explains why and how you might use
pmCourteous
,pmBlack
, andpmWhite
and then shows how to simulate the effects of the other usage modifiers that you cannot use with an offscreen graphics world.After you've created a palette and assigned it to an offscreen graphics world, you can pass indexes from your palette to the
PmForeColor
andPmBackColor
functions and then draw in the offscreen world. The advantage of using courteous colors for the offscreen graphics world is that otherwise you must hard-code colors into your code. If you or a software localizer wants to change the colors in the offscreen worlds, you can do so by changing the'pltt
' resource that defines the palette rather than making code changes and recompiling the application.The
pmBlack
andpmWhite
usage modifiers simply allow you to specify which colors map to white and which to black in a black-and-white environment. If your application is working with red and dark blue, for example, both might get mapped to black on a 1-bit device. By assigningpmWhite
to one andpmBlack
to the other, you assure that they are always distinct.Explicit colors in a palette attached to an offscreen graphics world are interpreted as courteous. Therefore, instead of using a palette, you should convert your pixel value to an RGB color and use this as the foreground or background color. After setting the current graphics device to the offscreen graphics world to set the color environment, convert your pixel value to the corresponding RGB color using the
IndexToColor
function. Then you can draw by passing the RGB color to theRGBForeColor
andRGBBackColor
functions.Both tolerant and animated colors are interpreted as courteous in an offscreen graphics world. To use these types of colors, you can change the color environment of the offscreen graphics world by assigning it a whole new color table. Listing 1-6 shows how to do this.
Listing 1-6 Changing the color environment of an offscreen graphics world
#define clutID 150 #define numcolor 256 WindowPtr myWindow; CTabHandle mycolors; PaletteHandlesrcPalette GetGWorld (&SavePort, &SaveGD); mycolors = GetCTable (clutID); /* create a new window */ myWindow = NewCWindow(nil, &BaseRect, "", TRUE, zoomDocProc, (WindowPtr) -1, TRUE, nil); SetGWorld((CGrafPtr)myWindow, SaveGD); DrawGrowIcon (myWindow); (*mycolors)->ctFlags |= 0x4000; /* create a 256-color palette */ srcPalette = NewPalette (numcolor, mycolors, pmCourteous, 0); /* call DoSetInhibited to set color usage */ DoSetInhibited(pmCourteous); SetPalette ((WindowPtr) myWindow, srcPalette, TRUE); GetGWorld (&SavePort, &SaveGD); err = NewGWorld (&offscreenGWorld, 8, &InitWindowSize, mycolors, nil, nil); if (err) Debugger(); SetGWorld (offscreenGWorld, nil); EraseRect (&InitWindowSize); DrawPicture (ThePict, &InitWindowSize); SetGWorld (SavePort, SaveGD);After defining constants and declaring variables, the code in Listing 1-6 calls the QuickDrawGetGWorld
function to get and save the current graphics port so that you can restore it later. TheGetCTable
function retrieves a handle to a color table--from a'clut'
resource with ID 150--and stores it in themycolors
variable. You will use this color table for the offscreen graphics world and to create a palette.The
NewCWindow
function creates a new window and theSetGWorld
function assigns the current graphics port to this newly created window. TheDrawGrowIcon
function draws the window's size box.The next piece of code:
(*mycolors)->ctFlags |= 0x4000;sets bit 14 of thectFlags
field in the color table. Setting this bit synchronizes the color table to a palette. It does this by reinterpreting thectTable
field of the color table. Normally, this field contains an array ofColorSpec
entries, each of which contains a pixel value and a color. After setting bit 14 of thectFlags
field, each array in thectTable
field contains an index value and a color.The
NewPalette
function creates a new palette from the color table retrieved by theGetCTable
function. It contains 256 colors. Initially, all the colors are courteous and must match exactly (have a zero tolerance value).The
DoSetInhibited
function (whose code is not shown here) uses the Palette ManagerSetEntryUsage
function to change the usage categories of the palette when the usage of the palette changes. For example, it sets the colors in the palette to courteous, tolerant, explicit, or animated, depending on menu selections that a user makes. TheDoSetInhibited
function also inhibits certain colors in the palette depending on the bit-depth of the screen on which the window is currently displayed. In this way, the palette can contain entries for multiple screen bit-depths and will display properly on each type of screen. See "Selecting the Right Color Set" (page 1-25) for an example of how to create a palette that will display on screens with different bit-depths. The application callsDoSetInhibited
at this point to set the palette for the appropriate screen depth. SincepmCourteous
is passed toDoSetInhibited
, the usage category is not being changed.The
SetPalette
function assigns the newly created palette to the window created byNewCWindow
. TheGetGWorld
function gets and saves the current graphics port so it can be restored later. TheNewGWorld
function creates an offscreen graphics world and theSetGWorld
function sets the current graphics port to the newly created offscreen graphics world.The
EraseRect
andDrawPicture
functions erase and draw in the offscreen graphics world.The final
SetGWorld
function restores the graphics port to the window created by theNewCWindow
function. (To move the offscreen drawing to the screen, use the QuickDrawCopyBits
function--see the chapter, "QuickDraw Drawing," in Inside Macintosh: Imaging With QuickDraw for an example of how to do this.) The colors from the offscreen world--which come from the color table--match the colors of the window--which are controlled by the palette--because the color table and the palette are identical and synchronized. The advantage of this synchronization is that your application doesn't have to use the offscreen world's color matching algorithm to synchronize the colors from the offscreen world with the colors of the palette. Having to do so would greatly slow down your application, and speed is one of the primary reasons to use an offscreen world for drawing in the first place.