home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-05-26 | 66.4 KB | 2,484 lines |
- Newsgroups: comp.sources.x
- From: envbvs@epb9.lbl.gov (Brian V. Smith)
- Subject: v19i126: xfig - Draw amd manipulate objects in an X-Window, Part14/27
- Message-ID: <1993May21.021542.6381@sparky.imd.sterling.com>
- X-Md4-Signature: 6b939c97ebf71c341a1318a8ccb213e8
- Sender: chris@sparky.imd.sterling.com (Chris Olson)
- Organization: Sterling Software
- Date: Fri, 21 May 1993 02:15:42 GMT
- Approved: chris@sparky.imd.sterling.com
-
- Submitted-by: envbvs@epb9.lbl.gov (Brian V. Smith)
- Posting-number: Volume 19, Issue 126
- Archive-name: xfig/part14
- Environment: X11
- Supersedes: xfig: Volume 16, Issue 6-30,39
-
- #! /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 14 (of 27)."
- # Contents: d_text.c u_elastic.c w_rottext.c
- # Wrapped by envbvs@epb9.lbl.gov.lbl.gov on Mon May 3 12:05:57 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'd_text.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'d_text.c'\"
- else
- echo shar: Extracting \"'d_text.c'\" \(21193 characters\)
- sed "s/^X//" >'d_text.c' <<'END_OF_FILE'
- X/*
- X * FIG : Facility for Interactive Generation of figures
- X * Copyright (c) 1985 by Supoj Sutanthavibul
- X * Copyright (c) 1992 by Brian V. Smith
- X * "Permission to use, copy, modify, distribute, and sell this software and its
- X * documentation for any purpose is hereby granted without fee, provided that
- X * the above copyright notice appear in all copies and that both the copyright
- X * notice and this permission notice appear in supporting documentation.
- X * No representations are made about the suitability of this software for
- X * any purpose. It is provided "as is" without express or implied warranty."
- X */
- X
- X#include "fig.h"
- X#include "resources.h"
- X#include "mode.h"
- X#include "object.h"
- X#include "paintop.h"
- X#include "u_create.h"
- X#include "u_fonts.h"
- X#include "u_list.h"
- X#include "u_search.h"
- X#include "w_canvas.h"
- X#include "w_drawprim.h"
- X#include "w_mousefun.h"
- X#include "w_setup.h"
- X#include "w_zoom.h"
- X
- Xextern PIX_ROT_FONT lookfont();
- X
- X#define CTRL_H 8
- X#define NL 10
- X#define CR 13
- X#define CTRL_X 24
- X#define SP 32
- X#define DEL 127
- X
- X#define BUF_SIZE 400
- X
- Xchar prefix[BUF_SIZE], /* part of string left of mouse click */
- X suffix[BUF_SIZE]; /* part to right of click */
- Xint leng_prefix, leng_suffix;
- Xstatic int char_ht;
- Xstatic int base_x, base_y;
- Xstatic PIX_ROT_FONT canvas_zoomed_font;
- X
- Xstatic int work_psflag, work_font, work_fontsize, work_textjust;
- Xstatic PIX_ROT_FONT work_fontstruct;
- Xstatic float work_angle;
- Xstatic finish_n_start();
- Xstatic init_text_input(), cancel_text_input();
- Xstatic wrap_up();
- Xint char_handler();
- Xstatic F_text *new_text();
- X
- Xstatic int cpy_n_char();
- Xstatic int prefix_length();
- Xstatic int initialize_char_handler();
- Xstatic int terminate_char_handler();
- Xstatic int erase_char_string();
- Xstatic int draw_char_string();
- Xstatic int turn_on_blinking_cursor();
- Xstatic int turn_off_blinking_cursor();
- Xstatic int move_blinking_cursor();
- X
- Xtext_drawing_selected()
- X{
- X canvas_kbd_proc = null_proc;
- X canvas_locmove_proc = null_proc;
- X canvas_middlebut_proc = null_proc;
- X canvas_leftbut_proc = init_text_input;
- X canvas_rightbut_proc = null_proc;
- X set_mousefun("posn cursor", "", "");
- X set_cursor(pencil_cursor);
- X}
- X
- Xstatic
- Xfinish_n_start(x, y)
- X{
- X wrap_up();
- X init_text_input(x, y);
- X}
- X
- Xfinish_text_input()
- X{
- X wrap_up();
- X text_drawing_selected();
- X draw_mousefun_canvas();
- X}
- X
- Xstatic
- Xcancel_text_input()
- X{
- X erase_char_string();
- X terminate_char_handler();
- X if (cur_t != NULL) {
- X draw_text(cur_t, PAINT);
- X toggle_textmarker(cur_t);
- X }
- X text_drawing_selected();
- X draw_mousefun_canvas();
- X reset_action_on();
- X}
- X
- Xstatic
- Xnew_text_line()
- X{
- X wrap_up();
- X if (work_angle < 90.0 - 0.001) {
- X cur_y += (int) ((float) char_ht * cur_textstep);
- X cur_x = base_x;
- X } else if (work_angle < 180.0 - 0.001) {
- X cur_x += (int) ((float) char_ht * cur_textstep);
- X cur_y = base_y;
- X } else if (work_angle < 270.0 - 0.001) {
- X cur_y -= (int) ((float) char_ht * cur_textstep);
- X cur_x = base_x;
- X } else {
- X cur_x -= (int) ((float) char_ht * cur_textstep);
- X cur_y = base_y;
- X }
- X init_text_input(cur_x, cur_y);
- X}
- X
- Xstatic
- Xwrap_up()
- X{
- X PR_SIZE size;
- X
- X reset_action_on();
- X erase_char_string();
- X terminate_char_handler();
- X
- X if (cur_t == NULL) { /* a brand new text */
- X if (leng_prefix == 0)
- X return;
- X cur_t = new_text();
- X add_text(cur_t);
- X } else { /* existing text modified */
- X strcat(prefix, suffix);
- X leng_prefix += leng_suffix;
- X if (leng_prefix == 0) {
- X delete_text(cur_t);
- X return;
- X }
- X if (!strcmp(cur_t->cstring, prefix)) {
- X /* we didn't change anything */
- X draw_text(cur_t, PAINT);
- X toggle_textmarker(cur_t);
- X return;
- X }
- X new_t = copy_text(cur_t);
- X change_text(cur_t, new_t);
- X if (strlen(new_t->cstring) >= leng_prefix) {
- X strcpy(new_t->cstring, prefix);
- X } else { /* free old and allocate new */
- X free(new_t->cstring);
- X if ((new_t->cstring = new_string(leng_prefix + 1)) != NULL)
- X strcpy(new_t->cstring, prefix);
- X }
- X size = pf_textwidth(canvas_font, leng_prefix, prefix);
- X new_t->height = size.y;
- X new_t->length = size.x; /* in pixels */
- X cur_t = new_t;
- X }
- X draw_text(cur_t, PAINT);
- X mask_toggle_textmarker(cur_t);
- X}
- X
- Xstatic
- Xinit_text_input(x, y)
- X int x, y;
- X{
- X int length, d;
- X PR_SIZE tsize;
- X
- X cur_x = x;
- X cur_y = y;
- X
- X set_action_on();
- X set_mousefun("reposn cursor", "finish text", "cancel");
- X draw_mousefun_canvas();
- X canvas_kbd_proc = char_handler;
- X canvas_middlebut_proc = finish_text_input;
- X canvas_leftbut_proc = finish_n_start;
- X canvas_rightbut_proc = cancel_text_input;
- X
- X /*
- X * set working font info to current settings. This allows user to change
- X * font settings while we are in the middle of accepting text without
- X * affecting this text i.e. we don't allow the text to change midway
- X * through
- X */
- X
- X put_msg("Ready for text input (from keyboard)");
- X if ((cur_t = text_search(cur_x, cur_y)) == NULL) { /* new text input */
- X leng_prefix = leng_suffix = 0;
- X *suffix = 0;
- X prefix[leng_prefix] = '\0';
- X base_x = cur_x;
- X base_y = cur_y;
- X
- X work_fontsize = cur_fontsize;
- X work_font = using_ps ? cur_ps_font : cur_latex_font;
- X work_psflag = using_ps;
- X work_textjust = cur_textjust;
- X work_angle = cur_elltextangle;
- X if (work_angle < 0.0)
- X work_angle += 360.0;
- X
- X /* load the X font and get its id for this font, size and angle UNZOOMED */
- X /* this is to get widths etc for the unzoomed chars */
- X canvas_font = lookfont(x_fontnum(work_psflag, work_font),
- X work_fontsize, work_angle*M_PI/180.0);
- X /* get the ZOOMED font for actually drawing on the canvas */
- X canvas_zoomed_font = lookfont(x_fontnum(work_psflag, work_font),
- X round(work_fontsize*zoomscale), work_angle*M_PI/180.0);
- X /* save the working font structure */
- X work_fontstruct = canvas_zoomed_font;
- X } else { /* clicked on existing text */
- X if (hidden_text(cur_t)) {
- X put_msg("Can't edit hidden text");
- X reset_action_on();
- X text_drawing_selected();
- X return;
- X }
- X /* update the working text parameters */
- X work_font = cur_t->font;
- X work_fontstruct = canvas_zoomed_font = cur_t->fontstruct;
- X work_fontsize = cur_t->size;
- X work_psflag = cur_t->flags;
- X work_textjust = cur_t->type;
- X work_angle = cur_t->angle*180.0/M_PI;
- X if (work_angle < 0.0)
- X work_angle += 360.0;
- X /* load the X font and get its id for this font, size and angle UNZOOMED */
- X /* this is to get widths etc for the unzoomed chars */
- X canvas_font = lookfont(x_fontnum(work_psflag, work_font),
- X work_fontsize, work_angle*M_PI/180.0);
- X
- X toggle_textmarker(cur_t);
- X draw_text(cur_t, ERASE);
- X base_x = cur_t->base_x;
- X base_y = cur_t->base_y;
- X length = cur_t->length;
- X switch (cur_t->type) {
- X case T_CENTER_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001)
- X base_x -= length / 2;
- X else if (work_angle < 180.0 - 0.001)
- X base_y += length / 2;
- X else if (work_angle < 270.0 - 0.001)
- X base_x += length / 2;
- X else
- X base_y -= length / 2;
- X break;
- X
- X case T_RIGHT_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001)
- X base_x -= length;
- X else if (work_angle < 180.0 - 0.001)
- X base_y += length;
- X else if (work_angle < 270.0 - 0.001)
- X base_x += length;
- X else
- X base_y -= length;
- X break;
- X } /* switch */
- X if (work_angle < 90.0 - 0.001 || (work_angle >= 180.0 - 0.001
- X && work_angle < 270.0 - 0.001))
- X d = abs(cur_x - base_x);
- X else
- X d = abs(cur_y - base_y);
- X leng_suffix = strlen(cur_t->cstring);
- X /* leng_prefix is # of char in the text before the cursor */
- X leng_prefix = prefix_length(cur_t->cstring, d);
- X leng_suffix -= leng_prefix;
- X cpy_n_char(prefix, cur_t->cstring, leng_prefix);
- X strcpy(suffix, &cur_t->cstring[leng_prefix]);
- X tsize = pf_textwidth(canvas_font, leng_prefix, prefix);
- X
- X if (work_angle < 90.0 - 0.001) {
- X cur_x = base_x + tsize.x;
- X cur_y = base_y;
- X } else if (work_angle < 180.0 - 0.001) {
- X cur_x = base_x;
- X cur_y = base_y - tsize.x;
- X } else if (work_angle < 270.0 - 0.001) {
- X cur_x = base_x - tsize.x;
- X cur_y = base_y;
- X } else {
- X cur_x = base_x;
- X cur_y = base_y + tsize.x;
- X }
- X }
- X char_ht = rot_char_height(canvas_font);
- X initialize_char_handler(canvas_win, finish_text_input,
- X base_x, base_y);
- X draw_char_string();
- X}
- X
- Xstatic
- XF_text *
- Xnew_text()
- X{
- X F_text *text;
- X PR_SIZE size;
- X
- X if ((text = create_text()) == NULL)
- X return (NULL);
- X
- X if ((text->cstring = new_string(leng_prefix + 1)) == NULL) {
- X free((char *) text);
- X return (NULL);
- X }
- X text->type = work_textjust;
- X text->font = work_font; /* put in current font number */
- X text->fontstruct = work_fontstruct;
- X text->size = work_fontsize;
- X text->angle = work_angle/180.0*M_PI; /* convert to radians */
- X text->flags = cur_textflags;
- X text->color = cur_color;
- X text->depth = cur_depth;
- X text->pen = 0;
- X size = pf_textwidth(canvas_font, leng_prefix, prefix);
- X text->length = size.x; /* in pixels */
- X text->height = size.y; /* in pixels */
- X text->base_x = base_x;
- X text->base_y = base_y;
- X strcpy(text->cstring, prefix);
- X text->next = NULL;
- X return (text);
- X}
- X
- Xstatic int
- Xcpy_n_char(dst, src, n)
- X char *dst, *src;
- X int n;
- X{
- X /* src must be longer than n chars */
- X
- X while (n--)
- X *dst++ = *src++;
- X *dst = '\0';
- X}
- X
- Xstatic int
- Xprefix_length(string, where_p)
- X char *string;
- X int where_p;
- X{
- X /* c stands for character unit and p for pixel unit */
- X int l, len_c, len_p;
- X int char_wid, where_c;
- X PR_SIZE size;
- X
- X len_c = strlen(string);
- X size = pf_textwidth(canvas_font, len_c, string);
- X len_p = size.x;
- X if (where_p >= len_p)
- X return (len_c); /* entire string is the prefix */
- X
- X char_wid = rot_char_width(canvas_font);
- X where_c = where_p / char_wid; /* estimated char position */
- X size = pf_textwidth(canvas_font, where_c, string);
- X l = size.x; /* actual length (pixels) of string of
- X * where_c chars */
- X if (l < where_p) {
- X do { /* add the width of next char to l */
- X l += (char_wid = rot_char_advance(canvas_font,
- X (unsigned char) string[where_c++]));
- X } while (l < where_p);
- X if (l - (char_wid >> 1) >= where_p)
- X where_c--;
- X } else if (l > where_p) {
- X do { /* subtract the width of last char from l */
- X l -= (char_wid = rot_char_advance(canvas_font,
- X (unsigned char) string[--where_c]));
- X } while (l > where_p);
- X if (l + (char_wid >> 1) >= where_p)
- X where_c++;
- X }
- X if (where_c < 0) {
- X fprintf(stderr, "xfig file %s line %d: Error in prefix_length - adjusted\n", __FILE__, __LINE__);
- X where_c = 0;
- X }
- X return (where_c);
- X}
- X
- X/*******************************************************************
- X
- X char handling routines
- X
- X*******************************************************************/
- X
- X#define BLINK_INTERVAL 700 /* milliseconds blink rate */
- X
- Xstatic Window pw;
- Xstatic int ch_height;
- Xstatic int cbase_x, cbase_y;
- Xstatic float rbase_x, rbase_y, rcur_x, rcur_y;
- X
- Xstatic (*cr_proc) ();
- X
- Xstatic
- Xdraw_cursor(x, y)
- X int x, y;
- X{
- X if (work_angle < 90.0 - 0.001) /* 0-89 degrees */
- X pw_vector(pw, x, y, x, y-ch_height, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X else if (work_angle < 180.0 - 0.001) /* 90-179 degrees */
- X pw_vector(pw, x-ch_height, y, x, y, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X else if (work_angle < 270.0 - 0.001) /* 180-269 degrees */
- X pw_vector(pw, x, y+ch_height, x, y, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X else /* 270-359 degrees */
- X pw_vector(pw, x, y, x+ch_height, y, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X}
- X
- Xstatic int
- Xinitialize_char_handler(p, cr, bx, by)
- X Window p;
- X int (*cr) ();
- X int bx, by;
- X{
- X pw = p;
- X cr_proc = cr;
- X rbase_x = cbase_x = bx; /* keep real base so dont have roundoff */
- X rbase_y = cbase_y = by;
- X rcur_x = cur_x;
- X rcur_y = cur_y;
- X
- X ch_height = rot_char_height(canvas_font);
- X turn_on_blinking_cursor(draw_cursor, draw_cursor,
- X cur_x, cur_y, (long) BLINK_INTERVAL);
- X}
- X
- Xstatic int
- Xterminate_char_handler()
- X{
- X turn_off_blinking_cursor();
- X cr_proc = NULL;
- X}
- X
- X/*
- X * we use INV_PAINT below instead of ERASE and PAINT to avoid interactions
- X * with the cursor. It means that we need to do a ERASE before we start the
- X * cursor and a PAINT after it is turned off.
- X */
- X
- Xstatic int
- Xerase_char_string()
- X{
- X pw_text(pw, cbase_x, cbase_y, INV_PAINT, canvas_zoomed_font,
- X prefix, DEFAULT_COLOR);
- X if (leng_suffix)
- X pw_text(pw, cur_x, cur_y, INV_PAINT, canvas_zoomed_font,
- X suffix, DEFAULT_COLOR);
- X}
- X
- Xstatic int
- Xdraw_char_string()
- X{
- X pw_text(pw, cbase_x, cbase_y, INV_PAINT, canvas_zoomed_font,
- X prefix, DEFAULT_COLOR);
- X if (leng_suffix)
- X pw_text(pw, cur_x, cur_y, INV_PAINT, canvas_zoomed_font,
- X suffix, DEFAULT_COLOR);
- X move_blinking_cursor(cur_x, cur_y);
- X}
- X
- Xstatic int
- Xdraw_suffix()
- X{
- X if (leng_suffix)
- X pw_text(pw, cur_x, cur_y, PAINT, canvas_zoomed_font,
- X suffix, DEFAULT_COLOR);
- X}
- X
- Xstatic int
- Xerase_suffix()
- X{
- X if (leng_suffix)
- X pw_text(pw, cur_x, cur_y, INV_PAINT, canvas_zoomed_font,
- X suffix, DEFAULT_COLOR);
- X}
- X
- Xstatic int
- Xdraw_char(c)
- Xchar c;
- X{
- X char s[2];
- X s[0]=c;
- X s[1]='\0';
- X pw_text(pw, cur_x, cur_y, INV_PAINT, canvas_zoomed_font,
- X s, DEFAULT_COLOR);
- X}
- X
- Xchar_handler(c)
- X unsigned char c;
- X{
- X float cwidth, cw2;
- X
- X if (cr_proc == NULL)
- X return;
- X
- X if (c == CR || c == NL) {
- X new_text_line();
- X } else if (c == DEL || c == CTRL_H) {
- X if (leng_prefix > 0) {
- X erase_char_string();
- X cwidth = (float) rot_char_advance(canvas_font,
- X (unsigned char) prefix[leng_prefix - 1]);
- X cw2 = cwidth/2.0;
- X /* correct text/cursor posn for justification and zoom factor */
- X switch (work_textjust) {
- X case T_LEFT_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001)
- X rcur_x -= cwidth; /* 0-89 deg, move the suffix left */
- X else if (work_angle < 180.0 - 0.001)
- X rcur_y += cwidth; /* 90-179 deg, move suffix down */
- X else if (work_angle < 270.0 - 0.001)
- X rcur_x += cwidth; /* 180-269 deg, move suffix right */
- X else
- X rcur_y -= cwidth; /* 270-359 deg, move suffix up */
- X break;
- X case T_CENTER_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001) {
- X rbase_x += cw2; /* 0-89 deg, move base right cw/2 */
- X rcur_x -= cw2; /* move suffix left by cw/2 */
- X } else if (work_angle < 180.0 - 0.001) {
- X rbase_y -= cw2; /* 90-179 deg, move base up cw/2 */
- X rcur_y += cw2; /* move suffix down cw/2 */
- X } else if (work_angle < 270.0 - 0.001) {
- X rbase_x -= cw2; /* 180-269 deg, move base left cw/2 */
- X rcur_x += cw2; /* move suffix right cw/2 */
- X } else {
- X rbase_y += cw2; /* 270-359 deg, move base down cw/2 */
- X rcur_y -= cw2; /* move suffix up cw/2 */
- X }
- X break;
- X case T_RIGHT_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001)
- X rbase_x += cwidth; /* 0-89 deg, move the prefix right */
- X else if (work_angle < 180.0 - 0.001)
- X rbase_y -= cwidth; /* 90-179 deg, move prefix up */
- X else if (work_angle < 270.0 - 0.001)
- X rbase_x -= cwidth; /* 180-269 deg, move prefix left */
- X else
- X rbase_y += cwidth; /* 270-359 deg, move prefix down */
- X break;
- X }
- X prefix[--leng_prefix] = '\0';
- X cbase_x = rbase_x; /* fix */
- X cbase_y = rbase_y;
- X cur_x = rcur_x;
- X cur_y = rcur_y;
- X draw_char_string();
- X }
- X } else if (c == CTRL_X) {
- X if (leng_prefix > 0) {
- X erase_char_string();
- X switch (work_textjust) {
- X case T_CENTER_JUSTIFIED:
- X while (leng_prefix--) /* subtract char width/2 per char */
- X if (work_angle < 90.0 - 0.001) /* 0-89 degrees */
- X rcur_x -= rot_char_advance(canvas_font,
- X (unsigned char) prefix[leng_prefix]) / 2.0;
- X else if (work_angle < 180.0 - 0.001) /* 90-179 degrees */
- X rcur_y += rot_char_advance(canvas_font,
- X (unsigned char) prefix[leng_prefix]) / 2.0;
- X else if (work_angle < 270.0 - 0.001) /* 180-269 degrees */
- X rcur_x += rot_char_advance(canvas_font,
- X (unsigned char) prefix[leng_prefix]) / 2.0;
- X else /* 270-359 degrees */
- X rcur_y -= rot_char_advance(canvas_font,
- X (unsigned char) prefix[leng_prefix]) / 2.0;
- X cur_x = cbase_x = rbase_x = rcur_x;
- X cur_y = cbase_y = rbase_y = rcur_y;
- X break;
- X case T_RIGHT_JUSTIFIED:
- X cbase_x = rbase_x = cur_x = rcur_x;
- X cbase_y = rbase_y = cur_y = rcur_y;
- X break;
- X case T_LEFT_JUSTIFIED:
- X cur_x = rcur_x = cbase_x = rbase_x;
- X cur_y = rcur_y = cbase_y = rbase_y;
- X break;
- X }
- X leng_prefix = 0;
- X *prefix = '\0';
- X draw_char_string();
- X }
- X } else if (c < SP) {
- X put_msg("Invalid character ignored");
- X } else if (leng_prefix + leng_suffix == BUF_SIZE) {
- X put_msg("Text buffer is full, character is ignored");
- X
- X /* normal text character */
- X } else {
- X draw_char_string();
- X cwidth = rot_char_advance(canvas_font, (unsigned char) c);
- X cw2 = cwidth/2.0;
- X /* correct text/cursor posn for justification and zoom factor */
- X switch (work_textjust) {
- X case T_LEFT_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001)
- X rcur_x += cwidth; /* 0-89 deg, move the suffix right */
- X else if (work_angle < 180.0 - 0.001)
- X rcur_y -= cwidth; /* 90-179 deg, move suffix up */
- X else if (work_angle < 270.0 - 0.001)
- X rcur_x -= cwidth; /* 180-269 deg, move suffix left */
- X else
- X rcur_y += cwidth; /* 270-359 deg, move suffix down */
- X break;
- X case T_CENTER_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001) {
- X rbase_x -= cw2; /* 0-89 deg, move base left cw/2 */
- X rcur_x += cw2; /* move suffix right by cw/2 */
- X } else if (work_angle < 180.0 - 0.001) {
- X rbase_y += cw2; /* 90-179 deg, move base down cw/2 */
- X rcur_y -= cw2; /* move suffix up cw/2 */
- X } else if (work_angle < 270.0 - 0.001) {
- X rbase_x += cw2; /* 180-269 deg, move base right cw/2 */
- X rcur_x -= cw2; /* move suffix left cw/2 */
- X } else {
- X rbase_y -= cw2; /* 270-359 deg, move base up cw/2 */
- X rcur_y += cw2; /* move suffix down cw/2 */
- X }
- X break;
- X case T_RIGHT_JUSTIFIED:
- X if (work_angle < 90.0 - 0.001)
- X rbase_x -= cwidth; /* 0-89 deg, move the prefix left */
- X else if (work_angle < 180.0 - 0.001)
- X rbase_y += cwidth; /* 90-179 deg, move prefix down */
- X else if (work_angle < 270.0 - 0.001)
- X rbase_x += cwidth; /* 180-269 deg, move prefix right */
- X else
- X rbase_y -= cwidth; /* 270-359 deg, move prefix up */
- X break;
- X }
- X prefix[leng_prefix++] = c;
- X prefix[leng_prefix] = '\0';
- X cbase_x = rbase_x;
- X cbase_y = rbase_y;
- X cur_x = rcur_x;
- X cur_y = rcur_y;
- X draw_char_string();
- X }
- X}
- X
- X/*******************************************************************
- X
- X blinking cursor handling routines
- X
- X*******************************************************************/
- X
- Xstatic int cursor_on, cursor_is_moving;
- Xstatic int cursor_x, cursor_y;
- Xstatic int (*erase) ();
- Xstatic int (*draw) ();
- Xstatic XtTimerCallbackProc blink();
- Xstatic unsigned long blink_timer;
- Xstatic XtIntervalId blinkid;
- Xstatic int stop_blinking = False;
- Xstatic int cur_is_blinking = False;
- X
- Xstatic int
- Xturn_on_blinking_cursor(draw_cursor, erase_cursor, x, y, msec)
- X int (*draw_cursor) ();
- X int (*erase_cursor) ();
- X int x, y;
- X unsigned long msec;
- X{
- X draw = draw_cursor;
- X erase = erase_cursor;
- X cursor_is_moving = 0;
- X cursor_x = x;
- X cursor_y = y;
- X blink_timer = msec;
- X draw(x, y);
- X cursor_on = 1;
- X if (!cur_is_blinking) { /* if we are already blinking, don't request
- X * another */
- X blinkid = XtAppAddTimeOut(tool_app, blink_timer, (XtTimerCallbackProc) blink,
- X (XtPointer) NULL);
- X cur_is_blinking = True;
- X }
- X stop_blinking = False;
- X}
- X
- Xstatic int
- Xturn_off_blinking_cursor()
- X{
- X if (cursor_on)
- X erase(cursor_x, cursor_y);
- X stop_blinking = True;
- X}
- X
- Xstatic XtTimerCallbackProc
- Xblink(client_data, id)
- X XtPointer client_data;
- X XtIntervalId *id;
- X{
- X if (!stop_blinking) {
- X if (cursor_is_moving)
- X return (0);
- X if (cursor_on) {
- X erase(cursor_x, cursor_y);
- X cursor_on = 0;
- X } else {
- X draw(cursor_x, cursor_y);
- X cursor_on = 1;
- X }
- X blinkid = XtAppAddTimeOut(tool_app, blink_timer, (XtTimerCallbackProc) blink,
- X (XtPointer) NULL);
- X } else {
- X stop_blinking = False; /* signal that we've stopped */
- X cur_is_blinking = False;
- X }
- X return (0);
- X}
- X
- Xstatic int
- Xmove_blinking_cursor(x, y)
- X int x, y;
- X{
- X cursor_is_moving = 1;
- X if (cursor_on)
- X erase(cursor_x, cursor_y);
- X cursor_x = x;
- X cursor_y = y;
- X draw(cursor_x, cursor_y);
- X cursor_on = 1;
- X cursor_is_moving = 0;
- X}
- X
- Xreload_text_fstructs()
- X{
- X F_text *t;
- X
- X /* reload the compound objects' texts */
- X reload_compoundfont(objects.compounds);
- X /* and the separate texts */
- X for (t=objects.texts; t != NULL; t = t->next)
- X reload_text_fstruct(t);
- X}
- X
- X/*
- X * Reload the font structure for texts in compounds.
- X */
- X
- Xreload_compoundfont(compounds)
- X F_compound *compounds;
- X{
- X F_compound *c;
- X F_text *t;
- X
- X for (c = compounds; c != NULL; c = c->next) {
- X reload_compoundfont(c->compounds);
- X for (t=c->texts; t != NULL; t = t->next)
- X reload_text_fstruct(t);
- X }
- X}
- X
- Xreload_text_fstruct(t)
- X F_text *t;
- X{
- X t->fontstruct = lookfont(x_fontnum(t->flags, t->font),
- X round(t->size*zoomscale), t->angle);
- X}
- END_OF_FILE
- if test 21193 -ne `wc -c <'d_text.c'`; then
- echo shar: \"'d_text.c'\" unpacked with wrong size!
- fi
- # end of 'd_text.c'
- fi
- if test -f 'u_elastic.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'u_elastic.c'\"
- else
- echo shar: Extracting \"'u_elastic.c'\" \(20435 characters\)
- sed "s/^X//" >'u_elastic.c' <<'END_OF_FILE'
- X/*
- X * FIG : Facility for Interactive Generation of figures
- X * Copyright (c) 1985 by Supoj Sutanthavibul
- X *
- X * "Permission to use, copy, modify, distribute, and sell this software and its
- X * documentation for any purpose is hereby granted without fee, provided that
- X * the above copyright notice appear in all copies and that both the copyright
- X * notice and this permission notice appear in supporting documentation.
- X * No representations are made about the suitability of this software for
- X * any purpose. It is provided "as is" without express or implied warranty."
- X */
- X
- X#include "fig.h"
- X#include "resources.h"
- X#include "mode.h"
- X#include "object.h"
- X#include "paintop.h"
- X#include "u_elastic.h"
- X#include "w_canvas.h"
- X#include "w_setup.h"
- X#include "w_zoom.h"
- X
- Xextern float compute_angle();
- X
- X/********************** EXPORTS **************/
- X
- Xint constrained;
- Xint fix_x, fix_y, work_numsides;
- Xfloat cur_angle;
- Xint x1off, x2off, y1off, y2off;
- XCursor cur_latexcursor;
- Xint from_x, from_y;
- Xdouble cosa, sina;
- Xint movedpoint_num;
- XF_point *left_point, *right_point;
- X
- X/**************** LOCAL ***********/
- X
- Xstatic void elastic_links();
- X
- X/*************************** BOXES *************************/
- X
- Xelastic_box(x1, y1, x2, y2)
- X int x1, y1, x2, y2;
- X{
- X /* line_style = RUBBER_LINE so that we don't scale it */
- X pw_vector(canvas_win, x1, y1, x1, y2, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X pw_vector(canvas_win, x1, y2, x2, y2, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X pw_vector(canvas_win, x2, y2, x2, y1, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X pw_vector(canvas_win, x2, y1, x1, y1, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X}
- X
- Xelastic_movebox()
- X{
- X register int x1, y1, x2, y2;
- X
- X x1 = cur_x + x1off;
- X x2 = cur_x + x2off;
- X y1 = cur_y + y1off;
- X y2 = cur_y + y2off;
- X elastic_box(x1, y1, x2, y2);
- X elastic_links(cur_x - fix_x, cur_y - fix_y, 1.0, 1.0);
- X}
- X
- Xmoving_box(x, y)
- X int x, y;
- X{
- X elastic_movebox();
- X adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_movebox();
- X}
- X
- Xresizing_box(x, y)
- X int x, y;
- X{
- X elastic_box(fix_x, fix_y, cur_x, cur_y);
- X cur_x = x;
- X cur_y = y;
- X elastic_box(fix_x, fix_y, cur_x, cur_y);
- X boxsize_msg();
- X}
- X
- Xconstrained_resizing_box(x, y)
- X int x, y;
- X{
- X elastic_box(fix_x, fix_y, cur_x, cur_y);
- X adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
- X elastic_box(fix_x, fix_y, cur_x, cur_y);
- X boxsize_msg();
- X}
- X
- Xscaling_compound(x, y)
- X int x, y;
- X{
- X elastic_scalecompound(cur_c);
- X adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_scalecompound(cur_c);
- X}
- X
- Xelastic_scalecompound(c)
- X F_compound *c;
- X{
- X int newx, newy, oldx, oldy, x1, y1, x2, y2;
- X float newd, oldd, scalefact;
- X
- X newx = cur_x - fix_x;
- X newy = cur_y - fix_y;
- X newd = sqrt((double) (newx * newx + newy * newy));
- X oldx = from_x - fix_x;
- X oldy = from_y - fix_y;
- X oldd = sqrt((double) (oldx * oldx + oldy * oldy));
- X scalefact = newd / oldd;
- X x1 = fix_x + (c->secorner.x - fix_x) * scalefact;
- X y1 = fix_y + (c->secorner.y - fix_y) * scalefact;
- X x2 = fix_x + (c->nwcorner.x - fix_x) * scalefact;
- X y2 = fix_y + (c->nwcorner.y - fix_y) * scalefact;
- X elastic_box(x1, y1, x2, y2);
- X}
- X
- X/*************************** LINES *************************/
- X
- Xelastic_line()
- X{
- X pw_vector(canvas_win, fix_x, fix_y, cur_x, cur_y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X}
- X
- Xfreehand_line(x, y)
- X int x, y;
- X{
- X elastic_line();
- X cur_x = x;
- X cur_y = y;
- X elastic_line();
- X length_msg(MSG_LENGTH);
- X}
- X
- Xlatex_line(x, y)
- X int x, y;
- X{
- X Cursor c;
- X
- X elastic_line();
- X latex_endpoint(fix_x, fix_y, x, y, &cur_x, &cur_y, latexarrow_mode,
- X (cur_pointposn == P_ANY) ? 1 : posn_rnd[cur_pointposn]);
- X elastic_line();
- X length_msg(MSG_LENGTH);
- X c = (x == cur_x && y == cur_y) ? null_cursor : crosshair_cursor;
- X if (c != cur_cursor) {
- X set_temp_cursor(c);
- X cur_cursor = c;
- X }
- X}
- X
- Xconstrainedangle_line(x, y)
- X int x, y;
- X{
- X float angle, dx, dy;
- X
- X if (x == cur_x && y == cur_y)
- X return;
- X
- X dx = x - fix_x;
- X dy = fix_y - y;
- X if (sqrt((double) (dx * dx + dy * dy)) < 7)
- X return;
- X if (dx == 0)
- X angle = -90;
- X else
- X angle = 180 * atan((double) (dy / dx)) / 3.1416;
- X
- X elastic_line();
- X if (manhattan_mode) {
- X if (mountain_mode) {
- X if (angle < -67.5)
- X angle90_line(x, y);
- X else if (angle < -22.5)
- X angle135_line(x, y);
- X else if (angle < 22.5)
- X angle0_line(x, y);
- X else if (angle < 67.5)
- X angle45_line(x, y);
- X else
- X angle90_line(x, y);
- X } else {
- X if (angle < -45)
- X angle90_line(x, y);
- X else if (angle < 45)
- X angle0_line(x, y);
- X else
- X angle90_line(x, y);
- X }
- X } else {
- X if (angle < 0)
- X angle135_line(x, y);
- X else
- X angle45_line(x, y);
- X }
- X elastic_line();
- X length_msg(MSG_LENGTH);
- X}
- X
- Xangle0_line(x, y)
- X int x, y;
- X{
- X cur_x = x;
- X cur_y = fix_y;
- X}
- X
- Xangle90_line(x, y)
- X int x, y;
- X{
- X cur_y = y;
- X cur_x = fix_x;
- X}
- X
- Xangle45_line(x, y)
- X int x, y;
- X{
- X if (abs(x - fix_x) < abs(y - fix_y)) {
- X cur_x = fix_x - y + fix_y;
- X cur_y = y;
- X } else {
- X cur_y = fix_y + fix_x - x;
- X cur_x = x;
- X }
- X}
- X
- Xangle135_line(x, y)
- X int x, y;
- X{
- X if (abs(x - fix_x) < abs(y - fix_y)) {
- X cur_x = fix_x + y - fix_y;
- X cur_y = y;
- X } else {
- X cur_y = fix_y + x - fix_x;
- X cur_x = x;
- X }
- X}
- X
- Xreshaping_line(x, y)
- X int x, y;
- X{
- X elastic_linelink();
- X adjust_pos(x, y, from_x, from_y, &cur_x, &cur_y);
- X elastic_linelink();
- X /* one or two lines moving with the move point? */
- X if (left_point != NULL && right_point != NULL) {
- X length_msg2(left_point->x,left_point->y,
- X right_point->x,right_point->y,cur_x,cur_y);
- X } else if (left_point != NULL) {
- X altlength_msg(MSG_LENGTH,left_point->x,left_point->y);
- X } else if (right_point != NULL) {
- X altlength_msg(MSG_LENGTH,right_point->x,right_point->y);
- X }
- X}
- X
- Xelastic_linelink()
- X{
- X if (left_point != NULL) {
- X pw_vector(canvas_win, left_point->x, left_point->y,
- X cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X }
- X if (right_point != NULL) {
- X pw_vector(canvas_win, right_point->x, right_point->y,
- X cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X }
- X}
- X
- Xmoving_line(x, y)
- X int x, y;
- X{
- X elastic_moveline(new_l->points);
- X adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_moveline(new_l->points);
- X}
- X
- Xelastic_moveline(pts)
- X F_point *pts;
- X{
- X F_point *p;
- X int dx, dy, x, y, xx, yy;
- X
- X p = pts;
- X if (p->next == NULL) { /* dot */
- X pw_vector(canvas_win, cur_x, cur_y, cur_x, cur_y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X } else {
- X dx = cur_x - fix_x;
- X dy = cur_y - fix_y;
- X x = p->x + dx;
- X y = p->y + dy;
- X for (p = p->next; p != NULL; x = xx, y = yy, p = p->next) {
- X xx = p->x + dx;
- X yy = p->y + dy;
- X pw_vector(canvas_win, x, y, xx, yy, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X }
- X }
- X elastic_links(dx, dy, 1.0, 1.0);
- X}
- X
- Xstatic void
- Xelastic_links(dx, dy, sx, sy)
- X int dx, dy;
- X float sx, sy;
- X{
- X F_linkinfo *k;
- X
- X if (cur_linkmode == SMART_OFF)
- X return;
- X
- X for (k = cur_links; k != NULL; k = k->next)
- X if (k->prevpt == NULL) {/* dot */
- X pw_vector(canvas_win, k->endpt->x, k->endpt->y,
- X k->endpt->x, k->endpt->y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X } else {
- X if (cur_linkmode == SMART_MOVE)
- X pw_vector(canvas_win, k->endpt->x + dx, k->endpt->y + dy,
- X k->prevpt->x, k->prevpt->y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X else if (cur_linkmode == SMART_SLIDE) {
- X if (k->endpt->x == k->prevpt->x) {
- X if (!k->two_pts)
- X pw_vector(canvas_win, k->prevpt->x,
- X k->prevpt->y, k->prevpt->x + dx, k->prevpt->y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X pw_vector(canvas_win, k->endpt->x + dx,
- X k->endpt->y + dy, k->prevpt->x + dx, k->prevpt->y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X } else {
- X if (!k->two_pts)
- X pw_vector(canvas_win, k->prevpt->x,
- X k->prevpt->y, k->prevpt->x, k->prevpt->y + dy,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X pw_vector(canvas_win, k->endpt->x + dx,
- X k->endpt->y + dy, k->prevpt->x, k->prevpt->y + dy,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X }
- X }
- X }
- X}
- X
- Xscaling_line(x, y)
- X int x, y;
- X{
- X elastic_scalepts(cur_l->points);
- X adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_scalepts(cur_l->points);
- X /* could add check for box here and do a boxsize_msg */
- X}
- X
- Xscaling_spline(x, y)
- X int x, y;
- X{
- X elastic_scalepts(cur_s->points);
- X adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_scalepts(cur_s->points);
- X}
- X
- Xelastic_scalepts(pts)
- X F_point *pts;
- X{
- X F_point *p;
- X int newx, newy, oldx, oldy, ox, oy, xx, yy;
- X float newd, oldd, scalefact;
- X
- X p = pts;
- X newx = cur_x - fix_x;
- X newy = cur_y - fix_y;
- X newd = sqrt((double) (newx * newx + newy * newy));
- X
- X oldx = from_x - fix_x;
- X oldy = from_y - fix_y;
- X oldd = sqrt((double) (oldx * oldx + oldy * oldy));
- X
- X scalefact = newd / oldd;
- X ox = fix_x + (p->x - fix_x) * scalefact;
- X oy = fix_y + (p->y - fix_y) * scalefact;
- X for (p = p->next; p != NULL; ox = xx, oy = yy, p = p->next) {
- X xx = fix_x + (p->x - fix_x) * scalefact;
- X yy = fix_y + (p->y - fix_y) * scalefact;
- X pw_vector(canvas_win, ox, oy, xx, yy, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X }
- X}
- X
- Xelastic_poly(x1, y1, x2, y2, numsides)
- X int x1, y1, x2, y2, numsides;
- X{
- X register float angle;
- X register int nx, ny, dx, dy, i;
- X float init_angle, mag;
- X int ox, oy;
- X
- X dx = x2 - x1;
- X dy = y2 - y1;
- X mag = sqrt((double) (dx * dx + dy * dy));
- X init_angle = compute_angle((float) dx, (float) dy);
- X ox = x2;
- X oy = y2;
- X
- X /* now append numsides points */
- X for (i = 1; i < numsides; i++) {
- X angle = init_angle - M_2PI * (float) i / (float) numsides;
- X if (angle < 0)
- X angle += M_2PI;
- X nx = x1 + round(mag * cos((double) angle));
- X ny = y1 + round(mag * sin((double) angle));
- X pw_vector(canvas_win, nx, ny, ox, oy, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X ox = nx;
- X oy = ny;
- X }
- X pw_vector(canvas_win, ox, oy, x2, y2, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X}
- X
- Xresizing_poly(x, y)
- X int x, y;
- X{
- X elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides);
- X cur_x = x;
- X cur_y = y;
- X work_numsides = cur_numsides;
- X elastic_poly(fix_x, fix_y, cur_x, cur_y, work_numsides);
- X length_msg(MSG_LENGTH);
- X}
- X
- X/*********************** ELLIPSES *************************/
- X
- Xelastic_ebr()
- X{
- X register int x1, y1, x2, y2;
- X int rx, ry;
- X
- X rx = cur_x - fix_x;
- X ry = cur_y - fix_y;
- X if (cur_angle != 0.0) {
- X angle_ellipse(fix_x, fix_y, rx, ry, cur_angle,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X } else {
- X x1 = fix_x + rx;
- X x2 = fix_x - rx;
- X y1 = fix_y + ry;
- X y2 = fix_y - ry;
- X pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X }
- X}
- X
- Xresizing_ebr(x, y)
- X int x, y;
- X{
- X elastic_ebr();
- X cur_x = x;
- X cur_y = y;
- X elastic_ebr();
- X length_msg(MSG_RADIUS);
- X}
- X
- Xconstrained_resizing_ebr(x, y)
- X int x, y;
- X{
- X elastic_ebr();
- X adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
- X elastic_ebr();
- X length_msg(MSG_RADIUS);
- X}
- X
- Xelastic_ebd()
- X{
- X int centx,centy;
- X centx = (fix_x+cur_x)/2;
- X centy = (fix_y+cur_y)/2;
- X if (cur_angle != 0.0) {
- X angle_ellipse(centx, centy, abs(cur_x-fix_x)/2,
- X abs(cur_y-fix_y)/2, cur_angle,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X } else {
- X pw_curve(canvas_win, fix_x, fix_y, cur_x, cur_y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X }
- X length_msg(MSG_DIAM);
- X}
- X
- Xresizing_ebd(x, y)
- X int x, y;
- X{
- X elastic_ebd();
- X cur_x = x;
- X cur_y = y;
- X elastic_ebd();
- X length_msg(MSG_DIAM);
- X}
- X
- Xconstrained_resizing_ebd(x, y)
- X int x, y;
- X{
- X elastic_ebd();
- X adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
- X elastic_ebd();
- X length_msg(MSG_DIAM);
- X}
- X
- Xelastic_cbr()
- X{
- X register int radius, x1, y1, x2, y2, rx, ry;
- X
- X rx = cur_x - fix_x;
- X ry = cur_y - fix_y;
- X radius = round(sqrt((double) (rx * rx + ry * ry)));
- X x1 = fix_x + radius;
- X x2 = fix_x - radius;
- X y1 = fix_y + radius;
- X y2 = fix_y - radius;
- X pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X}
- X
- Xresizing_cbr(x, y)
- X int x, y;
- X{
- X elastic_cbr();
- X cur_x = x;
- X cur_y = y;
- X elastic_cbr();
- X length_msg(MSG_RADIUS);
- X}
- X
- Xelastic_cbd()
- X{
- X register int x1, y1, x2, y2;
- X int radius, rx, ry;
- X
- X rx = (cur_x - fix_x) / 2;
- X ry = (cur_y - fix_y) / 2;
- X radius = round(sqrt((double) (rx * rx + ry * ry)));
- X x1 = fix_x + rx + radius;
- X x2 = fix_x + rx - radius;
- X y1 = fix_y + ry + radius;
- X y2 = fix_y + ry - radius;
- X pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X}
- X
- Xresizing_cbd(x, y)
- X int x, y;
- X{
- X elastic_cbd();
- X cur_x = x;
- X cur_y = y;
- X elastic_cbd();
- X length_msg(MSG_DIAM);
- X}
- X
- Xconstrained_resizing_cbd(x, y)
- X int x, y;
- X{
- X elastic_cbd();
- X adjust_box_pos(x, y, from_x, from_y, &cur_x, &cur_y);
- X elastic_cbd();
- X length_msg(MSG_DIAM);
- X}
- X
- Xelastic_moveellipse()
- X{
- X register int x1, y1, x2, y2;
- X
- X x1 = cur_x + x1off;
- X x2 = cur_x + x2off;
- X y1 = cur_y + y1off;
- X y2 = cur_y + y2off;
- X if (cur_angle != 0.0) {
- X angle_ellipse((x1+x2)/2, (y1+y2)/2, abs(x1-x2)/2, abs(y1-y2)/2, cur_angle,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X } else {
- X pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X }
- X}
- X
- Xmoving_ellipse(x, y)
- X int x, y;
- X{
- X elastic_moveellipse();
- X adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_moveellipse();
- X}
- X
- Xelastic_scaleellipse(e)
- X F_ellipse *e;
- X{
- X register int x1, y1, x2, y2;
- X int rx, ry;
- X int newx, newy, oldx, oldy;
- X float newd, oldd, scalefact;
- X
- X newx = cur_x - fix_x;
- X newy = cur_y - fix_y;
- X newd = sqrt((double) (newx * newx + newy * newy));
- X
- X oldx = from_x - fix_x;
- X oldy = from_y - fix_y;
- X oldd = sqrt((double) (oldx * oldx + oldy * oldy));
- X
- X scalefact = newd / oldd;
- X
- X rx = e->radiuses.x * scalefact;
- X ry = e->radiuses.y * scalefact;
- X if (cur_angle != 0.0) {
- X angle_ellipse(e->center.x, e->center.y, rx, ry, cur_angle,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X } else {
- X x1 = fix_x + rx;
- X x2 = fix_x - rx;
- X y1 = fix_y + ry;
- X y2 = fix_y - ry;
- X pw_curve(canvas_win, x1, y1, x2, y2, INV_PAINT, 1,
- X RUBBER_LINE, 0.0, 0, DEFAULT_COLOR);
- X }
- X}
- X
- Xscaling_ellipse(x, y)
- X int x, y;
- X{
- X elastic_scaleellipse(cur_e);
- X adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_scaleellipse(cur_e);
- X}
- X
- X/*************************** ARCS *************************/
- X
- Xreshaping_arc(x, y)
- X int x, y;
- X{
- X elastic_arclink();
- X adjust_pos(x, y, cur_a->point[movedpoint_num].x,
- X cur_a->point[movedpoint_num].y, &cur_x, &cur_y);
- X elastic_arclink();
- X if (movedpoint_num == 1) {
- X /* middle point */
- X length_msg2(cur_a->point[0].x, cur_a->point[0].y,
- X cur_a->point[2].x, cur_a->point[2].y,
- X cur_x, cur_y);
- X } else {
- X /* end point */
- X altlength_msg(MSG_LENGTH,cur_a->point[1].x,cur_a->point[1].y);
- X }
- X}
- X
- Xelastic_arclink()
- X{
- X switch (movedpoint_num) {
- X case 0:
- X pw_vector(canvas_win, cur_x, cur_y,
- X cur_a->point[1].x, cur_a->point[1].y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X break;
- X case 1:
- X pw_vector(canvas_win, cur_a->point[0].x, cur_a->point[0].y,
- X cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X pw_vector(canvas_win, cur_a->point[2].x, cur_a->point[2].y,
- X cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X break;
- X default:
- X pw_vector(canvas_win, cur_a->point[1].x, cur_a->point[1].y,
- X cur_x, cur_y, INV_PAINT, 1, RUBBER_LINE, 0.0,
- X DEFAULT_COLOR);
- X }
- X}
- X
- Xmoving_arc(x, y)
- X int x, y;
- X{
- X elastic_movearc(new_a);
- X adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_movearc(new_a);
- X}
- X
- Xelastic_movearc(a)
- X F_arc *a;
- X{
- X int dx, dy;
- X
- X dx = cur_x - fix_x;
- X dy = cur_y - fix_y;
- X pw_vector(canvas_win, a->point[0].x + dx, a->point[0].y + dy,
- X a->point[1].x + dx, a->point[1].y + dy,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X pw_vector(canvas_win, a->point[1].x + dx, a->point[1].y + dy,
- X a->point[2].x + dx, a->point[2].y + dy,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X}
- X
- Xscaling_arc(x, y)
- X int x, y;
- X{
- X elastic_scalearc(cur_a);
- X adjust_box_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_scalearc(cur_a);
- X}
- X
- Xelastic_scalearc(a)
- X F_arc *a;
- X{
- X int newx, newy, oldx, oldy;
- X float newd, oldd, scalefact;
- X F_pos p0, p1, p2;
- X
- X newx = cur_x - fix_x;
- X newy = cur_y - fix_y;
- X newd = sqrt((double) (newx * newx + newy * newy));
- X
- X oldx = from_x - fix_x;
- X oldy = from_y - fix_y;
- X oldd = sqrt((double) (oldx * oldx + oldy * oldy));
- X
- X scalefact = newd / oldd;
- X
- X p0 = a->point[0];
- X p1 = a->point[1];
- X p2 = a->point[2];
- X p0.x = fix_x + (p0.x - fix_x) * scalefact;
- X p0.y = fix_y + (p0.y - fix_y) * scalefact;
- X p1.x = fix_x + (p1.x - fix_x) * scalefact;
- X p1.y = fix_y + (p1.y - fix_y) * scalefact;
- X p2.x = fix_x + (p2.x - fix_x) * scalefact;
- X p2.y = fix_y + (p2.y - fix_y) * scalefact;
- X
- X pw_vector(canvas_win, p0.x, p0.y, p1.x, p1.y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X pw_vector(canvas_win, p1.x, p1.y, p2.x, p2.y,
- X INV_PAINT, 1, RUBBER_LINE, 0.0, DEFAULT_COLOR);
- X}
- X
- X/*************************** TEXT *************************/
- X
- Xmoving_text(x, y)
- X int x, y;
- X{
- X elastic_movetext();
- X adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_movetext();
- X}
- X
- Xelastic_movetext()
- X{
- X pw_text(canvas_win, cur_x + x1off, cur_y + y1off, INV_PAINT,
- X new_t->fontstruct, new_t->cstring, new_t->color);
- X}
- X
- X
- X/*************************** SPLINES *************************/
- X
- Xmoving_spline(x, y)
- X int x, y;
- X{
- X elastic_moveline(new_s->points);
- X adjust_pos(x, y, fix_x, fix_y, &cur_x, &cur_y);
- X elastic_moveline(new_s->points);
- X}
- X
- X/*********** AUXILIARY FUNCTIONS FOR CONSTRAINED MOVES ******************/
- X
- Xadjust_box_pos(curs_x, curs_y, orig_x, orig_y, ret_x, ret_y)
- X int curs_x, curs_y, orig_x, orig_y;
- X int *ret_x, *ret_y;
- X{
- X int xx, sgn_csr2fix_x, yy, sgn_csr2fix_y;
- X double mag_csr2fix_x, mag_csr2fix_y;
- X
- X switch (constrained) {
- X case MOVE_ARB:
- X *ret_x = curs_x;
- X *ret_y = curs_y;
- X break;
- X case BOX_HSTRETCH:
- X *ret_x = curs_x;
- X *ret_y = orig_y;
- X break;
- X case BOX_VSTRETCH:
- X *ret_x = orig_x;
- X *ret_y = curs_y;
- X break;
- X default:
- X /* calculate where scaled and stretched box corners would be */
- X xx = curs_x - fix_x;
- X sgn_csr2fix_x = signof(xx);
- X mag_csr2fix_x = (double) abs(xx);
- X
- X yy = curs_y - fix_y;
- X sgn_csr2fix_y = signof(yy);
- X mag_csr2fix_y = (double) abs(yy);
- X
- X if (mag_csr2fix_x * sina > mag_csr2fix_y * cosa) { /* above diagonal */
- X *ret_x = curs_x;
- X if (constrained == BOX_SCALE) {
- X if (cosa == 0.0) {
- X *ret_y = fix_y + sgn_csr2fix_y * (int) (mag_csr2fix_x);
- X } else {
- X *ret_y = fix_y + sgn_csr2fix_y * (int) (mag_csr2fix_x * sina / cosa);
- X }
- X } else {
- X *ret_y = fix_y + sgn_csr2fix_y * abs(fix_y - orig_y);
- X }
- X } else {
- X *ret_y = curs_y;
- X if (constrained == BOX_SCALE) {
- X if (sina == 0.0) {
- X *ret_x = fix_x + sgn_csr2fix_x * (int) (mag_csr2fix_y);
- X } else {
- X *ret_x = fix_x + sgn_csr2fix_x * (int) (mag_csr2fix_y * cosa / sina);
- X }
- X } else {
- X *ret_x = fix_x + sgn_csr2fix_x * abs(fix_x - orig_x);
- X }
- X }
- X } /* switch */
- X}
- X
- Xadjust_pos(curs_x, curs_y, orig_x, orig_y, ret_x, ret_y)
- X int curs_x, curs_y, orig_x, orig_y;
- X int *ret_x, *ret_y;
- X{
- X if (constrained) {
- X if (abs(orig_x - curs_x) > abs(orig_y - curs_y)) {
- X *ret_x = curs_x;
- X *ret_y = orig_y;
- X } else {
- X *ret_x = orig_x;
- X *ret_y = curs_y;
- X }
- X } else {
- X *ret_x = curs_x;
- X *ret_y = curs_y;
- X }
- X}
- END_OF_FILE
- if test 20435 -ne `wc -c <'u_elastic.c'`; then
- echo shar: \"'u_elastic.c'\" unpacked with wrong size!
- fi
- # end of 'u_elastic.c'
- fi
- if test -f 'w_rottext.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'w_rottext.c'\"
- else
- echo shar: Extracting \"'w_rottext.c'\" \(21004 characters\)
- sed "s/^X//" >'w_rottext.c' <<'END_OF_FILE'
- X/*
- X * FIG : Facility for Interactive Generation of figures
- X * Copyright (c) 1992 by Alan Richardson
- X *
- X * "Permission to use, copy, modify, distribute, and sell this software and its
- X * documentation for any purpose is hereby granted without fee, provided that
- X * the above copyright notice appear in all copies and that both the copyright
- X * notice and this permission notice appear in supporting documentation.
- X * No representations are made about the suitability of this software for
- X * any purpose. It is provided "as is" without express or implied warranty."
- X */
- X
- X#include "fig.h"
- X#include "w_rottext.h"
- X
- X/* ---------------------------------------------------------------------- */
- X
- X#define XROTMAX(a, b) ((a)>(b)?(a):(b))
- X
- X/* ---------------------------------------------------------------------- */
- X
- Xchar *my_strdup();
- Xchar *my_strtok();
- XXRotFontStruct *XRotLoadFont();
- Xvoid XRotUnloadFont();
- Xint XRotTextWidth();
- Xint XRotTextHeight();
- Xvoid XRotDrawString();
- Xvoid XRotDrawImageString();
- Xvoid XRotPaintString();
- Xvoid XRotDrawAlignedString();
- Xvoid XRotDrawAlignedImageString();
- Xvoid XRotPaintAlignedString();
- X
- X/* ---------------------------------------------------------------------- */
- X
- X/* *** Routine to mimic `strdup()' (some machines don't have it) *** */
- X
- Xchar *my_strdup(str)
- X char *str;
- X{
- X char *s;
- X
- X if(str==NULL) return (char *)NULL;
- X
- X s=(char *)malloc((unsigned)(strlen(str)+1));
- X if(!s)
- X { fprintf(stderr, "Error: my_strdup(): Couldn't do malloc\n");
- X exit(1); }
- X
- X strcpy(s, str);
- X
- X return s;
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** Routine to replace `strtok' : this one returns a zero
- X length string if it encounters two consecutive delimiters *** */
- X
- Xchar *my_strtok(str1, str2)
- X char *str1, *str2;
- X{
- X char *ret;
- X int i, j, stop;
- X static int start, len;
- X static char *stext;
- X
- X if(str2==NULL)
- X { fprintf(stderr, "Error: my_strtok(): null delimiter string\n");
- X exit(1);
- X }
- X
- X /* initialise if str1 not NULL ... */
- X if(str1!=NULL)
- X { start=0;
- X stext=str1;
- X len=strlen(str1);
- X }
- X
- X /* run out of tokens ? ... */
- X if(start>=len) return (char *)NULL;
- X
- X /* loop through characters ... */
- X for(i=start; i<len; i++)
- X {
- X /* loop through delimiters ... */
- X stop=0;
- X for(j=0; j<strlen(str2); j++) if(stext[i]==str2[j]) stop=1;
- X
- X if(stop) break;
- X }
- X
- X stext[i]='\0';
- X
- X ret=stext+start;
- X
- X start=i+1;
- X
- X return ret;
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** Load the rotated version of a given font *** */
- X
- XXRotFontStruct *XRotLoadFont(dpy, fontname, angle)
- X Display *dpy;
- X char *fontname;
- X float angle;
- X{
- X char val;
- X XImage *I1, *I2;
- X Pixmap canvas;
- X Window root;
- X int screen;
- X GC font_gc;
- X char text[3];
- X XFontStruct *fontstruct;
- X XRotFontStruct *rotfont;
- X int ichar, i, j, index, boxlen, dir;
- X int vert_w, vert_h, vert_len, bit_w, bit_h, bit_len;
- X int min_char, max_char;
- X unsigned char *vertdata, *bitdata;
- X int ascent, descent, lbearing, rbearing;
- X int on=1, off=0;
- X
- X dir=(int)(angle/90.0+0.01);
- X if (dir > 3)
- X dir -= 4;
- X
- X /* useful macros ... */
- X screen=DefaultScreen(dpy);
- X root=DefaultRootWindow(dpy);
- X
- X /* load the font ... */
- X fontstruct=XLoadQueryFont(dpy, fontname);
- X if(!fontstruct) {
- X fprintf(stderr,
- X "Error: XRotLoadFont(): XServer couldn't load the font `%s'\n",
- X fontname);
- X exit(1);
- X }
- X
- X /* boxlen is the square size that would enclose the largest character */
- X boxlen = max2(fontstruct->max_bounds.rbearing - fontstruct->max_bounds.lbearing,
- X fontstruct->max_bounds.ascent + fontstruct->max_bounds.descent);
- X boxlen *= 2;
- X
- X /* create the depth 1 canvas bitmap ... */
- X canvas=XCreatePixmap(dpy, root, boxlen, boxlen, 1);
- X
- X /* create a GC ... */
- X font_gc=XCreateGC(dpy, canvas, NULL, 0);
- X XSetBackground(dpy, font_gc, off);
- X
- X XSetFont(dpy, font_gc, fontstruct->fid);
- X
- X /* allocate space for rotated font ... */
- X rotfont=(XRotFontStruct *)malloc((unsigned)sizeof(XRotFontStruct));
- X if(!rotfont) {
- X fprintf(stderr,"Error: XRotLoadFont(): Couldn't do malloc\n");
- X exit(1);
- X }
- X
- X /* determine which characters are defined in font ... */
- X min_char=fontstruct->min_char_or_byte2;
- X max_char=fontstruct->max_char_or_byte2;
- X
- X /* we only want printing characters ... */
- X if(min_char<32) min_char=32;
- X if(max_char>126) max_char=126;
- X
- X /* some overall font data ... */
- X rotfont->name=my_strdup(fontname);
- X rotfont->dir=dir;
- X rotfont->min_char=min_char;
- X rotfont->max_char=max_char;
- X rotfont->max_ascent=fontstruct->max_bounds.ascent;
- X rotfont->max_descent=fontstruct->max_bounds.descent;
- X rotfont->height=rotfont->max_ascent+rotfont->max_descent;
- X rotfont->width=fontstruct->max_bounds.width;
- X
- X /* remember xfontstruct for `normal' text ... */
- X if(dir==0)
- X rotfont->xfontstruct=fontstruct;
- X
- X /* loop through each character ... */
- X for(ichar=min_char; ichar<=max_char; ichar++) {
- X
- X index=ichar-fontstruct->min_char_or_byte2;
- X /* per char dimensions ... */
- X ascent= rotfont->per_char[ichar-32].ascent=
- X fontstruct->per_char[index].ascent;
- X descent= rotfont->per_char[ichar-32].descent=
- X fontstruct->per_char[index].descent;
- X lbearing=rotfont->per_char[ichar-32].lbearing=
- X fontstruct->per_char[index].lbearing;
- X rbearing=rotfont->per_char[ichar-32].rbearing=
- X fontstruct->per_char[index].rbearing;
- X rotfont->per_char[ichar-32].width=
- X fontstruct->per_char[index].width;
- X
- X /* no need for the following with normal text */
- X if (dir == 0)
- X continue;
- X
- X /* some space chars have zero body, but a bitmap can't have ... */
- X if(!ascent && !descent)
- X ascent= rotfont->per_char[ichar-32].ascent= 1;
- X if(!lbearing && !rbearing)
- X rbearing=rotfont->per_char[ichar-32].rbearing=1;
- X
- X /* glyph width and height when vertical ... */
- X vert_w=rbearing-lbearing;
- X vert_h=ascent+descent;
- X
- X /* width in bytes ... */
- X vert_len=(vert_w-1)/8+1;
- X
- X XSetForeground(dpy, font_gc, off);
- X XFillRectangle(dpy, canvas, font_gc, 0, 0, boxlen, boxlen);
- X
- X /* draw the character centre top right on canvas ... */
- X sprintf(text, "%c", ichar);
- X XSetForeground(dpy, font_gc, on);
- X XDrawImageString(dpy, canvas, font_gc, boxlen/2-lbearing,
- X boxlen/2-descent, text, 1);
- X
- X /* reserve memory for first XImage ... */
- X vertdata=(unsigned char *) malloc((unsigned)(vert_len*vert_h));
- X if(!vertdata) {
- X fprintf(stderr,"Error: XRotLoadFont(): Couldn't do malloc\n");
- X exit(1);
- X }
- X
- X /* create the XImage ... */
- X I1=XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap,
- X 0, (char *) vertdata, vert_w, vert_h, 8, 0);
- X
- X if(!I1) {
- X fprintf(stderr,"Error: XRotLoadFont(): Couldn't create XImage\n");
- X exit(1);
- X }
- X
- X I1->byte_order=I1->bitmap_bit_order=MSBFirst;
- X
- X /* extract character from canvas ... */
- X XGetSubImage(dpy, canvas, boxlen/2, boxlen/2-vert_h,
- X vert_w, vert_h, 1, XYPixmap, I1, 0, 0);
- X I1->format=XYBitmap;
- X
- X /* width, height of rotated character ... */
- X if(dir==2) {
- X bit_w=vert_w; bit_h=vert_h;
- X } else {
- X bit_w=vert_h; bit_h=vert_w;
- X }
- X
- X /* width in bytes ... */
- X bit_len=(bit_w-1)/8+1;
- X
- X rotfont->per_char[ichar-32].glyph.bit_w=bit_w;
- X rotfont->per_char[ichar-32].glyph.bit_h=bit_h;
- X
- X /* reserve memory for the rotated image ... */
- X bitdata=(unsigned char *)calloc((unsigned)(bit_h*bit_len), 1);
- X if(!bitdata) {
- X fprintf(stderr,"Error: XRotLoadFont(): Couldn't do calloc\n");
- X exit(1);
- X }
- X
- X /* create the image ... */
- X I2=XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0,
- X (char *) bitdata, bit_w, bit_h, 8, 0);
- X
- X if(!I2) {
- X fprintf(stderr,"Error: XRotLoadFont(): Couldn't create XImage\n");
- X exit(1);
- X }
- X
- X I2->byte_order=I2->bitmap_bit_order=MSBFirst;
- X
- X /* map vertical data to rotated character ... */
- X for(j=0; j<bit_h; j++) {
- X for(i=0; i<bit_w; i++) {
- X /* map bits ... */
- X if(dir==1)
- X val=vertdata[i*vert_len + (vert_w-j-1)/8] & (128>>((vert_w-j-1)%8));
- X
- X else if(dir==2)
- X val=vertdata[(vert_h-j-1)*vert_len + (vert_w-i-1)/8] &
- X (128>>((vert_w-i-1)%8));
- X else
- X val=vertdata[(vert_h-i-1)*vert_len + j/8] & (128>>(j%8));
- X
- X if(val) bitdata[j*bit_len + i/8] =
- X bitdata[j*bit_len + i/8]|(128>>(i%8));
- X }
- X }
- X
- X /* create this character's bitmap ... */
- X rotfont->per_char[ichar-32].glyph.bm=
- X XCreatePixmap(dpy, root, bit_w, bit_h, 1);
- X
- X /* put the image into the bitmap ... */
- X XPutImage(dpy, rotfont->per_char[ichar-32].glyph.bm,
- X font_gc, I2, 0, 0, 0, 0, bit_w, bit_h);
- X
- X /* free the image and data ... */
- X XDestroyImage(I1);
- X XDestroyImage(I2);
- X free((char *)bitdata);
- X free((char *)vertdata);
- X }
- X
- X if (dir != 0)
- X XFreeFont(dpy, fontstruct);
- X
- X /* free pixmap and GC ... */
- X XFreePixmap(dpy, canvas);
- X XFreeGC(dpy, font_gc);
- X
- X return rotfont;
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** Free the resources associated with a rotated font *** */
- X
- Xvoid XRotUnloadFont(dpy, rotfont)
- X Display *dpy;
- X XRotFontStruct *rotfont;
- X{
- X int ichar;
- X
- X if(rotfont->dir==0) XFreeFont(dpy, rotfont->xfontstruct);
- X
- X else
- X /* loop through each character, freeing its pixmap ... */
- X for(ichar=rotfont->min_char-32; ichar<=rotfont->max_char-32; ichar++)
- X XFreePixmap(dpy, rotfont->per_char[ichar].glyph.bm);
- X
- X /* rotfont should never be referenced again ... */
- X free((char *)rotfont);
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** Return the width of a string *** */
- X
- Xint XRotTextWidth(rotfont, str, len)
- X XRotFontStruct *rotfont;
- X char *str;
- X int len;
- X{
- X int i, width=0, ichar;
- X
- X if(str==NULL)
- X return 0;
- X
- X if(rotfont->dir==0)
- X width=XTextWidth(rotfont->xfontstruct, str, len);
- X
- X else
- X for(i=0; i<len; i++) {
- X ichar=str[i]-32;
- X
- X /* make sure it's a printing character ... */
- X if((ichar>=0)&&(ichar<95))
- X width+=rotfont->per_char[ichar].width;
- X }
- X
- X return width;
- X}
- X
- X/* *** Return the height of a string *** */
- X
- Xint XRotTextHeight(rotfont, str, len)
- X XRotFontStruct *rotfont;
- X char *str;
- X int len;
- X{
- X int i, height=0, ichar;
- X int maxasc=0;
- X int maxdsc=0;
- X int dum;
- X XCharStruct ch;
- X
- X if(str==NULL) return 0;
- X
- X if(rotfont->dir==0) {
- X XTextExtents(rotfont->xfontstruct, str, len, &dum,&dum,&dum,&ch);
- X height = ch.ascent + ch.descent;
- X }
- X else
- X for(i=0; i<len; i++)
- X {
- X ichar=str[i]-32;
- X
- X /* make sure it's a printing character ... */
- X /* then find the highest and most descending */
- X if((ichar>=0)&&(ichar<95)) {
- X maxasc=max2(maxasc,rotfont->per_char[ichar].ascent);
- X maxdsc=max2(maxdsc,rotfont->per_char[ichar].descent);
- X }
- X /* and add the two together */
- X height = maxasc+maxdsc;
- X }
- X
- X return height;
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** A front end to XRotPaintString : mimics XDrawString *** */
- X
- Xvoid XRotDrawString(dpy, drawable, rotfont,gc, x, y, str, len)
- X Display *dpy;
- X Drawable drawable;
- X XRotFontStruct *rotfont;
- X GC gc;
- X int x, y;
- X char *str;
- X int len;
- X{
- X XRotPaintString(dpy, drawable, rotfont, gc, x, y, str, len, 0);
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** A front end to XRotPaintString : mimics XDrawImageString *** */
- X
- Xvoid XRotDrawImageString(dpy, drawable, rotfont, gc, x, y, str, len)
- X Display *dpy;
- X Drawable drawable;
- X XRotFontStruct *rotfont;
- X GC gc;
- X int x, y;
- X char *str;
- X int len;
- X{
- X XRotPaintString(dpy, drawable, rotfont, gc, x, y, str, len, 1);
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** Paint a simple string with a rotated font *** */
- X
- X/* *** The user should use one of the two front ends above *** */
- X
- Xvoid XRotPaintString(dpy, drawable, rotfont, gc, x, y, str, len, paintbg)
- X Display *dpy;
- X Drawable drawable;
- X XRotFontStruct *rotfont;
- X GC gc;
- X int x, y;
- X char *str;
- X int len;
- X int paintbg;
- X{
- X static GC my_gc=NULL;
- X XGCValues values;
- X int i, xp, yp, dir, ichar, width;
- X#ifdef X11R3
- X static Pixmap empty_stipple=(Pixmap)NULL;
- X#endif
- X
- X dir=rotfont->dir;
- X
- X if(!my_gc) my_gc=XCreateGC(dpy, drawable, NULL, 0);
- X
- X XCopyGC(dpy, gc, GCFunction|GCForeground|GCBackground, my_gc);
- X
- X /* a horizontal string is easy ... */
- X if(dir==0)
- X { XSetFillStyle(dpy, my_gc, FillSolid);
- X XSetFont(dpy, my_gc, rotfont->xfontstruct->fid);
- X if(!paintbg) XDrawString(dpy, drawable, my_gc, x, y, str, len);
- X else XDrawImageString(dpy, drawable, my_gc, x, y, str, len);
- X
- X return;
- X }
- X
- X /* vertical or upside down ... */
- X
- X /* to draw an `image string' we need to fill the background ... */
- X if(paintbg)
- X {
- X#ifdef X11R3
- X /* Release 3 doesn't have XGetGCValues(), so this is a
- X slightly slower fudge ... */
- X {
- X GC stipple_gc;
- X int bestw, besth;
- X
- X if(!empty_stipple)
- X { XQueryBestStipple(dpy, drawable, 1, 1, &bestw, &besth);
- X empty_stipple=XCreatePixmap(dpy, drawable, bestw, besth, 1);
- X
- X stipple_gc=XCreateGC(dpy, empty_stipple, NULL, 0);
- X XSetForeground(dpy, stipple_gc, 0);
- X
- X XFillRectangle(dpy, empty_stipple, stipple_gc, 0, 0, bestw+1, besth+1);
- X XFreeGC(dpy, stipple_gc);
- X }
- X
- X XSetStipple(dpy, my_gc, empty_stipple);
- X XSetFillStyle(dpy, my_gc, FillOpaqueStippled);
- X }
- X#else
- X /* get the foreground and background colors
- X ( note that this is not a round trip -> little speed penalty ) */
- X XGetGCValues(dpy, my_gc, GCForeground|GCBackground, &values);
- X
- X XSetForeground(dpy, my_gc, values.background);
- X XSetFillStyle(dpy, my_gc, FillSolid);
- X#endif
- X
- X width=XRotTextWidth(rotfont, str, strlen(str));
- X
- X if(dir==1)
- X XFillRectangle(dpy, drawable, my_gc, x-rotfont->max_ascent+1, y-width,
- X rotfont->height-1, width);
- X else if(dir==2)
- X XFillRectangle(dpy, drawable, my_gc, x-width, y-rotfont->max_descent+1,
- X width, rotfont->height-1);
- X else
- X XFillRectangle(dpy, drawable, my_gc, x-rotfont->max_descent+1,
- X y, rotfont->height-1, width);
- X
- X#ifndef X11R3
- X XSetForeground(dpy, my_gc, values.foreground);
- X#endif
- X }
- X
- X XSetFillStyle(dpy, my_gc, FillStippled);
- X
- X /* loop through each character in string ... */
- X for(i=0; i<len; i++)
- X {
- X ichar=str[i]-32;
- X
- X /* make sure it's a printing character ... */
- X if((ichar>=0)&&(ichar<95))
- X {
- X /* suitable offset ... */
- X if(dir==1)
- X { xp=x-rotfont->per_char[ichar].ascent;
- X yp=y-rotfont->per_char[ichar].rbearing; }
- X else if(dir==2)
- X { xp=x-rotfont->per_char[ichar].rbearing;
- X yp=y-rotfont->per_char[ichar].descent+1; }
- X else
- X { xp=x-rotfont->per_char[ichar].descent+1;
- X yp=y+rotfont->per_char[ichar].lbearing; }
- X
- X /* draw the glyph ... */
- X XSetStipple(dpy, my_gc, rotfont->per_char[ichar].glyph.bm);
- X
- X XSetTSOrigin(dpy, my_gc, xp, yp);
- X
- X XFillRectangle(dpy, drawable, my_gc, xp, yp,
- X rotfont->per_char[ichar].glyph.bit_w,
- X rotfont->per_char[ichar].glyph.bit_h);
- X
- X /* advance position ... */
- X if(dir==1) y-=rotfont->per_char[ichar].width;
- X else if(dir==2) x-=rotfont->per_char[ichar].width;
- X else y+=rotfont->per_char[ichar].width;
- X }
- X }
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** A front end to XRotPaintAlignedString : uses XRotDrawString *** */
- X
- Xvoid XRotDrawAlignedString(dpy, drawable, rotfont, gc, x, y,
- X text, align)
- X Display *dpy;
- X Drawable drawable;
- X XRotFontStruct *rotfont;
- X GC gc;
- X int x, y;
- X char *text;
- X int align;
- X{
- X XRotPaintAlignedString(dpy, drawable, rotfont, gc, x, y, text, align, 0);
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** A front end to XRotPaintAlignedString : uses XRotDrawImageString *** */
- X
- Xvoid XRotDrawAlignedImageString(dpy, drawable, rotfont, gc, x, y,
- X text, align)
- X Display *dpy;
- X Drawable drawable;
- X XRotFontStruct *rotfont;
- X GC gc;
- X int x, y;
- X char *text;
- X int align;
- X{
- X XRotPaintAlignedString(dpy, drawable, rotfont, gc, x, y, text, align, 1);
- X}
- X
- X
- X/* ---------------------------------------------------------------------- */
- X
- X
- X/* *** Routine to paint a string, possibly containing newline characters,
- X with alignment *** */
- X
- X/* *** The user should use one of the front ends above *** */
- X
- Xvoid XRotPaintAlignedString(dpy, drawable, rotfont, gc, x, y, text,
- X align, paintbg)
- X Display *dpy;
- X Drawable drawable;
- X XRotFontStruct *rotfont;
- X GC gc;
- X int x, y;
- X char *text;
- X int align;
- X int paintbg;
- X{
- X int xp, yp, dir;
- X int i, nl=1, max_width=0, this_width;
- X char *str1, *str2="\n\0", *str3;
- X
- X if(text==NULL) return;
- X
- X dir=rotfont->dir;
- X
- X /* count number of sections in string ... */
- X for(i=0; i<strlen(text); i++) if(text[i]=='\n') nl++;
- X
- X /* find width of longest section ... */
- X str1=my_strdup(text);
- X str3=my_strtok(str1, str2);
- X max_width=XRotTextWidth(rotfont, str3, strlen(str3));
- X
- X do
- X { str3=my_strtok((char *)NULL, str2);
- X if(str3)
- X max_width=XROTMAX(max_width,
- X XRotTextWidth(rotfont, str3, strlen(str3))); }
- X while(str3!=NULL);
- X
- X /* calculate vertical starting point according to alignment policy and
- X rotation angle ... */
- X if(dir==0)
- X { if((align==TLEFT)||(align==TCENTRE)||(align==TRIGHT))
- X yp=y+rotfont->max_ascent;
- X
- X else if((align==BLEFT)||(align==BCENTRE)||(align==BRIGHT))
- X yp=y-(nl-1)*rotfont->height - rotfont->max_descent;
- X
- X else
- X yp=y-(nl-1)/2*rotfont->height + rotfont->max_ascent -rotfont->height/2 -
- X ( (nl%2==0)?rotfont->height/2:0 ); }
- X
- X else if(dir==1)
- X { if((align==TLEFT)||(align==TCENTRE)||(align==TRIGHT))
- X xp=x+rotfont->max_ascent;
- X
- X else if((align==BLEFT)||(align==BCENTRE)||(align==BRIGHT))
- X xp=x-(nl-1)*rotfont->height - rotfont->max_descent;
- X
- X else
- X xp=x-(nl-1)/2*rotfont->height + rotfont->max_ascent -rotfont->height/2 -
- X ( (nl%2==0)?rotfont->height/2:0 ); }
- X
- X else if(dir==2)
- X { if((align==TLEFT)||(align==TCENTRE)||(align==TRIGHT))
- X yp=y-rotfont->max_ascent;
- X
- X else if((align==BLEFT)||(align==BCENTRE)||(align==BRIGHT))
- X yp=y+(nl-1)*rotfont->height + rotfont->max_descent;
- X
- X else
- X yp=y+(nl-1)/2*rotfont->height - rotfont->max_ascent +rotfont->height/2 +
- X ( (nl%2==0)?rotfont->height/2:0 ); }
- X
- X else
- X { if((align==TLEFT)||(align==TCENTRE)||(align==TRIGHT))
- X xp=x-rotfont->max_ascent;
- X
- X else if((align==BLEFT)||(align==BCENTRE)||(align==BRIGHT))
- X xp=x+(nl-1)*rotfont->height + rotfont->max_descent;
- X
- X else
- X xp=x+(nl-1)/2*rotfont->height - rotfont->max_ascent +rotfont->height/2 +
- X ( (nl%2==0)?rotfont->height/2:0 ); }
- X
- X str1=my_strdup(text);
- X str3=my_strtok(str1, str2);
- X
- X /* loop through each section in the string ... */
- X do
- X {
- X /* width of this section ... */
- X this_width=XRotTextWidth(rotfont, str3, strlen(str3));
- X
- X /* horizontal alignment ... */
- X if(dir==0)
- X { if((align==TLEFT)||(align==MLEFT)||(align==BLEFT))
- X xp=x;
- X
- X else if((align==TCENTRE)||(align==MCENTRE)||(align==BCENTRE))
- X xp=x-this_width/2;
- X
- X else
- X xp=x-max_width; }
- X
- X else if(dir==1)
- X { if((align==TLEFT)||(align==MLEFT)||(align==BLEFT))
- X yp=y;
- X
- X else if((align==TCENTRE)||(align==MCENTRE)||(align==BCENTRE))
- X yp=y+this_width/2;
- X
- X else
- X yp=y+max_width; }
- X
- X else if(dir==2)
- X { if((align==TLEFT)||(align==MLEFT)||(align==BLEFT))
- X xp=x;
- X
- X else if((align==TCENTRE)||(align==MCENTRE)||(align==BCENTRE))
- X xp=x+this_width/2;
- X
- X else
- X xp=x+max_width; }
- X
- X else
- X { if((align==TLEFT)||(align==MLEFT)||(align==BLEFT))
- X yp=y;
- X
- X else if((align==TCENTRE)||(align==MCENTRE)||(align==BCENTRE))
- X yp=y-this_width/2;
- X
- X else
- X yp=y-max_width; }
- X
- X /* draw the section ... */
- X if(!paintbg) XRotDrawString(dpy, drawable, rotfont, gc, xp, yp,
- X str3, strlen(str3));
- X else XRotDrawImageString(dpy, drawable, rotfont, gc, xp, yp,
- X str3, strlen(str3));
- X
- X str3=my_strtok((char *)NULL, str2);
- X
- X /* advance position ... */
- X if(dir==0) yp+=rotfont->height;
- X else if(dir==1) xp+=rotfont->height;
- X else if(dir==2) yp-=rotfont->height;
- X else xp-=rotfont->height;
- X }
- X while(str3!=NULL);
- X}
- X
- END_OF_FILE
- if test 21004 -ne `wc -c <'w_rottext.c'`; then
- echo shar: \"'w_rottext.c'\" unpacked with wrong size!
- fi
- # end of 'w_rottext.c'
- fi
- echo shar: End of archive 14 \(of 27\).
- cp /dev/null ark14isdone
- 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 24 25 26 27 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 27 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
-
- exit 0 # Just in case...
- --
- // chris@IMD.Sterling.COM | Send comp.sources.x submissions to:
- \X/ Amiga - The only way to fly! | sources-x@imd.sterling.com
- "It's intuitively obvious to the |
- most casual observer..." | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
-