executor/src/qPicstuff.c

2083 lines
54 KiB
C

/* Copyright 1986-1996 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_qPicstuff[] =
"$Id: qPicstuff.c 87 2005-05-25 01:57:33Z ctm $";
#endif
/* Forward declarations in QuickDraw.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "WindowMgr.h"
#include "ControlMgr.h"
#include "MemoryMgr.h"
#include "QuickDraw.h"
#include "CQuickDraw.h"
#include "OSUtil.h"
#include "ToolboxUtil.h"
#include "FontMgr.h"
#include "rsys/toolutil.h"
#include "rsys/cquick.h"
#include "rsys/picture.h"
#include "rsys/mman.h"
#include "rsys/xdata.h"
#include "rsys/tempalloc.h"
#include "rsys/print.h"
#include "rsys/executor.h"
/*
* Hooray for static variables. We have to do something like this because
* the StdGetPic routine doesn't actually supply a source byte pointer.
* We used to be nice and re-entrant, but Collate likes to patch out StdGetPic
* with a routine that uses PBRead() to supply values, and our old trick of
* requesting one chunk that is a picSize long doesn't work, because the
* picture Collate wants to print contains more than 32767 characters.
*
* We could still make *our* implementation re-entrant, but it's clear that
* Apple's isn't.
*/
PRIVATE unsigned char *nextbytep;
PRIVATE pascal void (*procp)(Ptr, INTEGER);
typedef void (*pfv)();
typedef struct {
pfv func;
LONGINT argcode;
} wps;
/*
* The top four bits that are used to describe how an opcode behaves are an
* encoded form of which of the operands (described in the remaining 28 bits)
* need to be scaled.
*
* Two bits are used for each operand. The msb is set only when the operand
* in question requies scaling only as a v quantity (i.e. if it is not set
* then the operand requires scaling either in both h and v or just h. Which
* it is depends on the type of the operand (e.g. rects require scaling of
* both components). The lower bit specifies whether or not to do any scaling.
*
* WoRDs and BYTes are taken to be relative quantities while other types are
* assumed to be absolute coordinates (this effects exactly what scaling is:
* relative quantities are scaled but not offset).
*
* Note the actual top four bits only specify an index into the array
* scalevalues. The array scalevalues is where the scaling info belongs.
*/
#define NOSCALE 0L
#define SCALE0 1L
#define SCALE01 2L
#define SCALE012V 3L
#define SCALE01V 4L
#define SCALE0V 5L
#define SCALE3 6L
#define SCALE35 7L
#define SCALEIT 1L
#define VONLY 2L
PRIVATE unsigned short scalevalues[16] = {
0x000, /* 00000000 0000 0000 NOSCALE */
0x001, /* 00000000 0000 0001 SCALE0 */
0x005, /* 00000000 0000 0101 SCALE01 */
0x035, /* 00000000 0011 0101 SCALE012V */
0x00D, /* 00000000 0000 1101 SCALE01V */
0x003, /* 00000000 0000 0011 SCALE0V */
0x040, /* 00000000 0100 0000 SCALE3 */
0x140, /* 00000001 0100 0000 SCALE35 */
/* the rest are all zeros */
};
#define xxx0() 0
#define xxx1(a) xxx0()|a
#define xxx2(a,b) xxx1(a)|(b<<4)
#define xxx3(a,b,c) xxx2(a,b)|(c<<8)
#define xxx4(a,b,c,d) xxx3(a,b,c)|(d<<12)
#define xxx5(a,b,c,d,e) xxx4(a,b,c,d)|(e<<16)
#define xxx6(a,b,c,d,e,f) xxx5(a,b,c,d,e)|(f<<20)
#define xxx7(a,b,c,d,e,f,g) xxx6(a,b,c,d,e,f)|(g<<24)
#define yyy1(s,a) (s<<28)|xxx1(a)
#define yyy2(s,a,b) (s<<28)|xxx2(a,b)
#define yyy3(s,a,b,c) (s<<28)|xxx3(a,b,c)
#define yyy4(s,a,b,c,d) (s<<28)|xxx4(a,b,c,d)
#define yyy5(s,a,b,c,d,e) (s<<28)|xxx5(a,b,c,d,e)
#define yyy6(s,a,b,c,d,e,f) (s<<28)|xxx6(a,b,c,d,e,f)
#define yyy7(s,a,b,c,d,e,f,g) (s<<28)|xxx7(a,b,c,d,e,f,g)
#define OVP 1L /* 0 bytes: oval point */
#define BYT 2L /* 1 byte */
#define WRD 3L /* 2 bytes */
#define LNG 4L /* 4 bytes */
#define PNT 5L /* 4 bytes */
#define RCT 6L /* 8 bytes */
#define PAT 7L /* 8 bytes */
#define TXT 8L /* first byte 0..255 tells how many succesive bytes */
#define RGN 9L /* first word tells how many inclusive bytes */
#define DAT 10L /* first word tells how many exclusive bytes */
#define SAM 11L /* Same, as in FrameSameRect */
#define RGB 12L /* RGB color */
#define PXP 13L /* PixPat */
#define SPL 14L /* Special ... do by hand */
#define PLY 15L /* polys have to be mapped differently from regions */
#define ARGMASK 0x0FFFFFFF /* everything except the scale bits */
A0(PRIVATE, void, nop)
{
}
A1(PRIVATE, void, thepat, Pattern *, p)
{
ROMlib_fill_pat (*p);
}
PRIVATE LONGINT txnumh, txnumv, txdenh, txdenv;
PRIVATE Rect srcpicframe, dstpicframe;
PRIVATE LONGINT picnumh, picnumv, picdenh, picdenv;
PRIVATE Point txtpoint;
/*
* TODO: reduce is exceedingly inefficient. Reconsider its use here.
*/
/*
* NOTE: reduce is used internally and hence doesn't treat its pointer
* arguments as pointers into syn space
*/
PRIVATE void reduce(LONGINT *nump, LONGINT *denp)
{
LONGINT num, den, max, i;
num = *nump;
den = *denp;
max = MIN(num / 2, den / 2);
for (i = max; i >= 2; --i) {
if ((num % i == 0) && (den % i == 0))
break;
}
if (i > 1) {
*nump = num / i;
*denp = den / i;
}
if (*nump > *denp) {
if (*denp && (*nump % *denp == 0)) {
*nump = (*nump) / (*denp);
*denp = 1;
}
} else {
if (*nump && (*denp % *nump == 0)) {
*denp = (*denp) / (*nump);
*nump = 1;
}
}
}
A2(PRIVATE, void, txratio, Point, num, Point, den)
{
txnumh = num.h;
txnumv = num.v;
txdenh = den.h;
txdenv = den.v;
reduce(&txnumh, &txdenh);
reduce(&txnumv, &txdenv);
}
A2(PRIVATE, void, line, Point, op, Point, np)
{
PORT_PEN_LOC (thePort).h = CW (op.h);
PORT_PEN_LOC (thePort).v = CW (op.v);
CALLLINE(np);
PORT_PEN_LOC (thePort).h = CW (np.h);
PORT_PEN_LOC (thePort).v = CW (np.v);
}
A3(PRIVATE, void, shrtline, Point, op, SignedByte, dh, SignedByte, dv)
{
PORT_PEN_LOC (thePort).h = CW(op.h);
PORT_PEN_LOC (thePort).v = CW(op.v);
op.h += dh;
op.v += dv;
CALLLINE (op);
PORT_PEN_LOC (thePort).h = CW(op.h);
PORT_PEN_LOC (thePort).v = CW(op.v);
}
PRIVATE void setnumerdenom(Point *nump, Point *denp)
{
LONGINT numerh, numerv, denomh, denomv;
numerh = txnumh * picnumh;
numerv = txnumv * picnumv;
denomh = txdenh * picdenh;
denomv = txdenv * picdenv;
reduce(&numerh, &denomh);
reduce(&numerv, &denomv);
nump->h = numerh;
nump->v = numerv;
denp->h = denomh;
denp->v = denomv;
}
A3(PRIVATE, void, longtext, Point, pt, StringPtr, s, Point *, pp)
{
Point save, numer, denom;
save = PORT_PEN_LOC (thePort);
pp->h = CW (pt.h);
pp->v = CW (pt.v);
PORT_PEN_LOC (thePort).h = CW (pt.h);
PORT_PEN_LOC (thePort).v = CW (pt.v);
setnumerdenom (&numer, &denom);
CALLTEXT ((INTEGER) U(s[0]), (Ptr) (s+1), numer, denom);
PORT_PEN_LOC (thePort) = save;
}
A3(PRIVATE, void, dhtext, unsigned char, dh, StringPtr, s, Point *, pp)
{
Point save, numer, denom;
pp->h = CW(CW(pp->h) + (dh));
save = PORT_PEN_LOC (thePort);
PORT_PEN_LOC (thePort) = *pp;
setnumerdenom (&numer, &denom);
CALLTEXT((INTEGER) U(s[0]), (Ptr) (s+1), numer, denom);
PORT_PEN_LOC (thePort) = save;
}
A3(PRIVATE, void, dvtext, unsigned char, dv, StringPtr, s, Point *, pp)
{
Point save, numer, denom;
pp->v = CW (CW (pp->v) + (dv));
save = PORT_PEN_LOC (thePort);
PORT_PEN_LOC (thePort) = *pp;
setnumerdenom (&numer, &denom);
CALLTEXT ((INTEGER)U(s[0]), (Ptr) (s+1), numer, denom);
PORT_PEN_LOC (thePort) = save;
}
A4(PRIVATE, void, dhdvtext, Byte, dh, Byte, dv,
StringPtr, s, Point *, pp)
{
Point save, numer, denom;
pp->h = CW(CW(pp->h) + (dh));
pp->v = CW(CW(pp->v) + (dv));
save = PORT_PEN_LOC (thePort);
PORT_PEN_LOC (thePort) = *pp;
setnumerdenom(&numer, &denom);
CALLTEXT ((INTEGER)U(s[0]), (Ptr) (s+1), numer, denom);
PORT_PEN_LOC (thePort) = save;
}
A1(PRIVATE, void, fillrct, Rect *, r)
{
CALLRECT (fill, r);
}
A3(PRIVATE, void, fillrrct, Rect *, r, INTEGER, ow, INTEGER, oh)
{
CALLRRECT (fill, r, ow, oh);
}
A1(PRIVATE, void, fillovl, Rect *, r)
{
CALLOVAL (fill, r);
}
A3(PRIVATE, void, fillarc, Rect *, r, INTEGER, stang, INTEGER, arcang)
{
CALLARC (fill, r, stang, arcang);
}
A1(PRIVATE, void, fillpoly, PolyHandle, p)
{
CALLPOLY (fill, p);
}
A1(PRIVATE, void, fillrgn, RgnHandle, r)
{
CALLRGN (fill, r);
}
PRIVATE RgnHandle saveclip;
A2 (PRIVATE, void, origin, INTEGER, dh, INTEGER, dv)
{
OffsetRect (&srcpicframe, dh, dv);
txtpoint.h = CW (CW (txtpoint.h) - dh);
txtpoint.v = CW (CW (txtpoint.v) - dv);
}
A1(PRIVATE, void, pnlochfrac, INTEGER, f)
{
/* make sure that we scale f, since it's fixed and can't be scaled
automatically */
}
A1(PRIVATE, void, myreadcment, INTEGER, kind)
{
C_ReadComment(kind, 0, (Handle) 0);
}
PRIVATE RGBColor saveHiliteRGB;
A0(PRIVATE, void, defhilite)
{
HiliteRGB = saveHiliteRGB;
}
A0(PRIVATE, void, hilitemode)
{
HiliteMode &= ~(0x80);
}
A1(PRIVATE, void, fillpixpat, PixPatHandle, ph)
{
if (CGrafPort_p (thePort))
{
HandToHand ((HIDDEN_Handle *) &ph);
CPORT_FILL_PIXPAT_X (theCPort) = RM (ph);
}
}
A2(PRIVATE, void, pnsize, INTEGER, pv, INTEGER, ph)
{
Point p;
p.h = CW(ph);
p.v = CW(pv);
ScalePt(&p, &srcpicframe, &dstpicframe);
PenSize(CW(p.h), CW(p.v));
}
A1(PRIVATE, void, textface, Byte, f)
{
TextFace(f);
}
A1(PRIVATE, void, charextra, INTEGER, extra)
{
/* TODO: Can't use CharExtra 'cause argument is Fixed */
}
A2(PRIVATE, void, shrtlinefrom, SignedByte, dh, SignedByte, dv)
{
Line(dh, dv);
}
A1(PRIVATE, void, setpicclip, RgnHandle, rh)
{
SectRgn(rh, saveclip, rh);
SetClip(rh);
}
PRIVATE void W_BackPat( Pattern pp )
{
BackPat( pp );
}
/* routines that associate a PICT font number with a font name */
typedef struct assoc_link
{
struct assoc_link *nextp;
StringPtr str;
INTEGER i;
}
assoc_link_t;
PRIVATE assoc_link_t *assoc_headp = 0;
PRIVATE void
begin_assoc (void)
{
/* Don't do anything */
}
PRIVATE assoc_link_t **
assoc_find_str (StringPtr sp)
{
assoc_link_t **retval;
for (retval = &assoc_headp;
*retval && EqualString ((*retval)->str, sp, FALSE, TRUE) != 0;
retval = &(*retval)->nextp)
;
return retval;
}
PRIVATE assoc_link_t **
assoc_find_i (INTEGER i)
{
assoc_link_t **retval;
for (retval = &assoc_headp;
*retval && (*retval)->i != i;
retval = &(*retval)->nextp)
;
return retval;
}
PRIVATE StringPtr
makestr (StringPtr sp)
{
StringPtr retval;
int len;
len = sp[0] + 1;
retval = malloc (len);
memcpy (retval, sp, len);
return retval;
}
PRIVATE void
add_assoc (INTEGER i, StringPtr sp)
{
assoc_link_t **pp;
pp = assoc_find_str (sp);
if (*pp)
(*pp)->i = i;
else
{
assoc_link_t *p;
p = malloc (sizeof *p);
p->nextp = 0;
p->str = makestr (sp);
p->i = i;
*pp = p;
}
}
PRIVATE StringPtr
assoc (INTEGER i)
{
StringPtr retval;
assoc_link_t **pp;
pp = assoc_find_i (i);
if (*pp)
retval = (*pp)->str;
else
retval = 0;
return retval;
}
PRIVATE void
end_assoc (void)
{
assoc_link_t *p, *nextp;
for (p = assoc_headp; p; p = nextp)
{
nextp = p->nextp;
free (p->str);
free (p);
}
assoc_headp = 0;
}
PRIVATE void W_TextFont( INTEGER f )
{
StringPtr sp;
sp = assoc (f);
if (sp)
{
INTEGER new_f;
GetFNum (sp, &new_f);
if (new_f)
f = CW (new_f);
}
TextFont( f );
}
PRIVATE void W_TextMode( INTEGER m )
{
TextMode( m );
}
PRIVATE void W_SpaceExtra( Fixed e )
{
SpaceExtra( e );
}
PRIVATE void W_PenMode( INTEGER m )
{
#define BACHMAN_HACK
#if defined(BACHMAN_HACK)
if ( m == 23 )
m = 7;
#endif
PenMode( m );
}
PRIVATE void W_PenPat( Pattern pp )
{
PenPat( pp );
}
PRIVATE void W_TextSize( INTEGER s )
{
TextSize( s );
}
PRIVATE void W_ForeColor( LONGINT c )
{
ForeColor( c );
}
PRIVATE void W_BackColor( LONGINT c )
{
BackColor( c );
}
PRIVATE void W_BackPixPat( PixPatHandle ph )
{
BackPixPat( ph );
}
PRIVATE void W_PenPixPat( PixPatHandle ph )
{
PenPixPat( ph );
}
PRIVATE void W_RGBForeColor( RGBColor *colorp )
{
RGBForeColor( colorp );
}
PRIVATE void W_RGBBackColor( RGBColor *colorp )
{
RGBBackColor( colorp );
}
PRIVATE void W_HiliteColor( RGBColor *colorp )
{
HiliteColor( colorp );
}
PRIVATE void W_OpColor( RGBColor *colorp )
{
OpColor( colorp );
}
PRIVATE void W_LineTo( INTEGER h, INTEGER v )
{
LineTo( h, v );
}
PRIVATE void W_FrameRect( Rect *r )
{
FrameRect( r );
}
PRIVATE void W_PaintRect( Rect *r )
{
PaintRect( r );
}
PRIVATE void W_EraseRect( Rect *r )
{
EraseRect( r );
}
PRIVATE void
reset_hilite_mode (void)
{
HiliteMode |= 0x80;
}
PRIVATE void W_InvertRect( Rect *r )
{
InvertRect( r );
reset_hilite_mode ();
}
PRIVATE void W_FrameRoundRect( Rect *r, INTEGER ow, INTEGER oh )
{
FrameRoundRect( r, ow, oh );
}
PRIVATE void W_PaintRoundRect( Rect *r, INTEGER ow, INTEGER oh )
{
PaintRoundRect( r, ow, oh );
}
PRIVATE void W_EraseRoundRect( Rect *r, INTEGER ow, INTEGER oh )
{
EraseRoundRect( r, ow, oh );
}
PRIVATE void W_InvertRoundRect( Rect *r, INTEGER ow, INTEGER oh )
{
InvertRoundRect( r, ow, oh );
reset_hilite_mode ();
}
PRIVATE void W_FrameOval( Rect *r )
{
FrameOval( r );
}
PRIVATE void W_PaintOval( Rect *r )
{
PaintOval( r );
}
PRIVATE void W_EraseOval( Rect *r )
{
EraseOval( r );
}
PRIVATE void W_InvertOval( Rect *r )
{
InvertOval( r );
reset_hilite_mode ();
}
PRIVATE void W_FrameArc( Rect *r, INTEGER start, INTEGER angle )
{
FrameArc( r, start, angle );
}
PRIVATE void W_PaintArc( Rect *r, INTEGER start, INTEGER angle )
{
PaintArc( r, start, angle );
}
PRIVATE void W_EraseArc( Rect *r, INTEGER start, INTEGER angle )
{
EraseArc( r, start, angle );
}
PRIVATE void W_InvertArc( Rect *r, INTEGER start, INTEGER angle )
{
InvertArc( r, start, angle );
reset_hilite_mode ();
}
PRIVATE void W_FramePoly( PolyHandle poly )
{
FramePoly( poly );
}
PRIVATE void W_PaintPoly( PolyHandle poly )
{
PaintPoly( poly );
}
PRIVATE void W_ErasePoly( PolyHandle poly )
{
ErasePoly( poly );
}
PRIVATE void W_InvertPoly( PolyHandle poly )
{
InvertPoly( poly );
reset_hilite_mode ();
}
PRIVATE void W_FrameRgn( RgnHandle rh )
{
FrameRgn( rh );
}
PRIVATE void W_PaintRgn( RgnHandle rh )
{
PaintRgn( rh );
}
PRIVATE void W_EraseRgn( RgnHandle rh )
{
EraseRgn( rh );
}
PRIVATE void W_InvertRgn( RgnHandle rh )
{
InvertRgn( rh );
reset_hilite_mode ();
}
PRIVATE void W_ReadComment( INTEGER kind, INTEGER size, Handle hand )
{
C_ReadComment( kind, size, hand );
}
PRIVATE void
fontname (INTEGER hsize, Handle hand)
{
char *p;
INTEGER i;
StringPtr sp;
p = (char *) STARH (hand);
i = CW (*(INTEGER *)p);
sp = (StringPtr) p + 2;
add_assoc (i, sp);
}
PRIVATE void
glyphstate (INTEGER hsize, Handle hand)
{
char *p;
p = (char *) STARH (hand);
warning_unimplemented ("partially implemented");
SetFractEnable (!p[2]);
SetFScaleDisable (p[3]);
}
PRIVATE wps wparray[] = {
{ (pfv) nop, xxx0(), /* 00 */ },
{ (pfv) setpicclip, yyy1(SCALE0, RGN), /* 01 */ },
{ (pfv) W_BackPat, xxx1(PAT), /* 02 */ },
{ (pfv) W_TextFont, xxx1(WRD), /* 03 */ },
{ (pfv) textface, xxx1(BYT), /* 04 */ },
{ (pfv) W_TextMode, xxx1(WRD), /* 05 */ },
{ (pfv) W_SpaceExtra, xxx1(LNG), /* 06 */ },
{ (pfv) pnsize, xxx2(WRD,WRD), /* 07 */ },
{ (pfv) W_PenMode, xxx1(WRD), /* 08 */ },
{ (pfv) W_PenPat, xxx1(PAT), /* 09 */ },
{ (pfv) thepat, xxx1(PAT), /* 0A */ },
{ (pfv) nop, xxx1(PNT), /* OvSize */ /* 0B */ },
{ (pfv) origin, xxx2(WRD, WRD), /* 0C */ },
{ (pfv) W_TextSize, xxx1(WRD), /* 0D */ },
{ (pfv) W_ForeColor, xxx1(LNG), /* 0E */ },
{ (pfv) W_BackColor, xxx1(LNG), /* 0F */ },
{ (pfv) txratio, xxx2(PNT, PNT), /* 10 */ },
{ (pfv) nop, xxx1(BYT), /* PicVers */ /* 11 */ },
{ (pfv) W_BackPixPat, xxx1(PXP), /* 12 */ },
{ (pfv) W_PenPixPat, xxx1(PXP), /* 13 */ },
{ (pfv) fillpixpat, xxx1(PXP), /* 14 */ },
{ (pfv) pnlochfrac, xxx1(WRD), /* 15 */ },
{ (pfv) charextra, xxx1(WRD), /* 16 */ },
{ (pfv) nop, xxx0(), /* reserved for Apple use */ /* 17 */ },
{ (pfv) nop, xxx0(), /* reserved for Apple use */ /* 18 */ },
{ (pfv) nop, xxx0(), /* reserved for Apple use */ /* 19 */ },
{ (pfv) W_RGBForeColor, xxx1(RGB), /* 1A */ },
{ (pfv) W_RGBBackColor, xxx1(RGB), /* 1B */ },
{ (pfv) hilitemode, xxx0(), /* 1C */ },
{ (pfv) W_HiliteColor,xxx1(RGB), /* 1D */ },
{ (pfv) defhilite, xxx0(), /* 1E */ },
{ (pfv) W_OpColor, xxx1(RGB), /* 1F */ },
{ (pfv) line, yyy2(SCALE01, PNT, PNT), /* 20 */ },
{ (pfv) W_LineTo, yyy1(SCALE0, PNT), /* 21 */ },
{ (pfv) shrtline, yyy3(SCALE012V, PNT, BYT, BYT), /* 22 */ },
{ (pfv) shrtlinefrom, yyy2(SCALE01V, BYT, BYT), /* 23 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 24 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 25 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 26 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 27 */ },
{ (pfv) longtext, yyy2(SCALE0, PNT, TXT), /* 28 */ },
{ (pfv) dhtext, yyy2(SCALE0, BYT, TXT), /* 29 */ },
{ (pfv) dvtext, yyy2(SCALE0V, BYT, TXT), /* 2A */ },
{ (pfv) dhdvtext, yyy3(SCALE01V, BYT, BYT, TXT), /* 2B */ },
{ (pfv) fontname, xxx1(DAT), /* 2C */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 2D */ },
{ (pfv) glyphstate, xxx1(DAT), /* 2E */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 2F */ },
{ (pfv) W_FrameRect, yyy1(SCALE0, RCT), /* 30 */ },
{ (pfv) W_PaintRect, yyy1(SCALE0, RCT), /* 31 */ },
{ (pfv) W_EraseRect, yyy1(SCALE0, RCT), /* 32 */ },
{ (pfv) W_InvertRect, yyy1(SCALE0, RCT), /* 33 */ },
{ (pfv) fillrct, yyy1(SCALE0, RCT), /* 34 */ },
{ (pfv) nop, xxx1(RCT), /* reserved for Apple use */ /* 35 */ },
{ (pfv) nop, xxx1(RCT), /* reserved for Apple use */ /* 36 */ },
{ (pfv) nop, xxx1(RCT), /* reserved for Apple use */ /* 37 */ },
{ (pfv) W_FrameRect, xxx2(SAM, RCT), /* 38 */ },
{ (pfv) W_PaintRect, xxx2(SAM, RCT), /* 39 */ },
{ (pfv) W_EraseRect, xxx2(SAM, RCT), /* 3A */ },
{ (pfv) W_InvertRect, xxx2(SAM, RCT), /* 3B */ },
{ (pfv) fillrct, xxx2(SAM, RCT), /* 3C */ },
{ (pfv) nop, xxx2(SAM, RCT), /* reserved for Apple use */ /* 3D */ },
{ (pfv) nop, xxx2(SAM, RCT), /* reserved for Apple use */ /* 3E */ },
{ (pfv) nop, xxx2(SAM, RCT), /* reserved for Apple use */ /* 3F */ },
{ (pfv) W_FrameRoundRect, yyy2(SCALE0, RCT, OVP), /* 40 */ },
{ (pfv) W_PaintRoundRect, yyy2(SCALE0, RCT, OVP), /* 41 */ },
{ (pfv) W_EraseRoundRect, yyy2(SCALE0, RCT, OVP), /* 42 */ },
{ (pfv) W_InvertRoundRect, yyy2(SCALE0, RCT, OVP), /* 43 */ },
{ (pfv) fillrrct, yyy2(SCALE0, RCT, OVP), /* 44 */ },
{ (pfv) nop, xxx2(RCT, OVP), /* Apple use */ /* 45 */ },
{ (pfv) nop, xxx2(RCT, OVP), /* Apple use */ /* 46 */ },
{ (pfv) nop, xxx2(RCT, OVP), /* Apple use */ /* 47 */ },
{ (pfv) W_FrameRoundRect, xxx3(SAM, RCT, OVP), /* 48 */ },
{ (pfv) W_PaintRoundRect, xxx3(SAM, RCT, OVP), /* 49 */ },
{ (pfv) W_EraseRoundRect, xxx3(SAM, RCT, OVP), /* 4A */ },
{ (pfv) W_InvertRoundRect, xxx3(SAM, RCT, OVP), /* 4B */ },
{ (pfv) fillrrct, xxx3(SAM, RCT, OVP), /* 4C */ },
{ (pfv) nop, xxx3(SAM, RCT, OVP), /* Apple use */ /* 4D */ },
{ (pfv) nop, xxx3(SAM, RCT, OVP), /* Apple use */ /* 4E */ },
{ (pfv) nop, xxx3(SAM, RCT, OVP), /* Apple use */ /* 4F */ },
{ (pfv) W_FrameOval, yyy1(SCALE0, RCT), /* 50 */ },
{ (pfv) W_PaintOval, yyy1(SCALE0, RCT), /* 51 */ },
{ (pfv) W_EraseOval, yyy1(SCALE0, RCT), /* 52 */ },
{ (pfv) W_InvertOval, yyy1(SCALE0, RCT), /* 53 */ },
{ (pfv) fillovl, yyy1(SCALE0, RCT), /* 54 */ },
{ (pfv) nop, xxx1(RCT), /* Apple use */ /* 55 */ },
{ (pfv) nop, xxx1(RCT), /* Apple use */ /* 56 */ },
{ (pfv) nop, xxx1(RCT), /* Apple use */ /* 57 */ },
{ (pfv) W_FrameOval, xxx2(SAM, RCT), /* 58 */ },
{ (pfv) W_PaintOval, xxx2(SAM, RCT), /* 59 */ },
{ (pfv) W_EraseOval, xxx2(SAM, RCT), /* 5A */ },
{ (pfv) W_InvertOval, xxx2(SAM, RCT), /* 5B */ },
{ (pfv) fillovl, xxx2(SAM, RCT), /* 5C */ },
{ (pfv) nop, xxx2(SAM, RCT), /* Apple use */ /* 5D */ },
{ (pfv) nop, xxx2(SAM, RCT), /* Apple use */ /* 5E */ },
{ (pfv) nop, xxx2(SAM, RCT), /* Apple use */ /* 5F */ },
{ (pfv) W_FrameArc, yyy3(SCALE0, RCT, WRD, WRD), /* 60 */ },
{ (pfv) W_PaintArc, yyy3(SCALE0, RCT, WRD, WRD), /* 61 */ },
{ (pfv) W_EraseArc, yyy3(SCALE0, RCT, WRD, WRD), /* 62 */ },
{ (pfv) W_InvertArc, yyy3(SCALE0, RCT, WRD, WRD), /* 63 */ },
{ (pfv) fillarc, yyy3(SCALE0, RCT, WRD, WRD), /* 64 */ },
{ (pfv) nop, xxx3(RCT, WRD, WRD), /* Apple use */ /* 65 */ },
{ (pfv) nop, xxx3(RCT, WRD, WRD), /* Apple use */ /* 66 */ },
{ (pfv) nop, xxx3(RCT, WRD, WRD), /* Apple use */ /* 67 */ },
{ (pfv) W_FrameArc, xxx6(WRD, WRD, SAM, RCT, WRD, WRD), /* 68 */ },
{ (pfv) W_PaintArc, xxx6(WRD, WRD, SAM, RCT, WRD, WRD), /* 69 */ },
{ (pfv) W_EraseArc, xxx6(WRD, WRD, SAM, RCT, WRD, WRD), /* 6A */ },
{ (pfv) W_InvertArc, xxx6(WRD, WRD, SAM, RCT, WRD, WRD), /* 6B */ },
{ (pfv) fillarc, xxx6(WRD, WRD, SAM, RCT, WRD, WRD), /* 6C */ },
{ (pfv) nop, xxx6(WRD, WRD, SAM, RCT, WRD, WRD),/* Apple use *//* 6D */ },
{ (pfv) nop, xxx6(WRD, WRD, SAM, RCT, WRD, WRD),/* Apple use *//* 6E */ },
{ (pfv) nop, xxx6(WRD, WRD, SAM, RCT, WRD, WRD),/* Apple use *//* 6F */ },
{ (pfv) W_FramePoly, yyy1(SCALE0, PLY), /* 70 */ },
{ (pfv) W_PaintPoly, yyy1(SCALE0, PLY), /* 71 */ },
{ (pfv) W_ErasePoly, yyy1(SCALE0, PLY), /* 72 */ },
{ (pfv) W_InvertPoly, yyy1(SCALE0, PLY), /* 73 */ },
{ (pfv) fillpoly, yyy1(SCALE0, PLY), /* 74 */ },
{ (pfv) nop, xxx1(PLY), /* Apple use */ /* 75 */ },
{ (pfv) nop, xxx1(PLY), /* Apple use */ /* 76 */ },
{ (pfv) nop, xxx1(PLY), /* Apple use */ /* 77 */ },
{ (pfv) W_FramePoly, xxx2(SAM, PLY), /* 78 */ },
{ (pfv) W_PaintPoly, xxx2(SAM, PLY), /* 79 */ },
{ (pfv) W_ErasePoly, xxx2(SAM, PLY), /* 7A */ },
{ (pfv) W_InvertPoly, xxx2(SAM, PLY), /* 7B */ },
{ (pfv) fillpoly, xxx2(SAM, PLY), /* 7C */ },
{ (pfv) nop, xxx2(SAM, PLY), /* Apple use */ /* 7D */ },
{ (pfv) nop, xxx2(SAM, PLY), /* Apple use */ /* 7E */ },
{ (pfv) nop, xxx2(SAM, RGN), /* Apple use */ /* 7F */ },
{ (pfv) W_FrameRgn, yyy1(SCALE0, RGN), /* 80 */ },
{ (pfv) W_PaintRgn, yyy1(SCALE0, RGN), /* 81 */ },
{ (pfv) W_EraseRgn, yyy1(SCALE0, RGN), /* 82 */ },
{ (pfv) W_InvertRgn, yyy1(SCALE0, RGN), /* 83 */ },
{ (pfv) fillrgn, yyy1(SCALE0, RGN), /* 84 */ },
{ (pfv) nop, xxx1(RGN), /* Apple use */ /* 85 */ },
{ (pfv) nop, xxx1(RGN), /* Apple use */ /* 86 */ },
{ (pfv) nop, xxx1(RGN), /* Apple use */ /* 87 */ },
{ (pfv) W_FrameRgn, xxx2(SAM, RGN), /* 88 */ },
{ (pfv) W_PaintRgn, xxx2(SAM, RGN), /* 89 */ },
{ (pfv) W_EraseRgn, xxx2(SAM, RGN), /* 8A */ },
{ (pfv) W_InvertRgn, xxx2(SAM, RGN), /* 8B */ },
{ (pfv) fillrgn, xxx2(SAM, RGN), /* 8C */ },
{ (pfv) nop, xxx2(SAM, RGN), /* Apple use */ /* 8D */ },
{ (pfv) nop, xxx2(SAM, RGN), /* Apple use */ /* 8E */ },
{ (pfv) nop, xxx2(SAM, RGN), /* Apple use */ /* 8F */ },
{ (pfv) nop, xxx1(SPL), /* unpacked bits rect 90 */ },
{ (pfv) nop, xxx1(SPL), /* unpacked bits rgn 91 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 92 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 93 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 94 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 95 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 96 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 97 */ },
{ (pfv) nop, xxx1(SPL), /* packed bits rect 98 */ },
{ (pfv) nop, xxx1(SPL), /* packed bits rgn 99 */ },
{ (pfv) nop, xxx1(SPL), /* direct bits rect */ /* 9A */ },
{ (pfv) nop, xxx1(SPL), /* direct bits rgn */ /* 9B */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 9C */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 9D */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 9E */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* 9F */ },
{ (pfv) myreadcment,xxx1(WRD), /* A0 */ },
{ (pfv) W_ReadComment,xxx2(WRD, DAT), /* A1 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A2 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A3 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A4 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A5 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A6 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A7 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A8 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* A9 */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* AA */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* AB */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* AC */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* AD */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* AE */ },
{ (pfv) nop, xxx1(DAT), /* reserved for Apple use */ /* AF */ },
};
#define RGBPat 2
/*
* NOTE: we move nextbytep even if we're calling someone else's routine
* so we can maintain the proper alignment in nextop()
*/
PRIVATE Byte eatByte()
{
Byte retval;
if (procp)
CToPascalCall(procp, CTOP_StdGetPic, &retval, sizeof(Byte));
else
retval = *nextbytep;
++nextbytep;
return retval;
}
PRIVATE INTEGER eatINTEGERX()
{
INTEGER retval;
if (procp)
CToPascalCall(procp, CTOP_StdGetPic, &retval, sizeof(INTEGER));
else
retval = *(INTEGER *)nextbytep;
nextbytep += sizeof(INTEGER);
return retval;
}
PRIVATE INTEGER eatINTEGER()
{
INTEGER retval;
retval = eatINTEGERX();
return CW(retval);
}
PRIVATE LONGINT eatLONGINTX()
{
LONGINT retval;
if (procp)
CToPascalCall(procp, CTOP_StdGetPic, &retval, sizeof(LONGINT));
else
retval = *(LONGINT *)nextbytep;
nextbytep += sizeof(LONGINT);
return retval;
}
PRIVATE LONGINT eatLONGINT()
{
LONGINT retval;
retval = eatLONGINTX();
return CL(retval);
}
PRIVATE void eatString(Str255 str)
{
str[0] = eatByte();
if (procp)
CToPascalCall(procp, CTOP_StdGetPic, str+1, str[0]);
else
BlockMove((Ptr) nextbytep, (Ptr) str+1, str[0]);
nextbytep += str[0];
}
PRIVATE void eatNBytes(LONGINT n)
{
char *bufp;
if (procp) {
TEMP_ALLOC_DECL (temp_alloc_space);
TEMP_ALLOC_ALLOCATE (bufp, temp_alloc_space, n);
CToPascalCall(procp, CTOP_StdGetPic, bufp, n);
TEMP_ALLOC_FREE (temp_alloc_space);
}
nextbytep += n;
}
A2(PRIVATE, void, eatRegion, RgnHandle, rh, Size, hs)
{
SignedByte state;
SetHandleSize((Handle) rh, hs);
if (procp) {
state = HGetState((Handle) rh);
HLock((Handle) rh);
CToPascalCall(procp, CTOP_StdGetPic, (Ptr) STARH(rh) + sizeof(INTEGER),
hs - sizeof(INTEGER));
HSetState((Handle) rh, state);
} else
BlockMove((Ptr) nextbytep, (Ptr) STARH(rh) + sizeof(INTEGER),
hs - sizeof(INTEGER));
HxX(rh, rgnSize) = CW(hs);
nextbytep += hs - sizeof(INTEGER);
}
A1(PRIVATE, void, eatRect, Rect *, rp)
{
rp->top = eatINTEGERX();
rp->left = eatINTEGERX();
rp->bottom = eatINTEGERX();
rp->right = eatINTEGERX();
}
A2(PRIVATE, void, eatPixMap, register PixMapPtr, pixp, INTEGER, rowb)
{
/* TODO: byte swapping stuff, testing */
/* x(pixp->baseAddr) = 0; will be set later */
pixp->rowBytes = rowb ? CW(rowb) : eatINTEGERX();
eatRect(&pixp->bounds);
pixp->pmVersion = eatINTEGERX();
pixp->packType = eatINTEGERX();
pixp->packSize = eatLONGINTX();
pixp->hRes = eatLONGINTX();
pixp->vRes = eatLONGINTX();
pixp->pixelType = eatINTEGERX();
pixp->pixelSize = eatINTEGERX();
pixp->cmpCount = eatINTEGERX();
pixp->cmpSize = eatINTEGERX();
pixp->planeBytes = eatLONGINTX();
(void) eatLONGINTX(); /* IMV-104 */
pixp->pmTable = RM((CTabHandle) NewHandle(sizeof(ColorTable)));
/* will be filled in later */
pixp->pmReserved = eatLONGINTX();
}
A2(PRIVATE, void, eatBitMap, BitMap *, bp, INTEGER, rowb)
{
bp->baseAddr = 0;
bp->rowBytes = rowb ? CW(rowb) : eatINTEGERX();
eatRect(&bp->bounds);
}
A2(PRIVATE, Size, eatpixdata, PixMapPtr, pixmap, BOOLEAN *, freep)
{
int rowb;
Size pic_data_size, final_data_size;
HIDDEN_Ptr temp_pp, dp;
Handle h;
Byte *inp;
Handle temph;
INTEGER length;
boolean_t insert_pad_byte_p;
int comp_bytes;
int height;
height = RECT_HEIGHT (&pixmap->bounds);
rowb = BITMAP_ROWBYTES (pixmap);
/* comp bytes is the number of bytes take up by each of r, g, b
per scanline */
comp_bytes = rowb / 4;
insert_pad_byte_p = (pixmap->pixelSize == CWC (32)
&& pixmap->cmpCount != CWC (4));
final_data_size = rowb * height;
if (pixmap->packType == CWC (2))
pic_data_size = 3 * comp_bytes * height;
else
pic_data_size = final_data_size;
if (rowb < 8 || pixmap->packType == CWC (2))
{
if (procp
|| pixmap->packType == CWC (2))
{
h = NewHandle (final_data_size);
/* The practice of trying again in SysZone comes from the
database "Panorama" which calls MaxMem, subtracts a
small number from that, then calls NewPtr with the
result (i.e. asking for all of memory minus a small
number of bytes), then later DrawPicture is called, and
our implementation runs out of memory. It's not clear
what happens on a Mac. This hack should be more
thoroughly investigated sometime. */
if (h == NULL)
{
ZONE_SAVE_EXCURSION
(SysZone,
{
h = NewHandle (final_data_size);
});
}
HLock (h);
if (procp)
CToPascalCall (procp, CTOP_StdGetPic, STARH (h), pic_data_size);
else if (pixmap->packType == CWC (2))
memcpy (STARH (h), nextbytep, pic_data_size);
pixmap->baseAddr = h->p;
*freep = TRUE;
}
else
{
pixmap->baseAddr = RM ((Ptr) nextbytep);
*freep = FALSE;
}
nextbytep += pic_data_size;
if (pic_data_size & 1)
++nextbytep;
}
else
{
uint8 *temp_scanline, *scanline, *ep;
h = NewHandle (final_data_size);
if (h == NULL)
{
ZONE_SAVE_EXCURSION
(SysZone,
{
h = NewHandle (final_data_size);
});
}
HLock(h);
pixmap->baseAddr = (*h).p; /* can't use STARH 'cause we don't */
/* want to byte swap the result */
temp_scanline = alloca (rowb);
for (scanline = (uint8 *) BITMAP_BASEADDR (pixmap),
ep = scanline + final_data_size;
scanline < ep;
scanline += rowb)
{
int i;
length = rowb > 250 ? eatINTEGER () : eatByte ();
if (procp)
{
temph = NewHandle (length);
HLock (temph);
CToPascalCall (procp, CTOP_StdGetPic, STARH (temph), length);
inp = (Byte *) STARH (temph);
}
else
{
inp = nextbytep;
temph = NULL;
}
dp.p = (Ptr) RM (temp_scanline);
temp_pp.p = (Ptr) RM (inp);
if (pixmap->pixelSize == CWC (16)
&& pixmap->packType == CWC (3))
unpack_int16_bits (&temp_pp, &dp, rowb);
else
UnpackBits (&temp_pp, &dp,
insert_pad_byte_p ? comp_bytes * 3 : rowb);
inp = MR ((unsigned char *) temp_pp.p);
if (pixmap->pixelSize == CWC (32))
{
for (i = 0; i < comp_bytes; i ++)
{
/* ### are the packed unused bytes first or last in
the packed scanline? */
if (insert_pad_byte_p)
scanline[i * 4] = 0;
else
scanline[i * 4] = temp_scanline[i + 3 * comp_bytes];
scanline[i * 4 + 1] = temp_scanline[i ];
scanline[i * 4 + 2] = temp_scanline[i + comp_bytes ];
scanline[i * 4 + 3] = temp_scanline[i + 2 * comp_bytes];
}
}
else
memcpy (scanline, temp_scanline, rowb);
if (!procp)
nextbytep = inp;
else
{
nextbytep += length;
DisposHandle (temph);
}
}
*freep = TRUE;
}
if (pixmap->packType == CWC (2))
{
uint8 *start, *src, *dst;
start = (uint8 *) BITMAP_BASEADDR (pixmap);
src = start + height * comp_bytes * 3;
dst = start + height * rowb;
while (src > start)
{
*--dst = *--src;
*--dst = *--src;
*--dst = *--src;
*--dst = 0;
}
}
pixmap->packType = CWC (0);
return final_data_size;
}
A2(PRIVATE, void, eatbitdata, register BitMap *, bp, BOOLEAN, packed)
{
INTEGER rowb;
Size datasize;
Ptr ep;
HIDDEN_Ptr dp, temp_pp;
Handle h;
Byte *inp;
INTEGER length;
Handle temph;
rowb = CW(bp->rowBytes) & ROWMASK;
datasize = (LONGINT) rowb * (CW(bp->bounds.bottom) - CW(bp->bounds.top));
if (!packed) {
if (procp) {
h = NewHandle(datasize);
if (!h)
{
THz savezone;
savezone = TheZone;
TheZone = SysZone;
h = NewHandle(datasize);
TheZone = savezone;
}
HLock(h);
CToPascalCall(procp, CTOP_StdGetPic, STARH(h), datasize);
bp->baseAddr = (*h).p;
} else
bp->baseAddr = RM((Ptr) nextbytep);
nextbytep += datasize;
} else {
h = NewHandle(datasize);
if (!h)
{
THz savezone;
savezone = TheZone;
TheZone = SysZone;
h = NewHandle(datasize);
TheZone = savezone;
}
HLock(h);
bp->baseAddr = (*h).p; /* can't use STARH */
for (dp.p = MR(bp->baseAddr), ep = dp.p + datasize; dp.p < ep; ) {
length = rowb > 250 ? eatINTEGER() : eatByte();
if (procp) {
temph = NewHandle(length);
HLock(temph);
CToPascalCall(procp, CTOP_StdGetPic, STARH(temph), length);
inp = (Byte *) STARH(temph);
} else {
inp = nextbytep;
#if !defined(LETGCCWAIL)
temph = 0;
#endif
}
inp = RM(inp);
dp.p = RM(dp.p);
temp_pp.p = (Ptr) inp;
UnpackBits(&temp_pp, &dp, rowb);
inp = (unsigned char *) temp_pp.p;
dp.p = MR(dp.p);
inp = MR(inp);
if (!procp)
nextbytep = inp;
else {
nextbytep += length;
DisposHandle(temph);
}
}
}
}
A1(PRIVATE, void, eatRGBColor, RGBColor *, rgbp)
{
rgbp->red = eatINTEGERX();
rgbp->green = eatINTEGERX();
rgbp->blue = eatINTEGERX();
}
A1(PRIVATE, void, eatColorTable, register PixMapPtr, pixmap)
{
register CTabPtr cp;
register ColorSpec *cspecp, *cspecep;
register CTabHandle ch;
ch = MR(pixmap->pmTable);
cp = STARH(ch);
/* cp->ctSeed = */ eatLONGINTX();
cp->ctSeed = CL (GetCTSeed ());
cp->ctFlags = eatINTEGERX();
cp->ctSize = eatINTEGERX();
SetHandleSize((Handle) ch, (Size)sizeof(ColorTable) - sizeof(cp->ctTable) +
(Cx(cp->ctSize)+1) * 4 * sizeof(INTEGER));
for (cspecp = HxX(ch, ctTable), cspecep = cspecp + Hx(ch, ctSize) + 1;
cspecp != cspecep; cspecp++) {
cspecp->value = eatINTEGERX();
eatRGBColor(&cspecp->rgb);
}
}
A1(PRIVATE, void, eatPattern, Pattern, pat)
{
pat[0] = eatByte();
pat[1] = eatByte();
pat[2] = eatByte();
pat[3] = eatByte();
pat[4] = eatByte();
pat[5] = eatByte();
pat[6] = eatByte();
pat[7] = eatByte();
}
A1 (PRIVATE, void, eatPixPat, PixPatHandle, pixpat)
{
RGBColor rgb;
Size datasize;
Handle temph;
LOCK_HANDLE_EXCURSION_1
(pixpat,
{
PIXPAT_TYPE_X (pixpat) = eatINTEGERX ();
if (PIXPAT_TYPE_X (pixpat) == CWC (RGBPat))
{
eatPattern (PIXPAT_1DATA (pixpat));
eatRGBColor (&rgb);
{
PixMapHandle patmap;
patmap = (PixMapHandle) NewHandleClear (sizeof (PixMap));
PIXMAP_TABLE_X (patmap) = (CTabHandle) RM (NewHandle (0));
PIXPAT_MAP_X (pixpat) = RM (patmap);
}
MakeRGBPat (pixpat, &rgb);
}
else
{
PixMapHandle patmap;
BOOLEAN free;
eatPattern (PIXPAT_1DATA (pixpat));
patmap = (PixMapHandle) NewHandle (sizeof (PixMap));
PIXPAT_MAP_X (pixpat) = RM (patmap);
LOCK_HANDLE_EXCURSION_1
(patmap,
{
PixMapPtr patmap_ptr = STARH (patmap);
eatPixMap (patmap_ptr, 0);
eatColorTable (patmap_ptr);
datasize = eatpixdata (patmap_ptr, &free);
temph = NewHandle (0); /* do not use NewEmptyHandle, because
the call to PtrToXHand below will
fail, with a nilHandleErr as per
IM Memory 2-62 */
PIXPAT_DATA_X (pixpat) = RM (temph);
PtrToXHand (BITMAP_BASEADDR (patmap_ptr), temph, datasize);
if (free)
DisposHandle (RecoverHandle (BITMAP_BASEADDR (patmap_ptr)));
HASSIGN_3
(pixpat,
patXMap, RM (NULL),
patXData, RM (NewHandleClear (sizeof (xdata_t))),
patXValid, RM (-1));
});
}
});
}
#define opEndPic 0xff
A1 (PRIVATE, unsigned short, nextop, INTEGER, vers)
{
unsigned int retval;
if (vers == 1)
{
retval = eatByte() & 0xFF;
}
else
{
/* require even alignment */
if ((int32) nextbytep & 1)
eatByte();
retval = eatINTEGER();
}
return retval;
}
#define SE(x) ((x & 0x80) ? x|(~0^0xff) : x & 0xff) /* sign extend */
P2(PUBLIC pascal trap, void, DrawPicture, PicHandle, pic, Rect *, destrp)
{
INTEGER words[2], *wp;
Point points[2], *pp;
Byte bytes[2], *bp;
Rect rects[3], *rp;
Handle hand;
LONGINT lng;
ULONGINT ac;
unsigned short sc;
unsigned int opcode;
INTEGER ovh, ovw;
Pattern ourpattern;
Str255 ourstring;
INTEGER hsize;
void (*f)();
INTEGER vers;
auto Fixed scaleh, scalev, tempf; /* "auto": cc -a bug avoidance */
RGBColor rgb;
BitMap bm;
auto PixMap pm; /* "auto": cc -a bug avoidance */
BOOLEAN packed;
GrafPort saveport, *the_port;
CGrafPtr the_cport;
#if 0
INTEGER tempshort;
#endif
INTEGER state;
BitMap *bmp;
QDProcsPtr grafprocp;
LONGINT templ;
SignedByte state2;
/* this is not saved automagically if the port is a color
grafport, hence we need to save and restore it */
Rect saveportbounds;
int16 version_2, version_2ext;
Fixed hRes, vRes;
PixPatHandle junk_pen_pixpat, junk_bk_pixpat, junk_fill_pixpat;
BOOLEAN saveFractEnable, saveFScaleDisable;
Byte saveHiliteMode;
#if 0
fprintf (stderr, "DrawPicture (%d): %d\n", debugnumber,
GetHandleSize (pic));
#endif
#if 0
/*
* NOTE: At one time I believed that picSize 10 pictures should be
* silently ignored, but I'm not convinced that this is true;
* it could be that a different bug was creating/passing spurious
* pictures. I know for a fact (having tested it on a Mac) that
* picSize 0 pictures should be printed (Word5 creates 'em sometimes).
* --ctm
*/
if (Hx(pic, picSize) <= 10)
/*-->*/ return;
#endif
#if !defined (LETGCCWAIL)
lng = 0;
ovh = 0;
ovw = 0;
hsize = 0;
#endif /* LETGCCWAIL */
#if 0
if (!pic || (CW (destrp->top) == CW (destrp->bottom)
&& CW (destrp->left) == CW (destrp->right)))
return;
#else
if (!pic || !pic->p || EmptyRect(destrp) || EmptyRect(&HxX(pic, picFrame)))
return;
#endif
saveHiliteMode = HiliteMode;
saveHiliteRGB = HiliteRGB;
saveFractEnable = FractEnable;
saveFScaleDisable = FScaleDisable;
begin_assoc ();
the_port = thePort;
if (CGrafPort_p (the_port))
the_cport = theCPort;
else
the_cport = NULL;
saveport = *the_port;
saveportbounds = PORT_BOUNDS (the_port);
PORT_CLIP_REGION_X (the_port) = RM (NewRgn ());
SetRectRgn (PORT_CLIP_REGION (the_port), -32768, -32768, 32767, 32767);
PORT_VIS_REGION_X (the_port) = RM (NewRgn ());
CopyRgn (PORT_VIS_REGION (&saveport),
PORT_VIS_REGION (the_port));
saveclip = NewRgn ();
CopyRgn (PORT_CLIP_REGION (&saveport), saveclip);
if (CGrafPort_p (the_port))
{
junk_pen_pixpat = NewPixPat ();
junk_bk_pixpat = NewPixPat ();
junk_fill_pixpat = NewPixPat ();
CPORT_PEN_PIXPAT_X (the_cport) = RM (junk_pen_pixpat);
CPORT_BK_PIXPAT_X (the_cport) = RM (junk_bk_pixpat);
CPORT_FILL_PIXPAT_X (the_cport) = RM (junk_fill_pixpat);
}
else
{
junk_pen_pixpat = junk_bk_pixpat = junk_fill_pixpat = 0;
}
/* These will replace the junk pixpats we just installed. */
BackPat (white);
ROMlib_fill_pat (black);
PenPat (black);
/* Free these up now, since they are no longer used. */
if (CGrafPort_p (the_port))
{
DisposPixPat (junk_pen_pixpat);
DisposPixPat (junk_bk_pixpat);
DisposPixPat (junk_fill_pixpat);
}
PORT_PEN_LOC (the_port).h = destrp->left; /* This is a guess, based on */
PORT_PEN_LOC (the_port).v = destrp->top; /* Word's EPS handling */
PORT_PEN_SIZE (the_port).h = PORT_PEN_SIZE (the_port).v = CWC (1);
PORT_PEN_MODE_X (the_port) = CWC (patCopy);
PORT_TX_FONT_X (the_port) = CWC (0);
PORT_TX_FACE_X (the_port) = 0;
PORT_TX_SIZE_X (the_port) = CWC (0);
PORT_SP_EXTRA_X (the_port) = CWC (0);
#if 0
/* this will fail if we are actually drawing to a
color graph port; we'll get spew colors instead of
b/w, so let ForeColor or BackColor do the work */
the_port->fgColor = CL(blackColor);
the_port->bkColor = CL(whiteColor);
#else
ForeColor (blackColor);
BackColor (whiteColor);
#endif
PORT_COLR_BIT_X (the_port) = CWC (0);
PORT_PAT_STRETCH_X (the_port) = CWC (0);
/*
* NOTE: I used to start pics out with srcXor because of a PICT
* in LightspeedC, but it turns out the problem is that
* srcOr with outline doesn't do what one might think
*/
TextMode(srcOr);
vers = 1;
state = HGetState((Handle) pic);
HLock((Handle) pic);
grafprocp = MR (the_port->grafProcs);
if (grafprocp)
{
procp = MR(grafprocp->getPicProc);
if (procp == P_StdGetPic)
procp = 0;
}
else
procp = 0;
nextbytep = (unsigned char *) (&HxX(pic, picSize) + 5);
hand = 0;
dstpicframe = *destrp;
srcpicframe = HxX (pic, picFrame);
picnumh = RECT_WIDTH (&dstpicframe);
picnumv = RECT_HEIGHT (&dstpicframe);
picdenh = RECT_WIDTH (&srcpicframe);
picdenv = RECT_HEIGHT (&srcpicframe);
txnumh = txdenh = txnumv = txdenv = 1;
reduce(&picnumh, &picdenh);
reduce(&picnumv, &picdenv);
txtpoint.h = CW(CW(dstpicframe.left) - CW(srcpicframe.left));
txtpoint.v = CW(CW(dstpicframe.top) - CW(srcpicframe.top));
scaleh = FixRatio (RECT_WIDTH (&dstpicframe), RECT_WIDTH (&srcpicframe));
scalev = FixRatio (RECT_HEIGHT (&dstpicframe), RECT_HEIGHT (&srcpicframe));
while ((opcode = nextop(vers)) != opEndPic)
{
wp = words;
pp = points;
bp = bytes;
rp = rects;
if (opcode < NELEM(wparray))
{
for (ac = wparray[opcode].argcode, sc = scalevalues[ac >> 28],
ac &= ARGMASK; ac; ac >>= 4, sc >>= 2) {
switch (ac & 0xF)
{
case OVP:
break;
case BYT:
*bp++ = eatByte();
if (sc & SCALEIT) {
tempf = ((LONGINT) bp[-1] << 16) |
(bp[-1] & 0x80 ? 0xFF000000 : 0);
if (sc & VONLY)
bp[-1] = FixMul(scalev, tempf) >> 16;
else
bp[-1] = FixMul(scaleh, tempf) >> 16;
}
break;
case WRD:
*wp++ = eatINTEGER();
if (sc & SCALEIT) {
tempf = (LONGINT) wp[-1] << 16;
if (sc & VONLY)
wp[-1] = FixMul(scalev, tempf) >> 16;
else
wp[-1] = FixMul(scaleh, tempf) >> 16;
}
break;
case LNG:
lng = eatLONGINT();
break;
case PNT:
pp->v = eatINTEGERX();
pp->h = eatINTEGERX();
if (sc & SCALEIT)
MapPt(pp, &srcpicframe, destrp);
pp->h = CW(pp->h);
pp->v = CW(pp->v);
++pp;
break;
case RCT:
eatRect(rp++);
if (sc & SCALEIT)
MapRect(&rp[-1], &srcpicframe, destrp);
break;
case PAT:
eatPattern(ourpattern);
break;
case TXT:
eatString(ourstring);
break;
case RGN:
case DAT:
case PLY:
hsize = eatINTEGER();
if (!hand)
hand = NewHandle(hsize);
if ((ac&0xf) == DAT) {
SetHandleSize(hand, hsize);
if (procp) {
state2 = HGetState(hand);
HLock(hand);
CToPascalCall(procp, CTOP_StdGetPic, STARH(hand),
hsize);
HSetState(hand, state2);
} else
BlockMove((Ptr) nextbytep, STARH(hand), hsize);
nextbytep += hsize;
} else
eatRegion((RgnHandle) hand, hsize);
if (sc & SCALEIT)
{
if ((ac&0xF) == PLY)
MapPoly((PolyHandle) hand, &srcpicframe, destrp);
else
MapRgn((RgnHandle) hand, &srcpicframe, destrp);
}
break;
case SAM:
ac = 0; /* we've already read everything */
break;
case RGB:
eatRGBColor(&rgb);
break;
case PXP:
if (!hand)
hand = NewHandle(sizeof(PixPat));
else
ReallocHandle(hand, sizeof(PixPat));
memset (STARH (hand), 0, sizeof (PixPat));
eatPixPat((PixPatHandle) hand);
break;
case SPL:
/* Apparently calling DrawPicture while a pict is open
can create a new pict that is much larger than the
previous one, due to the way we handle direct bits.
It looks like by the time we actually log the CopyBits
associated with direct bits, we've already done some
transformations (unpacking, and perhaps changing to
32-bpp). We need to have code here that saves all
the args that we're reading here and then writes them
to the open pict with the only change being the dest
rect modifications that we may need to do. Then we'll
have to set a flag (or call an internal variant of
CopyBits) to prevent the CopyBits from logging again.
Of course this could be problematic if people patch
out CopyBits */
if ( opcode == OP_DirectBitsRect
|| opcode == OP_DirectBitsRgn)
/* suck off `0xFF' baseaddr */
eatLONGINT ();
words[0] = eatINTEGER(); /* rowb */
packed = ( opcode == OP_PackBitsRect
|| opcode == OP_PackBitsRgn);
if (words[0] & 0x8000)
{
eatPixMap (&pm, words[0]);
if ( opcode != OP_DirectBitsRect
&& opcode != OP_DirectBitsRgn)
eatColorTable (&pm);
}
else
eatBitMap (&bm, words[0]);
eatRect (&rects[0]); /* src rect */
eatRect (&rects[1]); /* dst rect */
MapRect (&rects[1], &srcpicframe, destrp);
words[1] = eatINTEGER (); /* mode */
if ( opcode == OP_BitsRgn
|| opcode == OP_PackBitsRgn
|| opcode == OP_DirectBitsRgn)
{
if (!hand)
hand = NewHandle (0); /* NewEmptyHandle may cause
trouble here, since
SizeHandle won't properly
adjust it */
hsize = eatINTEGER();
eatRegion ((RgnHandle) hand, hsize);
MapRgn ((RgnHandle) hand, &srcpicframe, destrp);
}
else
{
if (hand)
DisposHandle (hand);
hand = NULL;
}
if (words[0] & 0x8000)
{
eatpixdata (&pm, &packed);
bmp = (BitMap *) &pm;
}
else
{
eatbitdata (&bm, packed);
bmp = &bm;
}
CopyBits (bmp, PORT_BITS_FOR_COPY (the_port),
&rects[0], &rects[1],
words[1], (RgnHandle) hand);
if (packed)
DisposHandle (RecoverHandle (BITMAP_BASEADDR (bmp)));
if (words[0] & 0x8000)
DisposHandle ((Handle) MR (pm.pmTable));
else if (!packed && procp)
DisposHandle (RecoverHandle (BITMAP_BASEADDR (bmp)));
break;
default:
gui_fatal ("unknown arg code `%d'",
ac & 0xF);
}
}
}
else if (opcode == 0x02FF)
{
version_2 = eatINTEGER ();
}
else if (opcode == 0x0C00)
{
/* extended v2 opcode header */
/* version */
version_2ext = eatINTEGER ();
/* reserved */
eatINTEGER ();
/* hres, Fixed */
hRes = eatLONGINT ();
/* vres, Fixed */
vRes = eatLONGINT ();
#define CLIFFS_QUICK_199_P2_HACK /* makes risk work properly */
#if defined (CLIFFS_QUICK_199_P2_HACK)
{
Rect new_src_pic_frame;
eatRect (&new_src_pic_frame);
if (! EmptyRect (&new_src_pic_frame))
srcpicframe = new_src_pic_frame;
}
#else
eatRect (&srcpicframe);
if (EmptyRect (&srcpicframe))
goto cleanup;
#endif
/* reserved */
eatLONGINT ();
}
else
{
warning_unexpected ("hit opcode `0x%X' with no table entry",
opcode);
if (opcode < 0x00D0)
; /* do nothing; no extra data */
else if (opcode < 0x0100) {
templ = eatLONGINT();
eatNBytes(templ + sizeof(LONGINT));
} else if (opcode < 0x8000)
eatNBytes((opcode >> 8) * 2);
else if (opcode < 0x8100)
; /* do nothing; no extra data */
else {
templ = eatLONGINT();
eatNBytes(templ);
}
}
if (opcode == OP_OvSize) {
points[0].h = CW(points[0].h);
points[0].v = CW(points[0].v);
ScalePt(&points[0], &srcpicframe, &dstpicframe);
points[0].h = CW(points[0].h);
points[0].v = CW(points[0].v);
ovh = points[0].v;
ovw = points[0].h;
} else if (opcode == OP_Version) {
vers = bytes[0];
} else if (opcode < NELEM(wparray)) {
f = wparray[opcode].func;
switch (wparray[opcode].argcode & ARGMASK) {
case xxx0():
#if !defined (__STDC__)
(*f)();
#else /* __STDC__ */
(* (void (*)(void)) f)();
#endif /* __STDC__ */
break;
case xxx1(BYT):
#if !defined (__STDC__)
(*f)(SE(bytes[0]));
#else /* __STDC__ */
(* (void (*)(Byte)) f)(SE(bytes[0]));
#endif /* __STDC__ */
break;
case xxx1(LNG):
#if !defined (__STDC__)
(*f)(lng);
#else /* __STDC__ */
(* (void (*)(LONGINT)) f)(lng);
#endif /* __STDC__ */
break;
case xxx1(PAT):
#if !defined (__STDC__)
(*f)(ourpattern);
#else /* __STDC__ */
(* (void (*)(Pattern)) f)(ourpattern);
#endif /* __STDC__ */
break;
case xxx1(PNT):
#if !defined (__STDC__)
(*f)(points[0]);
#else /* __STDC__ */
(* (void (*)(Point)) f)(points[0]);
#endif /* __STDC__ */
break;
case xxx1(RCT):
case xxx2(SAM, RCT):
#if !defined (__STDC__)
(*f)(&rects[0]);
#else /* __STDC__ */
(* (void (*)(Rect *)) f)(&rects[0]);
#endif /* __STDC__ */
break;
case xxx1(RGB):
#if !defined (__STDC__)
(*f)(&rgb);
#else /* __STDC__ */
(* (void (*)(RGBColor *)) f)(&rgb);
#endif /* __STDC__ */
break;
case xxx1(DAT):
#if !defined (__STDC__)
(*f)(hsize, hand);
#else /* __STDC__ */
(* (void (*)(INTEGER, Handle)) f)(hsize, hand);
#endif /* __STDC__ */
break;
case xxx1(PXP):
#if !defined (__STDC__)
(*f)(hand);
#else /* __STDC__ */
(* (void (*)(Handle)) f)(hand);
#endif /* __STDC__ */
hand = NULL;
break;
case xxx1(RGN):
case xxx1(PLY):
case xxx2(SAM, RGN):
case xxx2(SAM, PLY):
#if !defined (__STDC__)
(*f)(hand);
#else /* __STDC__ */
(* (void (*)(Handle)) f)(hand);
#endif /* __STDC__ */
break;
case xxx1(WRD):
#if !defined (__STDC__)
(*f)(words[0]);
#else /* __STDC__ */
(* (void (*)(INTEGER)) f)(words[0]);
#endif /* __STDC__ */
break;
case xxx1(SPL):
/* was done when the args were picked up */
break;
case xxx2(BYT, BYT):
#if !defined (__STDC__)
(*f)(SE(bytes[0]), SE(bytes[1]));
#else /* __STDC__ */
(* (void (*)(Byte, Byte)) f)
(SE(bytes[0]), SE(bytes[1]));
#endif /* __STDC__ */
break;
case xxx2(BYT, TXT):
#if !defined (__STDC__)
(*f)(SE(bytes[0]), ourstring, &txtpoint);
#else /* __STDC__ */
(* (void (*)(Byte, StringPtr, Point *)) f)
(SE(bytes[0]), ourstring, &txtpoint);
#endif /* __STDC__ */
break;
case xxx2(PNT, PNT):
#if !defined (__STDC__)
(*f)(points[0], points[1]);
#else /* __STDC__ */
(* (void (*)(Point, Point)) f)(points[0], points[1]);
#endif /* __STDC__ */
break;
case xxx2(PNT, TXT):
#if !defined (__STDC__)
(*f)(points[0], ourstring, &txtpoint);
#else /* __STDC__ */
(* (void (*)(Point, StringPtr, Point *)) f)
(points[0], ourstring, &txtpoint);
#endif /* __STDC__ */
break;
case xxx2(RCT, OVP):
case xxx3(SAM, RCT, OVP):
#if !defined (__STDC__)
(*f)(&rects[0], ovw, ovh);
#else /* __STDC__ */
(* (void (*)(Rect *, INTEGER, INTEGER)) f)
(&rects[0], ovw, ovh);
#endif /* __STDC__ */
break;
case xxx2(WRD, WRD):
#if !defined (__STDC__)
(*f)(words[0], words[1]);
#else /* __STDC__ */
(* (void (*)(INTEGER, INTEGER)) f)(words[0], words[1]);
#endif /* __STDC__ */
break;
case xxx3(BYT, BYT, TXT):
#if !defined (__STDC__)
(*f)(SE(bytes[0]), SE(bytes[1]), ourstring, &txtpoint);
#else /* __STDC__ */
(* (void (*)(Byte, Byte, StringPtr, Point *)) f)
(SE(bytes[0]), SE(bytes[1]), ourstring, &txtpoint);
#endif /* __STDC__ */
break;
case xxx3(PNT, BYT, BYT):
#if !defined (__STDC__)
(*f)(points[0], SE(bytes[0]), SE(bytes[1]));
#else /* __STDC__ */
(* (void (*)(Point, Byte, Byte)) f)
(points[0], SE(bytes[0]), SE(bytes[1]));
#endif /* __STDC__ */
break;
case xxx3(RCT, WRD, WRD):
case xxx4(SAM, RCT, WRD, WRD):
case xxx6(WRD, WRD, SAM, RCT, WRD, WRD):
#if !defined (__STDC__)
(*f)(&rects[0], words[0], words[1]);
#else /* __STDC__ */
(* (void (*)(Rect *, INTEGER, INTEGER)) f)
(&rects[0], words[0], words[1]);
#endif /* __STDC__ */
break;
case xxx2(WRD, DAT):
#if !defined (__STDC__)
(*f)(words[0], hsize, hand);
#else /* __STDC__ */
(* (void (*)(INTEGER, INTEGER, Handle)) f)
(words[0], hsize, hand);
#endif /* __STDC__ */
break;
default:
gui_assert(0);
break;
}
}
}
HSetState((Handle) pic, state);
if (hand)
DisposHandle(hand);
if (CGrafPort_p (the_port))
{
DisposPixPat (CPORT_PEN_PIXPAT (the_cport));
DisposPixPat (CPORT_BK_PIXPAT (the_cport));
DisposPixPat (CPORT_FILL_PIXPAT (the_cport));
}
do_textend (); /* in case some clowns included a textbegin without
a textend */
DisposeRgn (PORT_CLIP_REGION (the_port));
DisposeRgn (PORT_VIS_REGION (the_port));
*the_port = saveport;
PORT_BOUNDS (the_port) = saveportbounds;
DisposeRgn (saveclip);
saveclip = NULL;
end_assoc ();
SetFractEnable (saveFractEnable);
SetFScaleDisable (saveFScaleDisable);
HiliteRGB = saveHiliteRGB;
HiliteMode = saveHiliteMode;
}