JPEGView/Source/C/QuickDrawUtils.c
Aaron Giles 92bdb55672 JPEGView 3.3 for Macintosh
These are the sources for the final official release of JPEGView for the
Mac, back in 1994.
2015-02-05 00:18:10 -08:00

1 line
9.6 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"
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif
//=====================================================================================
// Includes specific to this module
//=====================================================================================
#include "QuickDrawUtils.h"
//=====================================================================================
// PortStackItem: structure to store port and device information for when we push/pop
// the current port.
//=====================================================================================
typedef struct PortStackItem {
CGrafPtr port;
GDHandle device;
} PortStackItem, *PortStackPtr, **PortStackHandle;
//=====================================================================================
// Global variables local to this module
//=====================================================================================
static PortStackItem gPortStack[64];
static PortStackPtr gPortStackPtr = gPortStack;
//=====================================================================================
// void PushPort(void)
//
// Pushes the current port and device onto the port stack.
//
// External calls: none
//=====================================================================================
void PushPort(void)
{
GetGWorld(&gPortStackPtr->port, &gPortStackPtr->device);
gPortStackPtr++;
}
//=====================================================================================
// void PopPort(void)
//
// Pops a port and device from the port stack into the current graphics environment.
//
// External calls: none
//=====================================================================================
void PopPort(void)
{
gPortStackPtr--;
SetGWorld(gPortStackPtr->port, gPortStackPtr->device);
}
//=====================================================================================
// void MySetPort(CGrafPtr thePort)
//
// Sets the current port; if nil is passed as the port, the current port is set to
// the window manager's port.
//
// External calls: none
//=====================================================================================
void MySetPort(CGrafPtr thePort)
{
if (!thePort) GetCWMgrPort(&thePort);
if (thePort) SetGWorld(thePort, nil);
}
extern GWorldPtr NewTempGWorld(short width, short height, short depth, CTabHandle colors)
{
Boolean oldState = GetQDxDispatchPatchState();
GWorldPtr theGWorld = nil;
OSErr theErr = noErr;
Rect theRect;
SetRect(&theRect, 0, 0, width, height);
do {
InstallQDxDispatchPatch(false);
theErr = NewGWorld(&theGWorld, depth, &theRect, colors, nil, keepLocal + useTempMem);
SetQDxDispatchPatchState(oldState);
if (theErr != noErr) {
if (IsMemAvailable(EstGWorldSize(&theRect, depth)))
theErr = NewGWorld(&theGWorld, depth, &theRect, colors, nil, keepLocal);
else theErr = memFullErr;
}
if (theErr != noErr) {
if (theRect.bottom == 8) {
theGWorld = nil;
break;
}
theRect.bottom -= height / 8;
if (theRect.bottom < 8) theRect.bottom = 8;
}
} while (theErr != noErr);
return (theErr == noErr) ? theGWorld : nil;
}
//=====================================================================================
// GWorldPtr MyNewGWorld(Rect *theRect, short theDepth, CTabHandle theColors,
// GDHandle theDevice, Boolean whiteBack, Boolean inTempMem)
//
// Creates a new GWorld, erases it, and initializes the colors.
//
// External calls: none
//=====================================================================================
GWorldPtr MyNewGWorld(Rect *theRect, short theDepth, CTabHandle theColors,
GDHandle theDevice, Boolean whiteBack, Boolean inTempMem)
{
Boolean oldState = GetQDxDispatchPatchState();
long flags = keepLocal;
GWorldPtr theGWorld;
PushPort();
MySetPort(nil);
if (inTempMem) {
flags += useTempMem;
InstallQDxDispatchPatch(false);
}
if (NewGWorld(&theGWorld, theDepth, theRect, theColors, theDevice, flags) == noErr) {
MySetPort(theGWorld);
LockPixels(GetGWorldPixMap(theGWorld));
RectRgn(theGWorld->visRgn, theRect);
RectRgn(theGWorld->clipRgn, theRect);
RGBForeColor(&gBlack);
RGBBackColor(&gWhite);
if (!whiteBack) PaintRect(theRect);
else EraseRect(theRect);
UnlockPixels(GetGWorldPixMap(theGWorld));
PopPort();
if (inTempMem) SetQDxDispatchPatchState(oldState);
return theGWorld;
}
PopPort();
if (inTempMem) SetQDxDispatchPatchState(oldState);
return nil;
}
extern void MaxRect(Rect *srcRect, Rect *boundingRect, Rect *dstRect)
{
dstRect->top = dstRect->left = 0;
if (Width(srcRect) > Height(srcRect)) {
dstRect->right = Width(boundingRect);
dstRect->bottom = (long)Height(srcRect) * Width(boundingRect) / (long)Width(srcRect);
} else {
dstRect->right = (long)Width(srcRect) * Height(boundingRect) / (long)Height(srcRect);
dstRect->bottom = Height(boundingRect);
}
OffsetRect(dstRect, boundingRect->left, boundingRect->top);
}
extern void MaxSquare(Rect *srcRect, Rect *squareRect)
{
*squareRect = *srcRect;
if (Width(srcRect) > Height(srcRect)) {
squareRect->left += (Width(srcRect) - Height(srcRect)) >> 1;
squareRect->right = squareRect->left + Height(srcRect);
} else {
squareRect->top += (Height(srcRect) - Width(srcRect)) >> 1;
squareRect->bottom = squareRect->top + Width(srcRect);
}
}
extern void CopyGWorldToGWorld(GWorldPtr gw1, GWorldPtr gw2, Rect *srcRect, Rect *dstRect,
short mode, RgnHandle mask)
{
PixMapHandle pm1 = GetGWorldPixMap(gw1), pm2 = GetGWorldPixMap(gw2);
GWorldFlags state1 = GetPixelsState(pm1), state2 = GetPixelsState(pm2);
char hstate1 = HGetState((Handle)pm1), hstate2 = HGetState((Handle)pm2);
PushPort();
MySetPort(gw2);
HLock((Handle)pm1);
HLock((Handle)pm2);
LockPixels(pm1);
LockPixels(pm2);
CopyBits((BitMap *)*pm1, (BitMap *)*pm2, srcRect, dstRect, mode, mask);
SetPixelsState(pm1, state1);
SetPixelsState(pm2, state2);
HSetState((Handle)pm1, hstate1);
HSetState((Handle)pm2, hstate2);
PopPort();
}
//=====================================================================================
// void GlobalRect(Rect *theRect, WindowPtr theWindow)
//
// Converts the given rectangle to global coordinates, relative to the window.
//
// External calls: none
//=====================================================================================
void GlobalRect(Rect *theRect, WindowPtr theWindow)
{
Boolean change = (theWindow != qd.thePort);
Point thePoint = { 0, 0 };
if (change) {
PushPort();
MySetPort((CGrafPtr)theWindow);
}
LocalToGlobal(&thePoint);
if (change) PopPort();
OffsetRect(theRect, thePoint.h, thePoint.v);
}
//=====================================================================================
// void GlobalRgn(RgnHandle theRgn, WindowPtr theWindow)
//
// Converts the given region to global coordinates, relative to the window.
//
// External calls: none
//=====================================================================================
void GlobalRgn(RgnHandle theRgn, WindowPtr theWindow)
{
Boolean change = (theWindow != qd.thePort);
Point thePoint = { 0, 0 };
if (change) {
PushPort();
MySetPort((CGrafPtr)theWindow);
}
LocalToGlobal(&thePoint);
if (change) PopPort();
OffsetRgn(theRgn, thePoint.h, thePoint.v);
}
//=====================================================================================
// void LocalRect(Rect *theRect, WindowPtr theWindow)
//
// Converts the given rectangle to local coordinates, relative to the window.
//
// External calls: none
//=====================================================================================
void LocalRect(Rect *theRect, WindowPtr theWindow)
{
Boolean change = (theWindow != qd.thePort);
Point thePoint = { 0, 0 };
if (change) {
PushPort();
MySetPort((CGrafPtr)theWindow);
}
GlobalToLocal(&thePoint);
if (change) PopPort();
OffsetRect(theRect, thePoint.h, thePoint.v);
}
//=====================================================================================
// void LocalRgn(RgnHandle theRgn, WindowPtr theWindow)
//
// Converts the given region to local coordinates, relative to the window.
//
// External calls: none
//=====================================================================================
void LocalRgn(RgnHandle theRgn, WindowPtr theWindow)
{
Boolean change = (theWindow != qd.thePort);
Point thePoint = { 0, 0 };
if (change) {
PushPort();
MySetPort((CGrafPtr)theWindow);
}
GlobalToLocal(&thePoint);
if (change) PopPort();
OffsetRgn(theRgn, thePoint.h, thePoint.v);
}
//=====================================================================================
// Boolean Clipped(Rect *theRect, RgnHandle clipRgn)
//
// Determines if the given rectangle is clipped by the region.
//
// External calls: none
//=====================================================================================
Boolean Clipped(Rect *theRect, RgnHandle clipRgn)
{
RgnHandle rectRgn, clippedRgn;
Boolean result = false;
if (!clipRgn || !theRect) return false;
if (rectRgn = NewRgn()) {
if (clippedRgn = NewRgn()) {
RectRgn(rectRgn, theRect);
SectRgn(rectRgn, clipRgn, clippedRgn);
result = !EqualRgn(rectRgn, clippedRgn);
DisposeRgn(clippedRgn);
}
DisposeRgn(rectRgn);
}
return result;
}