Important: The information in this document is obsolete and should not be used for new development.
CopyBits
You can use theCopyBits
procedure to copy a portion of a bitmap or a pixel map from one graphics port (or offscreen graphics world) into another graphics port.
PROCEDURE CopyBits (srcBits,dstBits: BitMap; srcRect,dstRect:\xF0Rect; mode:\xF0Integer; maskRgn:\xF0RgnHandle);
srcBits
- The source
BitMap
record.dstBits
- The destination
BitMap
record.srcRect
- The source rectangle.
dstRect
- The destination rectangle.
mode
- One of the eight source modes in which the copy is to be performed.
maskRgn
- A region to use as a clipping mask.
DESCRIPTION
TheCopyBits
procedure transfers any portion of a bitmap between two basic graphics ports, or any portion of a pixel map between two color graphics ports. You can useCopyBits
to move offscreen graphic images into an onscreen window, to blend colors for the image in a pixel map, and to shrink and expand images.Specify a source bitmap in the
srcBits
parameter and a destination bitmap in thedstBits
parameter. When copying images between color graphics ports, you must coerce eachCGrafPort
record to aGrafPort
record, dereference theportBits
fields of each, and then pass these "bitmaps" in thesrcBits
anddstBits
parameters. If your application copies a pixel image from a color graphics port calledMyColorPort
, for example, you could specifyGrafPtr(MyColorPort)^.portBits
in thesrcBits
parameter. In aCGrafPort
record, the high 2 bits of theportVersion
field are set. This field, which shares the same position in aCGrafPort
record as theportBits.rowBytes
field in aGrafPort
record, indicates toCopyBits
that you have passed it a handle to a pixel map rather than a bitmap.Using the
srcRect
anddstRect
parameters, you can specify identically or differently sized source and destination rectangles; for differently sized rectangles,CopyBits
scales the source image to fit the destination. As shown in Figure 3-27, for example, if the bit image is a circle in a square source rectangle, and the destination rectangle is not square, the bit image appears as an oval in the destination. When you specify rectangles in thesrcRect
anddstRect
parameters, use the local coordinate systems of, respectively, the source and destination graphics ports.Figure 3-27 Using
CopyBits
to stretch an image
In themode
parameter, specify one of the following source modes for transferring the bits from a source bitmap to a destination bitmap:
CONST {source modes for basic graphics ports} srcCopy = 0; {where source pixel is black, force } { destination pixel black; where source pixel } { is white, force destination pixel white} srcOr = 1; {where source pixel is black, force } { destination pixel black; where source pixel } { is white, leave destination pixel unaltered} srcXor = 2; {where source pixel is black, invert } { destination pixel; where source pixel is } { white, leave destination pixel unaltered} srcBic = 3; {where source pixel is black, force } { destination pixel white; where source pixel } { is white, leave destination pixel unaltered} notSrcCopy = 4; {where source pixel is black, force } { destination pixel white; where source pixel } { is white, force destination pixel black} notSrcOr = 5; {where source pixel is black, leave } { destination pixel unaltered; where source } { pixel is white, force destination pixel black} notSrcXor = 6; {where source pixel is black, leave } { destination pixel unaltered; where source } { pixel is white, invert destination pixel} notSrcBic = 7; {where source pixel is black, leave } { destination pixel unaltered; where source } { pixel is white, force destination pixel white}On computers running System 7, you can add dithering to any source mode by adding the following constant or the value it represents to the source mode:
CONST ditherCopy = 64; {add to source mode for dithering}Dithering is a technique that mixes existing colors to create the effect of additional colors. It also improves images that you shrink or that you copy from a direct pixel device to an indexed device. TheCopyBits
procedure always dithers images when shrinking them between pixel maps on direct devices.To use highlighting, you can add this constant or its value to the source mode:
CONST hilite= 50; {add to source or pattern mode for highlighting}With highlighting, QuickDraw replaces the background color with the highlight color when your application copies images between graphics ports. This has the visual effect of using a highlighting pen to select the object. (The global variableHiliteRGB
is read from parameter RAM when the machine starts. Basic graphics ports use the color stored in theHiliteRGB
global variable as the highlight color. Color graphics ports default to theHiliteRGB
global variable, but can be overridden by theHiliteColor
procedure, described in the chapter "Color QuickDraw.")When transferring pixels from a source pixel map to a destination pixel map, Color QuickDraw interprets the source mode constants differently than basic QuickDraw does. These constants have the following effects under Color QuickDraw:
CONST {source modes for color graphics ports} srcCopy = 0;{determine how close the color of the source } { pixel is to black, and assign this relative } { amount of foreground color to the } { destination pixel; determine how close the } { color of the source pixel is to white, and } { assign this relative amount of background } { color to the destination pixel} srcOr = 1;{determine how close the color of the source } { pixel is to black, and assign this relative } { amount of foreground color to the } { destination pixel} srcXor = 2;{where source pixel is black, invert the } { destination pixel--for a colored destination } { pixel, use the complement of its color } { if the pixel is direct, invert its index if } { the pixel is indexed} srcBic = 3;{determine how close the color of the source } { pixel is to black, and assign this relative } { amount of background color to the } { destination pixel} notSrcCopy = 4;{determine how close the color of the source } { pixel is to black, and assign this relative } { amount of background color to the } { destination pixel; determine how close the } { color of the source pixel is to white, and } { assign this relative amount of foreground } { color to the destination pixel} notSrcOr = 5; {determine how close the color of the source } { pixel is to white, and assign this relative } { amount of foreground color to the } { destination pixel} notSrcXor = 6; {where source pixel is white, invert the } { destination pixel--for a colored destination } { pixel, use the complement of its color } { if the pixel is direct, invert its index if } { the pixel is indexed} notSrcBic = 7; {determine how close the color of the source } { pixel is to white, and assign this relative } { amount of background color to the } { destination pixel}When you useCopyBits
on a computer running Color QuickDraw, you can also specify one of the following transfer modes in themode
parameter:
CONST {arithmetic transfer modes available in Color QuickDraw} blend = 32; {replace destination pixel with a blend } { of the source and destination pixel } { colors; if the destination is a bitmap or } { 1-bit pixel map, revert to srcCopy mode} addPin = 33; {replace destination pixel with the sum of } { the source and destination pixel colors-- } { up to a maximum allowable value; if } { the destination is a bitmap or } { 1-bit pixel map, revert to srcBic mode} addOver = 34; {replace destination pixel with the sum of } { the source and destination pixel colors-- } { but if the value of the red, green, or } { blue component exceeds 65,536, then } { subtract 65,536 from that value; if the } { destination is a bitmap or 1-bit } { pixel map, revert to srcXor mode} subPin = 35; {replace destination pixel with the } { difference of the source and destination } { pixel colors--but not less than a minimum } { allowable value; if the destination } { is a bitmap or 1-bit pixel map, revert to } { srcOr mode} transparent = 36; {replace the destination pixel with the } { source pixel if the source pixel isn't } { equal to the background color} addMax = 37; {compare the source and destination pixels, } { and replace the destination pixel with } { the color containing the greater } { saturation of each of the RGB components; } { if the destination is a bitmap or } { 1-bit pixel map, revert to srcBic mode} subOver = 38; {replace destination pixel with the } { difference of the source and destination } { pixel colors--but if the value of the } { red, green, or blue component is } { less than 0, add the negative result to } { 65,536; if the destination is a bitmap or } { 1-bit pixel map, revert to srcXor mode} adMin = 39; {compare the source and destination pixels, } { and replace the destination pixel with } { the color containing the lesser } { saturation of each of the RGB components; } { if the destination is a bitmap or } { 1-bit pixel map, revert to srcOr mode}You can pass a region handle in theMaskRgn
parameter to specify a mask region; the resulting image is always clipped to this mask region and to the boundary rectangle of the destination bitmap. If the destination bitmap is the current graphics port's bitmap, it's also clipped to the intersection of the graphics port's clipping region and visible region. If you don't want to clip to a masking region, just passNIL
for themaskRgn
parameter.SPECIAL CONSIDERATIONS
When you use theCopyBits
procedure to transfer an image between pixel maps, the source and destination images may be of different pixel depths, of different sizes, and they may have different color tables. However,CopyBits
assumes that the destination pixel map uses the same color table as the color table for the currentGDevice
record. (This is because the Color Manager requires an inverse table for translating the color table from the source pixel map to the destination pixel map.)The
CopyBits
procedure applies the foreground and background colors of the current graphics port to the image in the destination pixel map (or bitmap), even if the source image is a bitmap. This causes the foreground color to replace all black pixels in the destination and the background color to replace all white pixels. To avoid unwanted coloring of the image, use theRGBForeColor
procedure to set the foreground to black and use theRGBBackColor
procedure to set the background to white before callingCopyBits
.The source bitmap or pixel map must not occupy more memory than half the available stack space. The stack space required by
CopyBits
is roughly five times the value of therowBytes
field of the source pixel map: onerowBytes
value for the pixel map (or bitmap), an additionalrowBytes
value for dithering, anotherrowBytes
value when stretching or shrinking the source pixel map into the destination, anotherrowBytes
value for any color map changing, and a fifth additionalrowBytes
value for any color aliasing. If there is insufficient memory to complete aCopyBits
operation in Color QuickDraw, theQDError
function (described in the chapter "Color QuickDraw" in this book) returns the result code -143.If you use
CopyBits
to copy between two graphics ports that overlap, you must first use theLocalToGlobal
procedure to convert to global coordinates, and then specify the global variablescreenBits
for both thesrcBits
anddstBits
parameters.The
CopyBits
procedure may move or purge memory blocks in the application heap. Your application should not call this procedure at interrupt time.If you are reading directly from a NuBus
\x89 video card with a base address of Fs00000 and there is not a card in the slot (s-1) below it, CopyBits
reads addresses less than the base address of the pixel map. This causes a bus error. To work around the problem, remap thebaseAddr
field of the pixel map in your video card to at least 20 bytes above the NuBus boundary; an address link of Fs000020 precludes the problem.SEE ALSO
Listing 3-11 on page 3-29 illustrates how to useCopyBits
to scale an image when copying it from one window into another. Source modes are described in "Boolean Transfer Modes With 1-Bit Pixels" beginning on page 3-7. Plate 2 at the front of this book illustrates how to useCopyBits
to colorize an image in a color graphics port; Listing 4-5 on page 4-26 in the chapter "Color QuickDraw" shows the sample code that produced this plate. Listing 6-1 on page 6-5 in the chapter "Offscreen Graphics Worlds" illustrates how to useCopyBits
to copy an image from an offscreen graphics world to an onscreen color graphics port.Dithering, pixel maps, color graphics ports, the
RGBForeColor
andRGBBackColor
procedures, and color tables are explained in the chapter "Color QuickDraw." TheLocalToGlobal
procedure is described in the chapter "Basic QuickDraw." TheGDevice
record is described in the chapter "Graphics Devices." Inverse tables and the Color Manager are described in the chapter "Color Manager" in Advanced Color Imaging on the Mac OS."Copying Pixels Between Color Graphics Ports" in the chapter "Color QuickDraw" describes in greater detail how to use
CopyBits
to transfer colored images.The
CopyDeepMask
procedure (described on page 3-116) combines the functions of theCopyBits
andCopyMask
procedures. (TheCopyMask
procedure is described next.)