/*********************************************************************** * * TITLE: * text.c * * AUTHOR: * Cassie Mulnix * * DESCRIPTION: * This module is part of the OPPS editor, xopps. It contains * object routines to handle text objects. * * CHANGE HISTORY * * $Log: text.c,v $ * Revision 1.56 1994/12/31 03:15:14 kevin * fixed memory allocation problem after DialogTextGet * * Revision 1.55 1994/09/12 21:41:42 cassie * set option for new_page * * Revision 1.54 1994/08/10 22:05:48 cassie * removed call to DialogFlagSet in verify_fun since * it is already set in ok_button * * Revision 1.53 1994/07/20 19:06:35 clm * updated TRUE, ERROR etc in cancel & ok_button functions * to DIALOG_ constants * * Revision 1.52 1994/06/16 21:57:27 clm * updated to new dialog routines - extra parameter to DialogTextCreate * * Revision 1.51 1994/06/16 16:56:35 clm * updated to new gr_ routines using GR_ for font names * * Revision 1.50 1994/06/08 18:48:45 clm * removed Xm library includes since they are in dialog * * Revision 1.49 1994/06/01 22:27:07 clm * rewrote init functions to use dialog oellib functions * also don't initialize popups until object called * * Revision 1.48 1994/05/20 23:31:43 clm * updated with HP, SGI changes * * Revision 1.47 1994/05/04 23:34:36 clm * ported to ANSI C * * Revision 1.46 1993/05/21 16:01:58 clm * fixed buffer size for sav function * * Revision 1.45 1993/05/18 22:39:41 clm * added meaningful error messages for check_num and check_day * * Revision 1.44 1993/05/18 20:58:30 clm * added new message.c function * * Revision 1.43 1992/12/22 15:43:04 clm * fixed load and lim so text cannot be moved or loaded outside chart lines * * Revision 1.42 1992/12/10 21:45:40 clm * fixed new_index so chart is always object 0 * * Revision 1.41 1992/11/05 16:26:19 clm * fixed display of text for draw_layer > 0 * * Revision 1.40 1992/10/05 21:14:07 clm * fixed error checking of page value in load_text * * Revision 1.39 1992/10/02 20:45:21 clm * housekeeping.c * * Revision 1.38 1992/09/16 14:56:20 clm * fixed load function so doesn't add object if error in load * * Revision 1.37 1992/09/14 18:34:06 clm * added load_text function * * Revision 1.36 1992/09/14 18:06:45 clm * added page and layer to text object * * Revision 1.35 1992/08/26 16:43:51 clm * fixed error checking for text in load function * * Revision 1.34 1992/08/13 18:09:21 clm * fixed error checking for load module * * Revision 1.32 1992/08/04 17:01:10 clm * changed malloc and free to XtMalloc and XtFree * * Revision 1.31 1992/07/22 22:07:42 clm * changed mov function to reflect change in mover.c * * Revision 1.30 1992/07/10 16:04:00 clm * added snap_txt to lim function * * Revision 1.29 1992/07/08 17:55:52 clm * fixed comment format * * Revision 1.28 1992/06/03 16:40:35 clm * updated dialog shell * * Revision 1.27 1992/05/26 15:57:57 clm * incorporated rectangle routines * * Revision 1.25 1992/05/21 15:09:26 clm * removed help_button function * * Revision 1.23 1992/05/20 20:50:27 clm * fixed gr_text function call * * Revision 1.22 1992/05/20 19:50:57 clm * cleaned up file and help format * * Revision 1.21 1992/05/11 22:39:35 kevin * renamed project include file to xopps.h * * Revision 1.2 90/11/27 13:18:28 ana * First motif cut. Contains new pop up editing window. * * Revision 1.1 90/11/02 08:41:13 ana * Initial revision * *********************************************************************** * * WARNINGS: * * EXTERNAL CALLABLE COMPONENTS (PUBLIC): * * GLOBALS: * * WAIVERS: * * NOTES: * * MANPAGE: * ***********************************************************************/ #ifndef lint static char rcsid[] = "$Id: text.c,v 1.56 1994/12/31 03:15:14 kevin OEL $"; #endif /************************************************************************* global functions: add_text(x, y, just, text) - add object to data base ***************************************************************************/ /* local functions: dsp_text(i) - display text object edt_text(i, new) - change contents of text field rem_text(i) - remove text object lim_text(i) - limit range of motion of text object loc_text(i) - locate position of text object on screen mov_text(i) - move text object cpy_text(to, from) - copy text object msg_text(i) - display message on screen sav_text(i, file) - save text to file */ #include "xopps.h" static int font_values[] = { GR_COURIER, GR_COURIER_BOLD, GR_HELVETICA, GR_HELVETICA_BOLD, GR_TIMES, GR_TIMES_BOLD }; static int font_sizes[] = { 8, 10, 12, 14, 18, 24 }; /* local functions */ static void create_dialog(void); static int load_text(char *); /* load a text object */ static void txt_ok_button(void); /* Callback for ok button */ static void cancel_button(void); /* Callback for cancel button */ static void change_color(Widget, XtPointer, XtPointer); static void change_point(Widget, XtPointer, XtPointer); static void change_font(Widget, XtPointer, XtPointer); static void change_just(Widget, XtPointer, XtPointer); static void change_drawlyr(Widget, XtPointer, XtPointer); static void change_page(Widget, XtPointer, XtPointer); static void dsp_text(int); static void edt_text(int, int); static void rem_text(int, int); static void lim_text(int, int *, int *, int *, int *, int); static void loc_text(int, int); static void mov_text(int, int, int, int); static void cpy_text(struct obj *, struct obj *); static void msg_text(int, int); static void sav_text(int, FILE *, int); static void verify_fun(Widget, XtPointer, XtPointer); static struct ops txt_ops = { dsp_text, edt_text, rem_text, lim_text, loc_text, mov_text, cpy_text, msg_text, sav_text }; static DialogText *xoff, *yoff, *text; static DialogOption *fontw, *pointw; static DialogOption *color, *drawlyr; static DialogOption *just, *page; static Widget text_dialog; /* dialog shell for popup */ static Widget parent_shell; static int new_color; /* new color id */ static int new_point; /* new point id */ static int new_just; /* new just id */ static int new_font; /* new font id */ static int new_drawlyr; /* new layer id */ static int new_page; /* new page id */ /*********************************************************************** * * FUNCTION: * init_text_object() * * INPUTS: * parent (Widget) * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * registers the text object and sets the parent */ void init_text_object(Widget parent) { register_io_obj('T', load_text); /* register object */ parent_shell = parent; } /*********************************************************************** * * FUNCTION: * create_dialog() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * initializes the widgets for the text object */ static void create_dialog(void) { static char *page_list[] = { "All Pages", "Current Page" }; static char *layer[] = { "0", "1", "2", "3" }; static char *point[] = { "8", "10", "12", "14", "18", "24" }; static char *font_list[] = { "Courier", "Courier Bold", "Helvetica", "Helvetica Bold", "Times", "Times Bold" }; static char *just_list[] = { "Left", "Center", "Right" }; text_dialog = DialogInit(parent_shell, "Text Dialog", "text", verify_fun, (XtPointer)DIALOG_CANCEL); text = DialogTextCreate("Text ", 50, 100); DialogAddRow(2); xoff = DialogTextCreate("X-Offset ", 3, 3); yoff = DialogTextCreate("Y-Offset ", 3, 3); DialogAddRow(2); fontw = DialogOptionCreate("Font ", 6, 5, change_font, DIALOG_OPT_STR_ARY, font_list, font_values); pointw = DialogOptionCreate("Point ", 6, 10, change_point, DIALOG_OPT_STR_ARY, point, font_sizes); DialogAddRow(2); just = DialogOptionCreate("Just ", 3, 0, change_just, DIALOG_OPT_STR_ARY, just_list, NULL); page = DialogOptionCreate("Page ", 2, 1, change_page, DIALOG_OPT_STR_ARY, page_list, NULL); DialogAddRow(2); color = DialogOptionCreate("Color ", ncolor, 0, change_color, DIALOG_OPT_STR_ARY, color_name, color_index); drawlyr = DialogOptionCreate("Draw Layer ", 4, 0, change_drawlyr, DIALOG_OPT_STR_ARY, layer, NULL); DialogStdButtons(verify_fun, (XtPointer)DIALOG_UPDATE, verify_fun, (XtPointer)DIALOG_CANCEL, (XtCallbackProc)ShowHelp, "text"); } /*********************************************************************** * * FUNCTION: * change_color() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new color for text object */ static void change_color(Widget button, XtPointer option, XtPointer any_data) { new_color = (int)option; } /*********************************************************************** * * FUNCTION: * change_point() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new font point size for text object */ static void change_point(Widget button, XtPointer option, XtPointer any_data) { new_point = (int)option; } /*********************************************************************** * * FUNCTION: * change_font() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new font for text object */ static void change_font(Widget button, XtPointer option, XtPointer any_data) { new_font = (int)option; } /*********************************************************************** * * FUNCTION: * change_just() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new justification for text object */ static void change_just(Widget button, XtPointer option, XtPointer any_data) { new_just = (int)option; } /*********************************************************************** * * FUNCTION: * change_page() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new page for text object */ static void change_page(Widget button, XtPointer option, XtPointer any_data) { new_page = (int)option; } /*********************************************************************** * * FUNCTION: * change_drawlyr() * * INPUTS: * button (Widget) * option, any_data (XtPointer) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new drawlyr for text object */ static void change_drawlyr(Widget button, XtPointer option, XtPointer any_data) { new_drawlyr = (int)option; } /*********************************************************************** * * FUNCTION: * load_text() * * INPUTS: * buf (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * loads text object record */ static int load_text(char *buf) { int just, x, y, font, point, color, layer, page; char text[256]; int i; if (record_scan(buf + 1, "ddddddddq", &x, &y, &just, &font, &point, &color, &layer, &page, text) == 9) { if ((x < xlnary[0].z.lnptr->cord) || (x > xlnary[nxln-1].z.lnptr->cord)) { Warning("Illegal Text x %d", x); } else if ((y < ylnary[0].z.lnptr->cord) || (y > ylnary[nyln-1].z.lnptr->cord)) { Warning("Illegal Text y %d", y); } else if ((just < 0) || (just > 2)) { Warning("Illegal Text justification %d", just); } else if ((font != GR_COURIER) && (font != GR_COURIER_BOLD) && (font != GR_HELVETICA) && (font != GR_HELVETICA_BOLD) && (font != GR_TIMES) && (font != GR_TIMES_BOLD)) { Warning("Illegal Text font %d", font); } else if ((point != 8) && (point != 10) && (point != 12) && (point != 14) && (point != 18) && (point != 24)) { Warning("Illegal Text point %d", point); } else if ((color < 0) || (color > ncolor)) { Warning("Illegal Text color %d", color); } else if ((layer < 0) || (layer > 3)) { Warning("Illegal Text draw layer %d", layer); } else if ((page < 0) || (page > 7)) { Warning("Illegal Text page %d", page); } else { i = add_text(x, y, just, font, point, color, layer, page, text); (*(objary[i].opsptr->loc))(i, OBJECT); return 0; } return -1; } else { return -1; } } /*********************************************************************** * * FUNCTION: * add_text() * * INPUTS: * x, y, just, font, point, color, layer, page (int) * text (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * adds new text object */ int add_text(int x, int y, int just, int font, int point, int color, int layer, int page, char *text) { int i; /* index */ i = new_index(FALSE); objary[i].z.txtptr = (struct txt *)XtMalloc(sizeof(struct txt)); objary[i].z.txtptr->just = just; objary[i].z.txtptr->font = font; objary[i].z.txtptr->point = point; objary[i].z.txtptr->x = x; objary[i].z.txtptr->y = y; objary[i].z.txtptr->color = color; objary[i].z.txtptr->page = page; objary[i].z.txtptr->text = XtNewString(text); objary[i].type = OBJ_TXT; objary[i].opsptr = &txt_ops; objary[i].layer = layer; return i; } /*********************************************************************** * * FUNCTION: * cpy_text() * * INPUTS: * to, from (obj *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * copies text object from to text object to */ static void cpy_text(struct obj *to, struct obj *from) { if (from->type == OBJ_NUL) return; to->z.txtptr = (struct txt *)XtMalloc(sizeof(struct txt)); to->z.txtptr->just = from->z.txtptr->just; to->z.txtptr->font = from->z.txtptr->font; to->z.txtptr->point = from->z.txtptr->point; to->z.txtptr->x = from->z.txtptr->x; to->z.txtptr->y = from->z.txtptr->y; to->z.txtptr->color = from->z.txtptr->color; to->z.txtptr->page = from->z.txtptr->page; to->z.txtptr->text = XtNewString(from->z.txtptr->text); to->type = OBJ_TXT; to->layer = from->layer; to->opsptr = &txt_ops; to->rlist = copyRectList(from->rlist); } /*********************************************************************** * * FUNCTION: * rem_text() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * removes text object i */ static void rem_text(int i, int dir) { struct obj *objptr; switch (i) { case BACK: objptr = &objbck; break; case TEMP: objptr = &objtmp; break; default: objptr = &(objary[i]); break; } freeRectList(objptr->rlist); XtFree(objptr->z.txtptr->text); XtFree((char *)objptr->z.txtptr); rem_object(objptr); } /*********************************************************************** * * FUNCTION: * lim_text() * * INPUTS: * i (int) * x1, y1, x2, y2 (int *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * limits range of motion of text object */ static void lim_text(int i, int *x1, int *y1, int *x2, int *y2, int dir) { XRectangle *(*r)[]; r = getMoveRect(objary[i].rlist); if (snap_txt == TOG_OFF) { *x1 = xlnary[0].z.lnptr->cord; *y1 = ylnary[0].z.lnptr->cord; *x2 = xlnary[nxln-1].z.lnptr->cord - (1 + (*r)[0]->width); *y2 = ylnary[nyln-1].z.lnptr->cord - (1 + (*r)[0]->height); } else { *x1 = (*r)[0]->x; *y1 = ylnary[0].z.lnptr->cord; *x2 = (*r)[0]->x; *y2 = ylnary[nyln-1].z.lnptr->cord - (1 + (*r)[0]->height); } } /*********************************************************************** * * FUNCTION: * loc_text() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * locates posittion of text object i */ static void loc_text(int i, int dir) { struct txt *txtptr; /* local pointer */ XRectangle r; /* rectangle */ txtptr = objary[i].z.txtptr; r.width = gr_strwidth(txtptr->text, txtptr->font|txtptr->point); r.height = gr_txheight(txtptr->font|txtptr->point) - 1; r.x = txtptr->x - (txtptr->just % 3) * r.width / 2; r.y = txtptr->y - r.height; setRectList(objary[i].rlist, 1, &r, RL_PRIMARY); } /*********************************************************************** * * FUNCTION: * mov_text() * * INPUTS: * i, x, y (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * moves text object i to (x,y) */ static void mov_text(int i, int x, int y, int dir) { objary[i].z.txtptr->x += x; objary[i].z.txtptr->y += y; } /*********************************************************************** * * FUNCTION: * dsp_text() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays text object i on screen */ static void dsp_text(int i) { struct txt *txtptr; /* local pointer */ XRectangle *(*r)[]; txtptr = objary[i].z.txtptr; if (objary[i].layer != 0) { r = getMoveRect(objary[i].rlist); gr_rect_clear((*r)[0]->x, (*r)[0]->y, (*r)[0]->width, (*r)[0]->height); } gr_set_color(color_name[txtptr->color], color_gscale[txtptr->color]); if ((txtptr->page == current_page) || (txtptr->page == 0)) { gr_text(txtptr->x, txtptr->y, txtptr->text, txtptr->just % 3, (txtptr->font|txtptr->point), 0); } } /*********************************************************************** * * FUNCTION: * msg_text() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays text message on screen */ static void msg_text(int i, int dir) { char buf[64]; strcpy(buf, "Text: "); strncat(buf, objary[i].z.txtptr->text, 44); Message(buf); } /*********************************************************************** * * FUNCTION: * sav_text() * * INPUTS: * i (int) * fp (FILE *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * saves text record i to fp */ static void sav_text(int i, FILE *fp, int dir) { struct txt *txtptr; char buf[1024]; txtptr = objary[i].z.txtptr; buf[0] = 'T'; buf[1] = ' '; record_print(buf + 2, "ddddddddq", txtptr->x, txtptr->y, txtptr->just, txtptr->font, txtptr->point, txtptr->color, objary[i].layer, txtptr->page, txtptr->text); fputs(buf, fp); } /*********************************************************************** * * FUNCTION: * edt_text() * * INPUTS: * i, new (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * edits text object i */ static void edt_text(int i, int new) { char buf[4]; if (text_dialog == NULL) { create_dialog(); } (*(objary[i].opsptr->cpy))(&objtmp, &objary[i]); new_color = objtmp.z.txtptr->color; new_point = objtmp.z.txtptr->point; new_just = objtmp.z.txtptr->just; new_font = objtmp.z.txtptr->font; new_drawlyr = objtmp.layer; new_page = objtmp.z.txtptr->page; if (new) { (*(objary[i].opsptr->rem))(i, OBJECT); i = -1; } sprintf(buf, "%d", objtmp.z.txtptr->x); DialogTextSet(xoff, buf); sprintf(buf, "%d", objtmp.z.txtptr->y); DialogTextSet(yoff, buf); DialogOptionSet(fontw, new_font); DialogOptionSet(color, new_color); DialogOptionSet(pointw, new_point); DialogOptionSet(just, new_just); DialogOptionSet(drawlyr, new_drawlyr); DialogOptionSet(page, new_page); DialogTextSet(text, objtmp.z.txtptr->text); EditObject(i, text_dialog); } /*********************************************************************** * * FUNCTION: * txt_ok_button() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * checks input after ok button is pressed */ static void txt_ok_button(void) { int change = DIALOG_NO_CHANGE; /* temp boolean to see if changed */ char *buf; int val; val = DialogTextGetInt(xoff); if ((val < 0) || (val >= PAGE_WIDTH)) { Warning("Invalid X Offset"); change |= DIALOG_ERROR; } else if (val != objtmp.z.txtptr->x) { change |= DIALOG_UPDATE; objtmp.z.txtptr->x = val; } val = DialogTextGetInt(yoff); if ((val < 0) || (val >= PAGE_WIDTH)) { Warning("Invalid Y Offset"); change |= DIALOG_ERROR; } else if (val != objtmp.z.txtptr->y) { change |= DIALOG_UPDATE; objtmp.z.txtptr->y = val; } buf = DialogTextGet(text); if (strcmp(buf, objtmp.z.txtptr->text)) { change |= DIALOG_UPDATE; XtFree(objtmp.z.txtptr->text); objtmp.z.txtptr->text = buf; } else { XtFree(buf); } if (new_font != objtmp.z.txtptr->font) { change |= DIALOG_UPDATE; } objtmp.z.txtptr->font = DialogOptionGet(fontw); if (new_just != objtmp.z.txtptr->just) { change |= DIALOG_UPDATE; } objtmp.z.txtptr->just = DialogOptionGet(just); if (new_color != objtmp.z.txtptr->color) { change |= DIALOG_UPDATE; } objtmp.z.txtptr->color = DialogOptionGet(color); if (new_point != objtmp.z.txtptr->point) { change |= DIALOG_UPDATE; } objtmp.z.txtptr->point = DialogOptionGet(pointw); if (new_drawlyr != objtmp.layer) { change |= DIALOG_UPDATE; } objtmp.layer = DialogOptionGet(drawlyr); if (new_page != objtmp.z.txtptr->page) { change |= DIALOG_UPDATE; } objtmp.z.txtptr->page = DialogOptionGet(page); if (objtmp.z.txtptr->page != 0) { /* * if not printed on all pages, set page value to current page */ objtmp.z.txtptr->page = current_page; change |= DIALOG_UPDATE; } object_change = change; DialogFlagSet(change); } /*********************************************************************** * * FUNCTION: * cancel_button() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * discards any edits and closes edit window */ static void cancel_button(void) { object_change = DIALOG_CANCEL; DialogFlagSet(DIALOG_CANCEL); } /*********************************************************************** * * FUNCTION: * verify_fun() * * INPUTS: * w (Widget) * x, y (XtPointer) * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * validates that the popup dialog can be closed */ static void verify_fun(Widget w, XtPointer x, XtPointer y) { if ((int)x == DIALOG_CANCEL) { if (!ShellValidateClose(w)) return; cancel_button(); } else if ((int)x == DIALOG_UPDATE) { txt_ok_button(); } }