MACINTOSH C CARBON: A Hobbyist's Guide To Programming the Macintosh in C
Version 1.0
© 2001 K. J. Bricknell
CHAPTER 13
OFFSCREEN GRAPHICS WORLDS, PICTURES, CURSORS, AND ICONS
Offscreen Graphics Worlds
Introduction
An offscreen graphics world may be regarded as a virtual screen on which your application can draw a complex image without the user seeing the various steps involved. When your application draws into an offscreen graphics world, it draws into a part of memory not used by the video device. Thus the drawing process remains hidden from the user. When the drawing is completed, your application can copy the image from the offscreen graphics world to the active window using the CopyBits, CopyMask, or CopyDeepMask functions.
One of the key advantages of using an offscreen graphics world is speed. Copying a complex image from an offscreen graphics world to the active window is much faster than performing all the steps necessary to draw the image on-screen.
Creating an Offscreen Graphics World
The NewGWorld function is used to create an offscreen graphics world:
QDErr NewGWorld(GWorldPtr *offscreenGWorld,short PixelDepth,const Rect *boundsRect,
CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags)
Returns: A result code: noErr (no error); paramErr (illegal parameter); cDepthErr (invalid pixel depth). |
|
offscreenGWorld |
Pointer to the created offscreen graphics world. |
PixelDepth |
Pixel depth of the offscreen graphics world. Possible depths are 0, 1, 2, 4, 8, 16, and 32 bits per pixel. Specifying 0 sets the pixel depth to equal the greatest depth of those screens whose boundary rectangles intersect the rectangle passed in the boundRect parameter. 0 also causes NewGWorld to use the GDevice structure for this deepest device rather than create a new one. |
boundsRect |
The offscreen pixel maps's boundary and port rectangle. Applications typically pass in the port rectangle of the window to which the image in the offscreen graphics world will be copied. |
cTable |
Handle to a ColorTable structure. May be NULL. |
aGDevice |
Handle to a GDevice structure. This is used only when noNewDevice is passed in the flags parameter. NewGWorld will attach this GDevice structure to the offscreen graphics world. Should be NULL if 0 is passed in the PixelDepth parameter. |
flags |
Any combination of pixPurge (make base address of pixel image purgeable), noNewDevice (do not create offscreen GDevice structure), useTempMem (create base address for offscreen pixel image in temporary memory, and keepLocal (keep offscreen pixel image in main memory) may be passed in this parameter. |
Calling NewGWorld results in the creation of a new offscreen graphics port. The function returns, in the offscreenGWorld parameter, a pointer of type GWorldPtr which points to the graphics port:
typedef CGrafPtr GWorldPtr;
NewGWorld also establishes a link to an existing GDevice structure, or creates a new GDevice structure and establishes a link to that.
Passing 0 in the PixelDepth parameter, a window's port rectangle in the boundsRect parameter, NULL in both the cTable and aGDevice parameters, and 0 in the flags parameter:
- Allows QuickDraw to optimise the CopyBits, CopyMask, and CopyDeepMask functions used to copy the image into the window's port rectangle.
- Results in the default behaviour of NewGWorld, meaning that the base address of the offscreen pixel image is unpurgeable, memory in the application heap is used, and graphics accelerators can cache the offscreen pixel image.
Setting the Graphics Port
Before drawing into the offscreen graphics port, you should save the current graphics port and the current device's GDevice structure by calling GetGWorld. The offscreen graphics port should then be made the current port by a call to SetGWorld. After drawing into the offscreen graphics world, you should call SetGWorld to restore the saved graphics port as the current graphics port.
SetGWorld takes two parameters (port and gdh). If the port parameter is of type CGrafPtr, the current port is set to the port specified in the port parameter and the current device is set to the device specified in the gdh parameter. If the port parameter is of type GWorldPtr, the current port is set to the port specified in the port parameter, the gdh parameter is ignored, and the current device is set to the device linked to the offscreen graphics world.
Preparing to Draw Into an Offscreen Graphics World
After setting the offscreen graphics world as the current port, you should use the GetGWorldPixMap function to get a handle to the offscreen pixel map. This is required as the parameter in a call to the LockPixels function, which you must call before drawing to, or copying from, an offscreen graphics world.
LockPixels prevents the base address of an offscreen pixel image from being moved while you draw into it or copy from it. It returns true if the base address is not purgeable, or if the base address has not been purged by the Memory Manager. If LockPixels returns false, (meaning that the base address of the offscreen pixel image has been purged) your application must call the UpdateGWorld function to reallocate the offscreen pixel image and then reconstruct it.
As a related matter, note that the baseAddr field of the PixMap structure for an offscreen graphics world contains a handle, whereas the baseAddr field for an onscreen pixel map contains a pointer. Accordingly, the GetPixBaseAddr function must be used to obtain a pointer to the PixMap structure for an offscreen graphics world.
Copying an Offscreen Image into a Window
After drawing the image in the offscreen graphics world, your application should call SetGWorld to set the active window as the current graphics port preparatory to copying the image to that port.
Your application copies the image from the offscreen graphics world into the target window using CopyBits (or, if masking is required, CopyMask or CopyDeepMask). Note that CopyBits, CopyMask and CopyDeepMask expect their source and destination parameters to be pointers to bit maps, not pixel maps. (These functions date from the era of black-and-white Macintoshes, which is why they expect a pointer to a bitmap. By looking at certain information in the graphics ports, CopyBits, CopyMask, and CopyDeepMask can establish that you have passed the functions a handle to a pixel map rather than the base address of a bitmap.)
You must leave the pixel image locked while you are drawing into an offscreen graphics world or copying an image from it, and you should call UnlockPixels when you are finished the copying or drawing operation. (Calling UnlockPixels will assist in preventing heap fragmentation.)
Updating an Offscreen Graphics World
If, for example, you are using an offscreen graphics world to support the window updating process, you can use UpdateGWorld to carry certain changes affecting the window (resizing the window, changes to the pixel depth of the screen, etc.) through to the offscreen graphics world. Calling UpdateGWorld obviates the necessity to recreate the offscreen graphics world and redraw its contents.
Disposing of an Offscreen Graphics World
You should call DisposeGWorld when your application no longer needs the offscreen graphics world.
Pictures
Introduction
QuickDraw provides a set of functions that allow your application to record a number of drawing commands and subsequently play the recording back. The collection of drawing commands is called a picture.
You begin defining a picture by calling the function OpenCPicture. Your subsequent drawing commands are collected in a data structure of type Picture. The picture defined within this data structure may be drawn by calling the function DrawPicture.
The OpenCPicture function creates pictures in the extended version 2 format, which allows your application to specify resolutions for pictures.
The Picture Structure
The Picture structure is as follows:
struct Picture
{
short picSize; // For a version 1 picture: its size.
Rect picFrame; // Bounding rectangle for the picture.
};
typedef struct Picture Picture;
typedef Picture *PicPtr;
typedef PicPtr *PicHandle;
Field Descriptions
picSize |
This field is irrelevant for version 2 format and extended version 2 format pictures.
|
To determine the size of a picture in memory, use the Memory Manager function GetHandleSize.
To determine the size of a picture in a file of type 'PICT', use File Manager function PBGetFInfo.
To determine the size of a picture in a resource of type 'PICT', use the Resource Manager function MaxSizeResource.
|
|
picFrame |
The picture's bounding rectangle. When you draw into a differently sized rectangle, DrawPicture uses this rectangle to scale the picture. |
... |
Compact drawing commands and picture comments constitute the rest of the structure, which is of variable length. |
Opcodes: Drawing Commands and Picture Comments
The variable length field in a Picture structure contains data in the form of opcodes, which DrawPicture uses to determine what objects to draw or what mode to change for subsequent drawing. Opcodes can also specify picture comments, which are created using PicComment. A picture comment contains data or commands for special processing by output devices, such as PostScript printers.
You typically use QuickDraw commands when drawing to the screen and picture comments to include any special drawing commands for printers.
'PICT' Files, Resources, and Scrap Format
File Manager and Resource Manager functions are used to read pictures from, and write pictures to, a disk. Scrap Manager functions are used to read pictures from, and write pictures to, the scrap. (See Chapter 20.)
A picture can be stored as a 'PICT' resource in the resource fork of any file type. A picture can also be stored in the data fork of a file of type 'PICT'. The first 512 bytes of the data fork of a 'PICT' file are a header that your application can use for its own purposes.
The Scrap Manager maintains a storage area to hold the last data cut or copied by the user. This area is called the scrap. If your application supports cut, copy, and paste operations, it necessarily reads data from, and writes data to, the scrap. There are two standard scrap data formats, one of which is 'PICT'.
Creating Pictures
As previously stated, you use the OpenCPicture function to begin defining a picture. You pass information to OpenCPicture in the form of an OpenCPicParams structure:
struct OpenCPicParams
{
Rect srcRect; // Optimal bounding rectangle.
Fixed hRes; // Best horizontal resolution.
Fixed vRes; // Best vertical resolution.
short version; // Set to -2.
short reserved1; // (Reserved. Set to 0.)
long reserved2; // (Reserved. Set to 0.)
};
typedef struct OpenCPicParams OpenCPicParams;
This structure provides a simple mechanism for specifying resolutions when creating images. For example, applications that create pictures from scanned images can specify resolutions higher than 72 dpi.
You call ClosePicture to complete the collection of drawing (and picture comment) commands that define your picture.
Clipping Region
Before calling OpenCPicture, you should always use ClipRect to specify an appropriate clipping region. If you fail to do this, OpenCPicture will use the clipping region contained in the current graphics port object. By default, this region is very large (the size of the coordinate plane). In this circumstance, if you scale the picture when drawing it, the clipping region can become invalid and your picture will not be drawn. By the same token, if your application has previously set the clipping region for some other purpose, part of your drawing may be clipped.
Ordinarily, you should set the clipping region to equal the port rectangle of the current graphics port before recording a picture.
Opening and Drawing Pictures
You can retrieve pictures saved in 'PICT' files using File Manager functions. (The demonstration program at Chapter 18 shows how to read pictures from, and save pictures to, files of type 'PICT'.) You can retrieve pictures saved in the resource forks of other file types using the GetPicture function. You can retrieve pictures stored in the scrap using the Carbon Scrap Manager function GetScrapFlavorData.
When the picture is retrieved, you can call DrawPicture to draw the picture. The second parameter passed in the DrawPicture function is the destination rectangle, which should be specified in coordinates local to the current graphics port. DrawPicture shrinks or stretches the picture as necessary to make it fit into this rectangle.
When you are finished using a picture stored as a 'PICT' resource, you should use the resource Manager function ReleaseResource to release its memory.
Saving Pictures
To save a picture in a 'PICT' file, you should use the appropriate File Manager functions.2 (Remember that the first 512 bytes of a 'PICT' file are reserved for your application's own purposes.) To save pictures in a 'PICT' resource, you should use the appropriate Resource Manager functions. To place a picture in the scrap (for example, to respond to the user choosing the Copy command to copy a picture to the clipboard), you should use the Carbon Scrap Manager function PutScrapFlavorData.
Gathering Picture Information
GetPictInfo may be used to gather information about a single picture, and GetPixMapInfo may be used to gather colour information about a single pixel map or bit map. Each of these functions returns colour and resolution information in a PictInfo structure. A PictInfo structure can also contain information about the drawing objects, fonts, and comments in a picture.
Cursors
Introduction
A cursor is a 16-by-16 pixel image defined in a black-and-white cursor ('CURS') or colour cursor ('crsr') resource.
Cursor Movement, Hot Spot, Visibility, and Shape
Cursor Movement
Cursor movement is not the responsibility of your application. When the mouse is moved by the user, low-level interrupt-driven mouse functions move the cursor on the screen.
Cursor Hot Spot
A cursor's hot spot is that part of the cursor that actually points to an object on the screen. Mouse clicks only have an effect on that object when the hot spot, not the cursor as a whole, is over the object. Fig 1 illustrates two cursors and their hot spot points. Note that the hot spot is a point, not a bit.
Cursor Visibility
Generally speaking, your application should always make the cursor visible. There are, however, exceptions to this rule. For example, in a text-editing application, the cursor should be made invisible, and the insertion point made to blink, when the user begins entering text. In such cases, the cursor should be made visible again only when the user moves the mouse.
Cursor Shape
Your application should change the shape of the cursor in the following circumstances:
- To indicate that the user is over a certain area of the screen. When the cursor is in the menu bar, for example, it should usually have an arrow shape. When the user moves the cursor over a text document, the cursor shape should be changed to the I-beam shape.
- To provide feedback to the user indicating that a time-consuming operation is in progress. For example, if an operation will take a second or two, you should provide feedback to the user by changing the cursor to the wristwatch cursor (on Mac OS 8/9) or wait cursor (Mac OS X) (see Fig 2). If the operation will take several seconds and the only options available to the user are to stop the operation, wait until it is completed, or switch to another application, you should display an animated cursor (on Mac OS 8/9 or wait cursor (on Mac OS X).
|
If the operation takes longer than several seconds, you should display a dialog with a progress indicator. (See Chapter 25.)
|
Non-Animated Cursors
System 'CURS' and 'crsr' Resources
The System file in the System Folder contains a number of 'CURS' and 'crsr' resources. The following constants represent the 'CURS' resource IDs for the basic cursors shown at Fig 2:
Constant |
Value |
Description |
iBeamCursor |
1 |
Used in text editing. |
crossCursor |
2 |
Often used for manipulating graphics. |
plusCursor |
3 |
Often used for selecting fields in an array. |
watchCursor |
4 |
Used when a short operation is in progress. |
The following lists the 'CURS' and 'crsr' resource IDs for the additional cursors shown at Fig 3:
Constant |
Value |
Description |
- |
-20488 |
Contextual menu arrow cursor. |
- |
-20487 |
Alias arrow cursor. |
- |
-20486 |
Copy arrow cursor. |
- |
-20452 |
Resize left cursor. |
- |
-20451 |
Resize right cursor. |
- |
-20450 |
Resize left/right cursor. |
|
- |
-20877 |
Pointing hand cursor. |
- |
-20876 |
Open hand pointer. |
- |
-20875 |
Close hand pointer. |
Custom 'CURS' and 'crsr' Resources
To create custom cursors, you need to define 'CURS' or 'crsr' resources in the resource file of your application.
Changing Cursor Shape
Your application is responsible for setting the initial appearance of the cursor and for changing the appearance of the cursor as appropriate for your application.
Methodology 1
One method for changing cursor shape involves first getting a handle to the relevant cursor (either a custom cursor or one of the system cursors shown at Figs 2 and 3) by specifying its resource ID in a call to GetCursor or GetCCursor. GetCursor returns a handle to a Cursor structure. GetCCursor returns a handle to a CCrsr structure. The address of the Cursor or CCrsr structure is then used in a call to SetCursor or SetCCursor to change the cursor shape.
Methodology 2
Mac OS 8.5 introduced a new method for setting the cursor. You must pass one of the following constants, which are of type ThemeCursor, in the inCursor parameter of the function SetThemeCursor:
Constant |
Value |
Comments |
kThemeArrowCursor |
0 |
|
kThemeCopyArrowCursor |
1 |
|
kThemeAliasArrowCursor |
2 |
|
kThemeContextualMenuArrowCursor |
3 |
|
kThemeIBeamCursor |
4 |
|
kThemeCrossCursor |
5 |
|
kThemePlusCursor |
6 |
|
kThemeWatchCursor |
7 |
Can animate. |
kThemeClosedHandCursor |
8 |
|
kThemeOpenHandCursor |
9 |
|
kThemePointingHandCursor |
10 |
|
kThemeCountingUpHandCursor |
11 |
Can animate. |
kThemeCountingDownHandCursor |
12 |
Can animate. |
kThemeCountingUpAndDownHandCursor |
13 |
Can animate. |
kThemeSpinningCursor |
14 |
Can animate. |
kThemeResizeLeftCursor |
15 |
|
kThemeResizeRightCursor |
16 |
|
kThemeResizeLeftRightCursor |
17 |
|
Changing Cursor Shape in Response to Mouse-Moved Events
Most applications set the cursor to the I-beam shape when the cursor is inside a text-editing area of a document, and they change the cursor to an arrow when the cursor is inside the scroll bars. Your application can achieve this effect by requesting that the Event Manager report mouse-moved events if the user moves the cursor out of a region you specify in the mouseRgn parameter to the WaitNextEvent function. Then, when a mouse-moved event is detected in your main event loop, you can use SetCursor, SetCCursor, or SetThemeCursor, to change the cursor to the appropriate shape.
Changing Cursor Shape in Response to Resume Events
Your application also needs to set the cursor shape in response to resume events, normally by setting the arrow cursor.
Hiding Cursors
You can remove the cursor image from the screen using HideCursor. You can hide the cursor temporarily using ObscureCursor or you can hide the cursor in a given rectangle by using ShieldCursor. To display a hidden cursor, use ShowCursor. Note, however, that you do not need to explicitly show the cursor after your application uses ObscureCursor because the cursor automatically reappears when the user moves the mouse again.
Animated Cursors - Mac OS 8/9
Methodology 1
Mac OS 8.5 introduced a new function (SetThemeAnimatedCursor) for animating a specified cursor type. You must pass one of the following constants, which are of type ThemeCursor, in the inCursor parameter of SetThemeAnimatedCursor:
Constant |
Value |
kThemeWatchCursor |
7 |
kThemeCountingUpHandCursor |
11 |
kThemeCountingDownHandCursor |
12 |
kThemeCountingUpAndDownHandCursor |
13 |
kThemeSpinningCursor |
14 |
Methodology 2
Another methodology requires:
- A series of 'CURS' (or 'crsr') resources that make up the "frames" of the animation.
- An 'acur' resource, which collects and orders the 'CURS' frames into a single animation, specifying the IDs of the resources and the sequence for displaying them in the animation.
System 'acur', and 'CURS' Resources
The System file contains an 'acur' resource (ID -6079), together the associated eight 'CURS' resources, for an animated watch cursor. It also contains eight 'CURS' resources (IDs -20701 to -20708) for an animated spinning (beach ball) cursor and six 'CURS' resources (IDs -20709 to -20714) for an animated counting hand cursor.
Custom 'acur' and 'CURS' Resources
Fig 4 shows the structure of a compiled 'acur' resource, and an 'acur' resource and one of its associated 'CURS' resources being created using Resorcerer.
Creating the Animated Cursor
The following are the steps required to create the animated cursor:
- If you do not intend to use the system-supplied 'acur' and associated 'CURS' resources:
- Create a series of 'CURS' resources that make up the "frames" of the animation.
- Create an 'acur' resource.
Animated Cursor - Mac OS X
When the Mac OS X wait (spinning) cursor appears automatically, it means that the application has stopped calling an event handling API for more than a certain period of time (about two seconds).
Your application can also turn the wait cursor on and off using the QuickDraw function QDDisplayWaitCursor. Passing true in the forceWaitCursor parameter turns the cursor on and passing false resumes automatic operation. The function keeps track of nested calls.
Icons
Icons and the Finder - Icon Families
As stated at Chapter 9, the Finder uses icons to graphically represents objects, such as files and directories. Chapter 9 also introduced the subject of icon families, and stated that your application should provide the Finder with a family of specially designed icons for the application file itself and for each of the document types created by the application.
Other Icons - Icons, Colour Icons and Small Icons
Other icon types are the icon, colour icon, and small icon. Note that the Finder does not use or display these icon types.
Icon ('ICON')
The icon is a black-and-white icon defined in an 'ICON' resource, which contains a 32-by-32 pixel bit map. Icons do not need a mask because they are always displayed on a white background.
Colour Icon ('cicn')
The colour icon is defined in a 'cicn' resource, which includes a pixel map, a bit map, and a mask. You can use a 'cicn' resource to define a colour icon with any width and height and with a bit depth up to 8. Fig 5 shows an 8-bit 32 by 32 pixel 'cicn' resource being created using Resorcerer.
Small Icon ('SICN')
The small icon is a black-and-white icon defined in a 'SICN' resource. Small icons are 12 by 16 pixels even though they are stored in a resource as 16-by-16 pixel bitmaps. Small icons are of doubtful utility in the Carbon era and will not be considered further.
|
Typically, only the Finder and Navigation Services use small icons.
|
Icons in Windows, Menus, and Alert and Dialogs
The icons provided by your application for the Finder (or the default system-suppled icons used by the Finder if your application does not provide its own icons) are displayed on the desktop. Your application can also display icons in its menus, dialogs and windows.
Icons in Windows
You can display icons of any kind in your windows using the appropriate Icon Utilities functions.
Icons in Menus
The Menu Manager allows you to display icons of resource types 'ICON' (icon) and 'cicn' (colour icon) in menu items. The procedure is as follows:
- Create the icon resource with a resource ID between 257 and 511. Subtract 256 from the resource ID to get a value called the icon number. Specify the icon number in the Icon field of the menu item definition.
- For an icon ('ICON'), specify 0x1D in the keyboard equivalent field of the menu item definition to indicate to the Menu Manager that the icon should be reduced to fit into a 16-by-16 pixel rectangle. Otherwise, specify a value of 0x00, or a value greater than 0x20, in the keyboard equivalent field to cause the Menu Manager to expand the item's rectangle so as to display the icon at its normal 32-by-32 pixel size. (A value greater than 0x20 in the keyboard equivalent field specifies the item's Command-key equivalent.)
- For a colour icon ('cicn'), specify 0x00 or a value greater than 0x20 in the keyboard equivalent field. The Menu Manager automatically enlarges the enclosing rectangle of the menu item according to the rectangle specified in the 'cicn' resource. (Colour icons, unlike icons, can be any height or width.)
When the menu is displayed, the Menu Manager first looks for a 'cicn' resource with the resource ID calculated from the icon number and displays that icon if it is found. If a 'cicn' resource is not found,the Menu Manager searches for an 'ICON' resource and plots it in either a 32-by-32 pixel rectangle or a 16-by-16 bit rectangle, depending on the value in the menu item's keyboard equivalent field.
Icons in Alerts and Dialogs
The Dialog Manager allows you to display icons of resource types 'ICON' (icon) and 'cicn' (colour icon) in Mac OS 8/9 alerts and in dialogs. You can display the icon alone or within an image well.
To display the icon alone, the procedure is to define an item of type Icon and provide the resource ID of the icon in the item list ('DITL') resource for the dialog. This will cause the Dialog Manager to automatically display the icon whenever you display the alert or dialog using Dialog Manager functions.
To display the icon within an image well, include an image well control in the alert or dialog's item list and assign the resource ID of the icon to the control's minimum value field.
If you provide a colour icon ('cicn') resource with the same resource ID as an icon ('ICON') resource, the Dialog Manager displays the colour icon instead of the black-and-white icon.
On Mac OS 8/9, you would ordinarily use the Alert function (which does not automatically draw a system-supplied alert icon in the alert), or the StandardAlert function with kAlertPlainAlert passed in the inAlertType parameter, when you wish to display an alert containing your own icon (for example, in your application's About... alert). If you invoke an alert using the NoteAlert, CautionAlert, or StopAlert functions, or with the StandardAlert function with an alert type constant of other than kAlertPlainAlert passed in the inAlertType parameter, the Dialog Manager draws the system-supplied black-and-white icon as well as your icon. Since your icon is drawn last, you can obscure the system-suppled icon by positioning your icon at the same coordinates.
Drawing and Manipulating Icons
The Icon Utilities allow your application (and the system software) to draw and manipulate icons of any standard resource type in windows and, subject to the limitations and requirements previously described, in menus and dialogs.
You need to use Icon Utilities functions only if:
- You wish to draw icons in your application's windows.
- You wish to draw icons which are not recognised by the Menu Manager and the Dialog Manager in, respectively, menu items and dialogs.
Preamble - Icon Families, Suites, and Caches
Icon Families
You can define individual icons of resource types 'ICON' and 'cicn' that are not part of an icon family and use Icon Utilities functions to draw them as required. However, to display an icon effectively at a variety of sizes and bit depths, you should provide an icon family in the same way that you provide icon families for the Finder. The advantage of providing an icon family is that you can then leave it to functions such as PlotIconID, which are used to draw icons, to automatically determine which icon in the icon family is best suited to the specified destination rectangle and current display bit depth.
Icon Suites
Some Icon Utilities functions take as a parameter a handle to an icon suite. Typically, an icon suite comprises of one or more handles to icon resources from a single icon family which have been read into memory. The GetIconSuite function may be used to get a handle to an icon suite, which can then be passed to functions such as PlotIconSuite to draw that icon in the icon suite best suited to the destination rectangle and current display bit depth.
An icon suite can contain handles to all of the six icon resources that an icon family can contain. Alternatively, it can contain handles to only a subset of those resources.
When you create an icon suite from icon family resources, the associated resource file should remain open while you use Icon Utilities functions.
Drawing an Icon Directly From a Resource
To draw an icon from an icon family without first creating an icon suite, use the PlotIconID function. PlotIconID determines, from the size of the specified destination rectangle and the current bit depth of the display device, which icon to draw. The icon drawn is as follows:
Destination Rectangle Size |
Icon Drawn |
Width or height greater than or equal to 32. |
The 32-by-32 pixel icon with the appropriate bit depth. |
Less than 32 by 32 pixels and greater than 16 pixels wide or 12 pixels high. |
The 16-by-16 pixel icon with the appropriate bit depth. |
Icon Stretching and Shrinking
PlotIconID may stretch or shrink the icon to fit depending on the size of the destination rectangle,. To draw icons without stretching them, PlotIconID requires that the destination rectangle have the same dimensions as one of the standard icons.
Icon Alignment and Transform
In addition to destination rectangle and resource ID parameters, PlotIconID takes alignment and transform parameters. Icon Utilities functions can automatically align an icon within its destination rectangle. (For example, an icon which is taller than it is wide can be aligned to either the right or left of its destination rectangle.) These functions can also transform the appearance of the icon in standard ways analogous to Finder states for icons.
Variables of type IconAlignmentType and IconTransformType should be declared and assigned values representing alignment and transform requirements. Constants, such as kAlignAbsoluteCenter and kTransformNone, are available to specify alignment and transform requirements.
Getting an Icon Suite and Drawing One of Its Icons
The GetIconSuite function, with the constant kSelectorAllAvailableData passed in the third parameter, is used to get all icons from an icon family with a specified resource ID and to collect the handles to the data for each icon into an icon suite. An icon from this suite may then be drawn using PlotIconSuite which, like PlotIconID, takes destination rectangle, alignment and transform parameters and stretches or shrinks the icon if necessary.
Drawing Specific Icons From an Icon Family
If you need to plot a specific icon from an icon family rather than use the Icon Utilities to automatically select a family member, you must first create an icon suite that contains only the icon of the desired resource type together with its corresponding mask. Constants such as kSelectorLarge4Bit (an icon selector mask for an 'icl4' icon) are used as the third parameter of the GetIconSuite call to retrieve the required family member. You can then use PlotIconSuite to plot the icon.
Drawing Icons That Are Not Part of an Icon Family
To draw icons of resource type 'ICON' and 'cicn' in menu items and dialogs, you use Menu Manager and Dialog Manager functions such as SetItemIcon and SetDialogItem.
To draw resources of resource type 'ICON' and 'cicn' in your application's windows, you use the following functions:
Resource Type |
Function to Get Icon |
Functions to Draw Icon |
'ICON' |
GetIcon |
PlotIconHandle PlotIcon |
'cicn' |
GetCIcon |
PlotCIconHandle PlotCIcon |
The functions in this list ending in Handle allow you to specify alignment and transforms for the icon.
Manipulating Icons
The GetIconFromSuite function may be used to get a handle to the pixel data for a specific icon from an icon suite. You can then use this handle to manipulate the icon data, for example, to alter its colour or add three-dimensional shading.
The Icon Utilities also include functions which allow you to perform an action on one or more icons in an icon suite and to perform hit testing on icons.
Main Constants, Data Types and Functions - Offscreen Graphics Worlds
Constants
Flags for GWorldFlags Parameter
pixPurgeBit = 0 Set to make base address for offscreen pixel image purgeable.
noNewDeviceBit = 1 Set to not create a new GDevice structure for offscreen world.
pixelsPurgeableBit = 6 Set to make base address for pixel image purgeable.
pixelsLockedBit = 7 Set to lock base address for offscreen pixel image.
Data Types
typedef CGrafPtr GWorldPtr;
typedef unsigned long GWorldFlags;
Functions
Creating, Altering, and Disposing of Offscreen Graphics Worlds
QDErr NewGWorld(GWorldPtr *offscreenGWorld,short PixelDepth,
const Rect *boundsRect,CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags);
GWorldFlags UpdateGWorld(GWorldPtr *offscreenGWorld,short pixelDepth,
const Rect *boundsRect,CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags);
void DisposeGWorld(GWorldPtr offscreenGWorld);
Saving and Restoring Graphics Ports and Offscreen Graphics Worlds
void GetGWorld(CGrafPtr *port,GDHandle *gdh);
void SetGWorld(CGrafPtr port,GDHandle gdh);
Managing an Offscreen Graphics World's Pixel Image
PixMapHandle GetGWorldPixMap(GWorldPtr offscreenGWorld);
Boolean LockPixels(PixMapHandle pm);
void UnlockPixels(PixMapHandle pm);
void AllowPurgePixels(PixMapHandle pm);
void NoPurgePixels(PixMapHandle pm);
GWorldFlags GetPixelsState(PixMapHandle pm);
void SetPixelsState(PixMapHandle pm,GWorldFlags state);
Ptr GetPixBaseAddr(PixMapHandle pm);
Boolean PixMap32Bit(PixMapHandle pmHandle);
Main Constants, Data Types and Functions - Pictures
Constants
Verbs for the GetPictInfo, GetPixMapInfo, and NewPictInfo calls
returnColorTable = 0x0001 Return a ColorTable structure.
returnPalette = 0x0002 Return a Palette structure.
recordComments = 0x0004 Return comment information.
recordFontInfo = 0x0008 Return font information.
suppressBlackAndWhite = 0x0010 Do not include black and white.
Colour Pick Methods for the GetPictInfo, GetPixMapInfo, and NewPictInfo calls
systemMethod = 0 System color pick method.
popularMethod = 1 Most popular set of colors.
medianMethod = 2 A good average mix of colors.
Data Types
Picture
struct Picture
{
short picSize; // For a version 1 picture: its size.
Rect picFrame; // Bounding rectangle for the picture
};
typedef struct Picture Picture;
typedef Picture *PicPtr;
typedef PicPtr *PicHandle;
OpenCPicParams
struct OpenCPicParams
{
Rect srcRect; // Optimal bounding rectangle.
Fixed hRes; // Best horizontal resolution.
Fixed vRes; // Best vertical resolution.
short version; // Set to -2
short reserved1; // (Reserved. Set to 0.)
long reserved2; // (Reserved. Set to 0.)
};
typedef struct OpenCPicParams OpenCPicParams;
PictInfo
struct PictInfo
{
short version; // This is always zero, for now.
long uniqueColors; // Number of actual colors in the picture(s)/pixmap(s).
PaletteHandle thePalette; // Handle to the palette information.
CTabHandle theColorTable; // Handle to the color table.
Fixed hRes; // Maximum horizontal resolution for all the pixmaps.
Fixed vRes; // Maximum vertical resolution for all the pixmaps.
short depth; // Maximum depth for all the pixmaps (in the picture).
Rect sourceRect; // Picture frame rectangle (contains the entire picture).
long textCount; // Total number of text strings in the picture.
long lineCount; // Total number of lines in the picture.
long rectCount; // Total number of rectangles in the picture.
long rRectCount; // Total number of round rectangles in the picture.
long ovalCount; // Total number of ovals in the picture.
long arcCount; // Total number of arcs in the picture.
long polyCount; // Total number of polygons in the picture.
long regionCount; // Total number of regions in the picture.
long bitMapCount; // Total number of bitmaps in the picture.
long pixMapCount; // Total number of pixmaps in the picture.
long commentCount; // Total number of comments in the picture.
long uniqueComments; // The number of unique comments in the picture.
CommentSpecHandle commentHandle; // Handle to all the comment information.
long uniqueFonts; // The number of unique fonts in the picture.
FontSpecHandle fontHandle; // Handle to the FontSpec information.
Handle fontNamesHandle; // Handle to the font names.
long reserved1;
long reserved2;
};
typedef struct PictInfo PictInfo;
typedef PictInfo *PictInfoPtr;
typedef PictInfoPtr *PictInfoHandle;
CommentSpec
struct CommentSpec
{
short count; // Number of occurrences of this comment ID.
short ID; // ID for the comment in the picture.
};
typedef struct CommentSpec CommentSpec;
typedef CommentSpec *CommentSpecPtr;
typedef CommentSpecPtr *CommentSpecHandle;
FontSpec
struct FontSpec
{
short pictFontID; // ID of the font in the picture.
short sysFontID; // ID of the same font in the current system file.
long size[4]; // Bit array of all the sizes found (1..127) (bit 0 means > 127).
short style; // Combined style of all occurrances of the font.
long nameOffset; // Offset into the fontNamesHdl handle for the font's name.
};
typedef struct FontSpec FontSpec;
typedef FontSpec *FontSpecPtr;
typedef FontSpecPtr *FontSpecHandle;
Functions
Creating and Disposing of Pictures
PicHandle OpenCPicture(const OpenCPicParams *newHeader);
void PicComment(short kind,short dataSize,Handle dataHandle);
void ClosePicture(void);
void KillPicture(PicHandle myPicture);
Drawing Pictures
void DrawPicture(PicHandle myPicture,const Rect *dstRect)
PicHandle GetPicture(Integer picID);
Collecting Picture Information
OSErr GetPictInfo(PicHandle thePictHandle,PictInfo *thePictInfo,short verb,
short colorsRequested,short colorPickMethod,short version);
OSErr GetPixMapInfo(PixMapHandle thePixMapHandle,PictInfo *thePictInfo,short verb,
short colorsRequested,short colorPickMethod,short version);
OSErr NewPictInfo(PictInfoID *thePictInfoID,short verb,short colorsRequested,
short colorPickMethod,short version);
OSErr RecordPictInfo(PictInfoID thePictInfoID,PicHandle thePictHandle);
OSErr RecordPixMapInfo(PictInfoID thePictInfoID,PixMapHandle thePixMapHandle);
OSErr RetrievePictInfo(PictInfoID thePictInfoID,PictInfo *thePictInfo,
short colorsRequested);
OSErr DisposPictInfo(PictInfoID thePictInfoID);
Main Constants, Data Types and Functions - Cursors
Constants
iBeamCursor = 1
crossCursor = 2
plusCursor = 3
watchCursor = 4
Data Types
Cursor
struct Cursor
{
Bits16 data;
Bits16 mask;
Point hotSpot;
};
typedef struct Cursor Cursor;
typedef Cursor *CursPtr;
typedef CursPtr *CursHandle;
CCrsr
struct CCrsr
{
short crsrType; // Type of cursor.
PixMapHandle crsrMap; // The cursor's pixmap.
Handle crsrData; // Cursor's data.
Handle crsrXData; // Expanded cursor data.
short crsrXValid; // Depth of expanded data (0 if none).
Handle crsrXHandle; // Future use.
Bits16 crsr1Data; // One-bit cursor.
Bits16 crsrMask; // Cursor's mask.
Point crsrHotSpot; // Cursor's hotspot.
long crsrXTable; // Private.
long crsrID; // Private.
};
typedef struct CCrsr CCrsr;
typedef CCrsr *CCrsrPtr;
typedef CCrsrPtr *CCrsrHandle;
Acur
struct Acur
{
short n; // Number of cursors (frames).
short index; // (Reserved.)
short frame1; // 'CURS' resource ID for frame #1.
short fill1; // (Recerved.)
short frame2; // 'CURS' resource ID for frame #2.
short fill2; // (Reserved.)
short frameN; // 'CURS' resource ID for frame #n.
short fillN; // (Reserved.)
};
typedef struct Acur acur, *acurPtr, **acurHandle;
Functions
Initialising Cursors
void InitCursor(void);
void InitCursorCtl(acurHandle newCursors);
Changing Black-and-White Cursors
CursHandle GetCursor(short cursorID);
void SetCursor(const Cursor *crsr);
Changing Colour Cursors
CCrsrHandle GetCCursor(short crsrID);
void SetCCursor(CCrsrHandle cCrsr);
void AllocCursor(void)
void DisposCCursor(CCrsrHandle cCrsr);
void DisposeCCursor(CCrsrHandle cCrsr);
Hiding, Showing , and Animating Cursors
void HideCursor(void);
void ShowCursor(void);
void ObscureCursor(void);
void ShieldCursor(const Rect *shieldRect,Point offsetPt);
void RotateCursor(long counter);
pascal void SpinCursor(short increment);
Appearance Manager Constants, Data Types and Functions - Cursors
Constants
KThemeArrowCursor = 0
KThemeCopyArrowCursor = 1
KThemeAliasArrowCursor = 2
KThemeContextualMenuArrowCursor = 3
KThemeIBeamCursor = 4
KThemeCrossCursor = 5
KThemePlusCursor = 6
KThemeWatchCursor = 7 // Can animate
KThemeClosedHandCursor = 8
KThemeOpenHandCursor = 9
KThemePointingHandCursor = 10
KThemeCountingUpHandCursor = 11 // Can animate
KThemeCountingDownHandCursor = 12 // Can animate
KThemeCountingUpAndDownHandCursor = 13 // Can animate
KThemeSpinningCursor = 14 // Can Animate
KThemeResizeLeftCursor = 15
KThemeResizeRightCursor = 16
KThemeResizeLeftRightCursor = 17
Data Types
typedef UInt32 ThemeCursor;
Functions
OSStatus SetThemeCursor(ThemeCursor inCursor);
OSStatus SetAnimatedThemeCursor(ThemeCursor inCursor,UInt32 inAnimationStep);
Mac OS X Only
void QDDisplayWaitCursor(Boolean forceWaitCursor);
Main Constants, Data Types and Functions - Icons
Constants
Types for Icon Families
kLarge1BitMask = FOUR_CHAR_CODE('ICN#')
kLarge4BitData = FOUR_CHAR_CODE('icl4')
kLarge8BitData = FOUR_CHAR_CODE('icl8')
kSmall1BitMask = FOUR_CHAR_CODE('ics#')
kSmall4BitData = FOUR_CHAR_CODE('ics4')
kSmall8BitData = FOUR_CHAR_CODE('ics8')
kMini1BitMask = FOUR_CHAR_CODE('icm#')
kMini4BitData = FOUR_CHAR_CODE('icm4')
kMini8BitData = FOUR_CHAR_CODE('icm8')
IconAlignmentType Values
kAlignNone = 0x00
kAlignVerticalCenter = 0x01
kAlignTop = 0x02
kAlignBottom = 0x03
kAlignHorizontalCenter = 0x04
kAlignAbsoluteCenter = kAlignVerticalCenter | kAlignHorizontalCenter
kAlignCenterTop = kAlignTop | kAlignHorizontalCenter
kAlignCenterBottom = kAlignBottom | kAlignHorizontalCenter
kAlignLeft = 0x08
kAlignCenterLeft = kAlignVerticalCenter | kAlignLeft
kAlignTopLeft = kAlignTop | kAlignLeft
kAlignBottomLeft = kAlignBottom | kAlignLeft
kAlignRight = 0x0C
kAlignCenterRight = kAlignVerticalCenter | kAlignRight
kAlignTopRight = kAlignTop | kAlignRight
kAlignBottomRight = kAlignBottom | kAlignRight
IconTransformType Values
kTransformNone = 0x00
kTransformDisabled = 0x01
kTransformOffline = 0x02
kTransformOpen = 0x03
kTransformLabel1 = 0x0100
kTransformLabel2 = 0x0200
kTransformLabel3 = 0x0300
kTransformLabel4 = 0x0400
kTransformLabel5 = 0x0500
kTransformLabel6 = 0x0600
kTransformLabel7 = 0x0700
kTransformSelected = 0x4000
kTransformSelectedDisabled = kTransformSelected | kTransformDisabled
kTransformSelectedOffline = kTransformSelected | kTransformOffline
kTransformSelectedOpen = kTransformSelected | kTransformOpen
IconSelectorValue Masks
kSelectorLarge1Bit = 0x00000001
kSelectorLarge4Bit = 0x00000002
kSelectorLarge8Bit = 0x00000004
kSelectorSmall1Bit = 0x00000100
kSelectorSmall4Bit = 0x00000200
kSelectorSmall8Bit = 0x00000400
kSelectorMini1Bit = 0x00010000
kSelectorMini4Bit = 0x00020000
kSelectorMini8Bit = 0x00040000
kSelectorAllLargeData = 0x000000FF
kSelectorAllSmallData = 0x0000FF00
kSelectorAllMiniData = 0x00FF0000
kSelectorAll1BitData = kSelectorLarge1Bit | kSelectorSmall1Bit | kSelectorMini1Bit
kSelectorAll4BitData = kSelectorLarge4Bit | kSelectorSmall4Bit | kSelectorMini4Bit
kSelectorAll8BitData = kSelectorLarge8Bit | kSelectorSmall8Bit | kSelectorMini8Bit
kSelectorAllAvailableData = (long)0xFFFFFFFF
Data Types
typedef short IconAlignmentType;
typedef short IconTransformType;
typedef UInt32 IconSelectorValue;
typedef Handle IconSuiteRef;
typedef Handle IconCacheRef;
CIcon
struct CIcon
{
PixMap iconPMap; // Icon's pixMap.
BitMap iconMask; // Icon's mask.
BitMap iconBMap; // Icon's bitMap.
Handle iconData; // Icon's data.
short iconMaskData[1]; // Icon's mask and BitMap data.
};
typedef struct CIcon CIcon;
typedef CIcon *CIconPtr;
typedef CIconPtr *CIconHandle;
Functions
Drawing Icons From Resources
OSErr PlotIconID(constRect *theRect,IconAlignmentType align,IconTransformType transform,
short theResID);
void PlotIcon(const Rect *theRect,Handle theIcon);
OSErr PlotIconHandle(const Rect *theRect,IconAlignmentType align,
IconTransformType transform,Handle theIcon);
void PlotCIcon(const Rect *theRect,CIconHandle theIcon);
OSErr PlotCIconHandle(const Rect *theRect,IconAlignmentType align,
IconTransformType transform,CIconHandle theIcon);
OSErr PlotSICNHandle(const Rect *theRect,IconAlignmentType align,
IconTransformType transform,Handle theSICN);
Getting Icons From Resources Which do Not Belong to an Icon Family
Handle GetIcon(short iconID);
CIconHandle GetCIcon(short iconID);
Disposing of Icons
OSErr DisposeCIcon(CIconHandle theIcon);
Creating an Icon Suite
OSErr GetIconSuite(Handle *theIconSuite,short theResID,IconSelectorValue selector);
OSErr NewIconSuite(Handle *theIconSuite);
OSErr AddIconToSuite(Handle theIconData,Handle theSuite,ResType theType);
Getting Icons From an Icon Suite
OSErr GetIconFromSuite(Handle *theIconData,Handle theSuite,ResType theType);
Drawing Icons From an Icon Suite
OSErr PlotIconSuite(const Rect *theRect,IconAlignmentType align,
IconTransformType transform,Handle theIconSuite);
Performing Operations on Icons in an Icon Suite
OSErr ForEachIconDo(handle theSuite,IconSelectorValue selector, IconActionUPP action,
void *yourDataPtr);
Disposing of Icon Suites
OSErr DisposeIconSuite(Handle theIconSuite,Boolean disposeData);
Converting an Icon Mask to a Region
OSErr IconSuiteToRgn(RgnHandle theRgn,const Rect *iconRect,
IconAlignmentType align,Handle theIconSuite);
OSErr IconIDToRegion(RgnHandle theRgn,const Rect *iconRect,
IconAlignmentType align,short iconID);
Determining Whether a Point or Rectangle is Within an Icon
Boolean PtInIconSuite(Point testPt,const Rect *iconRect,IconAlignmentType align,
Handle theIconSuite);
Boolean PtInIconID(Point testPt,const Rect *iconRect,IconAlignmentType align,
short iconID);
Boolean RectInIconSuite(const Rect *testRect,const Rect *iconRect,IconAlignmentType align,
Handle theIconSuite);
Boolean RectInIconID(const Rect *testRect,const Rect *iconRect,IconAlignmentType align,
short iconID);
Working With Icon Caches
OSErr MakeIconCache(Handle *theHandle,IconGetterProcPtr makeIcon,void *yourDataPtr);
OSErr LoadIconCache(const Rect *theRect,IconAlignmentType align,
IconTransformType transform,Handle theIconCache);
|