home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / Palm Finder 2 / Src / App Sources / drawing.cpp < prev    next >
Encoding:
Text File  |  2001-06-23  |  6.4 KB  |  309 lines

  1. // drawing.cpp
  2.  
  3. #include "drawing.h"
  4. // debug:
  5. #include "events.h"
  6.  
  7.  
  8. // prototypes
  9. void    align (int& x, int& y, int width, int height, int xheight, h_align h, v_align v);
  10.  
  11.  
  12. //
  13. // draw_bitmap()
  14. //
  15. void draw_bitmap(int resID, int x, int y, h_align h, v_align v, ScrOperation copy_mode) {
  16.     // variables
  17.     int width, height;
  18.     Err err;
  19.     
  20.     // get bitmap
  21.     BitmapType** resH = (BitmapType**) DmGetResource (bitmapRsc, resID);
  22.     BitmapType* bitmap = (BitmapType*) MemHandleLock ((void**) resH);
  23.     // get dimensions
  24.     width = int(bitmap->width);
  25.     height = int(bitmap->height);
  26.     
  27.     align (x, y, width, height, height, h, v);
  28.     
  29.     // draw bitmap
  30.     if (copy_mode == scrCopy) {
  31.         WinDrawBitmap (bitmap, x, y);
  32.     } else {
  33.         draw_bits (bitmap, x, y, copy_mode);
  34.     }
  35.     
  36.     // release bitmap
  37.     err = MemHandleUnlock ((void**) resH);
  38. }
  39.  
  40. //
  41. // draw_bitmap_masked()
  42. //
  43. void         
  44. draw_bitmap_masked(int bitmapID, int maskID, int x, int y, h_align h, v_align v) {
  45.     draw_bitmap (maskID, x, y, h, v, scrANDNOT);
  46.     draw_bitmap (bitmapID, x, y, h, v, scrOR);
  47. }
  48.  
  49. //
  50. // copy_bits()
  51. //
  52. void        
  53. draw_bits(BitmapPtr bm, int x, int y, ScrOperation copy_mode) {
  54.     // variables
  55.     int                 bm_width, bm_height;
  56.     WinHandle        window = NULL;
  57.     GDevicePtr        gd;
  58.     unsigned long    gd_baseAddr, src_baseAddr, dest_baseAddr;
  59.     int                gd_rowBytes, gd_width, gd_height;
  60.     int                src_rowBytes;
  61.     WinHandle        off = NULL;
  62.     UInt16            err;
  63.     
  64.     // get dimensions
  65.     bm_width =         int(bm->width);
  66.     bm_height =         int(bm->height);
  67.     // check required params
  68.     if ((bm->version!=1) || (bm->pixelSize!=1))
  69.         goto error;
  70.     
  71.     // get dest window
  72.     window = WinGetDrawWindow();
  73.     if (window==NULL)
  74.         goto error;
  75.     gd = window->gDeviceP;
  76.     if (gd==NULL)
  77.         goto error;
  78.     // device must be version 0, uncompressed, and 1 bit/pixel (bitmap) 
  79.     if ((gd->version!=0) || (gd->compressed==1) || (gd->pixelSize!=1))
  80.         goto error;
  81.     // get dimensions
  82.     gd_baseAddr =     (unsigned long) gd->baseAddr;
  83.     gd_rowBytes =     gd->rowBytes;
  84.     gd_width =         gd->width;
  85.     gd_height =         gd->height;
  86.     
  87.     
  88.     // and with masking operations at the edges?
  89.     
  90.     // align bitmap's bytes with dest bytes
  91.     int bit_offset = x & 7;
  92.     int byte_offset = x>>3;
  93.     int byte_width = (bm_width + bit_offset +7) / 8;
  94.     if (byte_width > gd_rowBytes - byte_offset)
  95.         byte_width = gd_rowBytes - byte_offset;
  96.     int line_offset = y;
  97.     int line_height = bm_height;
  98.     if (line_height > gd_height - line_offset) 
  99.         line_height = gd_height - line_offset;
  100.     dest_baseAddr = gd_baseAddr + gd_rowBytes * line_offset + byte_offset;
  101.         
  102.     // how to deal with negative x and y?
  103.     int skip_bytes = -byte_offset;
  104.     if (skip_bytes<0)
  105.         skip_bytes = 0;
  106.     int skip_lines = -line_offset;
  107.     if (skip_lines<0)
  108.         skip_lines = 0;
  109.         
  110.     // debug:
  111.     /*
  112.     char        s[32];
  113.     StrIToA(s, skip_lines);
  114.     draw_string(s, 0,15, left_align, top_align);
  115.     */
  116.     
  117.     // special case for copy mode, so edges don't get clobbered
  118.     if (copy_mode == scrCopy) {
  119.         erase_rect(x, y, bm_width, bm_height);
  120.     }
  121.  
  122.     // create offscreen window
  123.     int off_width = byte_width*8;
  124.     int off_height = line_height;
  125.     off = WinCreateOffscreenWindow (off_width, off_height, screenFormat, &err);
  126.     if (off==NULL)
  127.         goto error;
  128.     if (off->gDeviceP==NULL)
  129.         goto error;
  130.     // draw bitmap into offscreen window
  131.     WinSetDrawWindow (off);
  132.     if (copy_mode==scrAND) {
  133.         paint_rect (0, 0, off_width, off_height);
  134.     } else {
  135.         erase_rect (0, 0, off_width, off_height);
  136.     }
  137.     WinDrawBitmap (bm, bit_offset, 0);
  138.     // get info on offscreen window
  139.     src_baseAddr = (unsigned long)  off->gDeviceP->baseAddr;
  140.     src_rowBytes = off->gDeviceP->rowBytes;
  141.         
  142.     // copy bitmap data to device
  143.     int    i_x, i_y;
  144.     char    *destP, *srcP;
  145.     for (i_y=skip_lines; i_y<line_height; i_y++) {
  146.         for (i_x=skip_bytes; i_x<byte_width; i_x++) {
  147.             srcP =     (char*) (src_baseAddr + src_rowBytes * i_y + i_x);
  148.             destP =    (char*) (dest_baseAddr + gd_rowBytes * i_y + i_x);
  149.             switch (copy_mode) {
  150.                 case scrOR:
  151.                 case scrCopy:
  152.                     *destP |= *srcP;
  153.                     break;
  154.                 case scrAND:
  155.                     *destP &= *srcP;
  156.                     break;
  157.                 case scrANDNOT:
  158.                     *destP &= ~(*srcP);
  159.                     break;
  160.                 case scrXOR:
  161.                     *destP ^= *srcP;
  162.                     break;
  163.                 default:
  164.                     break;
  165.             }
  166.         }
  167.     }
  168.     
  169.     error:
  170.     // restore draw window
  171.     if (window!=NULL)
  172.         WinSetDrawWindow(window);
  173.     // release offscreen window if allocated
  174.     if (off!=NULL)
  175.         WinDeleteWindow (off, false);
  176. }
  177.  
  178.  
  179. //
  180. // draw_string()
  181. //
  182. void draw_string(const char* s, int x, int y, h_align h, v_align v) {
  183.     // variables
  184.     int width, height, xheight;
  185.     unsigned short length;
  186.     
  187.     // check string
  188.     if (s==NULL) return;
  189.  
  190.     // get dimensions
  191.     length = StrLen(s);
  192.     width = int(FntCharsWidth(s, length));
  193.     height = int(FntLineHeight());
  194.     xheight = FntBaseLine();
  195.  
  196.     align (x, y, width, height, xheight, h, v);
  197.     WinDrawChars (s, length, x, y);
  198. }
  199.  
  200. //
  201. // draw_char()
  202. //
  203. void 
  204. draw_char(char c, int x, int y, h_align h, v_align v) {
  205.     char    s[2] = {c, 0};
  206.     draw_string(s, x, y, h, v);
  207. }
  208.  
  209. //
  210. // erase_rect()
  211. //
  212. void
  213. erase_rect(int x, int y, int width, int height) {
  214.     RectangleType r;
  215.     r.topLeft.x = x;
  216.     r.topLeft.y = y;
  217.     r.extent.x = width;
  218.     r.extent.y = height;
  219.     WinEraseRectangle(&r, 0);
  220. }
  221.  
  222. //
  223. // paint_rect()
  224. //
  225. void
  226. paint_rect(int x, int y, int width, int height) {
  227.     RectangleType r;
  228.     r.topLeft.x = x;
  229.     r.topLeft.y = y;
  230.     r.extent.x = width;
  231.     r.extent.y = height;
  232.     WinDrawRectangle(&r, 0);
  233. }
  234.  
  235. #pragma mark -
  236.  
  237. //
  238. // point_is_close()
  239. //
  240. Boolean 
  241. point_is_close(int x1, int y1, int x2, int y2, int slop) {
  242.     Boolean close = false;
  243.     
  244.     if ((Abs(x1-x2) <= slop) && (Abs(y1-y2) <= slop))
  245.         close = true;
  246.     
  247.     return close;
  248. }
  249.  
  250. //
  251. // get_bitmap_dimensions()
  252. // 
  253. void        
  254. get_bitmap_dimensions(int resID, int& height, int& width) {
  255.         // get bitmap
  256.         BitmapType** resH = (BitmapType**) DmGetResource (bitmapRsc, resID);
  257.         BitmapType* bitmap = (BitmapType*) MemHandleLock ((void**) resH);
  258.         // get dimensions
  259.         width = bitmap->width;
  260.         height = bitmap->height;
  261.         // release bitmap
  262.         Err err = MemHandleUnlock ((void**) resH);
  263. }
  264.  
  265. //
  266. // constrain_to_screen()
  267. //
  268. void        
  269. constrain_to_screen (short& x, short& y) {
  270.     short    width, height;
  271.     WinGetDisplayExtent (&width, &height);
  272.     if (x<0) x=0;
  273.     if (y<0) y=0;
  274.     if (x>width-1) x = width-1;
  275.     if (y>height-1) y = height-1;
  276. }
  277.  
  278. //
  279. // align()
  280. //
  281. void    align(int& x, int& y, int width, int height, int xheight, h_align h, v_align v) {
  282.     // horizontal align
  283.     switch (h) {
  284.         case center_align:
  285.             x -= width/2;
  286.             break;
  287.         case right_align:
  288.             x -= width;
  289.             break;
  290.         case left_align:
  291.         default:
  292.             break;
  293.     }
  294.     // vertical align
  295.     switch (v) {
  296.         case middle_align:
  297.             y -= height/2;
  298.             break;
  299.         case bottom_align:
  300.             y -= height;
  301.             break;
  302.         case baseline_align:
  303.             y -= xheight;
  304.             break;
  305.         case top_align:
  306.         default:
  307.             break;
  308.     }
  309. }