home *** CD-ROM | disk | FTP | other *** search
- // drawing.cpp
-
- #include "drawing.h"
- // debug:
- #include "events.h"
-
-
- // prototypes
- void align (int& x, int& y, int width, int height, int xheight, h_align h, v_align v);
-
-
- //
- // draw_bitmap()
- //
- void draw_bitmap(int resID, int x, int y, h_align h, v_align v, ScrOperation copy_mode) {
- // variables
- int width, height;
- Err err;
-
- // get bitmap
- BitmapType** resH = (BitmapType**) DmGetResource (bitmapRsc, resID);
- BitmapType* bitmap = (BitmapType*) MemHandleLock ((void**) resH);
- // get dimensions
- width = int(bitmap->width);
- height = int(bitmap->height);
-
- align (x, y, width, height, height, h, v);
-
- // draw bitmap
- if (copy_mode == scrCopy) {
- WinDrawBitmap (bitmap, x, y);
- } else {
- draw_bits (bitmap, x, y, copy_mode);
- }
-
- // release bitmap
- err = MemHandleUnlock ((void**) resH);
- }
-
- //
- // draw_bitmap_masked()
- //
- void
- draw_bitmap_masked(int bitmapID, int maskID, int x, int y, h_align h, v_align v) {
- draw_bitmap (maskID, x, y, h, v, scrANDNOT);
- draw_bitmap (bitmapID, x, y, h, v, scrOR);
- }
-
- //
- // copy_bits()
- //
- void
- draw_bits(BitmapPtr bm, int x, int y, ScrOperation copy_mode) {
- // variables
- int bm_width, bm_height;
- WinHandle window = NULL;
- GDevicePtr gd;
- unsigned long gd_baseAddr, src_baseAddr, dest_baseAddr;
- int gd_rowBytes, gd_width, gd_height;
- int src_rowBytes;
- WinHandle off = NULL;
- UInt16 err;
-
- // get dimensions
- bm_width = int(bm->width);
- bm_height = int(bm->height);
- // check required params
- if ((bm->version!=1) || (bm->pixelSize!=1))
- goto error;
-
- // get dest window
- window = WinGetDrawWindow();
- if (window==NULL)
- goto error;
- gd = window->gDeviceP;
- if (gd==NULL)
- goto error;
- // device must be version 0, uncompressed, and 1 bit/pixel (bitmap)
- if ((gd->version!=0) || (gd->compressed==1) || (gd->pixelSize!=1))
- goto error;
- // get dimensions
- gd_baseAddr = (unsigned long) gd->baseAddr;
- gd_rowBytes = gd->rowBytes;
- gd_width = gd->width;
- gd_height = gd->height;
-
-
- // and with masking operations at the edges?
-
- // align bitmap's bytes with dest bytes
- int bit_offset = x & 7;
- int byte_offset = x>>3;
- int byte_width = (bm_width + bit_offset +7) / 8;
- if (byte_width > gd_rowBytes - byte_offset)
- byte_width = gd_rowBytes - byte_offset;
- int line_offset = y;
- int line_height = bm_height;
- if (line_height > gd_height - line_offset)
- line_height = gd_height - line_offset;
- dest_baseAddr = gd_baseAddr + gd_rowBytes * line_offset + byte_offset;
-
- // how to deal with negative x and y?
- int skip_bytes = -byte_offset;
- if (skip_bytes<0)
- skip_bytes = 0;
- int skip_lines = -line_offset;
- if (skip_lines<0)
- skip_lines = 0;
-
- // debug:
- /*
- char s[32];
- StrIToA(s, skip_lines);
- draw_string(s, 0,15, left_align, top_align);
- */
-
- // special case for copy mode, so edges don't get clobbered
- if (copy_mode == scrCopy) {
- erase_rect(x, y, bm_width, bm_height);
- }
-
- // create offscreen window
- int off_width = byte_width*8;
- int off_height = line_height;
- off = WinCreateOffscreenWindow (off_width, off_height, screenFormat, &err);
- if (off==NULL)
- goto error;
- if (off->gDeviceP==NULL)
- goto error;
- // draw bitmap into offscreen window
- WinSetDrawWindow (off);
- if (copy_mode==scrAND) {
- paint_rect (0, 0, off_width, off_height);
- } else {
- erase_rect (0, 0, off_width, off_height);
- }
- WinDrawBitmap (bm, bit_offset, 0);
- // get info on offscreen window
- src_baseAddr = (unsigned long) off->gDeviceP->baseAddr;
- src_rowBytes = off->gDeviceP->rowBytes;
-
- // copy bitmap data to device
- int i_x, i_y;
- char *destP, *srcP;
- for (i_y=skip_lines; i_y<line_height; i_y++) {
- for (i_x=skip_bytes; i_x<byte_width; i_x++) {
- srcP = (char*) (src_baseAddr + src_rowBytes * i_y + i_x);
- destP = (char*) (dest_baseAddr + gd_rowBytes * i_y + i_x);
- switch (copy_mode) {
- case scrOR:
- case scrCopy:
- *destP |= *srcP;
- break;
- case scrAND:
- *destP &= *srcP;
- break;
- case scrANDNOT:
- *destP &= ~(*srcP);
- break;
- case scrXOR:
- *destP ^= *srcP;
- break;
- default:
- break;
- }
- }
- }
-
- error:
- // restore draw window
- if (window!=NULL)
- WinSetDrawWindow(window);
- // release offscreen window if allocated
- if (off!=NULL)
- WinDeleteWindow (off, false);
- }
-
-
- //
- // draw_string()
- //
- void draw_string(const char* s, int x, int y, h_align h, v_align v) {
- // variables
- int width, height, xheight;
- unsigned short length;
-
- // check string
- if (s==NULL) return;
-
- // get dimensions
- length = StrLen(s);
- width = int(FntCharsWidth(s, length));
- height = int(FntLineHeight());
- xheight = FntBaseLine();
-
- align (x, y, width, height, xheight, h, v);
- WinDrawChars (s, length, x, y);
- }
-
- //
- // draw_char()
- //
- void
- draw_char(char c, int x, int y, h_align h, v_align v) {
- char s[2] = {c, 0};
- draw_string(s, x, y, h, v);
- }
-
- //
- // erase_rect()
- //
- void
- erase_rect(int x, int y, int width, int height) {
- RectangleType r;
- r.topLeft.x = x;
- r.topLeft.y = y;
- r.extent.x = width;
- r.extent.y = height;
- WinEraseRectangle(&r, 0);
- }
-
- //
- // paint_rect()
- //
- void
- paint_rect(int x, int y, int width, int height) {
- RectangleType r;
- r.topLeft.x = x;
- r.topLeft.y = y;
- r.extent.x = width;
- r.extent.y = height;
- WinDrawRectangle(&r, 0);
- }
-
- #pragma mark -
-
- //
- // point_is_close()
- //
- Boolean
- point_is_close(int x1, int y1, int x2, int y2, int slop) {
- Boolean close = false;
-
- if ((Abs(x1-x2) <= slop) && (Abs(y1-y2) <= slop))
- close = true;
-
- return close;
- }
-
- //
- // get_bitmap_dimensions()
- //
- void
- get_bitmap_dimensions(int resID, int& height, int& width) {
- // get bitmap
- BitmapType** resH = (BitmapType**) DmGetResource (bitmapRsc, resID);
- BitmapType* bitmap = (BitmapType*) MemHandleLock ((void**) resH);
- // get dimensions
- width = bitmap->width;
- height = bitmap->height;
- // release bitmap
- Err err = MemHandleUnlock ((void**) resH);
- }
-
- //
- // constrain_to_screen()
- //
- void
- constrain_to_screen (short& x, short& y) {
- short width, height;
- WinGetDisplayExtent (&width, &height);
- if (x<0) x=0;
- if (y<0) y=0;
- if (x>width-1) x = width-1;
- if (y>height-1) y = height-1;
- }
-
- //
- // align()
- //
- void align(int& x, int& y, int width, int height, int xheight, h_align h, v_align v) {
- // horizontal align
- switch (h) {
- case center_align:
- x -= width/2;
- break;
- case right_align:
- x -= width;
- break;
- case left_align:
- default:
- break;
- }
- // vertical align
- switch (v) {
- case middle_align:
- y -= height/2;
- break;
- case bottom_align:
- y -= height;
- break;
- case baseline_align:
- y -= xheight;
- break;
- case top_align:
- default:
- break;
- }
- }