[comp.sources.x] v12i032: tgif, Part16/23

william@CS.UCLA.EDU (William Cheng) (03/14/91)

Submitted-by: william@CS.UCLA.EDU (William Cheng)
Posting-number: Volume 12, Issue 32
Archive-name: tgif/part16

---------------------------------> cut here <---------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 16 (of 23)."
# Contents:  text.c
# Wrapped by william@oahu on Wed Mar  6 09:57:52 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'text.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'text.c'\"
else
echo shar: Extracting \"'text.c'\" \(64034 characters\)
sed "s/^X//" >'text.c' <<'END_OF_FILE'
X/*
X * Author:	William Chia-Wei Cheng (william@cs.ucla.edu)
X *
X * Copyright (C) 1990, 1991, William Cheng.
X */
X#ifndef lint
Xstatic char RCSid[] =
X      "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/text.c,v 2.0 91/03/05 12:48:39 william Exp $";
X#endif
X
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "const.h"
X#include "types.h"
X
X#include "attr.e"
X#include "choice.e"
X#include "color.e"
X#include "cursor.e"
X#include "dup.e"
X#include "file.e"
X#include "font.e"
X#include "grid.e"
X#include "obj.e"
X#include "pattern.e"
X#include "poly.e"
X#include "prtgif.e"
X#include "raster.e"
X#include "ruler.e"
X#include "setup.e"
X
X#define PAINT 1
X#define FRONT_HIGHLIGHT 2
X#define MID_HIGHLIGHT 4
X#define BACK_HIGHLIGHT 8
X
X#define ERASE 0
X#define PAINT_NORM (PAINT)
X#define PAINT_INV (PAINT|FRONT_HIGHLIGHT|MID_HIGHLIGHT|BACK_HIGHLIGHT)
X#define PAINT_NORM_INV (PAINT|MID_HIGHLIGHT|BACK_HIGHLIGHT)
X#define PAINT_INV_NORM (PAINT|FRONT_HIGHLIGHT)
X#define PAINT_NORM_INV_NORM (PAINT|MID_HIGHLIGHT)
X
Xint		textDrawn = FALSE;
X
Xint		textJust = JUST_L;
Xint		textCursorShown = FALSE;
Xint		textCursorH; /* UNSCALED height of the text cursor */
Xstruct ObjRec	* curTextObj = NULL;
X
Xstatic struct ObjRec	* justDrawnTextObj = NULL;
X
Xstatic struct StrRec	* firstStr = NULL, * lastStr = NULL, * curStr = NULL;
X
Xstatic int	textOrigX = 20, textOrigY = 20, textCurX = 20, textCurY = 20;
X		/* textOrigX, textOrigY, textCurX, textCurY */
X		/*   are UNSCALED screen offsets */
Xstatic int	textW, textH; /* absolute for the current text font */
Xstatic int	textAbsX = INVALID, textAbsY = INVALID;
X		/* textAbsX and textAbsY are absolute coordinates */
Xstatic int	textCurIndex = 0;
Xstatic int	curStrW = 0; /* UNSCALED width of the current string */
Xstatic int	editingText = FALSE;
Xstatic int      lowGreekMap[] = { 11, 12, 31, 14, 15, 30, 13, 17, 19, 125, 20,
X                                21, 22, 23, -1, 25, 18, 26, 27, 28, 29, -1,
X                                124, 24, 123, 16 };
Xstatic int     upperGreekMap[] = { -1, -1, -1, 1, -1, 8, -1, -1, -1, -1, -1, 3,
X                                  -1, -1, -1, 5, 2, -1, 6, -1, -1, -1, 10,
X                                  4, 9, -1 };
X
Xstatic int	savedTextLtX, savedTextLtY, savedTextRbX, savedTextRbY;
X
Xstatic int	tmpAdjX, tmpAdjY;
X
X/* the following static variables are for handling text highlight */
Xstatic int		textEndX, textEndY, textEndIndex, textHighlight = FALSE;
Xstatic int		endStrW;
Xstatic struct StrRec	* endStr = NULL;
X
X#define BLUR 20
X
Xextern void	RedrawCurText ();
Xextern void	DrawTextObj ();
X
Xstatic
Xvoid BlurText (Win, gc, Just, Rotate, XOff, YOff, W, H)
X   Window	Win;
X   GC		gc;
X   int		Just, Rotate, XOff, YOff, W, H;
X   /* XOff and YOff are screen offsets (scaled and translated) */
X{
X   XPoint	v[5];
X
X   v[0].x = (short)XOff; v[0].y = (short)YOff;
X   v[1].x = (short)XOff; v[1].y = (short)YOff+H+1;
X   v[2].x = (short)XOff+W+1; v[2].y = (short)YOff+H+1;
X   v[3].x = (short)XOff+W+1; v[3].y = (short)YOff;
X   v[4].x = (short)XOff; v[4].y = (short)YOff;
X
X   XFillPolygon (mainDisplay, Win, gc, v, 5, Convex, CoordModeOrigin);
X}
X
Xstatic
Xvoid AddStr (PrevPtr, NextPtr, StrPtr)
X   struct StrRec	* PrevPtr, * NextPtr, * StrPtr;
X{
X   StrPtr->prev = PrevPtr;
X   StrPtr->next = NextPtr;
X
X   if (PrevPtr == NULL)
X      firstStr = StrPtr;
X   else
X      PrevPtr->next = StrPtr;
X
X   if (NextPtr == NULL)
X      lastStr = StrPtr;
X   else
X      NextPtr->prev = StrPtr;
X}
X
Xstatic Pixmap	textBackingPixmap;
Xstatic int	textBackingPixmapSize = INVALID;
Xstatic GC	rotateGC = NULL;
X
Xvoid CleanUpText ()
X{
X   if (textBackingPixmapSize != INVALID)
X   {
X      XFreePixmap (mainDisplay, textBackingPixmap);
X      textBackingPixmapSize = INVALID;
X   }
X   if (rotateGC != NULL) XFreeGC (mainDisplay, rotateGC);
X}
X
Xstatic
Xvoid PaintText (Win, gc, Str, Just, Rotate, XOff, YOff, xfs, ColorIndex, Pen,
X      Mode, FirstIndex, SecondIndex)
X   register int	XOff, YOff;
X   Window	Win;
X   GC		gc;
X   char		* Str;
X   int		Just, Rotate, ColorIndex, Pen, Mode, FirstIndex, SecondIndex;
X   XFontStruct	* xfs;
X   /* XOff and YOff are UNSCALED screen offset */
X{
X   register int		i, j;
X   register XImage	* from_image;
X   int			w, h, left, right, len;
X   XGCValues		values;
X
X   XOff >>= zoomScale;
X   YOff >>= zoomScale;
X
X   len = strlen (Str);
X
X   w = XTextWidth (xfs, Str, len) >> zoomScale;
X   h = canvasFontHeight >> zoomScale;
X
X   switch (Just)
X   {
X      case JUST_L: break;
X      case JUST_C:
X         switch (Rotate)
X         {
X            case ROTATE0: XOff -= w/2; break;
X            case ROTATE90: YOff -= w/2; break;
X            case ROTATE180: XOff += w/2; break;
X            case ROTATE270: YOff += w/2; break;
X         }
X         break;
X      case JUST_R:
X         switch (Rotate)
X         {
X            case ROTATE0: XOff -= w; break;
X            case ROTATE90: YOff -= w; break;
X            case ROTATE180: XOff += w; break;
X            case ROTATE270: YOff += w; break;
X         }
X         break;
X   }
X
X   if (Mode & PAINT)
X   {
X      if (Pen == NONEPAT) return;
X
X      if (zoomScale != 0)
X      {
X         values.foreground = colorPixels[ColorIndex];
X         values.function = GXcopy;
X         values.fill_style = FillOpaqueStippled;
X         values.stipple = patPixmap[BLUR];
X         XChangeGC (mainDisplay, gc,
X               GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
X
X         switch (Rotate)
X         {
X            case ROTATE0:
X               BlurText (Win, gc, Just, Rotate, XOff, YOff, w, h); break;
X            case ROTATE90:
X               BlurText (Win, gc, Just, Rotate, XOff-h, YOff, h, w); break;
X            case ROTATE180:
X               BlurText (Win, gc, Just, Rotate, XOff-w, YOff-h, w, h); break;
X            case ROTATE270:
X               BlurText (Win, gc, Just, Rotate, XOff, YOff-w, h, w); break;
X         }
X      }
X      else if (Rotate == ROTATE0)
X      {
X         values.foreground = colorPixels[ColorIndex];
X         values.function = GXcopy;
X         values.fill_style = FillOpaqueStippled;
X         values.stipple = patPixmap[Pen];
X         XChangeGC (mainDisplay, gc,
X               GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
X         XDrawString (mainDisplay, Win, gc, XOff, YOff+canvasFontAsc, Str, len);
X
X         switch (Mode)
X         {
X            case PAINT_NORM: break;
X            case PAINT_INV:
X               XSetForeground (mainDisplay, revDefaultGC,
X                     xorColorPixels[ColorIndex]);
X               XFillRectangle (mainDisplay, Win, revDefaultGC, XOff, YOff,
X                     w, h);
X               XSetForeground (mainDisplay, revDefaultGC, 1);
X               break;
X            case PAINT_NORM_INV:
X               left = XTextWidth (xfs, Str, FirstIndex);
X               XSetForeground (mainDisplay, revDefaultGC,
X                     xorColorPixels[ColorIndex]);
X               XFillRectangle (mainDisplay, Win, revDefaultGC, XOff+left, YOff,
X                     w-left, h);
X               XSetForeground (mainDisplay, revDefaultGC, 1);
X               break;
X            case PAINT_INV_NORM:
X               left = XTextWidth (xfs, Str, FirstIndex);
X               XSetForeground (mainDisplay, revDefaultGC,
X                     xorColorPixels[ColorIndex]);
X               XFillRectangle (mainDisplay, Win, revDefaultGC, XOff, YOff,
X                     left, h);
X               XSetForeground (mainDisplay, revDefaultGC, 1);
X               break;
X            case PAINT_NORM_INV_NORM:
X               left = XTextWidth (xfs, Str, FirstIndex);
X               right = XTextWidth (xfs, Str, SecondIndex);
X               XSetForeground (mainDisplay, revDefaultGC,
X                     xorColorPixels[ColorIndex]);
X               XFillRectangle (mainDisplay, Win, revDefaultGC, XOff+left, YOff,
X                     right-left, h);
X               XSetForeground (mainDisplay, revDefaultGC, 1);
X               break;
X         }
X      }
X      else if (w != 0)
X      {
X         if (w > textBackingPixmapSize || h > textBackingPixmapSize)
X         {
X            if (textBackingPixmapSize != INVALID)
X               XFreePixmap (mainDisplay, textBackingPixmap);
X
X            textBackingPixmap = XCreatePixmap (mainDisplay, mainWindow,
X                  max(w,h), max(w,h), mainDepth);
X            textBackingPixmapSize = max(w,h);
X         }
X         if (rotateGC == NULL)
X         {
X            values.foreground = 1;
X            values.background = 0;
X            values.fill_style = FillSolid;
X            values.function = GXcopy;
X            rotateGC = XCreateGC (mainDisplay, drawWindow,
X                  GCForeground | GCBackground | GCFillStyle | GCFunction,
X                  &values);
X         }
X
X         XSetForeground (mainDisplay, rotateGC, 0);
X         XFillRectangle (mainDisplay, textBackingPixmap, rotateGC, 0, 0, w, h);
X         XSetForeground (mainDisplay, rotateGC, 1);
X
X         XSetFont (mainDisplay, rotateGC, canvasFontPtr->fid);
X         XDrawString (mainDisplay, textBackingPixmap, rotateGC, 0,
X               canvasFontAsc, Str, len);
X         from_image = XGetImage (mainDisplay, textBackingPixmap, 0, 0, w, h, 1,
X               ZPixmap);
X
X         values.foreground = colorPixels[ColorIndex];
X         values.function = GXcopy;
X         values.fill_style = FillOpaqueStippled;
X         values.stipple = patPixmap[Pen];
X         values.line_width = 0;
X         XChangeGC (mainDisplay, gc, GCForeground | GCFunction | GCFillStyle |
X               GCStipple | GCLineWidth, &values);
X
X         switch (Rotate)
X         {
X            case ROTATE90:
X               for (i = 0; i < w; i++)
X                  for (j = 0; j < h; j++)
X                     if (XGetPixel (from_image, i, j) == 1)
X#ifdef sun
X                        XDrawPoint (mainDisplay, Win, gc, XOff-j, YOff+i);
X#else
X#ifdef ultrix
X                        XDrawPoint (mainDisplay, Win, gc, XOff-j, YOff+i);
X#else
X                        XDrawLine (mainDisplay, Win, gc, XOff-j, YOff+i,
X                              XOff-j, YOff+i);
X#endif
X#endif
X               break;
X            case ROTATE180:
X               for (i = 0; i < w; i++)
X                  for (j = 0; j < h; j++)
X                     if (XGetPixel (from_image, i, j) == 1)
X#ifdef sun
X                        XDrawPoint (mainDisplay, Win, gc, XOff-i, YOff-j);
X#else
X#ifdef ultrix
X                        XDrawPoint (mainDisplay, Win, gc, XOff-i, YOff-j);
X#else
X                        XDrawLine (mainDisplay, Win, gc, XOff-i, YOff-j,
X                              XOff-i, YOff-j);
X#endif
X#endif
X               break;
X            case ROTATE270:
X               for (i = 0; i < w; i++)
X                  for (j = 0; j < h; j++)
X                     if (XGetPixel (from_image, i, j) == 1)
X#ifdef sun
X                        XDrawPoint (mainDisplay, Win, gc, XOff+j, YOff-i);
X#else
X#ifdef ultrix
X                        XDrawPoint (mainDisplay, Win, gc, XOff+j, YOff-i);
X#else
X                        XDrawLine (mainDisplay, Win, gc, XOff+j, YOff-i,
X                              XOff+j, YOff-i);
X#endif
X#endif
X               break;
X         }
X
X         XDestroyImage (from_image);
X      }
X   }
X   else
X   {
X      values.foreground = myBgPixel;
X      values.function = GXcopy;
X      values.fill_style = FillSolid;
X      XChangeGC (mainDisplay, gc,
X            GCForeground | GCFunction | GCFillStyle, &values);
X
X      XFillRectangle (mainDisplay, Win, gc, XOff-1, YOff, w+1, h);
X   }
X}
X
Xstatic
Xvoid PaintCurText (Win, gc, Str, Just, XOff, YOff, xfs, ColorIndex, Pen,
X      Mode, FirstIndex, SecondIndex)
X   register int	XOff, YOff;
X   Window	Win;
X   GC		gc;
X   char		* Str;
X   int		Just, ColorIndex, Pen, Mode, FirstIndex, SecondIndex;
X   XFontStruct	* xfs;
X   /* XOff and YOff are UNSCALED screen offset */
X{
X   int		w, h, left, right, len;
X   XGCValues	values;
X
X   len = strlen (Str);
X
X   w = XTextWidth (xfs, Str, len);
X   h = canvasFontHeight;
X
X   switch (Just)
X   {
X      case JUST_L: break;
X      case JUST_C: XOff -= w/2; break;
X      case JUST_R: XOff -= w; break;
X   }
X
X   if (Mode & PAINT)
X   {
X      if (Pen == NONEPAT) return;
X
X      values.foreground = colorPixels[ColorIndex];
X      values.function = GXcopy;
X      values.fill_style = FillOpaqueStippled;
X      values.stipple = patPixmap[Pen];
X      XChangeGC (mainDisplay, gc,
X            GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
X      XDrawString (mainDisplay, Win, gc, XOff, YOff+canvasFontAsc, Str, len);
X
X      switch (Mode)
X      {
X         case PAINT_NORM: break;
X         case PAINT_INV:
X            XSetForeground (mainDisplay, revDefaultGC,
X                  xorColorPixels[ColorIndex]);
X            XFillRectangle (mainDisplay, Win, revDefaultGC, XOff, YOff,
X                  w, h);
X            XSetForeground (mainDisplay, revDefaultGC, 1);
X            break;
X         case PAINT_NORM_INV:
X            left = XTextWidth (xfs, Str, FirstIndex);
X            XSetForeground (mainDisplay, revDefaultGC,
X                  xorColorPixels[ColorIndex]);
X            XFillRectangle (mainDisplay, Win, revDefaultGC, XOff+left, YOff,
X                  w-left, h);
X            XSetForeground (mainDisplay, revDefaultGC, 1);
X            break;
X         case PAINT_INV_NORM:
X            left = XTextWidth (xfs, Str, FirstIndex);
X            XSetForeground (mainDisplay, revDefaultGC,
X                  xorColorPixels[ColorIndex]);
X            XFillRectangle (mainDisplay, Win, revDefaultGC, XOff, YOff,
X                  left, h);
X            XSetForeground (mainDisplay, revDefaultGC, 1);
X            break;
X         case PAINT_NORM_INV_NORM:
X            left = XTextWidth (xfs, Str, FirstIndex);
X            right = XTextWidth (xfs, Str, SecondIndex);
X            XSetForeground (mainDisplay, revDefaultGC,
X                  xorColorPixels[ColorIndex]);
X            XFillRectangle (mainDisplay, Win, revDefaultGC, XOff+left, YOff,
X                  right-left, h);
X            XSetForeground (mainDisplay, revDefaultGC, 1);
X            break;
X      }
X   }
X   else
X   {
X      values.foreground = myBgPixel;
X      values.function = GXcopy;
X      values.fill_style = FillSolid;
X      XChangeGC (mainDisplay, gc,
X            GCForeground | GCFunction | GCFillStyle, &values);
X
X      XFillRectangle (mainDisplay, Win, gc, XOff-1, YOff, w+1, h);
X   }
X}
X
Xvoid PutTextCursor ()
X{
X   XDrawLine (mainDisplay, drawWindow, defaultGC, textCurX,
X         textCurY, textCurX, textCurY+textCursorH);
X}
X
Xvoid EraseTextCursor ()
X{
X   XSetForeground (mainDisplay, revDefaultGC, myFgPixel^myBgPixel);
X   XDrawLine (mainDisplay, drawWindow, revDefaultGC, textCurX,
X         textCurY, textCurX, textCurY+textCursorH);
X   XSetForeground (mainDisplay, revDefaultGC, 1);
X}
X
Xvoid NewCurText ()
X{
X   struct TextRec	* text_ptr;
X
X   firstStr = lastStr = curStr =
X         (struct StrRec *) calloc (1, sizeof(struct StrRec));
X
X   text_ptr = (struct TextRec *) calloc (1, sizeof(struct TextRec));
X   text_ptr->font = curFont;
X   text_ptr->dpi = curFontDPI;
X   text_ptr->style = curStyle;
X   text_ptr->attr = NULL;
X   text_ptr->size = curSize;
X   text_ptr->just = textJust;
X   text_ptr->rotate = curRotate;
X   text_ptr->pen = penPat;
X   text_ptr->asc = canvasFontAsc;
X   text_ptr->des = canvasFontDes;
X   text_ptr->lines = 1;
X   text_ptr->first = firstStr;
X   text_ptr->last = lastStr;
X
X   curTextObj = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X   curTextObj->x = textAbsX;
X   curTextObj->y = textAbsY;
X   curTextObj->type = OBJ_TEXT;
X   curTextObj->color = colorIndex;
X   curTextObj->id = objId++;
X   curTextObj->dirty = FALSE;
X   curTextObj->detail.t = text_ptr;
X   curTextObj->fattr = curTextObj->lattr = NULL;
X   AddObj (NULL, topObj, curTextObj);
X
X   textW = 0;
X   textH = textCursorH;
X
X   textCursorShown = TRUE;
X   textHighlight = FALSE;
X}
X
Xvoid SetTextBBox (ObjPtr, Just, W, H, Rotate)
X   struct ObjRec	* ObjPtr;
X   int			Just, W, H, Rotate;
X{
X   register int	mw2, pw2;
X
X   switch (Just)
X   {
X      case JUST_L:
X         switch (Rotate)
X         {
X            case ROTATE0:
X               ObjPtr->obbox.ltx = ObjPtr->x; ObjPtr->obbox.rbx = ObjPtr->x+W;
X               ObjPtr->obbox.lty = ObjPtr->y; ObjPtr->obbox.rby = ObjPtr->y+H;
X               break;
X            case ROTATE90:
X               ObjPtr->obbox.ltx = ObjPtr->x-H; ObjPtr->obbox.rbx = ObjPtr->x;
X               ObjPtr->obbox.lty = ObjPtr->y; ObjPtr->obbox.rby = ObjPtr->y+W;
X               break;
X            case ROTATE180:
X               ObjPtr->obbox.ltx = ObjPtr->x-W; ObjPtr->obbox.rbx = ObjPtr->x;
X               ObjPtr->obbox.lty = ObjPtr->y-H; ObjPtr->obbox.rby = ObjPtr->y;
X               break;
X            case ROTATE270:
X               ObjPtr->obbox.ltx = ObjPtr->x; ObjPtr->obbox.rbx = ObjPtr->x+H;
X               ObjPtr->obbox.lty = ObjPtr->y-W; ObjPtr->obbox.rby = ObjPtr->y;
X               break;
X         }
X         break;
X      case JUST_C:
X         mw2 = W/2;
X         pw2 = W-W/2;
X         switch (Rotate)
X         {
X            case ROTATE0:
X               ObjPtr->obbox.ltx = ObjPtr->x-mw2;
X               ObjPtr->obbox.rbx = ObjPtr->x+pw2;
X               ObjPtr->obbox.lty = ObjPtr->y; ObjPtr->obbox.rby = ObjPtr->y+H;
X               break;
X            case ROTATE90:
X               ObjPtr->obbox.ltx = ObjPtr->x-H;
X               ObjPtr->obbox.rbx = ObjPtr->x;
X               ObjPtr->obbox.lty = ObjPtr->y-mw2;
X               ObjPtr->obbox.rby = ObjPtr->y+pw2;
X               break;
X            case ROTATE180:
X               ObjPtr->obbox.ltx = ObjPtr->x-pw2;
X               ObjPtr->obbox.rbx = ObjPtr->x+mw2;
X               ObjPtr->obbox.lty = ObjPtr->y-H;
X               ObjPtr->obbox.rby = ObjPtr->y;
X               break;
X            case ROTATE270:
X               ObjPtr->obbox.ltx = ObjPtr->x;
X               ObjPtr->obbox.rbx = ObjPtr->x+H;
X               ObjPtr->obbox.lty = ObjPtr->y-pw2;
X               ObjPtr->obbox.rby = ObjPtr->y+mw2;
X               break;
X         }
X         break;
X      case JUST_R:
X         switch (Rotate)
X         {
X            case ROTATE0:
X               ObjPtr->obbox.ltx = ObjPtr->x-W; ObjPtr->obbox.rbx = ObjPtr->x;
X               ObjPtr->obbox.lty = ObjPtr->y; ObjPtr->obbox.rby = ObjPtr->y+H;
X               break;
X            case ROTATE90:
X               ObjPtr->obbox.ltx = ObjPtr->x-H; ObjPtr->obbox.rbx = ObjPtr->x;
X               ObjPtr->obbox.lty = ObjPtr->y-W; ObjPtr->obbox.rby = ObjPtr->y;
X               break;
X            case ROTATE180:
X               ObjPtr->obbox.ltx = ObjPtr->x; ObjPtr->obbox.rbx = ObjPtr->x+W;
X               ObjPtr->obbox.lty = ObjPtr->y-H; ObjPtr->obbox.rby = ObjPtr->y;
X               break;
X            case ROTATE270:
X               ObjPtr->obbox.ltx = ObjPtr->x; ObjPtr->obbox.rbx = ObjPtr->x+H;
X               ObjPtr->obbox.lty = ObjPtr->y; ObjPtr->obbox.rby = ObjPtr->y+W;
X               break;
X         }
X         break;
X   }
X   ObjPtr->bbox.ltx = ObjPtr->obbox.ltx - 2;
X   ObjPtr->bbox.rbx = ObjPtr->obbox.rbx + 2;
X   ObjPtr->bbox.lty = ObjPtr->obbox.lty - 2;
X   ObjPtr->bbox.rby = ObjPtr->obbox.rby + 2;
X}
X
Xvoid UpdTextBBox (ObjPtr)
X   struct ObjRec	* ObjPtr;
X{
X   register int		num_lines;
X   struct StrRec	* s_ptr = ObjPtr->detail.t->first;
X   int			max_len = 0, w;
X
X   SaveCurFont ();
X   curFont = ObjPtr->detail.t->font;
X   curFontDPI = ObjPtr->detail.t->dpi;
X   curStyle = ObjPtr->detail.t->style;
X   curSize = ObjPtr->detail.t->size;
X   textJust = ObjPtr->detail.t->just;
X   SetCanvasFont ();
X
X   for (num_lines = 0; s_ptr != NULL; s_ptr = s_ptr->next, num_lines++)
X   {
X      w = XTextWidth (canvasFontPtr, s_ptr->s, strlen (s_ptr->s));
X      if (w > max_len) max_len = w;
X   }
X
X   ObjPtr->detail.t->asc = canvasFontAsc;
X   ObjPtr->detail.t->des = canvasFontDes;
X
X   SetTextBBox (ObjPtr, textJust, max_len, num_lines*textCursorH,
X         ObjPtr->detail.t->rotate);
X
X   RestoreCurFont ();
X}
X
Xvoid FreeTextObj (ObjPtr)
X   struct ObjRec	* ObjPtr;
X{
X   register struct StrRec	* s_ptr;
X
X   for (s_ptr = ObjPtr->detail.t->first; s_ptr != NULL; s_ptr = s_ptr->next)
X      cfree (s_ptr);
X
X   cfree (ObjPtr->detail.t);
X   cfree (ObjPtr);
X}
X
Xint CreateTextObj ()
X   /* returns TRUE if something got created */
X   /* returns FALSE otherwise */
X{
X   register int		i;
X   struct StrRec	* s_ptr;
X   struct AttrRec	* attr_ptr;
X   int			max_len = 0, w = 0, ltx = 0, lty = 0, rbx = 0, rby = 0;
X   int			scr_ltx = 0, scr_lty = 0;
X
X   if (!textCursorShown) return (FALSE);
X   EraseTextCursor ();
X
X   if (firstStr == lastStr && curStr->s[0] == '\0')
X   {  /* no text entered or all text erased */
X      if ((attr_ptr = curTextObj->detail.t->attr) != NULL)
X      {  /* the text being edited is an attribute */
X         if (attr_ptr->nameshown)
X         {
X            UnlinkAttr (attr_ptr);
X            FreeTextObj (curTextObj);
X            FreeAttr (attr_ptr);
X         }
X         else
X            UpdateAttr(curTextObj->detail.t, attr_ptr);
X
X         AdjObjBBox (attr_ptr->owner);
X      }
X      else
X         DelObj (curTextObj);
X
X      switch (textJust)
X      {
X         case JUST_L: scr_ltx = OFFSET_X(textAbsX)-2; break;
X         case JUST_C: scr_ltx = OFFSET_X(textAbsX)-textW/2-2; break;
X         case JUST_R: scr_ltx = OFFSET_X(textAbsX)-textW-2; break;
X      }
X      scr_lty = OFFSET_Y(textAbsY)-2;
X
X      ltx = (scr_ltx<<zoomScale)+drawOrigX;
X      lty = (scr_lty<<zoomScale)+drawOrigY;
X      rbx = ltx+((textW+5)<<zoomScale);
X      rby = lty+((textH+5)<<zoomScale);
X
X      if (editingText)
X      {
X         XClearArea (mainDisplay, drawWindow, scr_ltx, scr_lty,
X               textW+5, textH+5, FALSE);
X         RedrawAreas (botObj, savedTextLtX-(1<<zoomScale),
X               savedTextLtY-(1<<zoomScale), savedTextRbX+(1<<zoomScale),
X               savedTextRbY+(1<<zoomScale), ltx, lty, rbx, rby);
X      }
X      else
X         RedrawAnArea (botObj, ltx, lty, rbx, rby);
X
X      firstStr = lastStr = curStr = NULL;
X      textCursorShown = FALSE;
X      curTextObj = NULL;
X      if (editingText)
X      {
X         PopCurFont ();
X         ShowJust ();
X         ShowColor (FALSE);
X         ShowCurFont ();
X         editingText = FALSE;
X      }
X      textDrawn = FALSE;
X      justDrawnTextObj = NULL;
X      textHighlight = FALSE;
X      return (FALSE);
X   }
X
X   for (s_ptr = firstStr, i = 0; s_ptr != NULL; s_ptr = s_ptr->next, i++)
X   {
X      w = XTextWidth (canvasFontPtr, s_ptr->s, strlen (s_ptr->s));
X      if (w > max_len) max_len = w;
X   }
X
X   curTextObj->detail.t->last = lastStr;
X   curTextObj->detail.t->lines = i;
X
X   curTextObj->x = textAbsX-tmpAdjX;
X   curTextObj->y = textAbsY-tmpAdjY;
X
X   SetTextBBox (curTextObj, textJust, max_len, i*textCursorH, curRotate);
X
X   switch (textJust)
X   {
X      case JUST_L: scr_ltx = OFFSET_X(textAbsX)-2; break;
X      case JUST_C: scr_ltx = OFFSET_X(textAbsX)-textW/2-2; break;
X      case JUST_R: scr_ltx = OFFSET_X(textAbsX)-textW-2; break;
X   }
X   scr_lty = OFFSET_Y(textAbsY)-2;
X
X   ltx = (scr_ltx<<zoomScale)+drawOrigX;
X   lty = (scr_lty<<zoomScale)+drawOrigY;
X   rbx = ltx+((textW+5)<<zoomScale);
X   rby = lty+((textH+5)<<zoomScale);
X
X   if ((attr_ptr = curTextObj->detail.t->attr) != NULL)
X   {
X      UpdateAttr(curTextObj->detail.t, attr_ptr);
X      textDrawn = FALSE;
X      justDrawnTextObj = NULL;
X      AdjObjBBox (attr_ptr->owner);
X   }
X   else
X   {
X      textDrawn = TRUE;
X      justDrawnTextObj = curTextObj;
X   }
X
X   firstStr = lastStr = curStr = NULL;
X   textCursorShown = FALSE;
X   textCurIndex = 0;
X
X   if (editingText)
X   {
X      XClearArea (mainDisplay, drawWindow, scr_ltx, scr_lty,
X            textW+5, textH+5, FALSE);
X      RedrawAreas (botObj, savedTextLtX-(1<<zoomScale),
X            savedTextLtY-(1<<zoomScale), savedTextRbX+(1<<zoomScale),
X            savedTextRbY+(1<<zoomScale), ltx, lty, rbx, rby);
X      if (curRotate != ROTATE0)
X         DrawTextObj (drawWindow, drawOrigX, drawOrigY, curTextObj);
X   }
X   else
X   {
X      RedrawAnArea (botObj, ltx, lty, rbx, rby);
X      if (curRotate != ROTATE0)
X         DrawTextObj (drawWindow, drawOrigX, drawOrigY, curTextObj);
X   }
X
X   textOrigX = textOrigY = textCurX = textCurY = 20<<zoomScale;
X   curStrW = 0;
X   textW = textH = 0;
X   textCurIndex = 0;
X   textAbsX = textOrigX + drawOrigX;
X   textAbsY = textOrigY + drawOrigY;
X   curTextObj = NULL;
X
X   if (editingText)
X   {
X      PopCurFont ();
X      ShowJust ();
X      ShowColor (FALSE);
X      ShowCurFont ();
X      editingText = FALSE;
X   }
X   textHighlight = FALSE;
X   return (TRUE);
X}
X
Xvoid HighLightJustDrawnText ()
X{
X   AddNewSelObj (justDrawnTextObj);
X   UpdSelBBox ();
X   HighLightAnObj (justDrawnTextObj);
X   justDupped = FALSE;
X}
X
Xstatic
Xstruct ObjRec * FindTextObj (X, Y)
X   int  X, Y;
X   /* X and Y are absolute coordinates */
X{
X   register struct ObjRec       * obj_ptr;
X   register struct AttrRec      * attr_ptr;
X
X   for (obj_ptr = topObj; obj_ptr != NULL; obj_ptr = obj_ptr->next)
X      if (obj_ptr->type == OBJ_TEXT &&
X            X >= obj_ptr->bbox.ltx && X <= obj_ptr->bbox.rbx &&
X            Y >= obj_ptr->bbox.lty && Y <= obj_ptr->bbox.rby)
X         return (obj_ptr);
X      else
X      {
X         attr_ptr = obj_ptr->fattr;
X         for (; attr_ptr != NULL;  attr_ptr = attr_ptr->next)
X            if (X>=attr_ptr->obj->bbox.ltx && X<=attr_ptr->obj->bbox.rbx &&
X                  Y>=attr_ptr->obj->bbox.lty && Y<=attr_ptr->obj->bbox.rby &&
X                  attr_ptr->shown == TRUE)
X               return (attr_ptr->obj);
X      }
X   return (NULL);
X}
X
Xstatic
Xvoid SetTextCurX ()
X   /* set textCurX according to textCurIndex */
X{
X   register int	left = 0, w;
X   char		s[MAXSTRING+1];
X
X   strcpy (s, curStr->s);
X   s[textCurIndex] = '\0';
X
X   w = XTextWidth (canvasFontPtr, s, strlen (s));
X
X   switch (textJust)
X   {
X      case JUST_L: left = textOrigX; break;
X      case JUST_C: left = textOrigX-curStrW/2; break;
X      case JUST_R: left = textOrigX-curStrW; break;
X   }
X   textCurX = left + w;
X}
X
Xstatic
Xvoid HandleButton (Button_Ev)
X   XButtonEvent	* Button_Ev;
X{
X   int			grid_x, grid_y, x_off, y_off, amount, dx, dy;
X   int                  left, pressed_in_same_text = FALSE, x = 0;
X   int                  abs_x, abs_y, tmp_x, tmp_y;
X   struct ObjRec	* obj_ptr = NULL;
X   struct AttrRec       * attr_ptr;
X   char			* c_ptr, s[2];
X
X   if (Button_Ev->button == Button1)
X   {
X      x_off = Button_Ev->x; abs_x = (x_off<<zoomScale) + drawOrigX;
X      y_off = Button_Ev->y; abs_y = (y_off<<zoomScale) + drawOrigY;
X
X      if (textCursorShown)
X      {
X         switch (textJust)
X         {
X            case JUST_L: x = textOrigX-2; break;
X            case JUST_C: x = textOrigX-textW/2-2; break;
X            case JUST_R: x = textOrigX-textW-2; break;
X         }
X         if (x_off >= x && x_off <= x+textW+4 &&
X               y_off >= textOrigY-2 && y_off <= textOrigY+textH+2)
X            pressed_in_same_text = TRUE;
X         else
X            CreateTextObj (); /* end editing on the old text */
X      }
X      else
X         editingText = FALSE;
X
X      if (!pressed_in_same_text &&
X            (obj_ptr = FindTextObj (abs_x, abs_y)) == NULL)
X      {  /* cursor not within any existing text object */
X         GridXY (x_off, y_off, &grid_x, &grid_y);
X
X         textOrigX = textCurX = grid_x;
X         textOrigY = textCurY = grid_y;
X         textAbsX = (grid_x<<zoomScale) + drawOrigX;
X         textAbsY = (grid_y<<zoomScale) + drawOrigY;
X         tmpAdjX = tmpAdjY = 0;
X         NewCurText ();
X         RedrawCurText ();
X      }
X      else
X      {  /* cursor inside an existing text object */
X         if (pressed_in_same_text)
X         {
X            obj_ptr = curTextObj;
X            curStr = obj_ptr->detail.t->first;
X         }
X         else
X         {
X            curTextObj = obj_ptr;
X            savedTextLtX = obj_ptr->bbox.ltx;
X            savedTextLtY = obj_ptr->bbox.lty;
X            savedTextRbX = obj_ptr->bbox.rbx;
X            savedTextRbY = obj_ptr->bbox.rby;
X
X            PushCurFont ();
X            editingText = TRUE;
X
X            curFont = obj_ptr->detail.t->font;
X            curFontDPI = obj_ptr->detail.t->dpi;
X            curStyle = obj_ptr->detail.t->style;
X            curSize = obj_ptr->detail.t->size;
X            textJust = obj_ptr->detail.t->just;
X            curRotate = obj_ptr->detail.t->rotate;
X            penPat = obj_ptr->detail.t->pen;
X            SetCanvasFont ();
X            ShowJust ();
X            ShowPen ();
X            colorIndex = obj_ptr->color;
X            ShowColor (FALSE);
X            ShowCurFont ();
X
X            firstStr = curStr = obj_ptr->detail.t->first;
X            lastStr = obj_ptr->detail.t->last;
X
X            textAbsX = obj_ptr->x;
X            textAbsY = obj_ptr->y;
X            textOrigX = OFFSET_X(obj_ptr->x);
X            textOrigY = OFFSET_Y(obj_ptr->y);
X
X            switch (curRotate)
X            {
X               case ROTATE0:
X                  textW = obj_ptr->obbox.rbx - obj_ptr->obbox.ltx;
X                  textH = obj_ptr->obbox.rby - obj_ptr->obbox.lty;
X                  switch (textJust)
X                  {
X                     case JUST_L: tmpAdjX = (textW-(textW<<zoomScale))/2; break;
X                     case JUST_C: tmpAdjX = 0; break;
X                     case JUST_R: tmpAdjX = ((textW<<zoomScale)-textW)/2; break;
X                  }
X                  tmpAdjY = (textH-(textH<<zoomScale))/2;
X                  break;
X               case ROTATE90:
X                  dx = textAbsX - abs_x;
X                  dy = textAbsY - abs_y;
X                  abs_x = textAbsX - dy;
X                  abs_y = textAbsY + dx;
X                  textW = obj_ptr->obbox.rby - obj_ptr->obbox.lty;
X                  textH = obj_ptr->obbox.rbx - obj_ptr->obbox.ltx;
X                  switch (textJust)
X                  {
X                     case JUST_L:
X                        tmpAdjX = -((textW<<zoomScale)+textH)/2;
X                        tmpAdjY = (textW-(textH<<zoomScale))/2;
X                        break;
X                     case JUST_C:
X                        tmpAdjX = -textH/2;
X                        tmpAdjY = -(textH<<zoomScale)/2;
X                        break;
X                     case JUST_R:
X                        tmpAdjX = ((textW<<zoomScale)-textH)/2;
X                        tmpAdjY = -(textW+(textH<<zoomScale))/2;
X                        break;
X                  }
X                  break;
X               case ROTATE180:
X                  abs_x = 2*textAbsX - abs_x;
X                  abs_y = 2*textAbsY - abs_y;
X                  textW = obj_ptr->obbox.rbx - obj_ptr->obbox.ltx;
X                  textH = obj_ptr->obbox.rby - obj_ptr->obbox.lty;
X                  switch (textJust)
X                  {
X                     case JUST_L: tmpAdjX = -(textW+(textW<<zoomScale))/2; break;
X                     case JUST_C: tmpAdjX = 0; break;
X                     case JUST_R: tmpAdjX = (textW+(textW<<zoomScale))/2; break;
X                  }
X                  tmpAdjY = -(textH+(textH<<zoomScale))/2;
X                  break;
X               case ROTATE270:
X                  dx = textAbsX - abs_x;
X                  dy = textAbsY - abs_y;
X                  abs_x = textAbsX + dy;
X                  abs_y = textAbsY - dx;
X                  textW = obj_ptr->obbox.rby - obj_ptr->obbox.lty;
X                  textH = obj_ptr->obbox.rbx - obj_ptr->obbox.ltx;
X                  switch (textJust)
X                  {
X                     case JUST_L:
X                        tmpAdjX = -((textW<<zoomScale)-textH)/2;
X                        tmpAdjY = -(textW+(textH<<zoomScale))/2;
X                        break;
X                     case JUST_C:
X                        tmpAdjX = textH/2;
X                        tmpAdjY = -(textH<<zoomScale)/2;
X                        break;
X                     case JUST_R:
X                        tmpAdjX = ((textW<<zoomScale)+textH)/2;
X                        tmpAdjY = (textW-(textH<<zoomScale))/2;
X                        break;
X                  }
X                  break;
X            }
X            textAbsX += tmpAdjX; textOrigX = OFFSET_X(textAbsX);
X            textAbsY += tmpAdjY; textOrigY = OFFSET_Y(textAbsY);
X            abs_x += tmpAdjX; x_off = OFFSET_X(abs_x);
X            abs_y += tmpAdjY; y_off = OFFSET_Y(abs_y);
X         }
X
X         textCurY = textOrigY;
X         if (pressed_in_same_text)
X         {
X            while (y_off >= textCurY+textCursorH && curStr->next != NULL)
X            {
X               textCurY += textCursorH;
X               curStr = curStr->next;
X            }
X         }
X         else
X         {
X            tmp_y = textAbsY;
X            while ((y_off<<zoomScale)+drawOrigY >= tmp_y+textCursorH &&
X                  curStr->next != NULL)
X            {
X               textCurY += textCursorH;
X               tmp_y += textCursorH;
X               curStr = curStr->next;
X            }
X         }
X
X         curStrW = amount = XTextWidth (canvasFontPtr, curStr->s,
X               strlen (curStr->s));
X
X         textCurIndex = 0;
X         textCurX = textOrigX;
X
X         switch (textJust)
X         {
X            case JUST_L: break;
X            case JUST_C: textCurX -= (amount/2); break;
X            case JUST_R: textCurX -= amount; break;
X         }
X         left = textCurX;
X
X         s[1] = '\0';
X         c_ptr = curStr->s;
X         if (pressed_in_same_text)
X         {
X            for ( ; *c_ptr != '\0'; c_ptr++)
X            {
X               s[0] = *c_ptr;
X               amount = XTextWidth (canvasFontPtr, s, 1);
X
X               if (x_off < textCurX+amount/2)
X                  break;
X               else
X                  textCurX += amount;
X               textCurIndex++;
X            }
X         }
X         else
X         {
X            tmp_x = textAbsX;
X            switch (textJust)
X            {
X               case JUST_L: break;
X               case JUST_C: tmp_x -= (amount/2); break;
X               case JUST_R: tmp_x -= amount; break;
X            }
X
X            for ( ; *c_ptr != '\0'; c_ptr++)
X            {
X               s[0] = *c_ptr;
X               amount = XTextWidth (canvasFontPtr, s, 1);
X
X               if ((x_off<<zoomScale)+drawOrigX < tmp_x+amount/2)
X                  break;
X               else
X               {
X                  textCurX += amount;
X                  tmp_x += amount;
X               }
X               textCurIndex++;
X            }
X         }
X
X         attr_ptr = obj_ptr->detail.t->attr;
X         if (attr_ptr != NULL && attr_ptr->inherited && textCurY == textOrigY &&
X               attr_ptr->shown && attr_ptr->nameshown &&
X               textCurIndex < strlen (attr_ptr->name))
X         {  /* clicked in the name of an inherited attribute */
X            textCurIndex = strlen (attr_ptr->name);
X            textCurX = left + XTextWidth (canvasFontPtr, attr_ptr->name,
X                  textCurIndex);
X         }
X         textCursorShown = TRUE;
X         textHighlight = FALSE;
X         RedrawCurText ();
X      }
X   }
X   else if (Button_Ev->button == Button2)
X   {
X      if (!textCursorShown) return;
X
X      x_off = Button_Ev->x; abs_x = (x_off<<zoomScale) + drawOrigX;
X      y_off = Button_Ev->y; abs_y = (y_off<<zoomScale) + drawOrigY;
X
X      switch (textJust)
X      {
X         case JUST_L: x = textOrigX-2; break;
X         case JUST_C: x = textOrigX-textW/2-2; break;
X         case JUST_R: x = textOrigX-textW-2; break;
X      }
X
X      if (!(x_off >= x && x_off <= x+textW+2 &&
X            y_off >= textOrigY-2 && y_off <= textOrigY+textH+2))
X         return;
X
X      obj_ptr = curTextObj;
X      endStr = obj_ptr->detail.t->first;
X
X      textEndY = textOrigY;
X      while (y_off >= textEndY+textCursorH && endStr->next != NULL)
X      {
X         textEndY += textCursorH;
X         endStr = endStr->next;
X      }
X
X      endStrW = amount = XTextWidth (canvasFontPtr, endStr->s,
X            strlen (endStr->s));
X
X      textEndX = textOrigX;
X      switch (textJust)
X      {
X         case JUST_L: break;
X         case JUST_C: textEndX -= (amount/2); break;
X         case JUST_R: textEndX -= amount; break;
X      }
X      textEndIndex = 0;
X      left = textEndX;
X
X      s[1] = '\0';
X      c_ptr = endStr->s;
X      for ( ; *c_ptr != '\0'; c_ptr++)
X      {
X         s[0] = *c_ptr;
X         amount = XTextWidth (canvasFontPtr, s, 1);
X
X         if (x_off < textEndX+amount/2)
X            break;
X         else
X            textEndX += amount;
X         textEndIndex++;
X      }
X
X      attr_ptr = obj_ptr->detail.t->attr;
X      if (attr_ptr != NULL && attr_ptr->inherited && textEndY == textOrigY &&
X            attr_ptr->shown && attr_ptr->nameshown &&
X            textEndIndex < strlen (attr_ptr->name))
X      {
X         textEndIndex = strlen (attr_ptr->name);
X         textEndX = left + XTextWidth (canvasFontPtr, attr_ptr->name,
X               textEndIndex);
X      }
X      textHighlight = !(endStr == curStr && textEndIndex == textCurIndex);
X      RedrawCurText ();
X   }
X}
X
Xstatic
Xint NumLines ()
X{
X   register struct StrRec	* str_ptr;
X   register int			i = 0;
X
X   for (str_ptr = firstStr; str_ptr != NULL; str_ptr = str_ptr->next, i++) ;
X   return (i);
X}
X
Xstatic
Xvoid DeleteHighlightedText ()
X{
X   struct StrRec	* s_ptr, * s_ptr1, * new_cur_str = NULL;
X   int			highlighting = FALSE, new_cur_index = 0;
X   int			second_index, len;
X   int			i, y, new_cur_y = 0, len1, len2;
X   char			* s, msg[80];
X
X   if (!textHighlight) return;
X
X   y = textOrigY;
X   for (s_ptr = firstStr; s_ptr != NULL; y += textCursorH)
X   {
X      if (highlighting)
X      {  /* started deleting already */
X         if (s_ptr == curStr || s_ptr == endStr)
X         {
X            second_index = (s_ptr == curStr) ? textCurIndex : textEndIndex;
X            len1 = strlen (new_cur_str->s);
X            len2 = strlen (&(s_ptr->s[second_index]));
X            if (len1+len2 >= MAXSTRING)
X            {
X               sprintf (msg, "String length exceeds %1d.  String truncated.",
X                     MAXSTRING);
X               Msg (msg);
X               s_ptr->s[MAXSTRING-len1+second_index] = '\0';
X            }
X            strcat (new_cur_str->s, &(s_ptr->s[second_index]));
X            if (s_ptr == lastStr)
X               lastStr = s_ptr->prev;
X            else
X               s_ptr->next->prev = s_ptr->prev;
X            s_ptr->prev->next = s_ptr->next;
X            cfree (s_ptr);
X            break;
X         }
X         else
X         {  /* delete the whole line */
X            s_ptr1 = s_ptr->next;
X            s_ptr1->prev = s_ptr->prev;
X            cfree (s_ptr);
X            s_ptr = s_ptr1;
X         }
X      }
X      else
X      {  /* looking for the beginning ... */
X         if (s_ptr == curStr && s_ptr == endStr)
X         {  /* the whole string to be deleted is within s_ptr */
X            new_cur_str = s_ptr;
X            new_cur_index = min(textCurIndex,textEndIndex);
X            new_cur_y = y;
X            second_index = max(textCurIndex,textEndIndex);
X            s = new_cur_str->s;
X            len = strlen (&(s[second_index]));
X            for (i = 0; i <= len; i++) s[new_cur_index+i] = s[second_index+i];
X            break;
X         }
X         else if (s_ptr == curStr || s_ptr == endStr)
X         {  /* found the beginning */
X            new_cur_str = s_ptr;
X            new_cur_index = (s_ptr == curStr) ? textCurIndex : textEndIndex;
X            new_cur_y = y;
X            s_ptr->s[new_cur_index] = '\0';
X            highlighting = TRUE;
X            s_ptr = s_ptr->next;
X         }
X         else
X         {  /* still looking */
X            s_ptr = s_ptr->next;
X         }
X      }
X   }
X   textHighlight = FALSE;
X   curStr = new_cur_str;
X   textCurIndex = new_cur_index;
X   curStrW = XTextWidth (canvasFontPtr, curStr->s, strlen (curStr->s));
X   if (curStrW > textW) textW = curStrW;
X   textCurY = new_cur_y;
X   SetTextCurX ();
X}
X
Xstatic
Xvoid HandleCRLF (ColorIndex)
X   int	ColorIndex;
X{
X   register int		i, y;
X   struct StrRec	* str_ptr;
X   int			need_redraw = textHighlight;
X
X   if (textHighlight) DeleteHighlightedText ();
X
X   y = textCurY;
X   for (str_ptr = curStr; str_ptr != NULL; str_ptr = str_ptr->next)
X   {
X      PaintCurText (drawWindow, drawGC, str_ptr->s, textJust, textOrigX,
X            y, canvasFontPtr, ColorIndex, penPat, ERASE, INVALID, INVALID);
X      y += textCursorH;
X   }
X
X   str_ptr = (struct StrRec *) calloc (1, sizeof(struct StrRec));
X   strcpy (str_ptr->s, &curStr->s[textCurIndex]);
X   curStr->s[textCurIndex] = '\0';
X   AddStr (curStr, curStr->next, str_ptr);
X   curStr = str_ptr;
X   textCurY += textCursorH;
X   textCurIndex = 0;
X   curStrW = XTextWidth (canvasFontPtr, curStr->s, strlen (curStr->s));
X   SetTextCurX ();
X   i = textCursorH * NumLines ();
X   if (i > textH)
X   {
X      textH = i;
X      RedrawCurText ();
X   }
X   else if (need_redraw)
X      RedrawCurText ();
X   else
X   {
X      y = textCurY - textCursorH;
X      for (str_ptr = curStr->prev; str_ptr != NULL; str_ptr = str_ptr->next)
X      {
X         PaintCurText (drawWindow, drawGC, str_ptr->s, textJust,
X               textOrigX, y, canvasFontPtr, ColorIndex, penPat, PAINT_NORM,
X               INVALID, INVALID);
X         y += textCursorH;
X      }
X   }
X}
X
Xstatic
Xvoid HandleBS (ColorIndex)
X   int	ColorIndex;
X{
X   register int		i, y;
X   register char	* s;
X   struct StrRec	* str_ptr;
X   struct AttrRec       * attr_ptr;
X   int			len1, len2;
X   char			msg[80];
X
X   if (textHighlight)
X   {
X      DeleteHighlightedText ();
X      RedrawCurText ();
X      return;
X   }
X
X   attr_ptr = curTextObj->detail.t->attr;
X   if (firstStr == lastStr && attr_ptr != NULL && attr_ptr->inherited &&
X         attr_ptr->nameshown && textCurIndex == strlen(attr_ptr->name))
X      return;
X   else
X   {
X      if (textCurIndex != 0)
X      {
X         PaintCurText (drawWindow, drawGC, curStr->s, textJust,
X               textOrigX, textCurY, canvasFontPtr, ColorIndex, penPat, ERASE,
X               INVALID, INVALID);
X
X         s = curStr->s;
X         for (i = textCurIndex; i <= strlen (curStr->s); i++) s[i-1] = s[i];
X            textCurIndex--;
X
X         curStrW = XTextWidth (canvasFontPtr, curStr->s, strlen (curStr->s));
X         PaintCurText (drawWindow, drawGC, curStr->s, textJust, textOrigX,
X               textCurY, canvasFontPtr, ColorIndex, penPat, PAINT_NORM,
X               INVALID, INVALID);
X         SetTextCurX ();
X      }
X      else
X      {
X         if (curStr->prev != NULL)
X         {
X            y = textCurY - textCursorH;
X            for (str_ptr=curStr->prev; str_ptr!=NULL; str_ptr=str_ptr->next)
X            {
X               PaintCurText (drawWindow, drawGC, str_ptr->s, textJust,
X                     textOrigX, y, canvasFontPtr, ColorIndex, penPat, ERASE,
X                     INVALID, INVALID);
X               y += textCursorH;
X            }
X
X            if (curStr->next == NULL)
X               lastStr = curStr->prev;
X            else
X               curStr->next->prev = curStr->prev;
X            curStr->prev->next = curStr->next;
X            textCurIndex = strlen (curStr->prev->s);
X            len1 = strlen (curStr->prev->s);
X            len2 = strlen (curStr->s);
X            if (len1+len2 >= MAXSTRING)
X            {
X               sprintf (msg, "String length exceeds %1d.  String truncated.",
X                     MAXSTRING);
X               Msg (msg);
X               curStr->s[MAXSTRING-len1] = '\0';
X            }
X            strcat (curStr->prev->s, curStr->s);
X            cfree (curStr);
X            curStr = curStr->prev;
X            curStrW = XTextWidth (canvasFontPtr, curStr->s, strlen (curStr->s));
X            textCurY -= textCursorH;
X            SetTextCurX ();
X
X            y = textCurY;
X            for (str_ptr = curStr; str_ptr != NULL; str_ptr = str_ptr->next)
X            {
X               PaintCurText (drawWindow, drawGC, str_ptr->s, textJust,
X                     textOrigX, y, canvasFontPtr, ColorIndex, penPat,
X                     PAINT_NORM, INVALID, INVALID);
X               y += textCursorH;
X            }
X            if (curStrW > textW)
X            {
X               textW = curStrW;
X               RedrawCurText ();
X            }
X         }
X      }
X   }
X}
X
Xstatic
Xvoid HandleChar (Str, ColorIndex)
X   char	* Str;
X   int	ColorIndex;
X{
X   register int		i;
X   register char	* s;
X   register int		amount;
X   int			need_redraw;
X   char			msg[80];
X   XEvent		ev;
X
X   if (need_redraw = textHighlight) DeleteHighlightedText ();
X
X   if (textCurIndex+strlen (&(curStr->s[textCurIndex])) >= MAXSTRING)
X   {
X      sprintf (msg, "String length exceeds %1d.  Character ignored.",MAXSTRING);
X      Msg (msg);
X      RedrawCurText ();
X      while (XCheckWindowEvent (mainDisplay, drawWindow, KeyPressMask, &ev)) ;
X      return;
X   }
X
X   amount = XTextWidth (canvasFontPtr, Str, 1);
X 
X   if (textJust != JUST_L || textCurIndex != strlen (curStr->s))
X      PaintCurText (drawWindow, drawGC, curStr->s, textJust, textOrigX,
X            textCurY, canvasFontPtr, ColorIndex, penPat, ERASE,
X            INVALID, INVALID);
X
X   s = curStr->s;
X   for (i = strlen (curStr->s); i >= textCurIndex; i--) s[i+1] = s[i];
X   s[textCurIndex++] = *Str;
X
X   curStrW += amount;
X   if (!need_redraw)
X      PaintCurText (drawWindow, drawGC, curStr->s, textJust, textOrigX,
X            textCurY, canvasFontPtr, ColorIndex, penPat, PAINT_NORM,
X            INVALID, INVALID);
X   SetTextCurX ();
X   if (curStrW > textW)
X   {
X      textW = curStrW;
X      RedrawCurText ();
X   }
X   else if (need_redraw)
X      RedrawCurText ();
X}
X 
Xvoid DrawText (input)
X   XEvent	* input;
X{
X   char			s[80];
X   XKeyEvent		* key_ev;
X   KeySym		key_sym;
X   XComposeStatus	c_stat;
X
X   if (input->type == ButtonPress)
X      HandleButton (&(input->xbutton));
X   else if (input->type == KeyPress)
X   {
X      if (!textCursorShown) return;
X
X      key_ev = &(input->xkey);
X      XLookupString (key_ev, s, 80, &key_sym, &c_stat);
X
X      if (!((s[0]=='\r' && (key_sym & 0xff)=='\r') ||
X            (s[0]=='\n' && (key_sym & 0xff)=='\n') ||
X            (s[0]=='\b' && (key_sym & 0xff)=='\b') ||
X            (s[0]=='\b' && (key_sym & 0xff)=='h' &&
X            (key_ev->state & ControlMask)) ||
X            (s[0]=='\177' && (key_sym & 0x7f)=='\177') ||
X            (key_sym>='\040' && key_sym<='\177')))
X         return;
X
X      EraseTextCursor ();
X      s[1] = '\0';
X      switch (s[0])
X      {
X         case '\r':
X         case '\n': HandleCRLF (colorIndex); break;
X
X         case '\177': /* <DEL> */
X         case '\b': HandleBS (colorIndex); break;
X
X         default:
X            HandleChar (s, colorIndex);
X            break;
X      }
X      PutTextCursor ();
X      MarkRulers (textCurX>>zoomScale, textCurY>>zoomScale);
X      SetFileModified (TRUE);
X   }
X}
X
Xvoid DumpOneStr (FP, Str)
X   register FILE	* FP;
X   register char	* Str;
X{
X   for ( ; *Str != '\0'; Str++)
X   {
X      switch (*Str)
X      {
X         case '(':
X         case ')':
X         case '\\': fprintf (FP, "\\");
X      }
X      fprintf (FP, "%c", *Str);
X   }
X}
X
Xvoid DumpTextObj (FP, ObjPtr, PRTGIF)
X   FILE				* FP;
X   register struct ObjRec	* ObjPtr;
X   int				PRTGIF;
X{
X   int			x, y, font_size, xinc = 0, yinc = 0, color_index;
X   struct StrRec	* s_ptr;
X   struct TextRec	* text_ptr = ObjPtr->detail.t;
X
X   if (text_ptr->pen == NONEPAT) return;
X
X   if (!PRTGIF) SaveCurFont ();
X
X   curFont = text_ptr->font;
X   curFontDPI = text_ptr->dpi;
X   curStyle = text_ptr->style;
X   curSize = text_ptr->size;
X   textJust = text_ptr->just;
X   curRotate = text_ptr->rotate;
X   penPat = text_ptr->pen;
X
X   if (PRTGIF)
X   {
X      canvasFontAsc = text_ptr->asc;
X      canvasFontDes = text_ptr->des;
X      textCursorH = canvasFontAsc + canvasFontDes;
X      pointSize = (curFontDPI == FONT_DPI_75) ? pointSize75 : pointSize100;
X   }
X   else
X      SetCanvasFont ();
X
X   x = ObjPtr->x;
X   y = ObjPtr->y;
X
X   color_index = ObjPtr->color;
X   if (colorDump)
X      fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n",
X            ((float)tgifColors[color_index].red/maxRGB),
X            ((float)tgifColors[color_index].green/maxRGB),
X            ((float)tgifColors[color_index].blue/maxRGB));
X
X   if (curFont == FONT_SYM)
X   {
X      fprintf (FP, "/Symbol ");
X      font_size = pointSize[curSize];
X      fprintf (FP, "findfont [%1d 0 0 -%1d 0 0] makefont setfont\n",
X            font_size, font_size);
X   }
X   else
X   {
X      switch (curFont)
X      {
X         case FONT_TIM: fprintf (FP, "/Times"); break;
X         case FONT_COU: fprintf (FP, "/Courier"); break;
X         case FONT_HEL: fprintf (FP, "/Helvetica"); break;
X         case FONT_CEN: fprintf (FP, "/NewCenturySchlbk"); break;
X      }
X      switch (curStyle)
X      {
X         case STYLE_BI:
X            switch (curFont)
X            {
X               case FONT_TIM: fprintf (FP, "-BoldItalic "); break;
X               case FONT_COU: fprintf (FP, "-BoldOblique "); break;
X               case FONT_HEL: fprintf (FP, "-BoldOblique "); break;
X               case FONT_CEN: fprintf (FP, "-BoldItalic "); break;
X            }
X            break;
X         case STYLE_BR: fprintf (FP, "-Bold "); break;
X         case STYLE_NI:
X            switch (curFont)
X            {
X               case FONT_TIM: fprintf (FP, "-Italic "); break;
X               case FONT_COU: fprintf (FP, "-Oblique "); break;
X               case FONT_HEL: fprintf (FP, "-Oblique "); break;
X               case FONT_CEN: fprintf (FP, "-Italic "); break;
X            }
X            break;
X         case STYLE_NR:
X            switch (curFont)
X            {
X               case FONT_TIM: fprintf (FP, "-Roman "); break;
X               case FONT_COU: fprintf (FP, " "); break;
X               case FONT_HEL: fprintf (FP, " "); break;
X               case FONT_CEN: fprintf (FP, "-Roman "); break;
X            }
X            break;
X      }
X      font_size = pointSize[curSize];
X      fprintf (FP, "findfont [%1d 0 0 -%1d 0 0] makefont setfont\n",
X            font_size, font_size);
X   }
X
X   fprintf (FP, "   gsave\n");
X   switch (penPat)
X   {
X      case SOLIDPAT: break;
X      case BACKPAT: fprintf (FP, "      1 setgray\n"); break;
X      default:
X         if (!colorDump)
X            fprintf (FP, "      pat%1d 8 1 0 72 300 32 div div setpattern\n",
X                  penPat);
X         break;
X   }
X
X   switch (curRotate)
X   {
X      case ROTATE0: xinc = 0; yinc = textCursorH; break;
X      case ROTATE90: xinc = -textCursorH; yinc = 0; break;
X      case ROTATE180: xinc = 0; yinc = -textCursorH; break;
X      case ROTATE270: xinc = textCursorH; yinc = 0; break;
X   }
X
X   for (s_ptr = text_ptr->first; s_ptr != NULL; s_ptr = s_ptr->next)
X   {
X      switch (curRotate)
X      {
X         case ROTATE0:
X            fprintf (FP, "      %1d %1d moveto (", x, y+canvasFontAsc);
X            break;
X         case ROTATE90:
X            fprintf (FP, "      %1d %1d moveto 90 rotate (",x-canvasFontAsc,y);
X            break;
X         case ROTATE180:
X            fprintf (FP, "      %1d %1d moveto 180 rotate (",x,y-canvasFontAsc);
X            break;
X         case ROTATE270:
X            fprintf (FP, "      %1d %1d moveto 270 rotate (",x+canvasFontAsc,y);
X            break;
X      }
X      DumpOneStr (FP, s_ptr->s);
X      switch (textJust)
X      {
X         case JUST_L:
X            if (penPat == SOLIDPAT || penPat == BACKPAT || !colorDump)
X               fprintf (FP, ") show\n");
X            else
X            {
X               fprintf (FP, ") true charpath clip\n");
X               DumpPatFill (FP, penPat, 8, ObjPtr->bbox, "      ");
X            }
X            break;
X         case JUST_C:
X            if (penPat == SOLIDPAT || penPat == BACKPAT || !colorDump)
X               fprintf (FP, ") centertext show\n");
X            else
X            {
X               fprintf (FP, ") centertext true charpath clip\n");
X               DumpPatFill (FP, penPat, 8, ObjPtr->bbox, "      ");
X            }
X            break;
X         case JUST_R:
X            if (penPat == SOLIDPAT || penPat == BACKPAT || !colorDump)
X               fprintf (FP, ") righttext show\n");
X            else
X            {
X               fprintf (FP, ") righttext true charpath clip\n");
X               DumpPatFill (FP, penPat, 8, ObjPtr->bbox, "      ");
X            }
X            break;
X      }
X      if (penPat != SOLIDPAT && penPat != BACKPAT && s_ptr->next != NULL &&
X            colorDump)
X      {
X         fprintf (FP, "   grestore\n");
X         fprintf (FP, "   gsave\n");
X      }
X      switch (curRotate)
X      {
X         case ROTATE0: break;
X         case ROTATE90: fprintf (FP, "      -90 rotate \n"); break;
X         case ROTATE180: fprintf (FP, "      -180 rotate \n"); break;
X         case ROTATE270: fprintf (FP, "      -270 rotate \n"); break;
X      }
X      x += xinc;
X      y += yinc;
X   }
X   fprintf (FP, "   grestore\n\n");
X
X   if (!PRTGIF) RestoreCurFont ();
X}
X
Xvoid DrawTextObj (Win, XOff, YOff, ObjPtr)
X   Window		Win;
X   int			XOff, YOff;
X   struct ObjRec	* ObjPtr;
X{
X   struct TextRec	* text_ptr = ObjPtr->detail.t;
X   struct StrRec	* s_ptr;
X   int			x, y, xinc = 0, yinc = 0;
X
X   SaveCurFont ();
X   curFont = text_ptr->font;
X   curFontDPI = text_ptr->dpi;
X   curStyle = text_ptr->style;
X   curSize = text_ptr->size;
X   textJust = text_ptr->just;
X   curRotate = text_ptr->rotate;
X   SetCanvasFont ();
X
X   x = ObjPtr->x - XOff;
X   y = ObjPtr->y - YOff;
X
X   switch (curRotate)
X   {
X      case ROTATE0: xinc = 0; yinc = textCursorH; break;
X      case ROTATE90: xinc = -textCursorH; yinc = 0; break;
X      case ROTATE180: xinc = 0; yinc = -textCursorH; break;
X      case ROTATE270: xinc = textCursorH; yinc = 0; break;
X   }
X
X   for (s_ptr = text_ptr->first; s_ptr != NULL; s_ptr = s_ptr->next)
X   {
X      PaintText (Win, drawGC, s_ptr->s, textJust, curRotate, x, y,
X            canvasFontPtr, ObjPtr->color, text_ptr->pen, PAINT_NORM,
X            INVALID, INVALID);
X      x += xinc;
X      y += yinc;
X   }
X
X   if (curFontDPI != text_ptr->dpi) text_ptr->dpi = curFontDPI;
X   RestoreCurFont ();
X}
X
Xvoid RedrawCurText ()
X{
X   register int		x = 0, y;
X   struct StrRec	* s_ptr;
X   int			highlighting = FALSE, mode;
X   int			first_index = INVALID, second_index = INVALID;
X
X   if (!textCursorShown) return;
X
X   switch (textJust)
X   {
X      case JUST_L: x = textOrigX-2; break;
X      case JUST_C: x = textOrigX-textW/2-2; break;
X      case JUST_R: x = textOrigX-textW-2; break;
X   }
X   XClearArea (mainDisplay, drawWindow, x, textOrigY-2,
X         textW+5, textH+5, FALSE);
X   XDrawRectangle (mainDisplay, drawWindow, defaultGC, x, textOrigY-2,
X         textW+4, textH+4);
X
X   y = textOrigY;
X
X   for (s_ptr = curTextObj->detail.t->first; s_ptr != NULL; s_ptr = s_ptr->next)
X   {
X      if (textHighlight)
X      {
X         first_index = second_index = INVALID;
X         if (highlighting)
X         {
X            if (s_ptr == curStr || s_ptr == endStr)
X            {
X               mode = PAINT_INV_NORM;
X               first_index = (s_ptr == curStr) ? textCurIndex : textEndIndex;
X               highlighting = FALSE;
X            }
X            else
X            {
X               mode = PAINT_INV;
X               first_index = (s_ptr == curStr) ? textCurIndex : textEndIndex;
X            }
X         }
X         else
X         {
X            if (s_ptr == curStr && s_ptr == endStr)
X            {
X               mode = PAINT_NORM_INV_NORM;
X               first_index = min(textCurIndex,textEndIndex);
X               second_index = max(textCurIndex,textEndIndex);
X            }
X            else if (s_ptr == curStr || s_ptr == endStr)
X            {
X               mode = PAINT_NORM_INV;
X               first_index = (s_ptr == curStr) ? textCurIndex : textEndIndex;
X               highlighting = TRUE;
X            }
X            else
X               mode = PAINT_NORM;
X         }
X      }
X      else
X         mode = PAINT_NORM;
X
X      PaintCurText (drawWindow, drawGC, s_ptr->s, textJust, textOrigX, y,
X            canvasFontPtr, colorIndex, penPat, mode, first_index, second_index);
X      y += canvasFontHeight;
X   }
X
X   PutTextCursor ();
X}
X
Xvoid SaveString (FP, S)
X   FILE			* FP;
X   register char	* S;
X{
X   for ( ; *S != '\0'; S++)
X   {
X      if (*S == '\\')
X         fprintf (FP, "%s", "\\\\");
X      else if (*S == '"')
X         fprintf (FP, "%s", "\\\"");
X      else
X         putc (*S, FP);
X   }
X}
X
Xvoid SaveTextObj (FP, ObjPtr)
X   FILE			* FP;
X   struct ObjRec	* ObjPtr;
X{
X   register struct TextRec	* text_ptr = ObjPtr->detail.t;
X   register struct StrRec	* s_ptr;
X
X   fprintf (FP, "text('%s',", colorMenuItems[ObjPtr->color]);
X   fprintf (FP,
X         "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,[\n",
X         ObjPtr->x, ObjPtr->y, text_ptr->font, text_ptr->style, text_ptr->size,
X         text_ptr->lines, text_ptr->just, text_ptr->rotate, text_ptr->pen,
X         ObjPtr->obbox.rbx-ObjPtr->obbox.ltx,
X         ObjPtr->obbox.rby-ObjPtr->obbox.lty, ObjPtr->id, text_ptr->dpi,
X         text_ptr->asc, text_ptr->des);
X
X   for (s_ptr = text_ptr->first; s_ptr->next != NULL; s_ptr = s_ptr->next)
X   {
X      fprintf (FP, "\t\"", s_ptr->s);
X      SaveString (FP, s_ptr->s);
X      fprintf (FP, "\",\n", s_ptr->s);
X   }
X
X   fprintf (FP, "\t\"", s_ptr->s);
X   SaveString (FP, s_ptr->s);
X   fprintf (FP, "\"])", s_ptr->s);
X}
X
Xchar * ReadString (Str)
X   char	*	Str;
X{
X   register char	* s = Str;
X
X   for (s = Str; *s != '\0' && *s != '"'; s++)
X      if (*s == '\\')
X         strcpy (s, s+1);
X
X   if (*s == '"') s++;
X   return (s);
X}
X
Xvoid ReadTextObj (FP, Inbuf, ObjPtr, PRTGIF)
X   FILE			* FP;
X   char			* Inbuf;
X   struct ObjRec	* * ObjPtr;
X   int			PRTGIF;
X{
X   register int		i, max_len = 0, len;
X   struct StrRec	* s_ptr;
X   struct TextRec	* text_ptr;
X   char			color_str[80], * s;
X   char			tmp_str[MAXSTRING+1], inbuf[MAXSTRING+1];
X   int			num_lines, x, y, font, style, size;
X   int			text_just, rotate, pen;
X   int			bbox_w, bbox_h, dpi, asc, des;
X
X   * ObjPtr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X   s = FindChar ('(', Inbuf);
X   s = ParseStr (s, ',', color_str);
X   if (fileVersion <= 2)
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d", &x, &y, &font, &style,
X            &size, &num_lines, &text_just);
X      rotate = 0;
X      pen = 1;
X      (*ObjPtr)->id = objId++;
X      dpi = FONT_DPI_75;
X   }
X   else if (fileVersion <= 6)
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d", &x, &y, &font,
X            &style, &size, &num_lines, &text_just, &rotate, &pen);
X      (*ObjPtr)->id = objId++;
X      dpi = FONT_DPI_75;
X   }
X   else if (fileVersion <= 7)
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , %d , %d",
X            &x, &y, &font, &style, &size, &num_lines, &text_just, &rotate, &pen,
X            &bbox_w, &bbox_h);
X      (*ObjPtr)->id = objId++;
X      dpi = FONT_DPI_75;
X   }
X   else if (fileVersion <= 9)
X   {
X      sscanf (s,
X            "%d , %d , %d , %d , %d , %d , %d , %d , %d , %d , %d , %d , %d",
X            &x, &y, &font, &style, &size, &num_lines, &text_just, &rotate, &pen,
X            &bbox_w, &bbox_h, &((*ObjPtr)->id), &dpi);
X      if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1;
X   }
X   else
X   {
X      sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , %d , %d , %d , \
X            %d , %d , %d",
X            &x, &y, &font, &style, &size, &num_lines, &text_just, &rotate, &pen,
X            &bbox_w, &bbox_h, &((*ObjPtr)->id), &dpi, &asc, &des);
X      if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1;
X   }
X
X   text_ptr = (struct TextRec *) calloc (1, sizeof(struct TextRec));
X   text_ptr->lines = num_lines;
X
X   if (!PRTGIF) SaveCurFont ();
X
X   curFont = text_ptr->font = font;
X   curFontDPI = text_ptr->dpi = dpi;
X   curStyle = text_ptr->style = style;
X   curSize = text_ptr->size = size;
X   textJust = text_ptr->just = text_just;
X   curRotate = text_ptr->rotate = rotate;
X   penPat = text_ptr->pen = pen;
X
X   if (PRTGIF)
X   {
X      if (fileVersion < 10)
X      {
X         canvasFontAsc =
X               pDrawFontAsc[FontIndex(curFontDPI,curFont,curSize,curStyle)];
X         canvasFontDes =
X               pDrawFontDes[FontIndex(curFontDPI,curFont,curSize,curStyle)];
X      }
X      else
X      {
X         canvasFontAsc = asc;
X         canvasFontDes = des;
X      }
X      textCursorH = canvasFontAsc + canvasFontDes;
X   }
X   else
X      SetCanvasFont ();
X
X   text_ptr->asc = canvasFontAsc;
X   text_ptr->des = canvasFontDes;
X
X   for (i = 0; i < num_lines; i++)
X   {
X      fgets (inbuf, MAXSTRING, FP);
X      strcpy(tmp_str, FindChar ('"', inbuf));
X      s = ReadString (tmp_str);
X      *(--s) = '\0';
X      s_ptr = (struct StrRec *) calloc (1, sizeof(struct StrRec));
X      strcpy (s_ptr->s, tmp_str);
X      AddStr (lastStr, NULL, s_ptr);
X      if (PRTGIF)
X         len = strlen (tmp_str); /* assume string width = 1 pixel per char */
X      else
X         len = XTextWidth (canvasFontPtr, tmp_str, strlen (tmp_str));
X      if (len > max_len) max_len = len;
X   }
X   text_ptr->first = firstStr;
X   text_ptr->last = lastStr;
X
X   firstStr = lastStr = NULL;
X   textCurIndex = 0;
X
X   (*ObjPtr)->x = x;
X   (*ObjPtr)->y = y;
X
X   if (PRTGIF && fileVersion > 6)
X      SetTextBBox (*ObjPtr, text_just, bbox_w, bbox_h, rotate);
X   else
X      SetTextBBox (*ObjPtr, text_just, max_len, num_lines*textCursorH, rotate);
X
X   (*ObjPtr)->type = OBJ_TEXT;
X   (*ObjPtr)->color = FindColorIndex (color_str);
X   (*ObjPtr)->dirty = FALSE;
X   (*ObjPtr)->detail.t = text_ptr;
X
X   if (!PRTGIF)
X   {
X      if (curFontDPI != text_ptr->dpi) text_ptr->dpi = curFontDPI;
X      RestoreCurFont ();
X   }
X}
X
Xvoid ClearCurText ()
X{
X   if (textCursorShown)
X   {
X      EraseTextCursor ();
X      textCursorShown = FALSE;
X      if (editingText)
X      {
X         PopCurFont ();
X         ShowJust ();
X         ShowColor (FALSE);
X         ShowCurFont ();
X      }
X   }
X   firstStr = lastStr = curStr = NULL;
X   curTextObj = NULL;
X   textCurIndex = 0;
X   curStrW = 0;
X   editingText = FALSE;
X}
X
Xvoid AdjustCurText (XOff, YOff)
X   int	XOff, YOff;
X{
X   textOrigX += XOff;
X   textOrigY += YOff;
X   textCurX += XOff;
X   textCurY += YOff;
X}
X
Xstatic
Xint PaintLeftText (Str, Just, Rotate, LtX, LtY)
X   char	* Str;
X   int	Just, Rotate, LtX, LtY;
X   /* LtX and LtY are UNSCALED screen offset */
X{
X   register int	amount;
X
X   if (zoomScale != 0)
X   {
X      LtX >>= zoomScale;
X      LtY >>= zoomScale;
X      amount = XTextWidth (canvasFontPtr, Str, strlen (Str));
X      BlurText (drawWindow, drawGC, Just, Rotate, LtX, LtY,
X            (amount>>zoomScale)+1, (textCursorH>>zoomScale)+1);
X      return (amount);
X   }
X
X   LtY += canvasFontAsc;
X   amount = XTextWidth (canvasFontPtr, Str, strlen (Str));
X   XDrawString (mainDisplay, drawWindow, drawGC, LtX, LtY, Str, strlen (Str));
X
X   return (amount); /* return the length of the painted string */
X}
X
Xvoid RepaintFirstStr (ObjPtr, Str)
X   struct ObjRec	* ObjPtr;
X   char			* Str;
X   /* Replace (graphically) the FIRST string of the text in ObjPtr by Str */
X{
X   register char	* s = ObjPtr->detail.t->first->s, * s1 = Str;
X   char			tmp_str[MAXSTRING+1], * c_ptr;
X   int			len;
X   struct BBRec		bbox;
X   XGCValues		values;
X
X   bbox.ltx = ObjPtr->obbox.ltx; bbox.lty = ObjPtr->obbox.lty;
X   bbox.rbx = ObjPtr->obbox.rbx; bbox.rby = ObjPtr->obbox.rby;
X
X   c_ptr = tmp_str;
X   for ( ; *s != '\0' && *s1 != '\0' && *s1 == *s; *c_ptr++ = *s++, s1++) ;
X
X   if (*s == *s1) return; /* no updates */
X   ObjPtr->detail.t->attr->owner->dirty = TRUE;
X   *c_ptr = '\0';
X
X   SaveCurFont ();
X   curFont = ObjPtr->detail.t->font;
X   curFontDPI = ObjPtr->detail.t->dpi;
X   curStyle = ObjPtr->detail.t->style;
X   curSize = ObjPtr->detail.t->size;
X   textJust = ObjPtr->detail.t->just;
X   curRotate = ObjPtr->detail.t->rotate;
X   SetCanvasFont ();
X
X   if (*s != '\0')
X   {
X      values.foreground = myBgPixel;
X      values.function = GXcopy;
X      values.fill_style = FillSolid;
X      XChangeGC (mainDisplay, drawGC,
X            GCForeground | GCFunction | GCFillStyle, &values);
X
X      len = XTextWidth (canvasFontPtr, tmp_str, strlen (tmp_str));
X      XFillRectangle (mainDisplay, drawWindow, drawGC, OFFSET_X(bbox.ltx+len),
X            OFFSET_Y(bbox.lty), (bbox.rbx-bbox.ltx-len>>zoomScale)+1,
X               (textCursorH>>zoomScale)+1);
X
X      values.foreground = colorPixels[ObjPtr->color];
X      XChangeGC (mainDisplay, drawGC, GCForeground, &values);
X   }
X   else
X   {
X      values.foreground = colorPixels[ObjPtr->color];
X      values.function = GXcopy;
X      values.fill_style = FillSolid;
X      XChangeGC (mainDisplay, drawGC,
X            GCForeground | GCFunction | GCFillStyle, &values);
X   }
X
X   ObjPtr->bbox.rbx = ObjPtr->obbox.rbx = bbox.ltx + PaintLeftText (Str,
X         textJust, curRotate, bbox.ltx-drawOrigX, bbox.lty-drawOrigY);
X
X   RestoreCurFont ();
X}
END_OF_FILE
if test 64034 -ne `wc -c <'text.c'`; then
    echo shar: \"'text.c'\" unpacked with wrong size!
fi
# end of 'text.c'
fi
echo shar: End of archive 16 \(of 23\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 23 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
---------------------------------> cut here <---------------------------------
-- 
Bill Cheng // UCLA Computer Science Department // (213) 206-7135
3277 Boelter Hall // Los Angeles, California 90024 // USA
william@CS.UCLA.EDU      ...!{uunet|ucbvax}!cs.ucla.edu!william

--
Dan Heller
------------------------------------------------
O'Reilly && Associates		 Z-Code Software
Senior Writer			       President
argv@ora.com			argv@zipcode.com
------------------------------------------------
General Email: argv@sun.com
Comp-sources-x stuff: comp-sources.x@uunet.uu.net