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