home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xfig2.8 / part07 / text.c < prev   
C/C++ Source or Header  |  1990-07-02  |  7KB  |  285 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : Aug 1985.
  7.  *    2nd revision : Feb 1988.
  8.  *
  9.  *    %W%    %G%
  10. */
  11. #include "fig.h"
  12. #include "resources.h"
  13. #include "alloc.h"
  14. #include "const.h"
  15. #include "font.h"
  16. #include "func.h"
  17. #include "object.h"
  18. #include "paintop.h"
  19.  
  20. extern            (*canvas_kbd_proc)();
  21. extern            (*canvas_locmove_proc)();
  22. extern            (*canvas_leftbut_proc)();
  23. extern            (*canvas_middlebut_proc)();
  24. extern            (*canvas_rightbut_proc)();
  25. extern            null_proc();
  26. extern    char        *calloc();
  27. extern            set_popupmenu();
  28. extern    F_text        *text_search();
  29. extern    PIX_FONT    lookfont();
  30.  
  31. extern    int        font_button, size_button;
  32. extern    int        type_button;
  33.  
  34. extern    int        cur_font, cur_fontsize;
  35. extern            char_handler();
  36. extern    int        cur_x, cur_y;
  37. extern    char        prefix[], suffix[];
  38. extern    int        leng_prefix, leng_suffix;
  39. extern    int        cur_color;
  40. extern    int        cur_textstyle;
  41. extern    int        cur_textjust;
  42. extern    float        cur_angle;
  43.  
  44. extern    F_compound    objects;
  45.  
  46. static    int        char_ht, char_wid;
  47. static    int        base_x, base_y;
  48. static    F_text        *cur_text;
  49. static    PR_SIZE        tsize;
  50. static    PR_SIZE        ssize;
  51.  
  52. F_text            *create_text();
  53. static            finish_text_input();
  54. static            finish_n_start();
  55. static            init_text_input();
  56. static            wrap_up();
  57.  
  58. static
  59. finish_n_start(x, y)
  60. {
  61.     wrap_up();
  62.     init_text_input(x, y);
  63.     }
  64.  
  65. static
  66. finish_text_input()
  67. {
  68.     wrap_up();
  69.     text_drawing_selected();
  70.     }
  71.  
  72. static
  73. wrap_up()
  74. {
  75.     PR_SIZE        size;
  76.     int        kbd_received;
  77.  
  78.     reset_action_on();
  79.     kbd_received = terminate_char_handler();
  80.     if ( ! kbd_received) return;
  81.  
  82.     if (cur_text == NULL) {    /* a brand new text */
  83.         if (leng_prefix == 0) return;
  84.         cur_text = create_text();
  85.         insert_text(&objects.texts, cur_text);
  86.         }
  87.     else {            /* existing text modified */
  88.         strcat(prefix, suffix);
  89.         leng_prefix += leng_suffix;
  90.         if (leng_prefix == 0) {
  91.         delete_text(&objects.texts, cur_text);
  92.         cfree(cur_text->cstring);
  93.         free((char*)cur_text);
  94.         return;
  95.         }
  96.         if (strlen(cur_text->cstring) >= leng_prefix) { 
  97.         strcpy(cur_text->cstring, prefix);
  98.         }
  99.         else { /* free old and allocate new */
  100.         cfree(cur_text->cstring);
  101.         cur_text->cstring = calloc((unsigned)(leng_prefix+1), sizeof(char));
  102.         if (cur_text->cstring != NULL)
  103.           strcpy(cur_text->cstring, prefix);
  104.         }
  105.         size = pf_textwidth(cur_text->font, cur_text->size, leng_prefix, prefix);
  106.         cur_text->height = size.y;
  107.         cur_text->length = size.x;  /* in pixels */
  108.         }
  109.     draw_text(cur_text, PAINT);
  110.     clean_up();
  111.     set_action_object(F_TEXT, O_TEXT);
  112.     set_latesttext(cur_text);
  113.     set_modifiedflag();
  114.     }
  115.  
  116. static
  117. init_text_input(x, y)
  118. int    x, y;
  119. {
  120.     int basx;
  121.  
  122.     cur_x = x;
  123.     cur_y = y;
  124.  
  125.     set_action_on();
  126.     canvas_kbd_proc = char_handler;
  127.     canvas_middlebut_proc = finish_text_input;
  128.     canvas_leftbut_proc = finish_n_start;
  129.     canvas_rightbut_proc = null_proc;
  130.  
  131.     /* set current font info to indicator button settings */
  132.     cur_fontsize = size_button;
  133.     cur_font = font_button;
  134.     cur_textjust = type_button;
  135.  
  136.     /* load the X font and get its id for this font, size */
  137.     canvas_font = lookfont(cur_font, cur_fontsize);
  138.     char_ht = char_height(canvas_font);
  139.     char_wid = char_width(canvas_font);
  140.  
  141.     if ((cur_text = text_search(cur_x, cur_y)) == NULL) {    /* new text input */
  142.         leng_prefix = leng_suffix = 0;
  143.         *suffix = 0;
  144.         prefix[leng_prefix] = '\0';
  145.         base_x = cur_x;
  146.         base_y = cur_y;
  147.         }
  148.     else {         /* clicked on existing text */
  149.         /* leng_prefix is # of char in the text before the cursor */
  150.         leng_suffix = strlen(cur_text->cstring);
  151.         basx = cur_text->base_x;
  152.         if (cur_text->type == T_CENTER_JUSTIFIED)
  153.         basx -= cur_text->length/2;
  154.         else if (cur_text->type == T_RIGHT_JUSTIFIED)
  155.         basx -= cur_text->length;
  156.         leng_prefix = prefix_length(cur_text->cstring, cur_x - basx);
  157.         leng_suffix -= leng_prefix;
  158.         cpy_n_char(prefix, cur_text->cstring, leng_prefix);
  159.         strcpy(suffix, &cur_text->cstring[leng_prefix]);
  160.         tsize = pf_textwidth(cur_text->font, cur_text->size, leng_prefix, prefix);
  161.         ssize = pf_textwidth(cur_text->font, cur_text->size, leng_suffix, suffix);
  162.         cur_x = base_x = basx;
  163.         cur_y = base_y = cur_text->base_y;
  164.         cur_x += tsize.x;
  165.         cur_font = cur_text->font;
  166.         cur_fontsize = cur_text->size;
  167.         cur_textjust = cur_text->type;
  168.         }
  169.     initialize_char_handler(canvas_win, finish_text_input, 
  170.             base_x, base_y);
  171.     }
  172.  
  173. /* This procedure is called before any other text stuff here */
  174.  
  175. text_drawing_selected()
  176. {
  177.     canvas_kbd_proc = null_proc;
  178.     canvas_locmove_proc = null_proc;
  179.     canvas_middlebut_proc = null_proc;
  180.     canvas_leftbut_proc = init_text_input;
  181.     canvas_rightbut_proc = set_popupmenu;
  182.  
  183.     set_cursor(&pencil_cursor);
  184.     }
  185.  
  186. F_text *
  187. create_text()
  188. {
  189.     F_text        *text;
  190.     PR_SIZE        size;
  191.  
  192.     if ((Text_malloc(text)) == NULL) {
  193.         put_msg(Err_mem);
  194.         return(NULL);
  195.         }
  196.     text->cstring = calloc((unsigned)(leng_prefix+1), sizeof(char));
  197.     if (text->cstring == NULL) {
  198.         put_msg(Err_mem);
  199.         free((char *)text);
  200.         return(NULL);
  201.         }
  202.     text->type = cur_textjust;;
  203.     text->font = cur_font;    /* put in current font number */
  204.     text->size = cur_fontsize;    /* added 9/25/89 B.V.Smith */
  205.     text->angle = cur_angle;
  206.     text->style = cur_textstyle;
  207.     text->color = cur_color;
  208.     text->depth = 0;
  209.     text->pen = 0;
  210.     size = pf_textwidth(text->font, text->size, leng_prefix, prefix);
  211.     text->length = size.x;    /* in pixels */
  212.     text->height = size.y;    /* in pixels */
  213.     text->base_x = base_x;
  214.     text->base_y = base_y;
  215.     strcpy(text->cstring, prefix);
  216.     text->next = NULL;
  217.     return(text);
  218.     }
  219.  
  220. cpy_n_char(dst, src, n)
  221. char    *dst, *src;
  222. int     n;
  223. {
  224.     /* src must be longer than n chars */
  225.  
  226.     while (n--) *dst++ = *src++;
  227.     *dst = '\0';
  228.     }
  229.  
  230. int
  231. prefix_length(string, where_p)
  232. char        *string;
  233. int         where_p;
  234. {
  235.     /* c stands for character unit and p for pixel unit */
  236.     int        l, len_c, len_p;
  237.     int        char_wid, where_c;
  238.     PR_SIZE        size;
  239.  
  240.     if (canvas_font == NULL) 
  241.         fprintf(stderr,"Error, in prefix_length, canvas_font = NULL\n");
  242.     len_c = strlen(string);
  243.     size = pf_textwidth(cur_text->font, cur_text->size, len_c, string);
  244.     len_p = size.x;
  245.     if (where_p >= len_p) return(len_c); /* entire string is the preffix */
  246.  
  247.     char_wid = char_width(canvas_font);
  248.     where_c = where_p / char_wid;    /* estimated char position */
  249.     size = pf_textwidth(cur_text->font, cur_text->size, where_c, string);
  250.     l = size.x;    /* actual lenght (pixels) of string of where_c chars */
  251.     if (l < where_p) {
  252.         do {    /* add the width of next char to l */
  253.         l += (char_wid = char_advance(canvas_font,string[where_c++]));
  254.         } while (l < where_p);
  255.         if (l-(char_wid>>1) >= where_p) where_c--;
  256.         }
  257.     else if (l > where_p) {
  258.         do {    /* subtract the width of last char from l */
  259.         l -= (char_wid = char_advance(canvas_font,string[--where_c]));
  260.         } while (l > where_p);
  261.         if (l+(char_wid>>1) >= where_p) where_c++;
  262.         }
  263.     return(where_c);
  264.     }
  265.  
  266. draw_text(text, op)
  267. F_text    *text;
  268. int    op;
  269. {
  270.     PR_SIZE    size;
  271.     int x;
  272.  
  273.     x = text->base_x;
  274.     if (text->type == T_CENTER_JUSTIFIED || text->type == T_RIGHT_JUSTIFIED)
  275.         {
  276.         size = pf_textwidth(text->font,text->size,strlen(text->cstring),text->cstring);
  277.         if (text->type == T_CENTER_JUSTIFIED)
  278.             x -= size.x/2;
  279.         else
  280.             x -= size.x;
  281.         }
  282.     pw_text(canvas_win, x, text->base_y, 
  283.         op, text->font, text->size, text->cstring);
  284.     }
  285.