457 lines
11 KiB
C
457 lines
11 KiB
C
/* Copyright 1986, 1989, 1990, 1994, 1995 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_qPicture[] =
|
|
"$Id: qPicture.c 63 2004-12-24 18:19:43Z ctm $";
|
|
#endif
|
|
|
|
/* Forward declarations in QuickDraw.h (DO NOT DELETE THIS LINE) */
|
|
|
|
#include "rsys/common.h"
|
|
#include "QuickDraw.h"
|
|
#include "MemoryMgr.h"
|
|
|
|
#include "rsys/cquick.h"
|
|
#include "rsys/picture.h"
|
|
#include "rsys/mman.h"
|
|
|
|
PUBLIC PicHandle ROMlib_OpenPicture_helper (const Rect *pf,
|
|
const OpenCPicParams *params)
|
|
{
|
|
piccachehand pch;
|
|
PicHandle ph;
|
|
INTEGER *ip;
|
|
RgnHandle temprh;
|
|
|
|
HidePen();
|
|
pch = (piccachehand) NewHandle(sizeof(piccache));
|
|
PORT_PIC_SAVE_X (thePort) = (Handle) RM (pch);
|
|
ph = (PicHandle) NewHandle((Size) INITIALPICSIZE);
|
|
HxX(pch, pichandle) = RM(ph);
|
|
|
|
HxX(ph, picSize) = CWC(10 + 16 * sizeof(INTEGER));
|
|
HxX(ph, picFrame) = *pf;
|
|
ip = &HxX(ph, picSize) + 5;
|
|
ip[0] = CW(OP_Version);
|
|
ip[1] = CWC (0x2FF); /* see the explanation in IM-V p. 93 */
|
|
|
|
ip[2] = CWC (0x0c00); /* see IM:Imaging with QuickDraw A-22 - A-24 */
|
|
if (params)
|
|
{
|
|
ip[ 3] = params->version;
|
|
ip[ 4] = params->reserved1;
|
|
* (uint32 *) &ip[ 5] = (uint32) params->hRes;
|
|
* (uint32 *) &ip[ 7] = (uint32) params->vRes;
|
|
memcpy (&ip[ 9], ¶ms->srcRect, sizeof params->srcRect);
|
|
* (uint32 *) &ip[13] = (uint32) params->reserved2;
|
|
}
|
|
else
|
|
{
|
|
ip[ 3] = CWC (0xffff);
|
|
ip[ 4] = CWC (0xffff);
|
|
ip[ 5] = pf->left;
|
|
ip[ 6] = CWC (0x0000);
|
|
ip[ 7] = pf->top;
|
|
ip[ 8] = CWC (0x0000);
|
|
ip[ 9] = pf->right;
|
|
ip[10] = CWC (0x0000);
|
|
ip[11] = pf->bottom;
|
|
ip[12] = CWC (0x0000);
|
|
ip[13] = CWC (0x0000);
|
|
ip[14] = CWC (0x0000);
|
|
}
|
|
|
|
ip[15] = CWC (0x001e);
|
|
|
|
HxX(pch, picsize) = CLC(INITIALPICSIZE);
|
|
HxX(pch, pichowfar) = CL((LONGINT) Hx(ph, picSize));
|
|
temprh = RM(NewRgn());
|
|
HxX(pch, picclip) = temprh;
|
|
/* -32766 below is an attempt to force a reload */
|
|
SetRectRgn(HxP(pch, picclip), -32766, -32766, 32767, 32767);
|
|
PATASSIGN(HxX(pch, picbkpat),white);
|
|
HxX(pch, picfont) = 0;
|
|
HxX(pch, picface) = 0;
|
|
HxX(pch, picfiller) = 0;
|
|
HxX(pch, pictxmode) = CWC(srcOr);
|
|
HxX(pch, pictxsize) = 0;
|
|
HxX(pch, picspextra) = 0;
|
|
HxX(pch, pictxnum.h) = CWC(1);
|
|
HxX(pch, pictxnum.v) = CWC(1);
|
|
HxX(pch, pictxden.h) = CWC(1);
|
|
HxX(pch, pictxden.v) = CWC(1);
|
|
HxX(pch, picdrawpnloc.h) = 0;
|
|
HxX(pch, picdrawpnloc.v) = 0;
|
|
HxX(pch, pictextpnloc.h) = 0;
|
|
HxX(pch, pictextpnloc.v) = 0;
|
|
HxX(pch, picpnsize.h) = CWC(1);
|
|
HxX(pch, picpnsize.v) = CWC(1);
|
|
HxX(pch, picpnmode) = CWC(patCopy);
|
|
PATASSIGN(HxX(pch, picpnpat), black);
|
|
PATASSIGN(HxX(pch, picfillpat), black);
|
|
HxX(pch, piclastrect.top) = 0;
|
|
HxX(pch, piclastrect.left) = 0;
|
|
HxX(pch, piclastrect.bottom)= 0;
|
|
HxX(pch, piclastrect.right) = 0;
|
|
HxX(pch, picov.v) = 0;
|
|
HxX(pch, picov.h) = 0;
|
|
HxX(pch, picidunno) = 0;
|
|
HxX(pch, picforeColor) = CWC(blackColor);
|
|
HxX(pch, picbackColor) = CWC(whiteColor);
|
|
return(ph);
|
|
}
|
|
|
|
P1(PUBLIC pascal trap, PicHandle, OpenPicture, Rect *, pf)
|
|
{
|
|
PicHandle retval;
|
|
|
|
retval = ROMlib_OpenPicture_helper (pf, NULL);
|
|
return retval;
|
|
}
|
|
|
|
PRIVATE void updateclip( void )
|
|
{
|
|
piccachehand pch;
|
|
SignedByte state;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
if (!EqualRgn(PORT_CLIP_REGION (thePort), HxP(pch, picclip)))
|
|
{
|
|
CopyRgn (PORT_CLIP_REGION (thePort), HxP(pch, picclip));
|
|
PICOP(OP_Clip);
|
|
state = HGetState((Handle) PORT_CLIP_REGION (thePort));
|
|
HLock((Handle) PORT_CLIP_REGION (thePort));
|
|
PICWRITE (STARH (PORT_CLIP_REGION (thePort)),
|
|
Hx (PORT_CLIP_REGION (thePort), rgnSize));
|
|
HSetState ((Handle) PORT_CLIP_REGION (thePort), state);
|
|
}
|
|
}
|
|
|
|
PRIVATE BOOLEAN EqualPat( Pattern pat1, Pattern pat2 )
|
|
{
|
|
LONGINT *lp1, *lp2;
|
|
|
|
lp1 = (LONGINT *) pat1;
|
|
lp2 = (LONGINT *) pat2;
|
|
return lp1[0] == lp2[0] && lp1[1] == lp2[1];
|
|
}
|
|
|
|
PRIVATE void updateapat( Pattern srcpat, Pattern dstpat, INTEGER opcode)
|
|
{
|
|
if (!EqualPat(srcpat, dstpat)) {
|
|
PATASSIGN(dstpat, srcpat);
|
|
PICOP(opcode);
|
|
PICWRITE(srcpat, sizeof(Pattern));
|
|
}
|
|
}
|
|
|
|
PRIVATE void updateaninteger( INTEGER src, INTEGER *dstp, INTEGER opcode)
|
|
{
|
|
src = CW(src);
|
|
if (*dstp != src) {
|
|
*dstp = src;
|
|
PICOP(opcode);
|
|
PICWRITE(&src, sizeof(INTEGER));
|
|
}
|
|
}
|
|
|
|
PRIVATE void updatealongint( const LONGINT *srcp, LONGINT *dstp,
|
|
INTEGER opcode)
|
|
{
|
|
if (*dstp != *srcp) {
|
|
*dstp = *srcp;
|
|
PICOP(opcode);
|
|
PICWRITE(srcp, sizeof(LONGINT));
|
|
}
|
|
}
|
|
|
|
PRIVATE void updatebkpat( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
/* #warning Questionable code in updatebkpat */
|
|
/* FIXME */
|
|
if (CGrafPort_p (thePort))
|
|
updateapat (PIXPAT_1DATA (CPORT_BK_PIXPAT (thePort)),
|
|
HxX(pch, picbkpat), OP_BkPat);
|
|
else
|
|
updateapat (PORT_BK_PAT (thePort), HxX(pch, picbkpat), OP_BkPat);
|
|
}
|
|
|
|
PRIVATE void updatepnpat( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) MR(thePort->picSave);
|
|
/* #warning Questionable code in updatepnpat */
|
|
/* FIXME */
|
|
if (CGrafPort_p (thePort))
|
|
updateapat (PIXPAT_1DATA (CPORT_PEN_PIXPAT (thePort)),
|
|
HxX (pch, picpnpat), OP_PnPat);
|
|
else
|
|
updateapat (PORT_PEN_PAT (thePort), HxX(pch, picpnpat), OP_PnPat);
|
|
}
|
|
|
|
PRIVATE void updatefillpat( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) MR(thePort->picSave);
|
|
if (CGrafPort_p (thePort))
|
|
/* #warning Questionable code in updatefillpat */
|
|
updateapat (PIXPAT_1DATA (CPORT_FILL_PIXPAT (thePort)),
|
|
HxX (pch, picfillpat), OP_FillPat);
|
|
else
|
|
updateapat (PORT_FILL_PAT (thePort), HxX(pch, picfillpat), OP_FillPat);
|
|
}
|
|
|
|
PRIVATE void updatefont( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
updateaninteger (PORT_TX_FONT (thePort), &HxX(pch, picfont), OP_TxFont);
|
|
}
|
|
|
|
PRIVATE void updatetxmode( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
updateaninteger (PORT_TX_MODE (thePort), &HxX(pch, pictxmode), OP_TxMode);
|
|
}
|
|
|
|
PRIVATE void updatetxsize( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
updateaninteger(PORT_TX_SIZE (thePort), &HxX(pch, pictxsize), OP_TxSize);
|
|
}
|
|
|
|
PRIVATE void updatepnmode( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
updateaninteger(PORT_PEN_MODE (thePort), &HxX(pch, picpnmode), OP_PnMode);
|
|
}
|
|
|
|
PRIVATE void updateforeColor (void)
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
if (CGrafPort_p (thePort))
|
|
{
|
|
/* ### this isn't quite correct since we only want to write the
|
|
current color if it has changed. that requires we record the
|
|
current color, but the current `piccache' doesn't contain
|
|
that info */
|
|
PICOP (OP_RGBFgCol);
|
|
PICWRITE (&CPORT_RGB_FG_COLOR (thePort),
|
|
sizeof CPORT_RGB_FG_COLOR (thePort));
|
|
}
|
|
else
|
|
updatealongint (&PORT_FG_COLOR_X (thePort), &HxX(pch, picforeColor),
|
|
OP_FgColor);
|
|
}
|
|
|
|
PRIVATE void updatebackColor (void)
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
if (CGrafPort_p (thePort))
|
|
{
|
|
/* ### see comment in `updateforeColor ()' */
|
|
PICOP (OP_RGBBkCol);
|
|
PICWRITE (&CPORT_RGB_BK_COLOR (thePort),
|
|
sizeof CPORT_RGB_BK_COLOR (thePort));
|
|
}
|
|
else
|
|
updatealongint (&PORT_BK_COLOR_X (thePort),
|
|
&HxX(pch, picbackColor),
|
|
OP_BkColor);
|
|
}
|
|
|
|
PRIVATE void updatespextra( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
updatealongint(&PORT_SP_EXTRA_X (thePort), &HxX(pch, picspextra), OP_SpExtra);
|
|
}
|
|
|
|
PRIVATE void updatetxnumtxden( Point num, Point den )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
if (Hx(pch, pictxnum.h) != num.h || Hx(pch, pictxnum.v) != num.v ||
|
|
Hx(pch, pictxden.v) != den.v || Hx(pch, pictxden.h) != den.h) {
|
|
HxX(pch, pictxnum.h) = CW(num.h);
|
|
HxX(pch, pictxnum.v) = CW(num.v);
|
|
HxX(pch, pictxden.h) = CW(den.h);
|
|
HxX(pch, pictxden.v) = CW(den.v);
|
|
PICOP(OP_TxRatio);
|
|
num.h = CW(num.h);
|
|
num.v = CW(num.v);
|
|
PICWRITE(&num, sizeof(num));
|
|
den.h = CW(den.h);
|
|
den.v = CW(den.v);
|
|
PICWRITE(&den, sizeof(den));
|
|
}
|
|
}
|
|
|
|
PRIVATE void updatepnsize( void )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
updatealongint((LONGINT *) &thePort->pnSize,
|
|
(LONGINT *) &HxX(pch, picpnsize), OP_PnSize);
|
|
}
|
|
|
|
PRIVATE void updatetxface( void )
|
|
{
|
|
piccachehand pch;
|
|
Style f;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
if (HxX(pch, picface) != PORT_TX_FACE_X (thePort))
|
|
{
|
|
HxX(pch, picface) = PORT_TX_FACE_X (thePort);
|
|
f = PORT_TX_FACE (thePort);
|
|
PICOP(OP_TxFace);
|
|
PICWRITE(&f, sizeof(f));
|
|
if (sizeof(f) & 1)
|
|
PICWRITE("", 1); /* even things up */
|
|
}
|
|
}
|
|
|
|
PRIVATE void updateoval( Point *ovp )
|
|
{
|
|
piccachehand pch;
|
|
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
if (HxX(pch, picov.h) != ovp->h || HxX(pch, picov.v) != ovp->v)
|
|
{
|
|
HxX(pch, picov) = *ovp;
|
|
PICOP(OP_OvSize);
|
|
PICWRITE(ovp, sizeof(*ovp));
|
|
}
|
|
}
|
|
|
|
PUBLIC void ROMlib_textpicupdate( Point num, Point den )
|
|
{
|
|
updateclip();
|
|
updatefont();
|
|
updatetxface();
|
|
updatetxmode();
|
|
updatetxsize();
|
|
updatespextra();
|
|
updatetxnumtxden( num, den );
|
|
updateforeColor();
|
|
updatebackColor();
|
|
}
|
|
|
|
PUBLIC void ROMlib_drawingpicupdate( void )
|
|
{
|
|
updateclip();
|
|
updatepnsize();
|
|
updatepnmode();
|
|
updatepnpat();
|
|
updateforeColor();
|
|
updatebackColor();
|
|
}
|
|
|
|
PUBLIC void ROMlib_drawingverbpicupdate( GrafVerb v )
|
|
{
|
|
ROMlib_drawingpicupdate();
|
|
switch (v) {
|
|
case erase:
|
|
updatebkpat();
|
|
break;
|
|
case fill:
|
|
updatefillpat();
|
|
break;
|
|
case invert:
|
|
if (!(HiliteMode & 0x80))
|
|
{
|
|
PICOP (OP_HiliteColor);
|
|
PICWRITE (&HiliteRGB, sizeof HiliteRGB);
|
|
PICOP (OP_HiliteMode);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
PUBLIC void ROMlib_drawingverbrectpicupdate( GrafVerb v, Rect *rp )
|
|
{
|
|
piccachehand pch;
|
|
|
|
ROMlib_drawingverbpicupdate( v );
|
|
pch = (piccachehand) PORT_PIC_SAVE (thePort);
|
|
HxX(pch, piclastrect) = *rp; /* currently unused */
|
|
}
|
|
|
|
PUBLIC void ROMlib_drawingverbrectovalpicupdate( GrafVerb v, Rect *rp,
|
|
Point *ovp )
|
|
{
|
|
ROMlib_drawingverbrectpicupdate( v, rp );
|
|
updateoval( ovp );
|
|
}
|
|
|
|
P0(PUBLIC pascal trap, void, ClosePicture)
|
|
{
|
|
piccachehand pch;
|
|
|
|
if ((pch = (piccachehand) PORT_PIC_SAVE (thePort)))
|
|
{
|
|
PicHandle ph;
|
|
|
|
PICOP(OP_EndPic);
|
|
ph = HxP (pch, pichandle);
|
|
SetHandleSize ((Handle) ph, Hx (pch, pichowfar));
|
|
DisposeRgn(HxP(pch, picclip));
|
|
DisposHandle((Handle) pch);
|
|
PORT_PIC_SAVE_X (thePort) = RM (NULL);
|
|
ShowPen();
|
|
}
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, void, PicComment, INTEGER, kind, INTEGER, size,
|
|
Handle, hand)
|
|
{
|
|
CALLCOMMENT(kind, size, hand);
|
|
}
|
|
|
|
P3(PUBLIC pascal trap, void, ReadComment, INTEGER, kind, INTEGER, size,
|
|
Handle, hand)
|
|
{
|
|
CALLCOMMENT(kind, size, hand);
|
|
}
|
|
|
|
/* look in qPicStuff.c for DrawPicture */
|
|
|
|
|
|
P1(PUBLIC pascal trap, void, KillPicture, PicHandle, pic)
|
|
{
|
|
/*
|
|
* It's not clear what the Mac does in the case below. We really should
|
|
* test exactly how the Mac deals with DisposHandle being called on resource
|
|
* handles.
|
|
*/
|
|
SignedByte state;
|
|
|
|
state = HGetState((Handle)pic);
|
|
if (!(state & RSRCBIT))
|
|
DisposHandle((Handle) pic);
|
|
}
|