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

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. /* $Id: fontOp.c,v 1.3 1996/04/19 08:56:26 torsten Exp $ */
  16.  
  17. #include <X11/Intrinsic.h>
  18. #include <X11/StringDefs.h>
  19. #include <X11/cursorfont.h>
  20. #include <X11/Xos.h>
  21. #include <X11/Xatom.h>
  22. #include "xpaint.h"
  23. #include "Paint.h"
  24. #include "graphic.h"
  25. #include "misc.h"
  26. #include "ops.h"
  27.  
  28. static Atom targetAtom, selectionAtom;
  29.  
  30. #define    DELAY    500
  31.  
  32. typedef struct {
  33.     XtIntervalId id;
  34.     Boolean typing;
  35.     Boolean state;
  36.     int startX, startY, curX, curY, height;
  37.     XFontStruct *fi;
  38.     int insertX, insertY, insertSX, insertSY, insertH;
  39.     int zoom;
  40.     Widget w;
  41.     char *sptr;
  42.     int maxStrLen;
  43.     char minPos;
  44.     char *str;
  45.     Drawable drawable;
  46.     GC gc, gcx;
  47. } LocalInfo;
  48.  
  49. static void addString(Widget, LocalInfo *, int, char *);
  50.  
  51. static void 
  52. cursor(LocalInfo * l, Boolean flag)
  53. {
  54.     if (l->w == None)
  55.     return;
  56.     if (flag) {
  57.     XDrawLine(XtDisplay(l->w), XtWindow(l->w), l->gcx,
  58.         l->insertX, l->insertY, l->insertX, l->insertY + l->insertH);
  59.     l->state = !l->state;
  60.     } else if (l->state) {
  61.     XDrawLine(XtDisplay(l->w), XtWindow(l->w), l->gcx,
  62.         l->insertX, l->insertY, l->insertX, l->insertY + l->insertH);
  63.     l->state = False;
  64.     }
  65. }
  66.  
  67. static void 
  68. flash(LocalInfo * l)
  69. {
  70.     cursor(l, True);
  71.     l->id = XtAppAddTimeOut(XtWidgetToApplicationContext(l->w),
  72.               DELAY, (XtTimerCallbackProc) flash, (XtPointer) l);
  73. }
  74.  
  75. static void 
  76. gotSelection(Widget w, LocalInfo * l, Atom * selection, Atom * type,
  77.          XtPointer value, unsigned long *len, int *format)
  78. {
  79.     if (!l->typing)
  80.     return;
  81.  
  82.     if (len == 0 || value == NULL)
  83.     return;
  84.  
  85.     switch (*type) {
  86.     case XA_STRING:
  87.     addString(w, l, *len, (char *) value);
  88.     break;
  89.     }
  90.     XtFree((XtPointer) value);
  91. }
  92.  
  93. static void 
  94. press(Widget w, LocalInfo * l, XButtonEvent * event, OpInfo * info)
  95. {
  96.     if (event->button == Button1) {
  97.     cursor(l, False);
  98.  
  99.     XtVaGetValues(w, XtNfont, &l->fi, NULL);
  100.     if (l->fi == NULL)
  101.         return;
  102.  
  103.     l->w = w;
  104.     l->height = l->fi->ascent + l->fi->descent;
  105.     l->startX = l->curX = info->x;
  106.     l->startY = l->curY = info->y;
  107.     l->curY = l->curY - l->height / 2;
  108.     l->typing = True;
  109.  
  110.     if (info->surface == opWindow) {
  111.         l->insertH = l->height * info->zoom;
  112.         l->insertY = event->y - l->insertH / 2;
  113.         l->insertX = event->x;
  114.         l->insertSX = event->x;
  115.     }
  116.     l->sptr = l->str;
  117.  
  118.     if (l->id == (XtIntervalId) NULL)
  119.         flash(l);
  120.  
  121.     l->zoom = info->zoom;
  122.     l->gc = info->first_gc;
  123.     l->minPos = 0;
  124.  
  125.     UndoStartPoint(w, info, l->curX, l->curY);
  126.     if (info->surface == opPixmap)
  127.         l->drawable = info->drawable;
  128.     } else if (event->button == Button2) {
  129.     XtGetSelectionValue(w, selectionAtom, targetAtom,
  130.                 (XtSelectionCallbackProc) gotSelection, (XtPointer) l, event->time);
  131.     }
  132. }
  133.  
  134. static void 
  135. key(Widget w, LocalInfo * l, XKeyEvent * event, OpInfo * info)
  136. {
  137.     char buf[21];
  138.     KeySym keysym;
  139.     int len;
  140.  
  141.     if (l->w == None)
  142.     return;
  143.  
  144.     if ((len = XLookupString(event, buf, sizeof(buf) - 1, &keysym, NULL)) == 0)
  145.     return;
  146.  
  147.     l->zoom = info->zoom;
  148.     l->gc = info->first_gc;
  149.     l->drawable = info->drawable;
  150.     addString(w, l, len, buf);
  151. }
  152.  
  153. static void 
  154. addString(Widget w, LocalInfo * l, int len, char *buf)
  155. {
  156.     int i, width;
  157.     XRectangle rect;
  158.  
  159.     if (len != 0)
  160.     cursor(l, False);
  161.     for (i = 0; i < len; i++) {
  162.     if (l->sptr == l->str + l->maxStrLen - 5) {
  163.         int delta = l->sptr - l->str;
  164.         l->maxStrLen += 128;
  165.         l->str = (char *) XtRealloc((XtPointer) l->str, l->maxStrLen);
  166.         l->sptr = l->str + delta;
  167.     }
  168.     if (buf[i] == '\n' || buf[i] == '\r') {
  169.         l->curX = l->startX;
  170.         l->curY += l->height + 2;
  171.         l->insertX = l->insertSX;
  172.         l->insertY += l->insertH + 2 * l->zoom;
  173.  
  174.         *l->sptr++ = '\n';
  175.     } else if (buf[i] == 0x08 || buf[i] == 0x7f) {
  176.         if (l->sptr - l->str > l->minPos) {
  177.         l->sptr--;
  178.         if (*l->sptr == '\n') {
  179.             char *cp;
  180.             *l->sptr = '\0';
  181.             if ((cp = strrchr(l->str, '\n')) == NULL)
  182.             cp = l->str;
  183.             else
  184.             cp++;
  185.             width = XTextWidth(l->fi, cp, strlen(cp));
  186.             l->curX = l->startX + width;
  187.             l->curY -= l->height + 2;
  188.             l->insertX = (l->startX + width) * l->zoom;
  189.             l->insertY -= l->insertH + 2 * l->zoom;
  190.         } else {
  191.             width = XTextWidth(l->fi, l->sptr, 1);
  192.             l->curX -= width;
  193.             l->insertX -= width * l->zoom;
  194.  
  195.             /*
  196.             **  Now undraw the character.
  197.              */
  198.             XYtoRECT(l->curX, l->curY, l->curX + width, l->curY + l->height, &rect);
  199.             PwUpdateFromLast(w, &rect);
  200.         }
  201.         }
  202.     } else {
  203.         if (l->zoom == 1)
  204.         XDrawString(XtDisplay(w), XtWindow(w), l->gc,
  205.                 l->curX, l->curY + l->fi->ascent, &buf[i], 1);
  206.         XDrawString(XtDisplay(w), l->drawable, l->gc,
  207.             l->curX, l->curY + l->fi->ascent, &buf[i], 1);
  208.         width = XTextWidth(l->fi, &buf[i], 1);
  209.  
  210.         XYtoRECT(l->curX, l->curY, l->curX + width, l->curY + l->height, &rect);
  211.         PwUpdate(w, &rect, False);
  212.  
  213.         l->curX += width;
  214.         l->insertX += width * l->zoom;
  215.  
  216.         UndoGrow(w, l->curX, l->curY + l->height);
  217.         UndoGrow(w, l->curX, l->curY + l->height);
  218.  
  219.         *l->sptr++ = buf[i];
  220.     }
  221.     }
  222. }
  223.  
  224. /*
  225. **  Those public functions
  226.  */
  227. void *
  228. FontAdd(Widget w)
  229. {
  230.     static int inited = False;
  231.     LocalInfo *l = (LocalInfo *) XtMalloc(sizeof(LocalInfo));
  232.  
  233.     if (!inited) {
  234.     selectionAtom = XA_PRIMARY;
  235.     targetAtom = XA_STRING;
  236.     }
  237.     l->id = (XtIntervalId) NULL;
  238.     l->w = None;
  239.     l->typing = False;
  240.     l->state = False;
  241.  
  242.     l->maxStrLen = 128;
  243.     l->str = (char *) XtMalloc(l->maxStrLen);
  244.     l->gcx = GetGCX(w);
  245.  
  246.     OpAddEventHandler(w, opPixmap | opWindow, ButtonPressMask, FALSE,
  247.               (OpEventProc) press, l);
  248.     OpAddEventHandler(w, opPixmap, KeyPressMask, FALSE, (OpEventProc) key, l);
  249.  
  250.     SetIBeamCursor(w);
  251.  
  252.     return l;
  253. }
  254. void 
  255. FontRemove(Widget w, void *p)
  256. {
  257.     LocalInfo *l = (LocalInfo *) p;
  258.  
  259.     OpRemoveEventHandler(w, opPixmap | opWindow, ButtonPressMask, FALSE,
  260.              (OpEventProc) press, p);
  261.     OpRemoveEventHandler(w, opPixmap, KeyPressMask, FALSE, (OpEventProc) key, p);
  262.  
  263.     if (l->id != (XtIntervalId) NULL)
  264.     XtRemoveTimeOut(l->id);
  265.  
  266.     cursor(l, False);
  267.  
  268.     XtFree((XtPointer) l->str);
  269.     XtFree((XtPointer) l);
  270. }
  271. void 
  272. FontChanged(Widget w)
  273. {
  274.     LocalInfo *l;
  275.  
  276.     if (CurrentOp->add != FontAdd)
  277.     return;
  278.  
  279.     l = (LocalInfo *) GraphicGetData(w);
  280.  
  281.     XtVaGetValues(w, XtNfont, &l->fi, NULL);
  282.     if (l->fi == NULL)
  283.     return;
  284.  
  285.     cursor(l, False);
  286.     l->height = l->fi->ascent + l->fi->descent;
  287.  
  288.     l->minPos = l->sptr - l->str;
  289.     l->insertH = l->height * l->zoom;
  290. }
  291.