Q:
I use two offscreen GWorlds as sources drawing to a destination
window on screen. Everything works great when both source
and destination are the same size, but what technique can
I use if the destination window is smaller? Specifically,
I don't want to shrink the source but would like to select
sub-rectangles from within the source.
A:
QTNewGWorldFromPtr can be used to create smaller GWorlds
which reference larger ones.
OSErr QTNewGWorldFromPtr(
GWorldPtr *gw, /* on return, a pointer
to the offscreen */
OSType pixelFormat, /* pixel format for
the new GWorld */
const Rect *boundsRect, /* bounds and port
rect for the offscreen
pixel map */
CTabHandle cTable, /* same as the source
GWorld */
GDHandle aGDevice, /* NULL */
GWorldFlags flags, /* 0 */
void *baseAddr, /* adjust this value
to the new origin */
long rowBytes ); /* get this value
from the source GWorld */
|
Adjust the origin by adding (x * pixelSize(in bytes) + y
* rowBytes) to the baseAddr of the source GWorlds PixMap,
then use this new value as the baseAddr parameter passed
into QTNewGWorldFromPtr.
The caller is responsible for passing in a baseAddr that
isn't going to change during the lifetime of the returned
GWorld, therefore applications should first call LockPixels
for the GWorld being used as the source before calling QTNewGWorldFromPtr.
Listing 1 illustrates this technique.
Listing 1. CreateNewSubGWorld
/*
CreateNewSubGWorld
This function returns a new GWorld that points to a subset
of the main source GWorld. It checks that the inSubRect
rectangle is a true subset of the source GWorlds rectangle,
otherwise the new GWorld would work in an unpredictable
fashion. It also locks the source PixMap if it's not
locked. The source GWorlds PixMap should not be unlocked
or disposed while the sub-GWorld (which is referencing
the same pixel data) is in use.
In inSrcGWorld - a pointer to the source GWorld
inSubRect - the sub rectangle for the
new GWorld
Out outSubGWorld - address of a GWorldPtr, returns
the new subset GWorld
*/
OSErr CreateNewSubGWorld(GWorldPtr inSrcGWorld,
const Rect *inSubRect,
GWorldPtr *outSubGWorld)
{
PixMapHandle hPixMap = NULL;
long theRowBytes = 0L;
Ptr theBaseAddr = NULL;
OSType thePixelFormat;
UInt32 offset = 0L;
Rect theSubRect = *inSubRect;
Rect theSrcRect;
// sanity checks
if (NULL == inSrcGWorld || NULL == outSubGWorld)
return paramErr;
GetPortBounds(inSrcGWorld, &theSrcRect);
if (theSubRect.top < theSrcRect.top ||
theSubRect.left < theSrcRect.left ||
theSubRect.bottom > theSrcRect.bottom ||
theSubRect.right > theSrcRect.right) return paramErr;
// get what we need from the source GWorld
hPixMap = GetGWorldPixMap(inSrcGWorld);
if (!(GetPixelsState(hPixMap) && pixelsLocked))
LockPixels(hPixMap);
theBaseAddr = GetPixBaseAddr(hPixMap);
theRowBytes = QTGetPixMapHandleRowBytes(hPixMap);
thePixelFormat = GETPIXMAPPIXELFORMAT(*hPixMap);
// calculate the new origin of the pixels -
// - pixelSize is in bits, so divide by 8
// to turn it to bytes then modify the base
// address to point to our new origin
offset = ((inSubRect->left * (**hPixMap).pixelSize / 8) +
(inSubRect->top * theRowBytes));
theBaseAddr += offset;
// coordinate system normalized 0, 0
OffsetRect(&theSubRect, -theSubRect.left, -theSubRect.top);
return QTNewGWorldFromPtr(outSubGWorld,
thePixelFormat,
&theSubRect,
(**hPixMap).pmTable,
NULL,
0,
(void *)theBaseAddr,
theRowBytes);
}
|
|
References:
Technical Q&A QA1007, "LockPixels and DisposeGWorld with QTNewGWorldFromPtr"
[Mar 20 2001]
|