home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-247 / blobop.c < prev    next >
C/C++ Source or Header  |  1996-06-25  |  8KB  |  272 lines

  1.  
  2. /* +-------------------------------------------------------------------+ */
  3. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)           | */
  4. /* |                                       | */
  5. /* | Permission to use, copy, modify, and to distribute this software  | */
  6. /* | and its documentation for any purpose is hereby granted without   | */
  7. /* | fee, provided that the above copyright notice appear in all       | */
  8. /* | copies and that both that copyright notice and this permission    | */
  9. /* | notice appear in supporting documentation.     There is no           | */
  10. /* | representations about the suitability of this software for           | */
  11. /* | any purpose.  this software is provided "as is" without express   | */
  12. /* | or implied warranty.                           | */
  13. /* |                                       | */
  14. /* +-------------------------------------------------------------------+ */
  15.  
  16. /* $Id: blobOp.c,v 1.3 1996/04/19 09:05:37 torsten Exp $ */
  17.  
  18. #include <X11/Intrinsic.h>
  19. #include <X11/StringDefs.h>
  20. #include <X11/cursorfont.h>
  21. #include "xpaint.h"
  22. #include "misc.h"
  23. #include "Paint.h"
  24. #include "ops.h"
  25.  
  26. #define FILL        0x2
  27. #define POLY        0x1
  28. #define IsPoly(x)    (x & POLY)
  29. #define IsFill(x)    (x & FILL)
  30.  
  31. typedef struct {
  32.     Boolean flag;
  33.     int startX, startY, lastX, lastY;
  34.     GC gc1, gc2;
  35.     int npoints, size;
  36.     XPoint *points, *real;
  37. } LocalInfo;
  38.  
  39. static void 
  40. press(Widget w, LocalInfo * l, XButtonEvent * event, OpInfo * info)
  41. {
  42.     XRectangle undo;
  43.  
  44.     if (info->surface == opWindow)
  45.     return;
  46.  
  47.     if ((event->state & AllButtonsMask) != 0)
  48.     return;
  49.  
  50.     l->lastX = l->startX = event->x;
  51.     l->lastY = l->startY = event->y;
  52.     l->npoints = 0;
  53.     if (IsFill(l->flag)) {
  54.     l->points[l->npoints].x = event->x;
  55.     l->points[l->npoints].y = event->y;
  56.     l->real[l->npoints].x = info->x;
  57.     l->real[l->npoints].y = info->y;
  58.     l->npoints++;
  59.     }
  60.     undo.x = event->x;
  61.     undo.y = event->y;
  62.     undo.width = 1;
  63.     undo.height = 1;
  64.  
  65.     if (event->button == Button2) {
  66.     l->gc1 = info->second_gc;
  67.     l->gc2 = info->first_gc;
  68.     } else {
  69.     l->gc1 = info->first_gc;
  70.     l->gc2 = info->second_gc;
  71.     }
  72.  
  73.     UndoStartPoint(w, info, event->x, event->y);
  74.  
  75.     XDrawLine(XtDisplay(w), info->drawable, l->gc1,
  76.           l->lastX, l->lastY, event->x, event->y);
  77.     if (!info->isFat)
  78.     XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
  79.           l->lastX, l->lastY, event->x, event->y);
  80.  
  81.     PwUpdate(w, &undo, False);
  82. }
  83.  
  84. static void 
  85. motion(Widget w, LocalInfo * l, XMotionEvent * event, OpInfo * info)
  86. {
  87.     XRectangle undo;
  88.  
  89.     if (info->surface == opWindow)
  90.     return;
  91.  
  92.     XDrawLine(XtDisplay(w), info->drawable, l->gc1,
  93.           l->lastX, l->lastY, event->x, event->y);
  94.     if (!info->isFat)
  95.     XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
  96.           l->lastX, l->lastY, event->x, event->y);
  97.  
  98.     UndoGrow(w, event->x, event->y);
  99.  
  100.     undo.x = MIN(l->lastX, event->x);
  101.     undo.y = MIN(l->lastY, event->y);
  102.     undo.width = MAX(l->lastX, event->x) - undo.x + 1;
  103.     undo.height = MAX(l->lastY, event->y) - undo.y + 1;
  104.  
  105.     l->lastX = event->x;
  106.     l->lastY = event->y;
  107.     if (IsFill(l->flag)) {
  108.     l->points[l->npoints].x = event->x;
  109.     l->points[l->npoints].y = event->y;
  110.     l->real[l->npoints].x = info->x;
  111.     l->real[l->npoints].y = info->y;
  112.     l->npoints++;
  113.     if (l->npoints > l->size - 3) {
  114.         l->size += 256;
  115.         l->real = (XPoint *) XtRealloc((XtPointer) l->real,
  116.                        sizeof(XPoint) * l->size);
  117.         l->points = (XPoint *) XtRealloc((XtPointer) l->points,
  118.                          sizeof(XPoint) * l->size);
  119.     }
  120.     }
  121.     PwUpdate(w, &undo, False);
  122. }
  123. static void 
  124. release(Widget w, LocalInfo * l, XButtonEvent * event, OpInfo * info)
  125. {
  126.     XRectangle undo;
  127.  
  128.     int mask;
  129.     /*
  130.     **    Check to make sure all buttons are up, before doing this
  131.      */
  132.     mask = AllButtonsMask;
  133.     switch (event->button) {
  134.     case Button1:
  135.     mask ^= Button1Mask;
  136.     break;
  137.     case Button2:
  138.     mask ^= Button2Mask;
  139.     break;
  140.     case Button3:
  141.     mask ^= Button3Mask;
  142.     break;
  143.     case Button4:
  144.     mask ^= Button4Mask;
  145.     break;
  146.     case Button5:
  147.     mask ^= Button5Mask;
  148.     break;
  149.     }
  150.     if ((event->state & mask) != 0)
  151.     return;
  152.     l->points[l->npoints].x = event->x;
  153.     l->points[l->npoints].y = event->y;
  154.     l->real[l->npoints].x = info->x;
  155.     l->real[l->npoints].y = info->y;
  156.     l->npoints++;
  157.  
  158.     UndoGrow(w, event->x, event->y);
  159.  
  160.     undo.x = MIN(l->lastX, event->x);
  161.     undo.y = MIN(l->lastY, event->y);
  162.     undo.width = MAX(l->lastX, event->x) - undo.x + 1;
  163.     undo.height = MAX(l->lastY, event->y) - undo.y + 1;
  164.  
  165.     if (IsFill(l->flag)) {
  166.     if (!info->isFat)
  167.         XFillPolygon(XtDisplay(w), XtWindow(w), l->gc2,
  168.              l->real, l->npoints, Complex, CoordModeOrigin);
  169.     XFillPolygon(XtDisplay(w), info->drawable, l->gc2,
  170.              l->real, l->npoints, Complex, CoordModeOrigin);
  171.     l->points[l->npoints].x = l->points[0].x;
  172.     l->points[l->npoints].y = l->points[0].y;
  173.     l->real[l->npoints].x = l->real[0].x;
  174.     l->real[l->npoints].y = l->real[0].y;
  175.     l->npoints++;
  176.     if (!info->isFat)
  177.         XDrawLines(XtDisplay(w), XtWindow(w), l->gc1,
  178.                l->real, l->npoints, CoordModeOrigin);
  179.     XDrawLines(XtDisplay(w), info->drawable, l->gc1,
  180.            l->real, l->npoints, CoordModeOrigin);
  181.     } else {
  182.     l->lastX = event->x;
  183.     l->lastY = event->y;
  184.     XDrawLine(XtDisplay(w), info->drawable, l->gc1,
  185.           l->lastX, l->lastY, l->startX, l->startY);
  186.     if (!info->isFat)
  187.         XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
  188.               l->lastX, l->lastY, l->startX, l->startY);
  189.  
  190.     }
  191.  
  192.     PwUpdate(w, NULL, False);
  193. }
  194.  
  195. /*
  196. **  Those public functions
  197.  */
  198. void *
  199. FreehandAdd(Widget w)
  200. {
  201.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  202.  
  203.     XtVaSetValues(w, XtNcompress, False, NULL);
  204.     l->flag = 0;
  205.  
  206.     l->size = 256;
  207.     l->real = (XPoint *) XtCalloc(sizeof(XPoint), l->size);
  208.     l->points = (XPoint *) XtCalloc(sizeof(XPoint), l->size);
  209.  
  210.     OpAddEventHandler(w, opPixmap, ButtonPressMask, FALSE,
  211.               (OpEventProc) press, l);
  212.     OpAddEventHandler(w, opPixmap, ButtonMotionMask, FALSE,
  213.               (OpEventProc) motion, l);
  214.     OpAddEventHandler(w, opPixmap, ButtonReleaseMask, FALSE,
  215.               (OpEventProc) release, l);
  216.     SetPencilCursor(w);
  217.  
  218.     return l;
  219. }
  220. void 
  221. FreehandRemove(Widget w, void *l)
  222. {
  223.     OpRemoveEventHandler(w, opPixmap, ButtonPressMask, FALSE,
  224.              (OpEventProc) press, l);
  225.     OpRemoveEventHandler(w, opPixmap, ButtonMotionMask, FALSE,
  226.              (OpEventProc) motion, l);
  227.     OpRemoveEventHandler(w, opPixmap, ButtonReleaseMask, FALSE,
  228.              (OpEventProc) release, l);
  229.  
  230.     XtFree((XtPointer) ((LocalInfo *) l)->real);
  231.     XtFree((XtPointer) ((LocalInfo *) l)->points);
  232.     XtFree((XtPointer) l);
  233. }
  234.  
  235. void *
  236. FFreehandAdd(Widget w)
  237. {
  238.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  239.     l->flag = FILL;
  240.  
  241.     l->size = 256;
  242.     l->real = (XPoint *) XtCalloc(sizeof(XPoint), l->size);
  243.     l->points = (XPoint *) XtCalloc(sizeof(XPoint), l->size);
  244.  
  245.     XtVaSetValues(w, XtNcompress, True, NULL);
  246.  
  247.     OpAddEventHandler(w, opPixmap, ButtonPressMask, FALSE,
  248.               (OpEventProc) press, l);
  249.     OpAddEventHandler(w, opPixmap, ButtonMotionMask, FALSE,
  250.               (OpEventProc) motion, l);
  251.     OpAddEventHandler(w, opPixmap, ButtonReleaseMask, FALSE,
  252.               (OpEventProc) release, l);
  253.  
  254.     SetPencilCursor(w);
  255.  
  256.     return l;
  257. }
  258.  
  259. void 
  260. FFreehandRemove(Widget w, void *l)
  261. {
  262.     OpRemoveEventHandler(w, opPixmap, ButtonPressMask, FALSE,
  263.              (OpEventProc) press, l);
  264.     OpRemoveEventHandler(w, opPixmap, ButtonMotionMask, FALSE,
  265.              (OpEventProc) motion, l);
  266.     OpRemoveEventHandler(w, opPixmap, ButtonReleaseMask, FALSE,
  267.              (OpEventProc) release, l);
  268.     XtFree((XtPointer) ((LocalInfo *) l)->real);
  269.     XtFree((XtPointer) ((LocalInfo *) l)->points);
  270.     XtFree((XtPointer) l);
  271. }
  272.