home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / os2 / hpgl312.zip / CHARDRAW.C < prev    next >
C/C++ Source or Header  |  1993-04-18  |  12KB  |  505 lines

  1. /*
  2.    Copyright (c) 1991 - 1993 Heinz W. Werntges.  All rights reserved.
  3.    Distributed by Free Software Foundation, Inc.
  4.  
  5. This file is part of HP2xx.
  6.  
  7. HP2xx is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  9. to anyone for the consequences of using it or for whether it serves any
  10. particular purpose or works at all, unless he says so in writing.  Refer
  11. to the GNU General Public License, Version 2 or later, for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. HP2xx, but only under the conditions described in the GNU General Public
  15. License.  A copy of this license is supposed to have been
  16. given to you along with HP2xx so you can know your rights and
  17. responsibilities.  It should be in a file named COPYING.  Among other
  18. things, the copyright notice and this notice must be preserved on all
  19. copies.
  20.  
  21. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  22. */
  23.  
  24. /** CHARDRAW.c: Implementation of characters by draw/move commands
  25.  **
  26.  ** 92/02/19 HWW  V 1.00b Derived from pplib.cpp and sprite.cpp (V 1.2)
  27.  ** 92/02/27 HWW  V 2.00b Many changes - last: bug fixed in adjust_text_par()
  28.  ** 92/03/03 HWW  V 2.01a LB != PB: acknowledged by introducing LB_Mode
  29.  ** 92/04/28 HWW  V 2.01b VAX seems to mix up tp & TP --> TEXTP instead
  30.  ** 92/05/28 HWW  V 2.02a plot_symbol_char() added
  31.  ** 92/10/15 HWW  V 2.02b Line types acknowledged
  32.  ** 92/10/17 HWW  V 2.03  RS6000 bug fixed in code_to_ucoord()
  33.  ** 93/02/09 HWW  V 2.03b Comments added; prepared for more fonts; 
  34.  **              Font OV bug fixed (8-bit codes now checked!)
  35.  ** 93/04/13 HWW  V 2.04a plot_user_char() added (code by A. Treindl)
  36.  **/
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <math.h>
  42. #include "bresnham.h"
  43. #include "hp2xx.h"
  44. #include "chardraw.h"
  45. #include "charset0.h"
  46.  
  47. /**
  48.  ** NOTE: There is code here masked off by symbol STROKED_FONTS
  49.  ** In an earlier version it had some meaning but is now inactive.
  50.  ** I left it here in the hope that some day it may resume its
  51.  ** earlier purpose which was:
  52.  **   Loading of external fonts (here: Hershey fonts as within the
  53.  **   Borland BGI fonts.)
  54.  **/
  55.  
  56. extern    HPGL_Pt        HP_pos, P1, P2;
  57. extern    LineType    CurrentLineType, GlobalLineType;
  58.  
  59. TEXTPAR    TEXTP, *tp = &TEXTP;
  60.  
  61.  
  62.  
  63. void    code_to_ucoord (char c, HPGL_Pt *pp)
  64. /**
  65.  ** Converts internal one-byte code (in c) for a character vector
  66.  ** into HP-GL coordinates (pointed to by pp)
  67.  **/
  68. {
  69. double    x,y;
  70.  
  71.   /*
  72.    * RS6000 bug fix:
  73.    *     outer braces of casts removed, costing 2 double ops
  74.    * My guess: "char" is unsigned on RS6000
  75.    */
  76.   x = (double) (c >> 4)   - 1.0;    /* Bits 4,5,6 --> value 0..7 */
  77.   y = (double) (c & 0x0f) - 4.0;    /* Bits 0-3   --> value 0..f */
  78.  
  79.   pp->x = tp->Txx * x + tp->Txy * y + tp->refpoint.x + tp->offset.x;
  80.   pp->y = tp->Tyx * x + tp->Tyy * y + tp->refpoint.y + tp->offset.y;
  81. }
  82.  
  83.  
  84.  
  85.  
  86. void    ASCII_to_char (int c)
  87. /**
  88.  ** Main user interface: Convert ASCII code c into a sequence
  89.  ** of move/draw vectors which draw a corresponding character
  90.  **/
  91. {
  92. HPGL_Pt    p;
  93. char    *ptr;
  94.  
  95.   CurrentLineType = LT_solid;
  96.   switch (tp->font)
  97.   {
  98.     case 0:    /* charset 0, limited to 7 bit ASCII    */
  99.     if (c & 0x80)
  100.     {
  101.         fprintf (stderr,
  102.             "Illegal char in string: %c replaced by blank!\n", c);
  103.         c = ' ';
  104.     }
  105.     ptr = &charset0[c][0];
  106.     break;
  107.  
  108.     default:    /* Currently, there is just one charset    */
  109.     fprintf (stderr,
  110.         "Charset %d not supported -- replaced by blank!\n", tp->font);
  111.         c = ' ';
  112.     ptr = &charset0[c][0];
  113.     break;
  114.   }
  115.  
  116.   for (; *ptr; ptr++)    /* Draw this char    */
  117.   {
  118.     code_to_ucoord (*ptr & 0x7f, &p);
  119.     if (*ptr & 0x80)    /* High bit is draw flag */
  120.         Pen_action_to_tmpfile (DRAW_TO, &p, FALSE);
  121.     else
  122.         Pen_action_to_tmpfile (MOVE_TO, &p, FALSE);
  123.   }
  124.  
  125.   /* Update cursor: to next character origin!    */
  126.  
  127.   tp->refpoint.x += tp->chardiff.x;
  128.   tp->refpoint.y += tp->chardiff.y;
  129.   CurrentLineType = GlobalLineType;
  130. }
  131.  
  132.  
  133. /**********************************************************************/
  134.  
  135. void    init_text_par (void)
  136. {
  137.   tp->width    = 0.005  * (P2.x - P1.x);
  138.   tp->height    = 0.0075 * (P2.y - P1.y);
  139.   tp->espace    = 0.0;
  140.   tp->eline    = 0.0;
  141.   tp->dir    = 0.0;
  142.   tp->slant    = 0.0;
  143.   tp->font    = 0;
  144.   tp->orig    = 1;            /* Font number: 0 = old    */
  145.   tp->refpoint    = tp->CR_point = HP_pos;
  146.   tp->offset.x    = tp->offset.y = 0.0;
  147.   adjust_text_par();
  148. }
  149.  
  150.  
  151.  
  152.  
  153. void    adjust_text_par (void)
  154. /**
  155.  ** Width, height, space, line, dir,
  156.  ** slant, as given in
  157.  ** structure declaration
  158.  **/
  159. {
  160. double    cdir,sdir;
  161.  
  162. /**
  163.  ** Here, we use space & line as basic data, since these parameters
  164.  ** are affected by SI and SR commands, not width or height!
  165.  **/
  166.   tp->space    =  tp->width  * 1.5;
  167.   tp->line    =  tp->height * 2.0;
  168.  
  169.   cdir        =  cos (tp->dir);
  170.   sdir        =  sin (tp->dir);
  171.   tp->Txx    =  tp->width * cdir / 4.0;
  172.   tp->Tyx    =  tp->width * sdir / 4.0;
  173.   tp->Txy    =  tp->height* (tp->slant * cdir - sdir) / 6.0;
  174.   tp->Tyy    =  tp->height* (tp->slant * sdir + cdir) / 6.0;
  175.  
  176.   tp->chardiff.x=  tp->space * (1.0 + tp->espace) * cdir;
  177.   tp->chardiff.y=  tp->space * (1.0 + tp->espace) * sdir;
  178.   tp->linediff.x=  tp->line  * (1.0 + tp->eline ) * sdir;
  179.   tp->linediff.y= -tp->line  * (1.0 + tp->eline ) * cdir;
  180.  
  181. #ifdef STROKED_FONTS
  182.   if (init_font (tp->font))
  183.   {
  184.     fprintf (stderr, "\007 init_font() failed for font #%d\n", tp->font);
  185.     fprintf (stderr, "Font 0 used instead!\n");
  186.     tp->font = 0;
  187.   }
  188. #endif
  189. }
  190.  
  191.  
  192.  
  193. #define    HEIGHT_FAC    0.5
  194. #define    WIDTH_FAC    0.666666666
  195.  
  196.  
  197. void    get_label_offset (char *txt, LB_Mode mode)
  198. /**
  199.  ** Depending on the current HP-GL label mode, a string may have different
  200.  ** x and y offsets. These offsets are accounted for here:
  201.  **/
  202. {
  203. float        dx=0.0, dy=0.0;
  204. static    float    nc, nl, nc_max;
  205.  
  206.   switch (mode)
  207.   {
  208.     case LB_direct:    /* Get number of printable plot cells    */
  209.     nc = nl = nc_max = 0.0;
  210.     for (; *txt && *txt != _CR; txt++)    /* to ETX or CR */
  211.         if (*txt >=' ' && ((*txt&'\x80') == 0))
  212.             nc++;            /* Printable ?    */
  213.         else if (*txt == _BS)        /* Backspace ?    */
  214.             nc--;
  215.         else if (*txt == _HT)
  216.             nc -= 0.5;
  217.     break;
  218.  
  219.     case LB_buffered:
  220.     /* Max number of printable plot cells + lines    */
  221.     nc = nl = nc_max = 0.0;
  222.     for (; *txt; txt++)
  223.         if (*txt >=' ' && ((*txt&'\x80') == 0))
  224.             nc++;
  225.         else if (*txt == _BS)
  226.             nc--;
  227.         else if (*txt == _HT)
  228.             nc -= 0.5;
  229.         else if (*txt == _LF)
  230.             nl++;
  231.         else if (*txt == _VT)
  232.             nl--;
  233.         else if (*txt == _CR)
  234.         {
  235.             if (nc > nc_max)
  236.                 nc_max = nc;
  237.             nc = 0.0;
  238.         }
  239.     if (nc > nc_max)
  240.         nc_max = nc;
  241.     nc = nc_max;    /* Use longest row for adjustment    */
  242.     break;
  243.  
  244.     case LB_buffered_in_use:
  245.     break;    /* Use data from earlier LB_buffered call    */
  246.   }
  247.  
  248.   switch (tp->orig)
  249.   {
  250.     case  1:
  251.     case  2:
  252.     case  3:
  253.         dx = 0.0;
  254.         break;
  255.     case 11:
  256.     case 12:
  257.     case 13:
  258.         dx = 0.5 * WIDTH_FAC;
  259.         break;
  260.     case  4:
  261.     case  5:
  262.     case  6:
  263.     case 14:
  264.     case 15:
  265.     case 16:
  266.         dx = 0.5 * (1.0 - WIDTH_FAC);
  267.         tp->refpoint.x -= tp->chardiff.x * nc/2.0;
  268.         tp->refpoint.y -= tp->chardiff.y * nc/2.0;
  269.         break;
  270.     case  7:
  271.     case  8:
  272.     case  9:
  273.         dx = 1.0 - WIDTH_FAC;
  274.         tp->refpoint.x -= tp->chardiff.x * nc;
  275.         tp->refpoint.y -= tp->chardiff.y * nc;
  276.         break;
  277.     case 17:
  278.     case 18:
  279.     case 19:
  280.         dx = 1.0 - 1.5 * WIDTH_FAC;
  281.         tp->refpoint.x -= tp->chardiff.x * nc;
  282.         tp->refpoint.y -= tp->chardiff.y * nc;
  283.         break;
  284.   }
  285.  
  286.   switch (tp->orig)
  287.   {
  288.     case  1:
  289.     case  4:
  290.     case  7:
  291.         dy = 0.0;
  292.         if (mode == LB_buffered || mode == LB_buffered_in_use)
  293.         {
  294.             tp->refpoint.x -= tp->linediff.x * nl;
  295.             tp->refpoint.y -= tp->linediff.y * nl;
  296.         }
  297.         break;
  298.     case 11:
  299.     case 14:
  300.     case 17:
  301.         dy = 0.5 * HEIGHT_FAC;
  302.         if (mode == LB_buffered || mode == LB_buffered_in_use)
  303.         {
  304.             tp->refpoint.x -= tp->linediff.x * nl;
  305.             tp->refpoint.y -= tp->linediff.y * nl;
  306.         }
  307.         break;
  308.     case  2:
  309.     case  5:
  310.     case  8:
  311.     case 12:
  312.     case 15:
  313.     case 18:
  314.         dy = -0.5 * HEIGHT_FAC;
  315.         if (mode == LB_buffered || mode == LB_buffered_in_use)
  316.         {
  317.             tp->refpoint.x -= tp->linediff.x * nl/2.0;
  318.             tp->refpoint.y -= tp->linediff.y * nl/2.0;
  319.         }
  320.         break;
  321.     case  3:
  322.     case  6:
  323.     case  9:
  324.         dy = -HEIGHT_FAC;
  325.         if (mode == LB_buffered || mode == LB_buffered_in_use)
  326.         {
  327.             tp->refpoint.x += tp->linediff.x * (nl-1.0);
  328.             tp->refpoint.y += tp->linediff.y * (nl-1.0);
  329.         }
  330.         break;
  331.     case 13:
  332.     case 16:
  333.     case 19:
  334.         dy = -1.5 * HEIGHT_FAC;
  335.         if (mode == LB_buffered || mode == LB_buffered_in_use)
  336.         {
  337.             tp->refpoint.x += tp->linediff.x * (nl-1.0);
  338.             tp->refpoint.y += tp->linediff.y * (nl-1.0);
  339.         }
  340.         break;
  341.   }
  342.  
  343.   tp->offset.x = tp->chardiff.x * dx - tp->linediff.x * dy;
  344.   tp->offset.y = tp->chardiff.y * dx - tp->linediff.y * dy;
  345. }
  346.  
  347.  
  348.  
  349.  
  350.  
  351. void    plot_string (char *txt, LB_Mode mode)
  352. /**
  353.  ** String txt cannot simply be processed char-by-char. Depending on
  354.  ** the current label mode, its origin must first be calculated properly.
  355.  ** Then, there are some special control characters which affect cursor
  356.  ** position but don't draw anything. Finally, characters can be drawn
  357.  ** one-by-one.
  358.  **/
  359. {
  360. char    *txt0;
  361.  
  362.   txt0 = txt;
  363.   tp->refpoint = HP_pos;
  364.   get_label_offset (txt, mode);
  365.  
  366.   while (*txt)
  367.   {
  368.     switch (*txt)
  369.     {
  370.       case ' ':
  371.         tp->refpoint.x += tp->chardiff.x;
  372.         tp->refpoint.y += tp->chardiff.y;
  373.         break;
  374.       case _CR:
  375.         tp->refpoint = tp->CR_point;
  376.         switch (mode)
  377.         {
  378.           case LB_direct:
  379.             get_label_offset (txt+1, mode);
  380.             break;
  381.           case LB_buffered:
  382.             get_label_offset (txt0, LB_buffered_in_use);
  383.             break;
  384.           default:
  385.             break;
  386.         }
  387.         break;
  388.       case _LF:
  389.         tp->CR_point.x += tp->linediff.x;
  390.         tp->CR_point.y += tp->linediff.y;
  391.         tp->refpoint.x += tp->linediff.x;
  392.         tp->refpoint.y += tp->linediff.y;
  393.         break;
  394.       case _BS:
  395.         tp->refpoint.x -= tp->chardiff.x;
  396.         tp->refpoint.y -= tp->chardiff.y;
  397.         break;
  398.       case _HT:
  399.         tp->refpoint.x -= 0.5 * tp->chardiff.x;
  400.         tp->refpoint.y -= 0.5 * tp->chardiff.y;
  401.         break;
  402.       case _VT:
  403.         tp->CR_point.x -= tp->linediff.x;
  404.         tp->CR_point.y -= tp->linediff.y;
  405.         tp->refpoint.x -= tp->linediff.x;
  406.         tp->refpoint.y -= tp->linediff.y;
  407.         break;
  408.       case _SO:
  409.       case _SI:    /* Not implemented yet    */
  410.         break;
  411.       default:
  412. #ifdef STROKED_FONTS
  413.         if (tp->font)
  414.             ASCII_to_font ((int) *txt);
  415.         else
  416. #endif
  417.             ASCII_to_char ((int) *txt);
  418.            break;
  419.     }
  420. /**
  421.  ** Move to next reference point, e. g. the next character origin
  422.  **/
  423.     Pen_action_to_tmpfile (MOVE_TO, &tp->refpoint, FALSE);
  424.     txt++;
  425.   }
  426. }
  427.  
  428.  
  429.  
  430.  
  431.  
  432. void    plot_symbol_char (char c)
  433. /**
  434.  ** Special case: Symbol plotting. This requires a special
  435.  ** x and y offset (for proper centering) but then simply amounts to
  436.  ** drawing a single character.
  437.  **/
  438. {
  439. static    double    dx = 0.5 * (1.0 - WIDTH_FAC), dy = -0.5 * HEIGHT_FAC;
  440.  
  441.   tp->refpoint.x= HP_pos.x - tp->chardiff.x / 2.0;
  442.   tp->refpoint.y= HP_pos.y - tp->chardiff.y / 2.0;
  443.   tp->offset.x    = tp->chardiff.x * dx - tp->linediff.x * dy;
  444.   tp->offset.y    = tp->chardiff.y * dx - tp->linediff.y * dy;
  445.  
  446. #ifdef STROKED_FONTS
  447.   if (tp->font)
  448.     ASCII_to_font ((int) c);
  449.   else
  450. #endif
  451.     ASCII_to_char ((int) c);
  452. /**
  453.  ** Move to next reference point, e. g. the next character origin
  454.  **/
  455.   Pen_action_to_tmpfile (MOVE_TO, &tp->refpoint, FALSE);
  456. }
  457.  
  458.  
  459.  
  460.  
  461. void    plot_user_char (FILE *hd)
  462. /**
  463.  ** added by Alois Treindl 12-apr-93
  464.  **/
  465. {
  466. HPGL_Pt    p;
  467. double    x, y;
  468. float    fx, fy;
  469. int    pendown = FALSE;
  470.  
  471.   tp->refpoint        = HP_pos;
  472.   CurrentLineType    = LT_solid;
  473.   p.x = tp->refpoint.x + tp->offset.x;
  474.   p.y = tp->refpoint.y + tp->offset.y;
  475.  
  476.   while (read_float(&fx, hd) == 0)
  477.   {
  478.     if (fx >= 99)
  479.         pendown = TRUE;
  480.     else if (fx <= -99)
  481.         pendown = FALSE;
  482.     else
  483.     {
  484.         if (read_float(&fy, hd) != 0)
  485.             break;
  486.         x = fx;
  487.         y = fy * 2.0 / 3.0;
  488.         p.x += tp->Txx * x + tp->Txy * y;
  489.         p.y += tp->Tyx * x + tp->Tyy * y;
  490.         if (pendown)
  491.             Pen_action_to_tmpfile (DRAW_TO, &p, FALSE);
  492.         else
  493.             Pen_action_to_tmpfile (MOVE_TO, &p, FALSE);
  494.     }
  495.   }
  496.  
  497.   /* Update cursor: to next character origin!   */
  498.  
  499.   tp->refpoint.x += tp->chardiff.x;
  500.   tp->refpoint.y += tp->chardiff.y;
  501.   Pen_action_to_tmpfile (MOVE_TO, &tp->refpoint, FALSE);
  502.   CurrentLineType = GlobalLineType;
  503. }
  504.  
  505.