mirror of
https://github.com/aaronsgiles/JPEGView.git
synced 2024-06-06 21:29:27 +00:00
92bdb55672
These are the sources for the final official release of JPEGView for the Mac, back in 1994.
1 line
49 KiB
C
1 line
49 KiB
C
/*********************************************************/
|
|
/* This source code copyright (c) 1991-2001, Aaron Giles */
|
|
/* See the Read Me file for licensing information. */
|
|
/* Contact email: mac@aarongiles.com */
|
|
/*********************************************************/
|
|
|
|
//=====================================================================================
|
|
// Generic includes for Macintosh headers
|
|
//=====================================================================================
|
|
|
|
#if THINK_C
|
|
#include "THINK.Header"
|
|
#include <stddef.h>
|
|
#elif applec
|
|
#pragma load ":Headers:MPW.Header"
|
|
#elif __MWERKS__
|
|
//#include "MW.Header"
|
|
#else
|
|
#include "JPEGView.h"
|
|
#endif
|
|
|
|
//=====================================================================================
|
|
// Includes specific to this module
|
|
//=====================================================================================
|
|
|
|
#include "Bottlenecks.h"
|
|
|
|
//=====================================================================================
|
|
// FixedPort: Holds old StdBits procedure information for when we fix up a port's
|
|
// StdBits function to fix the QuickTime 1.5 bug.
|
|
//=====================================================================================
|
|
|
|
typedef struct FixedPort
|
|
{
|
|
struct FixedPort *next;
|
|
CGrafPtr port;
|
|
CQDProcs *oldprocs;
|
|
CQDProcs newprocs;
|
|
QDBitsUPP oldbits;
|
|
} FixedPort, *FixedPortPtr, **FixedPortHandle;
|
|
|
|
//=====================================================================================
|
|
// Global variables local to this module
|
|
//=====================================================================================
|
|
|
|
static JVDrawParamsHandle gDrawParamsRoot = nil;
|
|
static FixedPortPtr gFixedPortRoot = nil;
|
|
static CQDProcs gBottlenecks;
|
|
static QDBitsUPP gJVFixedBitsProc;
|
|
static DeviceLoopDrawingUPP gDeviceCopy;
|
|
|
|
//=====================================================================================
|
|
// Prototypes for functions local to this module
|
|
//=====================================================================================
|
|
|
|
static OSErr DitherTableInit(void);
|
|
static JVDrawParamsHandle FindParams(CGrafPtr thePort);
|
|
static pascal void JVFixedBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
short mode, RgnHandle mask);
|
|
static pascal void JVBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
|
|
RgnHandle mask);
|
|
static void DrawOnAndOffscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
JVDrawParamsHandle theParams);
|
|
static void DrawOnscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
JVDrawParamsHandle theParams);
|
|
static void DrawOffscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
JVDrawParamsHandle theParams);
|
|
static pascal void DeviceCopy(short depth, short deviceFlags, GDHandle targetDevice,
|
|
void *tempParams);
|
|
static void CustomCopy(PixMap *src, Rect *srcRect, Rect *dstRect, Boolean dither,
|
|
RgnHandle mask, short quality);
|
|
static Boolean IsGrayDevice(GDHandle theGDevice);
|
|
static void DrawVHighQuality(PixMapPtr src, PixMapHandle dst, Rect *srcRect,
|
|
Rect *dstRect, Boolean dither, RgnHandle mask);
|
|
static void DrawHighQuality(PixMapPtr src, PixMapHandle dst, Rect *srcRect,
|
|
Rect *dstRect, Boolean dither, RgnHandle mask);
|
|
static void ShowScaleDither(Boolean scaling, Boolean dither, Boolean state,
|
|
JVDrawParamsHandle theParams);
|
|
static void CopyFields(CGrafPtr src, CGrafPtr dst, Rect *srcRect, Rect *dstRect);
|
|
static Boolean DiffPixPat(PixPatHandle pp1, PixPatHandle pp2);
|
|
static pascal void JVTextProc(short count, Ptr textAddr, Point numer, Point denom);
|
|
static pascal void JVLineProc(Point newPt);
|
|
static pascal void JVRectProc(GrafVerb verb, Rect *r);
|
|
static pascal void JVRRectProc(GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight);
|
|
static pascal void JVOvalProc(GrafVerb verb, Rect *r);
|
|
static pascal void JVArcProc(GrafVerb verb, Rect *r, short startAngle, short arcAngle);
|
|
static pascal void JVPolyProc(GrafVerb verb, PolyHandle poly);
|
|
static pascal void JVRgnProc(GrafVerb verb, RgnHandle rgn);
|
|
|
|
//=====================================================================================
|
|
// OSErr DrawingInit(void)
|
|
//=====================================================================================
|
|
// Initializes the bottlenecks record and the dithering table.
|
|
//=====================================================================================
|
|
|
|
extern OSErr DrawingInit(void)
|
|
{
|
|
KeepSpinning();
|
|
SetStdCProcs(&gBottlenecks);
|
|
gBottlenecks.textProc = NewQDTextProc((ProcPtr)JVTextProc);
|
|
gBottlenecks.lineProc = NewQDLineProc((ProcPtr)JVLineProc);
|
|
gBottlenecks.rectProc = NewQDRectProc((ProcPtr)JVRectProc);
|
|
gBottlenecks.rRectProc = NewQDRRectProc((ProcPtr)JVRRectProc);
|
|
gBottlenecks.ovalProc = NewQDOvalProc((ProcPtr)JVOvalProc);
|
|
gBottlenecks.arcProc = NewQDArcProc((ProcPtr)JVArcProc);
|
|
gBottlenecks.polyProc = NewQDPolyProc((ProcPtr)JVPolyProc);
|
|
gBottlenecks.rgnProc = NewQDRgnProc((ProcPtr)JVRgnProc);
|
|
gBottlenecks.bitsProc = NewQDBitsProc((ProcPtr)JVBitsProc);
|
|
gJVFixedBitsProc = NewQDBitsProc((ProcPtr)JVFixedBitsProc);
|
|
gDeviceCopy = NewDeviceLoopDrawingProc((ProcPtr)DeviceCopy);
|
|
KeepSpinning();
|
|
return DitherTableInit();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// OSErr DitherTableInit(void)
|
|
//=====================================================================================
|
|
// Initializes the dithering and scaling tables.
|
|
//=====================================================================================
|
|
|
|
static OSErr DitherTableInit(void)
|
|
{
|
|
Handle tempHandle;
|
|
uchar *theTable;
|
|
short *table;
|
|
short i, j, k;
|
|
|
|
KeepSpinning();
|
|
if (!(tempHandle = NewHandleClear((3 + 4 + 5 + 6 + 7 + 8) * 256)))
|
|
FatalError(errNoMemory);
|
|
HLockHi(tempHandle);
|
|
theTable = gScaleTable = (uchar *)StripAddress(*tempHandle);
|
|
for (i = 3; i <= 8; i++)
|
|
for (j = 0; j < 256; j++)
|
|
for (k = 0; k < i; k++) *theTable++ = j;
|
|
KeepSpinning();
|
|
|
|
if (!(tempHandle = NewHandleClear(sizeof(short) * 512))) FatalError(errNoMemory);
|
|
HLockHi(tempHandle);
|
|
table = gErrTable = (short *)StripAddress(*tempHandle) + 256;
|
|
for (i = j = 1; i < 0x08; i++, j++) table[i] = j, table[-i] = -j;
|
|
for (i = 0x08; i < 0x18; i++, j += !(i & 1) ? 1 : 0) table[i] = j, table[-i] = -j;
|
|
for (i = 0x18; i < 0x38; i++, j += !(i & 3) ? 1 : 0) table[i] = j, table[-i] = -j;
|
|
for (i = 0x38; i < 0x78; i++, j += !(i & 7) ? 1 : 0) table[i] = j, table[-i] = -j;
|
|
for ( ; i <= 0x100; i++) {
|
|
if (i != 0x100) table[i] = j;
|
|
table[-i] = -j;
|
|
}
|
|
KeepSpinning();
|
|
return noErr;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// JVDrawParamsHandle NewDrawParams(Rect *bounds, short quality, Boolean quantize,
|
|
// NestedProgressPtr progress, Handle privateData)
|
|
//=====================================================================================
|
|
// Creates and begins initializing a JVDrawParamsHandle in preparation for drawing.
|
|
//=====================================================================================
|
|
|
|
extern JVDrawParamsHandle NewDrawParams(Rect *bounds, short quality, Boolean quantize,
|
|
NestedProgressPtr progress, Handle privateData)
|
|
{
|
|
JVDrawParamsHandle theParams;
|
|
|
|
if (theParams = (JVDrawParamsHandle)NewHandleClear(sizeof(JVDrawParams))) {
|
|
(*theParams)->bounds = *bounds;
|
|
(*theParams)->quality = quality;
|
|
(*theParams)->quantize = quantize;
|
|
if (progress) {
|
|
(*theParams)->progress = *progress;
|
|
(*theParams)->progress.prog.progressRefCon = (long)theParams;
|
|
}
|
|
(*theParams)->privateData = privateData;
|
|
}
|
|
return theParams;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// SetUpDrawPort(JVDrawParamsHandle theParams, short whichPort, CGrafPtr thePort,
|
|
// Rect *srcRect, Rect *dstRect, Boolean dither)
|
|
//=====================================================================================
|
|
// Initialize one of the three drawing ports in the JVDrawParamsHandle.
|
|
//=====================================================================================
|
|
|
|
extern void SetUpDrawPort(JVDrawParamsHandle theParams, short whichPort, CGrafPtr thePort,
|
|
Rect *srcRect, Rect *dstRect, Boolean dither)
|
|
{
|
|
JVPortParams port;
|
|
|
|
port.port = thePort;
|
|
port.outer = (*theParams)->bounds;
|
|
MapRect(&port.outer, srcRect, dstRect);
|
|
port.dither = dither;
|
|
switch (whichPort) {
|
|
case kOnscreenPort:
|
|
(*theParams)->on = port;
|
|
break;
|
|
case kOffscreenPort1:
|
|
(*theParams)->off = port;
|
|
break;
|
|
case kOffscreenPort2:
|
|
(*theParams)->extra = port;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//=====================================================================================
|
|
// OSErr PreflightDrawing(JVDrawParamsHandle theParams)
|
|
//=====================================================================================
|
|
// Inserts theParams into the local linked list of current drawing environments, and
|
|
// creates a new destination port with the bottleneck procedures installed.
|
|
//=====================================================================================
|
|
|
|
extern OSErr PreflightDrawing(JVDrawParamsHandle theParams)
|
|
{
|
|
Rect bounds = (*theParams)->bounds, dbounds = { 0, 0, 1, 32 }, outer;
|
|
GWorldPtr theGWorld;
|
|
RgnHandle tempRgn;
|
|
Rect theRect;
|
|
|
|
(*theParams)->next = gDrawParamsRoot;
|
|
(*theParams)->progress.aborted = false;
|
|
gDrawParamsRoot = theParams;
|
|
dbounds.right = Width(&(*theParams)->bounds);
|
|
if (theGWorld = MyNewGWorld(&dbounds, 32, nil, nil, false, false)) {
|
|
(*GetGWorldPixMap(theGWorld))->rowBytes &= 0xc000;
|
|
if (tempRgn = NewRgn()) {
|
|
SetEmptyRgn(theGWorld->visRgn);
|
|
if ((*theParams)->on.port) {
|
|
CopyRgn((*theParams)->on.port->visRgn, tempRgn);
|
|
InsetRgn(tempRgn, -1, -1);
|
|
outer = (*theParams)->on.outer;
|
|
MapRgn(tempRgn, &outer, &bounds);
|
|
UnionRgn(tempRgn, theGWorld->visRgn, theGWorld->visRgn);
|
|
}
|
|
if ((*theParams)->off.port) {
|
|
CopyRgn((*theParams)->off.port->visRgn, tempRgn);
|
|
InsetRgn(tempRgn, -1, -1);
|
|
outer = (*theParams)->off.outer;
|
|
MapRgn(tempRgn, &outer, &bounds);
|
|
UnionRgn(tempRgn, theGWorld->visRgn, theGWorld->visRgn);
|
|
if ((*theParams)->extra.port) {
|
|
CopyRgn((*theParams)->extra.port->visRgn, tempRgn);
|
|
InsetRgn(tempRgn, -1, -1);
|
|
outer = (*theParams)->extra.outer;
|
|
MapRgn(tempRgn, &outer, &bounds);
|
|
UnionRgn(tempRgn, theGWorld->visRgn, theGWorld->visRgn);
|
|
}
|
|
}
|
|
theRect = (*theParams)->bounds;
|
|
RectRgn(theGWorld->clipRgn, &theRect);
|
|
if (!(*theParams)->off.port && !(*theParams)->on.port)
|
|
CopyRgn(theGWorld->clipRgn, theGWorld->visRgn);
|
|
DisposeRgn(tempRgn);
|
|
theGWorld->grafProcs = &gBottlenecks;
|
|
(*theParams)->dummy = theGWorld;
|
|
return noErr;
|
|
}
|
|
DisposeGWorld(theGWorld);
|
|
}
|
|
return memFullErr;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// OSErr PostflightDrawing(JVDrawParamsHandle theParams)
|
|
//=====================================================================================
|
|
// Removes theParams from the local linked list of current drawing environments,
|
|
// disposing of the temporary destination port.
|
|
//=====================================================================================
|
|
|
|
extern OSErr PostflightDrawing(JVDrawParamsHandle theParams)
|
|
{
|
|
JVDrawParamsHandle params;
|
|
OSErr theErr = noErr;
|
|
|
|
if ((*theParams)->progress.aborted) theErr = codecAbortErr;
|
|
if ((*theParams)->dummy) DisposeGWorld((*theParams)->dummy);
|
|
if (theParams == gDrawParamsRoot) gDrawParamsRoot = (*theParams)->next;
|
|
else for (params = gDrawParamsRoot; params; params = (*params)->next)
|
|
if ((*params)->next == theParams) {
|
|
(*params)->next = (*theParams)->next;
|
|
break;
|
|
}
|
|
return theErr;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// JVDrawParamsHandle FindParams(CGrafPtr thePort)
|
|
//=====================================================================================
|
|
// Locates the parameter set associated with the given port.
|
|
//=====================================================================================
|
|
|
|
static JVDrawParamsHandle FindParams(CGrafPtr thePort)
|
|
{
|
|
JVDrawParamsHandle theParams;
|
|
|
|
for (theParams = gDrawParamsRoot; theParams; theParams = (*theParams)->next)
|
|
if ((*theParams)->dummy == thePort) return theParams;
|
|
return nil;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// OSErr FixBits(CGrafPtr, Boolean on)
|
|
//=====================================================================================
|
|
// Turns on/off the QuickTime 1.5 image bug fix for a given port.
|
|
//=====================================================================================
|
|
|
|
extern OSErr FixBits(CGrafPtr thePort, Boolean on)
|
|
{
|
|
FixedPortPtr theFixedPort;
|
|
|
|
if (gQTVersion != 0x0150) return noErr;
|
|
if (on) {
|
|
if (theFixedPort = (FixedPortPtr)NewPtrClear(sizeof(FixedPort))) {
|
|
theFixedPort->next = gFixedPortRoot;
|
|
gFixedPortRoot = theFixedPort;
|
|
theFixedPort->port = thePort;
|
|
if (theFixedPort->oldprocs = thePort->grafProcs)
|
|
theFixedPort->newprocs = *thePort->grafProcs;
|
|
else SetStdCProcs(&theFixedPort->newprocs);
|
|
theFixedPort->oldbits = theFixedPort->newprocs.bitsProc;
|
|
theFixedPort->newprocs.bitsProc = gJVFixedBitsProc;
|
|
thePort->grafProcs = &theFixedPort->newprocs;
|
|
} else return memFullErr;
|
|
} else {
|
|
for (theFixedPort = gFixedPortRoot; theFixedPort; theFixedPort = theFixedPort->next)
|
|
if (theFixedPort->port == thePort) break;
|
|
if (!theFixedPort) return paramErr;
|
|
thePort->grafProcs = theFixedPort->oldprocs;
|
|
if (theFixedPort == gFixedPortRoot) gFixedPortRoot = theFixedPort->next;
|
|
else {
|
|
for (theFixedPort = theFixedPort; theFixedPort->next;
|
|
theFixedPort = theFixedPort->next)
|
|
if (theFixedPort->next->port == thePort) break;
|
|
if (theFixedPort) theFixedPort->next = theFixedPort->next->next;
|
|
theFixedPort = theFixedPort->next;
|
|
}
|
|
DisposePtr((Ptr)theFixedPort);
|
|
}
|
|
return noErr;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVFixedBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
|
|
// RgnHandle mask)
|
|
//=====================================================================================
|
|
// Bottleneck routine to fix things under QuickTime 1.5 so that drawing cropped
|
|
// images works correctly. Thanks for Mark Krueger for the bugfix!
|
|
//=====================================================================================
|
|
|
|
static pascal void JVFixedBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
short mode, RgnHandle mask)
|
|
{
|
|
long offsetH = srcRect->left, offsetV = srcRect->top, rb = src->rowBytes;
|
|
Rect saveSrcBounds = src->bounds, tmpSrcRect = *srcRect;
|
|
FixedPortPtr theFixedPort;
|
|
Ptr saveBaseAddr = nil;
|
|
|
|
for (theFixedPort = gFixedPortRoot; theFixedPort; theFixedPort = theFixedPort->next)
|
|
if (theFixedPort->port == (CGrafPtr)qd.thePort) break;
|
|
if (!theFixedPort) return;
|
|
if (offsetH || offsetV) {
|
|
if (rb & 0xc000) {
|
|
rb &= 0x3fff;
|
|
saveBaseAddr = src->baseAddr;
|
|
if (src->pmVersion == 2) LockPixels(&src);
|
|
if (src->pmVersion == 4)
|
|
src->baseAddr += offsetV * rb + ((offsetH * src->pixelSize) >> 3);
|
|
else if (src->pmVersion == 1)
|
|
src->baseAddr = StripAddress(src->baseAddr) + offsetV * rb +
|
|
((offsetH * src->pixelSize) >> 3);
|
|
OffsetRect(&tmpSrcRect, -offsetH, -offsetV);
|
|
} else {
|
|
BitMap *srcB = (BitMap *)src;
|
|
saveBaseAddr = srcB->baseAddr;
|
|
srcB->baseAddr += offsetH + (offsetV * rb);
|
|
OffsetRect(&tmpSrcRect, -offsetH, -offsetV);
|
|
}
|
|
}
|
|
src->bounds = tmpSrcRect;
|
|
CallQDBitsProc(theFixedPort->oldbits, (BitMap *)src, &tmpSrcRect, dstRect, mode, mask);
|
|
src->bounds = saveSrcBounds;
|
|
if (saveBaseAddr) src->baseAddr = saveBaseAddr;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
|
|
// RgnHandle mask)
|
|
//=====================================================================================
|
|
// Bottleneck routine for CopyBits.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVBitsProc(PixMap *src, Rect *srcRect, Rect *dstRect, short mode,
|
|
RgnHandle mask)
|
|
{
|
|
#if applec
|
|
#pragma unused(mode, mask)
|
|
#endif
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
PixMapHandle onPixMap = nil, offPixMap = nil;
|
|
Boolean scaling = false;
|
|
char offState;
|
|
|
|
if (!theParams || (*theParams)->progress.aborted ||
|
|
((*theParams)->progress.aborted = CheckAbort(theParams))) return;
|
|
PushPort();
|
|
(*theParams)->src = src;
|
|
(*theParams)->srcrect = *srcRect;
|
|
(*theParams)->dstrect = *dstRect;
|
|
if ((*theParams)->off.port) {
|
|
offPixMap = GetGWorldPixMap((*theParams)->off.port);
|
|
offState = GetPixelsState(offPixMap);
|
|
LockPixels(offPixMap);
|
|
scaling = !EqualSizeRect(&(*theParams)->bounds, &(*theParams)->off.outer);
|
|
}
|
|
if ((*theParams)->on.port) {
|
|
onPixMap = GetGWorldPixMap((*theParams)->on.port);
|
|
if (!scaling) scaling = !EqualSizeRect(&(*theParams)->bounds, &(*theParams)->on.outer);
|
|
}
|
|
if (Height(dstRect) > 8)
|
|
ShowScaleDither(scaling, (*theParams)->on.dither, true, theParams);
|
|
if ((*theParams)->quantize) FillHistogram(src);
|
|
if ((*theParams)->on.port && (*theParams)->off.port)
|
|
DrawOnAndOffscreen(src, srcRect, dstRect, theParams);
|
|
else if ((*theParams)->on.port) DrawOnscreen(src, srcRect, dstRect, theParams);
|
|
else if ((*theParams)->off.port) DrawOffscreen(src, srcRect, dstRect, theParams);
|
|
if (Height(dstRect) > 8)
|
|
ShowScaleDither(scaling, (*theParams)->on.dither, false, theParams);
|
|
if ((*theParams)->off.port) SetPixelsState(offPixMap, offState);
|
|
if (gSlideShow && !(*theParams)->progress.aborted)
|
|
(*theParams)->progress.aborted = CheckAbort(theParams);
|
|
PopPort();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void DrawOnAndOffscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
// JVDrawParamsHandle theParams)
|
|
//=====================================================================================
|
|
// Do CopyBits drawing for both onscreen and offscreen.
|
|
//=====================================================================================
|
|
|
|
static void DrawOnAndOffscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
JVDrawParamsHandle theParams)
|
|
{
|
|
PixMapHandle offPixMap = GetGWorldPixMap((*theParams)->off.port);
|
|
Rect onDstRect = *dstRect, offDstRect = *dstRect;
|
|
char hState = HGetState((Handle)offPixMap);
|
|
RgnHandle tempRgn;
|
|
|
|
PushPort();
|
|
MapRect(&onDstRect, &(*theParams)->bounds, &(*theParams)->on.outer);
|
|
MapRect(&offDstRect, &(*theParams)->bounds, &(*theParams)->off.outer);
|
|
MySetPort((*theParams)->off.port);
|
|
(*theParams)->dstrect = offDstRect;
|
|
CustomCopy(src, srcRect, &offDstRect, (*theParams)->off.dither, nil,
|
|
(*theParams)->quality);
|
|
if ((*theParams)->extra.port) {
|
|
Rect extraDstRect = *dstRect;
|
|
MapRect(&extraDstRect, &(*theParams)->bounds, &(*theParams)->extra.outer);
|
|
MySetPort((*theParams)->extra.port);
|
|
(*theParams)->dstrect = extraDstRect;
|
|
CustomCopy(src, srcRect, &extraDstRect, (*theParams)->extra.dither, nil,
|
|
(*theParams)->quality);
|
|
}
|
|
HLock((Handle)offPixMap);
|
|
(*theParams)->src = *offPixMap;
|
|
(*theParams)->srcrect = offDstRect;
|
|
(*theParams)->dstrect = onDstRect;
|
|
MySetPort((*theParams)->on.port);
|
|
DeviceLoop((*theParams)->on.port->visRgn, gDeviceCopy, (long)theParams, singleDevices);
|
|
if ((*theParams)->newupdates && (tempRgn = NewRgn())) {
|
|
RectRgn(tempRgn, &onDstRect);
|
|
DiffRgn((*theParams)->newupdates, tempRgn, (*theParams)->newupdates);
|
|
DisposeRgn(tempRgn);
|
|
}
|
|
HSetState((Handle)offPixMap, hState);
|
|
PopPort();
|
|
if (onDstRect.bottom >= (*theParams)->endprogress) (*theParams)->endprogress = 0;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void DrawOnscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
// JVDrawParamsHandle theParams)
|
|
//=====================================================================================
|
|
// Do CopyBits drawing for onscreen.
|
|
//=====================================================================================
|
|
|
|
static void DrawOnscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
JVDrawParamsHandle theParams)
|
|
{
|
|
#if applec
|
|
#pragma unused(src, srcRect)
|
|
#endif
|
|
Rect onDstRect = *dstRect;
|
|
RgnHandle tempRgn;
|
|
|
|
PushPort();
|
|
MapRect(&onDstRect, &(*theParams)->bounds, &(*theParams)->on.outer);
|
|
(*theParams)->dstrect = onDstRect;
|
|
MySetPort((*theParams)->on.port);
|
|
DeviceLoop((*theParams)->on.port->visRgn, gDeviceCopy, (long)theParams, singleDevices);
|
|
if ((*theParams)->newupdates && (tempRgn = NewRgn())) {
|
|
RectRgn(tempRgn, &onDstRect);
|
|
DiffRgn((*theParams)->newupdates, tempRgn, (*theParams)->newupdates);
|
|
DisposeRgn(tempRgn);
|
|
}
|
|
PopPort();
|
|
if (onDstRect.bottom >= (*theParams)->endprogress) (*theParams)->endprogress = 0;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void DrawOffscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
// JVDrawParamsHandle theParams)
|
|
//=====================================================================================
|
|
// Do CopyBits drawing for offscreen.
|
|
//=====================================================================================
|
|
|
|
static void DrawOffscreen(PixMap *src, Rect *srcRect, Rect *dstRect,
|
|
JVDrawParamsHandle theParams)
|
|
{
|
|
Rect offDstRect = *dstRect;
|
|
|
|
PushPort();
|
|
MapRect(&offDstRect, &(*theParams)->bounds, &(*theParams)->off.outer);
|
|
(*theParams)->dstrect = offDstRect;
|
|
MySetPort((*theParams)->off.port);
|
|
CustomCopy(src, srcRect, &offDstRect, (*theParams)->off.dither, nil,
|
|
(*theParams)->quality);
|
|
if ((*theParams)->extra.port) {
|
|
Rect extraDstRect = *dstRect;
|
|
MapRect(&extraDstRect, &(*theParams)->bounds, &(*theParams)->extra.outer);
|
|
(*theParams)->dstrect = extraDstRect;
|
|
MySetPort((*theParams)->extra.port);
|
|
CustomCopy(src, srcRect, &extraDstRect, (*theParams)->extra.dither, nil,
|
|
(*theParams)->quality);
|
|
}
|
|
PopPort();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void DeviceCopy(short depth, short deviceFlags, GDHandle targetDevice,
|
|
// void *tempParams)
|
|
//=====================================================================================
|
|
// Stub for calling CustomCopy for each device in the device list.
|
|
//=====================================================================================
|
|
|
|
static pascal void DeviceCopy(short depth, short deviceFlags, GDHandle targetDevice,
|
|
void *tempParams)
|
|
{
|
|
#if applec
|
|
#pragma unused(depth, deviceFlags)
|
|
#endif
|
|
JVDrawParamsHandle theParams = (JVDrawParamsHandle)tempParams;
|
|
Rect srcRect = (*theParams)->srcrect, dstRect = (*theParams)->dstrect;
|
|
GDHandle oldDevice = GetGDevice();
|
|
|
|
SetGDevice(targetDevice);
|
|
CustomCopy((*theParams)->src, &srcRect, &dstRect, (*theParams)->on.dither,
|
|
(*theParams)->on.port->visRgn, (*theParams)->quality);
|
|
SetGDevice(oldDevice);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// Boolean IsGrayDevice(GDHandle theGDevice)
|
|
//=====================================================================================
|
|
// Checks an 8-bit device's color table and returns true if it's all grayscales.
|
|
//=====================================================================================
|
|
|
|
static Boolean IsGrayDevice(GDHandle theGDevice)
|
|
{
|
|
PixMapHandle thePixMap = (*theGDevice)->gdPMap;
|
|
ColorSpec *theSpec;
|
|
short i;
|
|
|
|
if ((*thePixMap)->pmTable && (*(*thePixMap)->pmTable)->ctSize == 255) {
|
|
theSpec = (*(*thePixMap)->pmTable)->ctTable;
|
|
for (i = 0; i < 256; i++) {
|
|
if (theSpec->rgb.red != theSpec->rgb.green ||
|
|
theSpec->rgb.red != theSpec->rgb.blue) return false;
|
|
theSpec++;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CustomCopy(PixMap *src, Rect *srcRect, Rect *dstRect, Boolean dither,
|
|
// RgnHandle mask, short quality)
|
|
//=====================================================================================
|
|
// Do our custom copying.
|
|
//=====================================================================================
|
|
|
|
static void CustomCopy(PixMap *src, Rect *srcRect, Rect *dstRect, Boolean dither,
|
|
RgnHandle mask, short quality)
|
|
{
|
|
PixMapHandle dst = (*GetGDevice())->gdPMap;
|
|
Boolean oldState;
|
|
|
|
if ((*dst)->pixelType != RGBDirect) {
|
|
ITabHandle theITab = (*GetGDevice())->gdITable;
|
|
CTabHandle theCTab = (*dst)->pmTable;
|
|
if (theCTab && ((*dst)->pixelSize == 8))
|
|
if (!theITab || ((*theITab)->iTabRes != 5) ||
|
|
((*theITab)->iTabSeed != (*theCTab)->ctSeed))
|
|
MakeITable(nil, nil, 5);
|
|
}
|
|
ClipRect(dstRect);
|
|
RGBForeColor(&gBlack);
|
|
RGBBackColor(&gWhite);
|
|
SpinIndef();
|
|
switch (quality) {
|
|
case iqVHigh:
|
|
DrawVHighQuality(src, dst, srcRect, dstRect, dither, mask);
|
|
break;
|
|
case iqHigh:
|
|
DrawHighQuality(src, dst, srcRect, dstRect, dither, mask);
|
|
break;
|
|
case iqMedium:
|
|
oldState = GetQDxDispatchPatchState();
|
|
if (oldState) RemoveQDxDispatchPatch();
|
|
CallProperBitsProc((BitMap *)src, srcRect, dstRect,
|
|
dither ? srcCopy + ditherCopy : srcCopy, mask);
|
|
if (oldState) InstallQDxDispatchPatch(true);
|
|
break;
|
|
}
|
|
KeepSpinning();
|
|
return;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void DrawVHighQuality(PixMapPtr src, PixMapHandle dst, Rect *srcRect, Rect *dstRect,
|
|
// Boolean dither, RgnHandle mask)
|
|
//=====================================================================================
|
|
// Do very high-quality custom drawing.
|
|
//=====================================================================================
|
|
|
|
static void DrawVHighQuality(PixMapPtr src, PixMapHandle dst, Rect *srcRect,
|
|
Rect *dstRect, Boolean dither, RgnHandle mask)
|
|
{
|
|
short srcDepth = (src->rowBytes & 0x8000) ? src->pixelSize : 1;
|
|
|
|
if (srcDepth == 32 && (dither || (*dst)->pixelSize == 32)) {
|
|
switch ((*dst)->pixelSize) {
|
|
case 8:
|
|
if (IsGrayDevice(GetGDevice())) break;
|
|
case 16:
|
|
case 32:
|
|
DoCustomCopy(src, *dst, srcRect, dstRect, false, (*dst)->pixelSize);
|
|
return;
|
|
}
|
|
}
|
|
CallProperBitsProc((BitMap *)src, srcRect, dstRect,
|
|
dither ? srcCopy + ditherCopy : srcCopy, mask);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void DrawHighQuality(PixMapPtr src, PixMapHandle dst, Rect *srcRect, Rect *dstRect,
|
|
// Boolean dither, RgnHandle mask)
|
|
//=====================================================================================
|
|
// Do high-quality custom drawing.
|
|
//=====================================================================================
|
|
|
|
static void DrawHighQuality(PixMapPtr src, PixMapHandle dst, Rect *srcRect,
|
|
Rect *dstRect, Boolean dither, RgnHandle mask)
|
|
{
|
|
short srcDepth = (src->rowBytes & 0x8000) ? src->pixelSize : 1;
|
|
|
|
if ((srcDepth == 32) && (dither || (*dst)->pixelSize == 32)) {
|
|
switch ((*dst)->pixelSize) {
|
|
case 32:
|
|
break;
|
|
case 8:
|
|
if (IsGrayDevice(GetGDevice())) break;
|
|
case 16:
|
|
DoCustomCopy(src, *dst, srcRect, dstRect, true, (*dst)->pixelSize);
|
|
return;
|
|
}
|
|
}
|
|
CallProperBitsProc((BitMap *)src, srcRect, dstRect,
|
|
dither ? srcCopy + ditherCopy : srcCopy, mask);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void ShowScaleDither(Boolean scaling, Boolean dither, Boolean state,
|
|
// JVDrawParamsHandle theParams)
|
|
//=====================================================================================
|
|
// Do high-quality custom drawing.
|
|
//=====================================================================================
|
|
|
|
static void ShowScaleDither(Boolean scaling, Boolean dither, Boolean state,
|
|
JVDrawParamsHandle theParams)
|
|
{
|
|
if ((*theParams)->progress.prog.progressProc) {
|
|
if (scaling) CallICMProgressProc((*theParams)->progress.prog.progressProc,
|
|
codecProgressUpdateScaling, state,
|
|
(*theParams)->progress.prog.progressRefCon);
|
|
else if (dither) CallICMProgressProc((*theParams)->progress.prog.progressProc,
|
|
codecProgressUpdateDithering, state,
|
|
(*theParams)->progress.prog.progressRefCon);
|
|
}
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CopyFields(CGrafPtr src, CGrafPtr dst, Rect *srcRect, Rect *dstRect)
|
|
//=====================================================================================
|
|
// Sets the drawing parameters of the dst port to be indentical to those in the src
|
|
// port.
|
|
//=====================================================================================
|
|
|
|
static void CopyFields(CGrafPtr src, CGrafPtr dst, Rect *srcRect, Rect *dstRect)
|
|
{
|
|
Point thePoint;
|
|
long x, y;
|
|
|
|
MySetPort(dst);
|
|
CopyRgn(src->clipRgn, dst->clipRgn);
|
|
MapRgn(dst->clipRgn, srcRect, dstRect);
|
|
thePoint = src->pnLoc;
|
|
MapPt(&thePoint, srcRect, dstRect);
|
|
MoveTo(thePoint.h, thePoint.v);
|
|
x = (long)src->pnSize.h * (long)Width(dstRect) / (long)Width(srcRect);
|
|
y = (long)src->pnSize.v * (long)Height(dstRect) / (long)Height(srcRect);
|
|
PenSize(x ? x : 1, y ? y : 1);
|
|
PenMode(src->pnMode);
|
|
TextFont(src->txFont);
|
|
TextFace(src->txFace);
|
|
TextMode(src->txMode);
|
|
x = (long)src->txSize * (long)Height(dstRect) / (long)Height(srcRect);
|
|
TextSize(x ? x : 1);
|
|
y = (long)src->spExtra * (long)Width(dstRect) / (long)Width(srcRect);
|
|
SpaceExtra(y ? y : 1);
|
|
if (src->portVersion & 0x8000) {
|
|
PixPatHandle thePixPat;
|
|
if (DiffPixPat(src->pnPixPat, dst->pnPixPat) && (thePixPat = NewPixPat())) {
|
|
CopyPixPat(src->pnPixPat, thePixPat);
|
|
PenPixPat(thePixPat);
|
|
}
|
|
if (DiffPixPat(src->bkPixPat, dst->bkPixPat) && (thePixPat = NewPixPat())) {
|
|
CopyPixPat(src->bkPixPat, thePixPat);
|
|
BackPixPat(thePixPat);
|
|
}
|
|
RGBForeColor(&src->rgbFgColor);
|
|
RGBBackColor(&src->rgbBkColor);
|
|
} else {
|
|
PenPat(&((GrafPtr)src)->pnPat);
|
|
BackPat(&((GrafPtr)src)->bkPat);
|
|
ForeColor(src->fgColor);
|
|
BackColor(src->bkColor);
|
|
}
|
|
}
|
|
|
|
//=====================================================================================
|
|
// Boolean DiffPixPat(PixPatHandle pp1, PixPatHandle pp2)
|
|
//=====================================================================================
|
|
// Compares two PixPatHandles; returns true if they're different.
|
|
//=====================================================================================
|
|
|
|
static Boolean DiffPixPat(PixPatHandle pp1, PixPatHandle pp2)
|
|
{
|
|
Size size1, size2;
|
|
ulong *p1, *p2;
|
|
|
|
if (!pp1) return false;
|
|
if (!pp2) return true;
|
|
if ((*pp1)->patType != (*pp2)->patType) return true;
|
|
if (!(*pp1)->patData) return false;
|
|
if (!(*pp2)->patData) return true;
|
|
size1 = GetHandleSize((*pp1)->patData);
|
|
size2 = GetHandleSize((*pp2)->patData);
|
|
if (size1 != size2) return true;
|
|
p1 = (ulong *)*(*pp1)->patData;
|
|
p2 = (ulong *)*(*pp2)->patData;
|
|
size1 >>= 2;
|
|
while (size1--) if (*p1++ != *p2++) return true;
|
|
return false;
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVTextProc(short count, void *textAddr, Point numer, Point denom)
|
|
//=====================================================================================
|
|
// Bottleneck to handle text drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVTextProc(short count, Ptr textAddr, Point numer, Point denom)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect bounds, outer;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
CallProperTextProc(count, textAddr, numer, denom);
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
CallProperTextProc(count, textAddr, numer, denom);
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
CallProperTextProc(count, textAddr, numer, denom);
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVLineProc(Point newPt)
|
|
//=====================================================================================
|
|
// Bottleneck to handle line drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVLineProc(Point newPt)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect bounds, outer;
|
|
Point thePoint;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
thePoint = newPt;
|
|
MapPt(&thePoint, &bounds, &outer);
|
|
CallProperLineProc(thePoint);
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
thePoint = newPt;
|
|
MapPt(&thePoint, &bounds, &outer);
|
|
CallProperLineProc(thePoint);
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
thePoint = newPt;
|
|
MapPt(&thePoint, &bounds, &outer);
|
|
CallProperLineProc(thePoint);
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVRectProc(GrafVerb verb, Rect *r)
|
|
//=====================================================================================
|
|
// Bottleneck to handle rectangle drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVRectProc(GrafVerb verb, Rect *r)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect theRect, bounds, outer;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperRectProc(verb, &theRect);
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperRectProc(verb, &theRect);
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperRectProc(verb, &theRect);
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVRRectProc(GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight)
|
|
//=====================================================================================
|
|
// Bottleneck to handle rounded rectangle drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVRRectProc(GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect theRect, bounds, outer;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperRRectProc(verb, &theRect, ovalWidth, ovalHeight);
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperRRectProc(verb, &theRect, ovalWidth, ovalHeight);
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperRRectProc(verb, &theRect, ovalWidth, ovalHeight);
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVOvalProc(GrafVerb verb, Rect *r)
|
|
//=====================================================================================
|
|
// Bottleneck to handle oval drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVOvalProc(GrafVerb verb, Rect *r)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect theRect, bounds, outer;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperOvalProc(verb, &theRect);
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperOvalProc(verb, &theRect);
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperOvalProc(verb, &theRect);
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVArcProc(GrafVerb verb, Rect *r, short startAngle, short arcAngle)
|
|
//=====================================================================================
|
|
// Bottleneck to handle arc drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVArcProc(GrafVerb verb, Rect *r, short startAngle, short arcAngle)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect theRect, bounds, outer;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperArcProc(verb, &theRect, startAngle, arcAngle);
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperArcProc(verb, &theRect, startAngle, arcAngle);
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
theRect = *r;
|
|
MapRect(&theRect, &bounds, &outer);
|
|
CallProperArcProc(verb, &theRect, startAngle, arcAngle);
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVPolyProc(GrafVerb verb, PolyHandle poly)
|
|
//=====================================================================================
|
|
// Bottleneck to handle polygon drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVPolyProc(GrafVerb verb, PolyHandle poly)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect bounds, outer;
|
|
PolyHandle thePoly;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
thePoly = poly;
|
|
if (HandToHand((Handle *)&thePoly) == noErr) {
|
|
MapPoly(thePoly, &bounds, &outer);
|
|
CallProperPolyProc(verb, thePoly);
|
|
DisposeHandle((Handle)thePoly);
|
|
}
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
thePoly = poly;
|
|
if (HandToHand((Handle *)&thePoly) == noErr) {
|
|
MapPoly(thePoly, &bounds, &outer);
|
|
CallProperPolyProc(verb, thePoly);
|
|
DisposeHandle((Handle)thePoly);
|
|
}
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
thePoly = poly;
|
|
if (HandToHand((Handle *)&thePoly) == noErr) {
|
|
MapPoly(thePoly, &bounds, &outer);
|
|
CallProperPolyProc(verb, thePoly);
|
|
DisposeHandle((Handle)thePoly);
|
|
}
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// pascal void JVRgnProc(GrafVerb verb, RgnHandle rgn)
|
|
//=====================================================================================
|
|
// Bottleneck to handle polygon drawing.
|
|
//=====================================================================================
|
|
|
|
static pascal void JVRgnProc(GrafVerb verb, RgnHandle rgn)
|
|
{
|
|
JVDrawParamsHandle theParams = FindParams((CGrafPtr)qd.thePort);
|
|
Rect bounds, outer;
|
|
RgnHandle theRgn;
|
|
|
|
if (!theParams) return;
|
|
bounds = (*theParams)->bounds;
|
|
KeepSpinning();
|
|
if ((*theParams)->off.port) {
|
|
PushPort();
|
|
outer = (*theParams)->off.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->off.port, &bounds, &outer);
|
|
if (theRgn = NewRgn()) {
|
|
CopyRgn(rgn, theRgn);
|
|
MapRgn(theRgn, &bounds, &outer);
|
|
CallProperRgnProc(verb, theRgn);
|
|
DisposeHandle((Handle)theRgn);
|
|
}
|
|
PopPort();
|
|
if ((*theParams)->extra.port) {
|
|
PushPort();
|
|
outer = (*theParams)->extra.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->extra.port, &bounds, &outer);
|
|
if (theRgn = NewRgn()) {
|
|
CopyRgn(rgn, theRgn);
|
|
MapRgn(theRgn, &bounds, &outer);
|
|
CallProperRgnProc(verb, theRgn);
|
|
DisposeHandle((Handle)theRgn);
|
|
}
|
|
PopPort();
|
|
}
|
|
}
|
|
KeepSpinning();
|
|
if ((*theParams)->on.port) {
|
|
PushPort();
|
|
outer = (*theParams)->on.outer;
|
|
CopyFields((CGrafPtr)qd.thePort, (*theParams)->on.port, &bounds, &outer);
|
|
if (theRgn = NewRgn()) {
|
|
CopyRgn(rgn, theRgn);
|
|
MapRgn(theRgn, &bounds, &outer);
|
|
CallProperRgnProc(verb, theRgn);
|
|
DisposeHandle((Handle)theRgn);
|
|
}
|
|
PopPort();
|
|
}
|
|
KeepSpinning();
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperBitsProc(BitMap *src, Rect *srcRect, Rect *dstRect, short mode,
|
|
// RgnHandle mask)
|
|
//=====================================================================================
|
|
// Call StdBits, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperBitsProc(BitMap *src, Rect *srcRect, Rect *dstRect, short mode,
|
|
RgnHandle mask)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->bitsProc)
|
|
CallQDBitsProc(((CGrafPtr)qd.thePort)->grafProcs->bitsProc, (BitMap *)src,
|
|
srcRect, dstRect, mode, mask);
|
|
else StdBits((BitMap *)src, srcRect, dstRect, mode, mask);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperTextProc(short count, const void *textAddr, Point numer, Point denom)
|
|
//=====================================================================================
|
|
// Call StdText, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperTextProc(short count, Ptr textAddr, Point numer, Point denom)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->textProc)
|
|
CallQDTextProc(((CGrafPtr)qd.thePort)->grafProcs->textProc, count, textAddr,
|
|
numer, denom);
|
|
else StdText(count, textAddr, numer, denom);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperLineProc(Point newPt)
|
|
//=====================================================================================
|
|
// Call StdLine, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperLineProc(Point newPt)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->lineProc)
|
|
CallQDLineProc(((CGrafPtr)qd.thePort)->grafProcs->lineProc, newPt);
|
|
else StdLine(newPt);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperRectProc(GrafVerb verb, Rect *r)
|
|
//=====================================================================================
|
|
// Call StdRect, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperRectProc(GrafVerb verb, Rect *r)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->rectProc)
|
|
CallQDRectProc(((CGrafPtr)qd.thePort)->grafProcs->rectProc, verb, r);
|
|
else StdRect(verb, r);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperRRectProc(GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight)
|
|
//=====================================================================================
|
|
// Call StdRRect, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperRRectProc(GrafVerb verb, Rect *r, short ovalWidth, short ovalHeight)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->rRectProc)
|
|
CallQDRRectProc(((CGrafPtr)qd.thePort)->grafProcs->rRectProc, verb, r, ovalWidth,
|
|
ovalHeight);
|
|
else StdRRect(verb, r, ovalWidth, ovalHeight);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperOvalProc(GrafVerb verb, Rect *r)
|
|
//=====================================================================================
|
|
// Call StdOval, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperOvalProc(GrafVerb verb, Rect *r)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->ovalProc)
|
|
CallQDOvalProc(((CGrafPtr)qd.thePort)->grafProcs->ovalProc, verb, r);
|
|
else StdOval(verb, r);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperArcProc(GrafVerb verb, Rect *r, short startAngle, short arcAngle)
|
|
//=====================================================================================
|
|
// Call StdArc, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperArcProc(GrafVerb verb, Rect *r, short startAngle, short arcAngle)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->arcProc)
|
|
CallQDArcProc(((CGrafPtr)qd.thePort)->grafProcs->arcProc, verb, r, startAngle,
|
|
arcAngle);
|
|
else StdArc(verb, r, startAngle, arcAngle);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperPolyProc(GrafVerb verb, PolyHandle poly)
|
|
//=====================================================================================
|
|
// Call StdPoly, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperPolyProc(GrafVerb verb, PolyHandle poly)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->polyProc)
|
|
CallQDPolyProc(((CGrafPtr)qd.thePort)->grafProcs->polyProc, verb, poly);
|
|
else StdPoly(verb, poly);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperRgnProc(GrafVerb verb, RgnHandle rgn)
|
|
//=====================================================================================
|
|
// Call StdRgn, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperRgnProc(GrafVerb verb, RgnHandle rgn)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->rgnProc)
|
|
CallQDRgnProc(((CGrafPtr)qd.thePort)->grafProcs->rgnProc, verb, rgn);
|
|
else StdRgn(verb, rgn);
|
|
}
|
|
|
|
//=====================================================================================
|
|
// void CallProperPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
|
|
// RgnHandle mask, PixMap *matte, Rect *matteRect, short flags)
|
|
//=====================================================================================
|
|
// Call StdRgn, or a bottleneck function, as appropriate for the current port.
|
|
//=====================================================================================
|
|
|
|
extern void CallProperPixProc(PixMap *src, Rect *srcRect, MatrixRecord *matrix, short mode,
|
|
RgnHandle mask, PixMap *matte, Rect *matteRect, short flags)
|
|
{
|
|
if (qd.thePort->grafProcs && ((CGrafPtr)qd.thePort)->grafProcs->newProc1)
|
|
CallStdPixProc((StdPixUPP)((CGrafPtr)qd.thePort)->grafProcs->newProc1, src,
|
|
srcRect, matrix, mode, mask, matte, matteRect, flags);
|
|
else StdPix(src, srcRect, matrix, mode, mask, matte, matteRect, flags);
|
|
}
|