home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / util / edit / jade / src / render.c < prev    next >
C/C++ Source or Header  |  1994-09-09  |  22KB  |  782 lines

  1. /* render.c -- System-independant rendering
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #include <assert.h>
  24.  
  25. #ifdef HAVE_AMIGA
  26. # ifdef _DCC
  27. #  define GfxBase_DECLARED
  28. # endif
  29. # include <clib/graphics_protos.h>
  30. # include <graphics/gfxbase.h>
  31. # include <graphics/gfxmacros.h>
  32. extern struct GfxBase *GfxBase;
  33. #endif
  34.  
  35. _PR void cursor(VW *, bool);
  36. _PR void pen_to_line(VW *, long);
  37. _PR void pen_to_pos(VW *, long, long);
  38. _PR void pen_to_glyph_pos(VW *, long, long);
  39. _PR void draw_bit(VW *, int, u_char *, int, long, long);
  40. _PR void draw_line(VW *, LINE *, long);
  41. _PR void redraw_all(VW *);
  42. _PR void redraw_region(VW *, POS *, POS *);
  43. _PR void redraw_lines(VW *, long, long);
  44. _PR void redraw_lines_clr(VW *, long, long);
  45. _PR void redraw_line_from(VW *, long, long);
  46. _PR void redraw_rect(VW *, POS *, POS *, bool);
  47. _PR void cut_paste_lines(VW *, long, long);
  48. _PR void draw_message_line(VW *);
  49. _PR void redraw_message(VW *, u_char *, int);
  50. _PR void redraw_cmd_line(VW *, u_char *, u_char *, long, long);
  51. _PR void redraw_cmd_line_from(VW *, u_char *, u_char *, long, long, long);
  52. _PR void cmd_line_cursor(VW *, bool);
  53.  
  54. /* I hope this is enough!? :-| */
  55. static u_char glyph_buf[512];
  56.  
  57. static void
  58. pen_to_cursor(VW *vw)
  59. {
  60.     register int x, y;
  61.     calc_cursor_offset(vw);
  62.     y = vw->vw_FontStart +
  63.     ((vw->vw_CursorPos.pos_Line - vw->vw_StartLine) * vw->vw_FontY);
  64.     x = vw->vw_XStartPix +
  65.     ((vw->vw_LastCursorOffset - vw->vw_StartCol) * vw->vw_FontX);
  66.     if(x < vw->vw_XStartPix)
  67.     x = vw->vw_XStartPix;
  68.     MOVE(vw, x, y);
  69. }
  70.  
  71. void
  72. pen_to_line(VW *vw, long line)
  73. {
  74.     MOVE(vw, vw->vw_XStartPix,
  75.      vw->vw_FontStart + ((line - vw->vw_StartLine) * vw->vw_FontY));
  76. }
  77.  
  78. void
  79. pen_to_pos(VW *vw, long col, long line)
  80. {
  81.     TX *tx = vw->vw_Tx;
  82.     int x, y;
  83.     y = vw->vw_FontStart + ((line - vw->vw_StartLine) * vw->vw_FontY);
  84.     assert(line < tx->tx_NumLines);
  85.     x = vw->vw_XStartPix + ((glyph_col(tx, col, line) - vw->vw_StartCol)
  86.                 * vw->vw_FontX);
  87.     if(x < vw->vw_XStartPix)
  88.     x = vw->vw_XStartPix;
  89.     MOVE(vw, x, y);
  90. }
  91.  
  92. void
  93. pen_to_glyph_pos(VW *vw, long gcol, long line)
  94. {
  95.     int x, y;
  96.     y = vw->vw_FontStart + ((line - vw->vw_StartLine) * vw->vw_FontY);
  97.     x = vw->vw_XStartPix + ((gcol - vw->vw_StartCol) * vw->vw_FontX);
  98.     if(x < vw->vw_XStartPix)
  99.     x = vw->vw_XStartPix;
  100.     MOVE(vw, x, y);
  101. }
  102.  
  103. void
  104. cursor(VW *vw, bool status)
  105. {
  106.     if((vw->vw_Flags & VWFF_SLEEPING) == 0)
  107.     {
  108.     if(vw->vw_Flags & VWFF_STATUS_CURS)
  109.     {
  110.         PEN_X(vw) = vw->vw_XStartPix
  111.             + ((vw->vw_MessageLen < vw->vw_MaxX)
  112.                ? vw->vw_MessageLen
  113.                : (vw->vw_MaxX - 1)) * vw->vw_FontX;
  114.         PEN_Y(vw) = vw->vw_MessageFontY;
  115.         TEXT(vw, P_BLOCK, " ", 1);
  116.     }
  117.     else
  118.     {
  119.         if(vw->vw_CursorPos.pos_Line < vw->vw_StartLine + vw->vw_MaxY)
  120.         {
  121.         int pencol;
  122.         LINE *line = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  123.         long cursoff = vw->vw_CursorPos.pos_Col;
  124.         int inblk = cursor_in_block(vw);
  125.         if((status && inblk) || (!status && !inblk))
  126.             pencol = P_TEXT;
  127.         else
  128.             pencol = P_BLOCK;
  129.         pen_to_cursor(vw);
  130.         if((cursoff + 1) >= line->ln_Strlen)
  131.             TEXT(vw, pencol, " ", 1);
  132.         else
  133.             TEXT(vw, pencol, char_glyphs(vw->vw_Tx,
  134.                          line->ln_Line[cursoff]), 1);
  135.         }
  136.     }
  137.     }
  138. }
  139.  
  140. /*
  141.  * draws a section of a line of bytes, beg and end are x ordinates
  142.  */
  143. void
  144. draw_bit(VW *vw, int colour, u_char *str, int slen, long beg, long end)
  145. {
  146.     long startx = vw->vw_StartCol;
  147.     long endx = vw->vw_MaxX + startx + 1;
  148.     long length;
  149.     if(end < startx)
  150.     return;
  151.     if(beg < startx)
  152.     beg = startx;
  153.     if(end > endx)
  154.     end = endx;
  155.     if((length = end - beg) <= 0)
  156.     return;
  157.     slen -= beg;
  158.     if(slen <= 0)
  159.     return;
  160.     if(slen < length)
  161.     length = slen;
  162.     TEXT(vw, colour, str + beg, length);
  163. }
  164.  
  165. static void
  166. draw_block_line(VW *vw, long blockStartCol, long blockEndCol,
  167.         long drawEndCol, bool useBEC)
  168. {
  169.     int xend = ((drawEndCol - vw->vw_StartCol) * vw->vw_FontX)
  170.            + vw->vw_XStartPix;
  171.     if(PEN_X(vw) < vw->vw_XEndPix)
  172.     {
  173.     int rectblocks = vw->vw_Flags & VWFF_RECTBLOCKS;
  174.     if(useBEC || rectblocks)
  175.     {
  176.         int xblkend = ((blockEndCol - vw->vw_StartCol)
  177.                * vw->vw_FontX) + vw->vw_XStartPix;
  178.         if(rectblocks)
  179.         {
  180.         if((((PEN_X(vw) - vw->vw_XStartPix) / vw->vw_FontX)
  181.             + vw->vw_StartCol) < blockStartCol)
  182.         {
  183.             PEN_X(vw) = ((blockStartCol - vw->vw_StartCol)
  184.                  * vw->vw_FontX) + vw->vw_XStartPix;
  185.         }
  186.         }
  187.         if(xblkend >= xend)
  188.         xblkend = xend;
  189.         if(xblkend > PEN_X(vw))
  190.         {
  191.         SET_AREA(vw, PEN_X(vw), PEN_Y(vw) - FONT_ASCENT(vw),
  192.              xblkend - PEN_X(vw), vw->vw_FontY);
  193.         }
  194.     }
  195.     else
  196.     {
  197.         SET_AREA(vw, PEN_X(vw), PEN_Y(vw) - FONT_ASCENT(vw),
  198.                xend - PEN_X(vw), vw->vw_FontY);
  199.     }
  200.     }
  201. }
  202.  
  203. /*
  204.  * pen should be at start of line to draw (line should be cleared first)
  205.  */
  206. void
  207. draw_line(VW *vw, LINE *line, long lineNum)
  208. {
  209.     long glyphs = make_glyph_array(vw->vw_Tx, line->ln_Line, 0,
  210.                    line->ln_Strlen-1, glyph_buf,
  211.                    vw->vw_StartCol, vw->vw_MaxX);
  212.     if(vw->vw_BlockStatus != 0)
  213.     TEXT(vw, P_TEXT, glyph_buf, glyphs);
  214.     else
  215.     {
  216.     long block0col = glyph_col(vw->vw_Tx, vw->vw_BlockS.pos_Col,
  217.                    vw->vw_BlockS.pos_Line);
  218.     long block1col = glyph_col(vw->vw_Tx, vw->vw_BlockE.pos_Col,
  219.                    vw->vw_BlockE.pos_Line);
  220.     u_char *glyph_line = glyph_buf - vw->vw_StartCol;
  221.     long abs_glyphs = glyphs + vw->vw_StartCol;
  222.     if(vw->vw_Flags & VWFF_RECTBLOCKS)
  223.     {
  224.         if(block0col > block1col)
  225.         {
  226.         long tmp;
  227.         tmp = block0col;
  228.         block0col = block1col;
  229.         block1col = tmp;
  230.         }
  231.     }
  232.     switch(line_in_block(vw, lineNum))
  233.     {
  234.     case 0: /* none of line in block */
  235.         TEXT(vw, P_TEXT, glyph_buf, glyphs);
  236.         break;
  237.     case 1: /* whole of line in block */
  238.         TEXT(vw, P_BLOCK, glyph_buf, glyphs);
  239.         draw_block_line(vw, block0col, block1col,
  240.                 vw->vw_StartCol + vw->vw_MaxX, FALSE);
  241.         break;
  242.     case 2: /* start of line in block */
  243.         draw_bit(vw, P_BLOCK, glyph_line, abs_glyphs, 0, block1col);
  244.         draw_bit(vw, P_TEXT, glyph_line, abs_glyphs, block1col,
  245.              abs_glyphs);
  246.         draw_block_line(vw, block0col, block1col,
  247.                 vw->vw_StartCol + vw->vw_MaxX, TRUE);
  248.         break;
  249.     case 3: /* end of line in block */
  250.         draw_bit(vw, P_TEXT, glyph_line, abs_glyphs, 0, block0col);
  251.         draw_bit(vw, P_BLOCK, glyph_line, abs_glyphs, block0col,
  252.              abs_glyphs);
  253.         draw_block_line(vw, block0col, block1col,
  254.                 vw->vw_StartCol + vw->vw_MaxX, FALSE);
  255.         break;
  256.     case 4: /* middle of line in block */
  257.         draw_bit(vw, P_TEXT, glyph_line, abs_glyphs, 0, block0col);
  258.         draw_bit(vw, P_BLOCK, glyph_line, abs_glyphs, block0col,
  259.              block1col);
  260.         draw_bit(vw, P_TEXT, glyph_line, abs_glyphs, block1col,
  261.              abs_glyphs);
  262.         draw_block_line(vw, block0col, block1col,
  263.                 vw->vw_StartCol + vw->vw_MaxX, TRUE);
  264.         break;
  265.     }
  266.     }
  267. }
  268.  
  269. /*
  270.  * pen should be at first draw position, draws from character XSTART to the
  271.  * end of the line.
  272.  */
  273. static void
  274. draw_line_part(VW *vw, LINE *line, long lineNum, long xStart,
  275.            long glyph_xStart)
  276. {
  277.     u_char *src = line->ln_Line + xStart;
  278.     u_long srclen = (line->ln_Strlen - 1) - xStart;
  279.     long glyphs = make_glyph_array(vw->vw_Tx, src, glyph_xStart, srclen,
  280.                    glyph_buf, 0,
  281.                    (vw->vw_StartCol+vw->vw_MaxX)-glyph_xStart);
  282.     if(vw->vw_BlockStatus != 0)
  283.     TEXT(vw, P_TEXT, glyph_buf, glyphs);
  284.     else
  285.     {
  286.     long block0col = glyph_col(vw->vw_Tx, vw->vw_BlockS.pos_Col,
  287.                    vw->vw_BlockS.pos_Line);
  288.     long block1col = glyph_col(vw->vw_Tx, vw->vw_BlockE.pos_Col,
  289.                    vw->vw_Blo