812 lines
20 KiB
C
812 lines
20 KiB
C
/* Copyright 1986 - 1996 by Abacus Research and
|
|
* Development, Inc. All rights reserved.
|
|
*/
|
|
|
|
#if !defined (OMIT_RCSID_STRINGS)
|
|
char ROMlib_rcsid_qStdRgn[] =
|
|
"$Id: qStdRgn.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 "QuickDraw.h"
|
|
#include "CQuickDraw.h"
|
|
#include "MemoryMgr.h"
|
|
#include "ToolboxUtil.h"
|
|
|
|
#include "rsys/quick.h"
|
|
#include "rsys/cquick.h"
|
|
#include "rsys/picture.h"
|
|
#include "rsys/prefs.h"
|
|
#include "rsys/notmac.h"
|
|
#include "rsys/mman.h"
|
|
#include "rsys/flags.h"
|
|
#include "rsys/host.h"
|
|
#include "rsys/vdriver.h"
|
|
#include "rsys/tempalloc.h"
|
|
|
|
#include "rsys/xdblt.h"
|
|
#include "rsys/srcblt.h"
|
|
#include "rsys/dirtyrect.h"
|
|
|
|
PUBLIC WriteWhenType ROMlib_when = WriteInBltrgn;
|
|
|
|
|
|
void
|
|
ROMlib_WriteWhen (WriteWhenType when)
|
|
{
|
|
ROMlib_when = when;
|
|
}
|
|
|
|
|
|
void
|
|
ROMlib_blt_rgn_update_dirty_rect
|
|
(RgnHandle rh,
|
|
int16 mode, boolean_t tile_src_p, int bpp,
|
|
const PixMap *src_pm, PixMap *dst_pm,
|
|
const Rect *src_rect, const Rect *dst_rect,
|
|
uint32 fg_color, uint32 bk_color)
|
|
{
|
|
boolean_t screen_dst_p, update_dirty_p;
|
|
Rect bbox;
|
|
TEMP_ALLOC_DECL (temp_alloc_space);
|
|
|
|
if (mode == mask)
|
|
mode = patCopy;
|
|
else if (mode >= hilite
|
|
|| ((mode == patXor
|
|
|| mode == srcXor)
|
|
&& !(HiliteMode & 128)))
|
|
mode = hilite;
|
|
|
|
if (mode == grayishTextOr)
|
|
{
|
|
if (bpp == 1)
|
|
{
|
|
PixMap *new_src_pm = alloca (sizeof *new_src_pm);
|
|
int baseaddr_size, height, row_bytes;
|
|
uint8 *new_bits, *s, *d;
|
|
int y;
|
|
|
|
/* Make a copy of the source bitmap, so we can dither it. */
|
|
*new_src_pm = *src_pm;
|
|
height = RECT_HEIGHT (&new_src_pm->bounds);
|
|
row_bytes = BITMAP_ROWBYTES (new_src_pm);
|
|
baseaddr_size = row_bytes * height;
|
|
TEMP_ALLOC_ALLOCATE (new_bits, temp_alloc_space, baseaddr_size);
|
|
new_src_pm->baseAddr = (Ptr) RM (new_bits);
|
|
|
|
s = (uint8 *) MR (src_pm->baseAddr);
|
|
d = new_bits;
|
|
for (y = 0; y < height; y++)
|
|
{
|
|
int x, mask;
|
|
mask = (y & 1) ? 0xAA : 0x55;
|
|
for (x = row_bytes - 1; x >= 0; x--)
|
|
d[x] = s[x] & mask;
|
|
s += row_bytes;
|
|
d += row_bytes;
|
|
}
|
|
|
|
src_pm = new_src_pm;
|
|
}
|
|
else
|
|
{
|
|
RGBColor fg_rgb, bk_rgb;
|
|
const rgb_spec_t *dst_rgb_spec;
|
|
|
|
dst_rgb_spec = pixmap_rgb_spec (dst_pm);
|
|
ROMlib_fg_bk (NULL, NULL, &fg_rgb, &bk_rgb, dst_rgb_spec,
|
|
active_screen_addr_p (dst_pm), bpp <= 8);
|
|
|
|
AVERAGE_COLOR (&fg_rgb, &bk_rgb, 0x8000, &fg_rgb);
|
|
|
|
if (dst_rgb_spec)
|
|
fg_color = ((*dst_rgb_spec->rgbcolor_to_pixel)
|
|
(dst_rgb_spec, &fg_rgb, TRUE));
|
|
else
|
|
fg_color = Color2Index (&fg_rgb);
|
|
}
|
|
|
|
mode = srcOr;
|
|
}
|
|
else if ((IMV_XFER_MODE_P (mode)
|
|
|| mode == hilite)
|
|
&& bpp > 1)
|
|
{
|
|
PixMap *new_src_pm;
|
|
int row_bytes;
|
|
void *new_bits;
|
|
|
|
Rect convert_src_rect;
|
|
int top, left;
|
|
int bbox_width, bbox_height;
|
|
|
|
new_src_pm = (PixMap *) alloca (sizeof *new_src_pm);
|
|
|
|
bbox = RGN_BBOX (rh);
|
|
bbox_width = RECT_WIDTH (&bbox);
|
|
bbox_height = RECT_HEIGHT (&bbox);
|
|
|
|
row_bytes = ((bbox_width * bpp + 31) / 32) * 4;
|
|
new_src_pm->rowBytes = CW (row_bytes);
|
|
TEMP_ALLOC_ALLOCATE (new_bits, temp_alloc_space,
|
|
row_bytes * bbox_height);
|
|
new_src_pm->baseAddr = (Ptr) RM (new_bits);
|
|
|
|
pixmap_set_pixel_fields (new_src_pm, bpp);
|
|
|
|
new_src_pm->pmTable = RM (ROMlib_dont_depthconv_ctab);
|
|
|
|
top = (CW (src_rect->top)
|
|
+ (CW (bbox.top) - CW (dst_rect->top)));
|
|
left = (CW (src_rect->left)
|
|
+ (CW (bbox.left) - CW (dst_rect->left)));
|
|
|
|
convert_src_rect.top = CW (top);
|
|
convert_src_rect.left = CW (left);
|
|
convert_src_rect.bottom = CW (top + bbox_height);
|
|
convert_src_rect.right = CW (left + bbox_width);
|
|
|
|
if (mode == transparent
|
|
|| mode == hilite)
|
|
{
|
|
convert_transparent (src_pm, dst_pm, new_src_pm,
|
|
&convert_src_rect, &bbox,
|
|
mode,
|
|
tile_src_p,
|
|
/* #warning "have mat figure out what the tiling offsets should be" */
|
|
0, 0);
|
|
}
|
|
else
|
|
{
|
|
CTabHandle ctab;
|
|
ITabHandle itab;
|
|
|
|
ctab = PIXMAP_TABLE (GD_PMAP (MR (TheGDevice)));
|
|
itab = GD_ITABLE (MR (TheGDevice));
|
|
|
|
convert_pixmap_with_IMV_mode (src_pm, dst_pm, new_src_pm,
|
|
ctab, ctab, itab,
|
|
&convert_src_rect, &bbox,
|
|
mode,
|
|
&CPORT_OP_COLOR (theCPort),
|
|
tile_src_p,
|
|
/* #warning "have mat figure out what the tiling offsets should be" */
|
|
0, 0);
|
|
}
|
|
|
|
src_pm = new_src_pm;
|
|
dst_rect = src_rect = &bbox;
|
|
mode = srcCopy;
|
|
pixmap_black_white (src_pm, &fg_color, &bk_color);
|
|
tile_src_p = FALSE;
|
|
}
|
|
|
|
/* #warning "don't ignore dither mode at some point in the future" */
|
|
|
|
mode &= 0x3F;
|
|
if (mode >= 0x20 && mode <= 0x2F)
|
|
{
|
|
static const INTEGER funny_mode_lookup[16] =
|
|
{
|
|
srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr,
|
|
patCopy, patBic, patXor, patOr, patOr, patBic, patXor, patOr,
|
|
};
|
|
mode = funny_mode_lookup[mode - 0x20];
|
|
}
|
|
else if (mode == hilite)
|
|
mode = patXor;
|
|
|
|
if (tile_src_p)
|
|
mode |= 0x8;
|
|
else
|
|
mode &= 0x37;
|
|
|
|
screen_dst_p = active_screen_addr_p (dst_pm);
|
|
|
|
update_dirty_p = srcblt_rgn (rh, mode, ROMlib_log2[bpp],
|
|
(blt_bitmap_t *) src_pm,
|
|
(blt_bitmap_t *) dst_pm,
|
|
(Point *) src_rect, (Point *) dst_rect,
|
|
fg_color, bk_color);
|
|
|
|
/* if drawing to the screen, update the dirty rect (or copy the
|
|
image straight to screen) */
|
|
if (screen_dst_p && update_dirty_p)
|
|
{
|
|
const Rect *r = &RGN_BBOX (rh);
|
|
int dst_top = CW (dst_pm->bounds.top);
|
|
int dst_left = CW (dst_pm->bounds.left);
|
|
|
|
dirty_rect_accrue (CW (r->top) - dst_top, CW (r->left) - dst_left,
|
|
CW (r->bottom) - dst_top, CW (r->right) - dst_left);
|
|
if (ROMlib_when == WriteInBltrgn)
|
|
{
|
|
dirty_rect_update_screen ();
|
|
vdriver_flush_display();
|
|
}
|
|
}
|
|
|
|
TEMP_ALLOC_FREE (temp_alloc_space);
|
|
}
|
|
|
|
|
|
const int ROMlib_log2[] =
|
|
{
|
|
-1,
|
|
0,
|
|
1,
|
|
-1, 2,
|
|
-1, -1, -1, 3,
|
|
-1, -1, -1, -1, -1, -1, -1, 4,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5,
|
|
};
|
|
|
|
|
|
const uint32 ROMlib_pixel_tile_scale[6] =
|
|
{
|
|
0xFFFFFFFF,
|
|
0x55555555,
|
|
0x11111111,
|
|
0x01010101,
|
|
0x00010001,
|
|
0x00000001,
|
|
};
|
|
|
|
const uint32 ROMlib_pixel_size_mask[6] =
|
|
{
|
|
0x00000001,
|
|
0x00000003,
|
|
0x0000000F,
|
|
0x000000FF,
|
|
0x0000FFFF,
|
|
0xFFFFFFFF,
|
|
};
|
|
|
|
#define BLT_PAT_SIMPLE(rh, mode, pixpat_accessor, pattern_accessor) \
|
|
do { \
|
|
GrafPtr the_port = thePort; \
|
|
if (CGrafPort_p (the_port)) \
|
|
blt_pixpat_to_pixmap_simple_mode (rh, mode, \
|
|
pixpat_accessor ((CGrafPtr) the_port), \
|
|
CPORT_PIXMAP ((CGrafPtr) the_port)); \
|
|
else \
|
|
blt_pattern_to_bitmap_simple_mode (rh, mode, pattern_accessor (the_port), \
|
|
&the_port->portBits); \
|
|
} while (0)
|
|
|
|
|
|
#define BLT_PAT_FANCY(rh, mode, pixpat_accessor, pattern_accessor) \
|
|
do { \
|
|
GrafPtr the_port = thePort; \
|
|
if (CGrafPort_p (the_port)) \
|
|
{ \
|
|
PixMapHandle cport_pmap = CPORT_PIXMAP ((CGrafPtr) the_port); \
|
|
LOCK_HANDLE_EXCURSION_1 \
|
|
(cport_pmap, \
|
|
{ \
|
|
blt_fancy_pat_mode_to_pixmap (rh, mode, \
|
|
pixpat_accessor ((CGrafPtr) \
|
|
the_port), \
|
|
NULL, STARH (cport_pmap)); \
|
|
}); \
|
|
} \
|
|
else if (active_screen_addr_p (&the_port->portBits)) \
|
|
{ \
|
|
PixMap copy_of_screen; \
|
|
copy_of_screen = *(STARH (GD_PMAP (MR (TheGDevice)))); \
|
|
copy_of_screen.bounds = the_port->portBits.bounds; \
|
|
blt_fancy_pat_mode_to_pixmap (rh, mode, NULL, \
|
|
pattern_accessor (the_port), \
|
|
©_of_screen); \
|
|
} \
|
|
else \
|
|
{ \
|
|
/* We shouldn't get here; we don't allow fancy blits to old-style \
|
|
* grafports not on the screen. \
|
|
*/ \
|
|
gui_abort (); \
|
|
} \
|
|
} while (0)
|
|
|
|
|
|
static void
|
|
blt_pattern_to_bitmap_simple_mode (RgnHandle rh, INTEGER mode,
|
|
Pattern src, BitMap *dst)
|
|
{
|
|
PixMapHandle main_gd_pmap;
|
|
GDHandle main_gd;
|
|
uint32 bk_pixel, fg_pixel;
|
|
int bpp, dst_top, dst_left;
|
|
boolean_t screen_dst_p;
|
|
PixMap dst_pixmap;
|
|
GrafPtr the_port;
|
|
boolean_t update_dirty_p;
|
|
|
|
main_gd = MR (MainDevice);
|
|
main_gd_pmap = GD_PMAP (main_gd);
|
|
screen_dst_p = active_screen_addr_p (dst);
|
|
bpp = PIXMAP_PIXEL_SIZE (main_gd_pmap);
|
|
|
|
the_port = thePort;
|
|
|
|
/* ### is this if necessary? */
|
|
if (screen_dst_p)
|
|
{
|
|
dst_pixmap = *STARH (main_gd_pmap);
|
|
ROMlib_fg_bk (&fg_pixel, &bk_pixel, NULL, NULL,
|
|
pixmap_rgb_spec (STARH (main_gd_pmap)),
|
|
TRUE, FALSE);
|
|
}
|
|
else
|
|
{
|
|
dst_pixmap.pixelSize = CWC (1);
|
|
dst_pixmap.baseAddr = dst->baseAddr;
|
|
dst_pixmap.rowBytes = dst->rowBytes | PIXMAP_DEFAULT_ROWBYTES_X;
|
|
dst_pixmap.pmTable = RM (ROMlib_bw_ctab);
|
|
|
|
ROMlib_fg_bk (&fg_pixel, &bk_pixel, NULL, NULL, NULL, FALSE, FALSE);
|
|
}
|
|
|
|
dst_pixmap.bounds = dst->bounds;
|
|
dst_top = CW (dst_pixmap.bounds.top);
|
|
dst_left = CW (dst_pixmap.bounds.left);
|
|
|
|
/* Actually do the blt. */
|
|
update_dirty_p = xdblt_pattern (rh, mode, -dst_left, -dst_top, src,
|
|
&dst_pixmap, fg_pixel, bk_pixel);
|
|
|
|
/* Update the real screen as appropriate. */
|
|
if (screen_dst_p && update_dirty_p)
|
|
{
|
|
const Rect *r = &RGN_BBOX (rh);
|
|
dirty_rect_accrue (CW (r->top) - dst_top, CW (r->left) - dst_left,
|
|
CW (r->bottom) - dst_top, CW (r->right) - dst_left);
|
|
if (ROMlib_when == WriteInBltrgn)
|
|
{
|
|
dirty_rect_update_screen ();
|
|
vdriver_flush_display();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
blt_pixpat_to_pixmap_simple_mode (RgnHandle rh, INTEGER mode,
|
|
PixPatHandle srch, PixMapHandle dsth)
|
|
{
|
|
boolean_t screen_dst_p;
|
|
int dst_top, dst_left;
|
|
boolean_t update_dirty_p;
|
|
|
|
LOCK_HANDLE_EXCURSION_2
|
|
(srch, dsth,
|
|
{
|
|
PixPat *src = STARH (srch);
|
|
PixMap *dst = STARH (dsth);
|
|
GrafPtr the_port = thePort;
|
|
|
|
screen_dst_p = active_screen_addr_p (dst);
|
|
|
|
dst_top = CW (dst->bounds.top);
|
|
dst_left = CW (dst->bounds.left);
|
|
|
|
if (src->patType == CWC (pixpat_old_style_pattern))
|
|
{
|
|
const rgb_spec_t *dst_rgb_spec;
|
|
uint32 fg_color;
|
|
uint32 bk_color;
|
|
|
|
dst_rgb_spec = pixmap_rgb_spec (dst);
|
|
canonical_from_bogo_color (PORT_FG_COLOR (the_port), dst_rgb_spec,
|
|
&fg_color, NULL);
|
|
canonical_from_bogo_color (PORT_BK_COLOR (the_port), dst_rgb_spec,
|
|
&bk_color, NULL);
|
|
|
|
update_dirty_p = xdblt_pattern (rh, mode, -dst_left, -dst_top,
|
|
src->pat1Data, dst, fg_color,
|
|
bk_color);
|
|
}
|
|
else
|
|
{
|
|
boolean_t xdata_valid_p;
|
|
boolean_t handle_size_wrong_p;
|
|
xdata_handle_t xh;
|
|
|
|
xh = (xdata_handle_t) MR (src->patXData);
|
|
if (!xh)
|
|
{
|
|
warning_unexpected ("xdata handle NULL_STRING");
|
|
xh = (xdata_handle_t) NewHandle (sizeof (xdata_t));
|
|
HxX (xh, raw_pat_bits_mem) = RM (NULL);
|
|
src->patXData = (Handle) RM (xh);
|
|
xdata_valid_p = FALSE;
|
|
handle_size_wrong_p = FALSE;
|
|
}
|
|
else
|
|
{
|
|
handle_size_wrong_p = (GetHandleSize ((Handle) xh)
|
|
!= sizeof (xdata_t));
|
|
xdata_valid_p = (!handle_size_wrong_p
|
|
&& (HxX (xh, magic_cookie)
|
|
== XDATA_MAGIC_COOKIE));
|
|
}
|
|
|
|
if (src->patXValid == CWC (-1)
|
|
|| !xdata_valid_p)
|
|
{
|
|
if (xdata_valid_p)
|
|
{
|
|
Ptr raw = HxX (xh, raw_pat_bits_mem);
|
|
if (raw)
|
|
{
|
|
DisposPtr (raw);
|
|
HxX (xh, raw_pat_bits_mem) = NULL;
|
|
}
|
|
}
|
|
else if (handle_size_wrong_p)
|
|
{
|
|
SetHandleSize ((Handle) xh, sizeof (xdata_t));
|
|
warning_unexpected ("invalid xdata size; appl juked xdata maybe");
|
|
}
|
|
|
|
xdata_for_pixpat_with_space (src, dst, xh);
|
|
|
|
src->patXValid = CWC (0);
|
|
}
|
|
else
|
|
{
|
|
update_xdata_if_needed (xh, src, dst);
|
|
}
|
|
|
|
LOCK_HANDLE_EXCURSION_1
|
|
(xh,
|
|
{
|
|
xdata_t *x = STARH (xh);
|
|
update_dirty_p = (*x->blt_func) (rh, mode, -dst_left,
|
|
-dst_top, x, dst);
|
|
});
|
|
}
|
|
});
|
|
|
|
/* Update the real screen as appropriate. */
|
|
if (screen_dst_p && update_dirty_p)
|
|
{
|
|
const Rect *r = &RGN_BBOX (rh);
|
|
dirty_rect_accrue (CW (r->top) - dst_top, CW (r->left) - dst_left,
|
|
CW (r->bottom) - dst_top, CW (r->right) - dst_left);
|
|
if (ROMlib_when == WriteInBltrgn)
|
|
{
|
|
dirty_rect_update_screen ();
|
|
vdriver_flush_display();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
blt_fancy_pat_mode_to_pixmap (RgnHandle rh, int mode,
|
|
PixPatHandle pixpat_handle,
|
|
Pattern pattern, /* valid iff !pixpat_handle */
|
|
PixMap *pixmap)
|
|
{
|
|
PixMap converted_pm;
|
|
PixMap pattern_pm;
|
|
Rect bbox;
|
|
int row_bytes;
|
|
void *new_bits;
|
|
xdata_handle_t xh;
|
|
xdata_t *x;
|
|
boolean_t apply_fg_bk_p;
|
|
int bpp, log2_bpp;
|
|
TEMP_ALLOC_DECL (temp_alloc_space);
|
|
|
|
/* Set up xdata for the thing being blitted. */
|
|
bpp = CW (pixmap->pixelSize);
|
|
log2_bpp = ROMlib_log2[bpp];
|
|
|
|
if (!pixpat_handle)
|
|
{
|
|
xh = xdata_for_pattern (pattern, pixmap);
|
|
apply_fg_bk_p = TRUE;
|
|
}
|
|
else
|
|
{
|
|
#if 0
|
|
LOCK_HANDLE_EXCURSION_1
|
|
(pixpat_handle,
|
|
#endif
|
|
{
|
|
PixPat *pixpat = STARH (pixpat_handle);
|
|
if (pixpat->patType == CWC (pixpat_type_orig))
|
|
{
|
|
xh = xdata_for_pattern (pixpat->pat1Data, pixmap);
|
|
apply_fg_bk_p = TRUE;
|
|
}
|
|
else /* newer-style pixpat */
|
|
{
|
|
xh = xdata_for_pixpat (pixpat, pixmap);
|
|
apply_fg_bk_p = FALSE;
|
|
}
|
|
#if 0
|
|
});
|
|
#else
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* Set up the pattern bitmap. */
|
|
HLock ((Handle) xh);
|
|
x = STARH (xh);
|
|
pattern_pm.bounds.top = CWC (0);
|
|
pattern_pm.bounds.left = CWC (0);
|
|
pattern_pm.bounds.bottom = CW (x->height_minus_1 + 1);
|
|
pattern_pm.bounds.right = CW ((x->row_bytes << (5 - x->log2_bpp)) >> 2);
|
|
pattern_pm.rowBytes = CW (x->row_bytes);
|
|
if (x->pat_bits)
|
|
pattern_pm.baseAddr = (Ptr) RM (x->pat_bits);
|
|
else
|
|
pattern_pm.baseAddr = (Ptr) RM (&x->pat_value);
|
|
|
|
pixmap_set_pixel_fields (&pattern_pm, 1 << x->log2_bpp);
|
|
pattern_pm.pmTable = RM (ROMlib_dont_depthconv_ctab);
|
|
|
|
/* When dealing with an old-style pattern, we need to apply fg/bk colors. */
|
|
if (apply_fg_bk_p)
|
|
{
|
|
uint32 *p, *end, fg_pixel, bk_pixel, tiled_fg_pixel, tiled_bk_pixel;
|
|
|
|
ROMlib_fg_bk (&fg_pixel, &bk_pixel, NULL, NULL,
|
|
pixmap_rgb_spec (pixmap),
|
|
active_screen_addr_p (pixmap), FALSE);
|
|
|
|
/* Tile the pixel values out to 32 bpp. */
|
|
tiled_fg_pixel = ((fg_pixel & ROMlib_pixel_size_mask[log2_bpp])
|
|
* ROMlib_pixel_tile_scale[log2_bpp]);
|
|
tiled_bk_pixel = ((bk_pixel & ROMlib_pixel_size_mask[log2_bpp])
|
|
* ROMlib_pixel_tile_scale[log2_bpp]);
|
|
|
|
/* Note that we don't care if we clobber the bits of this temp xdata. */
|
|
p = (uint32 *) MR (pattern_pm.baseAddr);
|
|
end = (uint32 *) ((char *) p + x->byte_size);
|
|
for (; p != end; p++)
|
|
{
|
|
uint32 v = *p;
|
|
/* #warning "not sure how this interacts w/RGB" */
|
|
*p = (v & tiled_fg_pixel) | ((~v) & tiled_bk_pixel);
|
|
}
|
|
}
|
|
|
|
/* Set up the converted bitmap. */
|
|
bbox = RGN_BBOX (rh);
|
|
converted_pm.bounds = bbox;
|
|
row_bytes = (((RECT_WIDTH (&bbox) << log2_bpp) + 31U) / 32) * 4;
|
|
converted_pm.rowBytes = CW (row_bytes);
|
|
TEMP_ALLOC_ALLOCATE (new_bits, temp_alloc_space,
|
|
row_bytes * RECT_HEIGHT (&bbox));
|
|
converted_pm.baseAddr = (Ptr) RM (new_bits);
|
|
|
|
pixmap_set_pixel_fields (&converted_pm, 1 << log2_bpp);
|
|
converted_pm.pmTable = RM (ROMlib_dont_depthconv_ctab);
|
|
|
|
if (mode == transparent || mode == hilite)
|
|
{
|
|
convert_transparent (&pattern_pm, pixmap, &converted_pm,
|
|
&bbox, &bbox,
|
|
mode,
|
|
TRUE,
|
|
/* #warning "have mat figure out what the tiling offsets should be" */
|
|
0, 0);
|
|
}
|
|
else
|
|
{
|
|
RGBColor op_color;
|
|
CTabHandle ctab;
|
|
ITabHandle itab;
|
|
|
|
ctab = PIXMAP_TABLE (GD_PMAP (MR (TheGDevice)));
|
|
itab = GD_ITABLE (MR (TheGDevice));
|
|
|
|
if (CGrafPort_p (thePort))
|
|
op_color = CPORT_OP_COLOR (theCPort);
|
|
else /* I have no idea what I'm supposed to do in this case */
|
|
op_color = ROMlib_black_rgb_color;
|
|
|
|
convert_pixmap_with_IMV_mode (&pattern_pm, pixmap, &converted_pm,
|
|
ctab, ctab, itab,
|
|
&bbox, &bbox,
|
|
mode, &op_color, TRUE,
|
|
/* #warning "have mat figure out what the tiling offsets should be" */
|
|
0, 0);
|
|
}
|
|
|
|
{
|
|
uint32 fg, bk;
|
|
|
|
pixmap_black_white (pixmap, &fg, &bk);
|
|
srcblt_rgn (rh, srcCopy, log2_bpp,
|
|
(blt_bitmap_t *) &converted_pm, (blt_bitmap_t *) pixmap,
|
|
(Point *) &bbox, (Point *) &bbox,
|
|
fg, bk);
|
|
}
|
|
|
|
if (active_screen_addr_p (pixmap))
|
|
{
|
|
const Rect *r = &RGN_BBOX (rh);
|
|
int dst_top = CW (pixmap->bounds.top);
|
|
int dst_left = CW (pixmap->bounds.left);
|
|
|
|
dirty_rect_accrue (CW (r->top) - dst_top, CW (r->left) - dst_left,
|
|
CW (r->bottom) - dst_top, CW (r->right) - dst_left);
|
|
if (ROMlib_when == WriteInBltrgn)
|
|
{
|
|
dirty_rect_update_screen ();
|
|
vdriver_flush_display();
|
|
}
|
|
}
|
|
|
|
HUnlock ((Handle) xh);
|
|
xdata_free (xh);
|
|
|
|
TEMP_ALLOC_FREE (temp_alloc_space);
|
|
}
|
|
|
|
|
|
/* Returns the actual bpp to be used for the destination. */
|
|
static inline int
|
|
theport_bpp (void)
|
|
{
|
|
GrafPtr the_port = thePort;
|
|
int bpp;
|
|
|
|
if (CGrafPort_p (the_port))
|
|
bpp = PIXMAP_PIXEL_SIZE (CPORT_PIXMAP ((CGrafPtr) the_port));
|
|
else if (active_screen_addr_p (&the_port->portBits))
|
|
bpp = PIXMAP_PIXEL_SIZE (GD_PMAP (MR (MainDevice)));
|
|
else
|
|
bpp = 1;
|
|
|
|
return bpp;
|
|
}
|
|
|
|
|
|
inline void
|
|
ROMlib_blt_pn (RgnHandle rh, INTEGER mode)
|
|
{
|
|
int bpp = theport_bpp ();
|
|
|
|
mode &= 0x3F;
|
|
if (mode < 8)
|
|
mode |= 8;
|
|
if (mode >= hilite || (mode == patXor && !(HiliteMode & 128)))
|
|
mode = hilite;
|
|
|
|
if (bpp == 1 || (!IMV_XFER_MODE_P (mode) && mode != hilite))
|
|
{
|
|
/* I have no idea where this table came from. It's just been
|
|
* passed down from the old black and white blitter.
|
|
*/
|
|
static const uint8 imvxfer_pat_mode_lookup[8] =
|
|
{ patCopy, patBic, patXor, patOr, patOr, patBic, patXor, patOr };
|
|
|
|
if (mode >= 0x20 && mode <= 0x2F)
|
|
mode = imvxfer_pat_mode_lookup[mode & 7];
|
|
else if (mode == hilite)
|
|
mode = patXor;
|
|
BLT_PAT_SIMPLE (rh, mode, CPORT_PEN_PIXPAT, PORT_PEN_PAT);
|
|
}
|
|
else
|
|
{
|
|
BLT_PAT_FANCY (rh, mode, CPORT_PEN_PIXPAT, PORT_PEN_PAT);
|
|
}
|
|
}
|
|
|
|
|
|
P2 (PUBLIC pascal trap, void, StdRgn,
|
|
GrafVerb, verb, RgnHandle, rgn)
|
|
{
|
|
RgnHandle rh;
|
|
Rect r;
|
|
|
|
if (!rgn || EmptyRgn (rgn))
|
|
return;
|
|
|
|
if (HxX (rgn, rgnSize) & CWC (0x8000))
|
|
{
|
|
warning_unexpected ("negative rgnSize = 0x%x\n", HxX (rgn, rgnSize));
|
|
return;
|
|
}
|
|
|
|
PIC_SAVE_EXCURSION
|
|
({
|
|
ROMlib_drawingverbpicupdate (verb);
|
|
PICOP (OP_frameRgn + (int) verb);
|
|
LOCK_HANDLE_EXCURSION_1
|
|
(rgn,
|
|
{
|
|
RgnPtr rp = STARH (rgn);
|
|
PICWRITE (rp, CW (rp->rgnSize));
|
|
});
|
|
});
|
|
|
|
/* intersect the region to be drawn with the
|
|
port bounds and port rect */
|
|
rh = NewRgn ();
|
|
r = PORT_BOUNDS (thePort);
|
|
|
|
RectRgn (rh, &r);
|
|
SectRgn (rgn, rh, rh);
|
|
|
|
if (verb == frame)
|
|
{
|
|
RgnHandle rsave;
|
|
Point pen_size;
|
|
|
|
/* remove the current region from rgnSave */
|
|
/* #warning "How does XOR remove it? e.g. two framerects in a row." */
|
|
pen_size = PORT_PEN_SIZE (thePort);
|
|
rsave = (RgnHandle) PORT_REGION_SAVE (thePort);
|
|
if (rsave)
|
|
XorRgn (rgn, rsave, rsave);
|
|
|
|
/* construct the frame */
|
|
/* #warning "We inset the region AFTER we've clipped it to the port bounds???" */
|
|
InsetRgn (rh, CW (pen_size.h), CW (pen_size.v));
|
|
XorRgn (rgn, rh, rh);
|
|
|
|
/* now `paint' the frame */
|
|
verb = paint;
|
|
}
|
|
|
|
/* can this check be moved up? */
|
|
/* if verb == frame, we juke region_save above, so this check
|
|
* probably can't be moved up. on the other hand, are we supposed
|
|
* to juke region_save if the pen isn't visible? -Mat */
|
|
if (PORT_PEN_VIS (thePort) < 0)
|
|
{
|
|
DisposeRgn (rh);
|
|
return;
|
|
}
|
|
|
|
SectRgn (rh, PORT_VIS_REGION (thePort), rh);
|
|
SectRgn (rh, PORT_CLIP_REGION (thePort), rh);
|
|
|
|
if (GWorld_p (thePort))
|
|
LockPixels (CPORT_PIXMAP (thePort));
|
|
|
|
switch (verb)
|
|
{
|
|
case paint:
|
|
ROMlib_blt_pn (rh, PORT_PEN_MODE (thePort));
|
|
break;
|
|
case erase:
|
|
BLT_PAT_SIMPLE (rh, patCopy, CPORT_BK_PIXPAT, PORT_BK_PAT);
|
|
break;
|
|
case invert:
|
|
{
|
|
int bpp = theport_bpp ();
|
|
/* FIXME: is it ok to thrash the fill pattern here? */
|
|
ROMlib_fill_pat (black);
|
|
if (bpp == 1 || (HiliteMode & 128))
|
|
BLT_PAT_SIMPLE (rh, patXor, CPORT_FILL_PIXPAT, PORT_FILL_PAT);
|
|
else
|
|
BLT_PAT_FANCY (rh, hilite, CPORT_FILL_PIXPAT, PORT_FILL_PAT);
|
|
}
|
|
break;
|
|
case fill:
|
|
BLT_PAT_SIMPLE (rh, patCopy, CPORT_FILL_PIXPAT, PORT_FILL_PAT);
|
|
break;
|
|
default:
|
|
gui_fatal ("unknown GrafVerb");
|
|
break;
|
|
}
|
|
|
|
if (GWorld_p (thePort))
|
|
UnlockPixels (CPORT_PIXMAP (thePort));
|
|
|
|
SET_HILITE_BIT ();
|
|
DisposeRgn (rh);
|
|
}
|