home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / may94 / util / edit / jade.lha / Jade / src / render.c < prev    next >
C/C++ Source or Header  |  1994-04-19  |  16KB  |  595 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. #ifdef HAVE_AMIGA
  24. # ifdef _DCC
  25. #  define GfxBase_DECLARED
  26. # endif
  27. # include <clib/graphics_protos.h>
  28. # include <graphics/gfxbase.h>
  29. # include <graphics/gfxmacros.h>
  30. extern struct GfxBase *GfxBase;
  31. #endif
  32.  
  33. _PR void pentocursor(VW *);
  34. _PR void pentoline(VW *, short);
  35. _PR void pentopos(VW *, short, short);
  36. _PR void cursor(VW *, bool);
  37. _PR void drawbit(VW *, int, u_char *, int, long, long);
  38. _PR void drawline(VW *, LINE *, long);
  39. _PR void drawlinelength(VW *, LINE *, long, long, long);
  40. _PR void redrawall(VW *);
  41. _PR void redrawallfrom(VW *, long, long);
  42. _PR void redrawregion(VW *, POS *, POS *);
  43. _PR void redrawline(VW *, long);
  44. _PR void redrawlines(VW *, long, long);
  45. _PR void redrawlinesclr(VW *, long, long);
  46. _PR void redrawlinefrom(VW *, long, long);
  47. _PR void redrawrect(VW *, POS *, POS *, bool);
  48. _PR void cutpastelines(VW *, long, long);
  49.  
  50. void
  51. pentocursor(VW *vw)
  52. {
  53.     int x, y;
  54.     x = vw->vw_XStartPix +
  55.     ((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) * vw->vw_FontX);
  56.     if(x < vw->vw_XStartPix)
  57.     x = vw->vw_XStartPix;
  58.     y = vw->vw_FontStart +
  59.     ((vw->vw_CursorPos.pos_Line - vw->vw_StartLine) * vw->vw_FontY);
  60.     MOVE(vw, x, y);
  61. }
  62.  
  63. /*
  64.  * note actual y coordinate not line number
  65.  */
  66. void
  67. pentoline(VW *vw, short yPos)
  68. {
  69.     MOVE(vw, vw->vw_XStartPix, vw->vw_FontStart + (yPos * vw->vw_FontY));
  70. }
  71.  
  72. /*
  73.  * this also takes coordinates...
  74.  */
  75. void
  76. pentopos(VW *vw, short xPos, short yPos)
  77. {
  78.     int x, y;
  79.     x = vw->vw_XStartPix + (xPos * vw->vw_FontX);
  80.     if(x < vw->vw_XStartPix)
  81.     x = vw->vw_XStartPix;
  82.     y = vw->vw_FontStart + (yPos * vw->vw_FontY);
  83.     MOVE(vw, x, y);
  84. }
  85.  
  86. void
  87. cursor(VW *vw, bool status)
  88. {
  89.     if(!vw->vw_Sleeping
  90.        && (vw->vw_CursorPos.pos_Line < vw->vw_StartLine + vw->vw_MaxY))
  91.     {
  92.     int pencol;
  93.     LINE *line = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  94.     long cursoff = vw->vw_CursorPos.pos_Col;
  95.     int inblk = cursinblock(vw);
  96.     if((status && inblk) || (!status && !inblk))
  97.         pencol = P_TEXT;
  98.     else
  99.         pencol = P_BLOCK;
  100.     pentocursor(vw);
  101.     if((cursoff + 1) >= line->ln_Strlen)
  102.         TEXT(vw, pencol, " ", 1);
  103.     else
  104.         TEXT(vw, pencol, line->ln_Line + cursoff, 1);
  105.     }
  106. }
  107.  
  108. /*
  109.  * draws a section of a line of text, beg and end are x ordinates
  110.  */
  111. void
  112. drawbit(VW *vw, int colour, u_char *str, int slen, long beg, long end)
  113. {
  114.     long startx = vw->vw_StartCol;
  115.     long endx = vw->vw_MaxX + startx + 1;
  116.     long length;
  117.     if(end <= startx)
  118.     return;
  119.     if(beg < startx)
  120.     beg = startx;
  121.     if(end > endx)
  122.     end = endx;
  123.     if((length = end - beg - 1) <= 0)
  124.     return;
  125.     slen -= beg;
  126.     if(slen <= 0)
  127.     return;
  128.     if(slen < length)
  129.     length = slen;
  130.     TEXT(vw, colour, str + beg, length);
  131. }
  132.  
  133. static void
  134. drawblockline(VW *vw, long blockStartCol, long blockEndCol,
  135.           long drawEndCol, bool useBEC)
  136. {
  137.     int xend = ((drawEndCol - vw->vw_StartCol) * vw->vw_FontX)
  138.            + vw->vw_XStartPix;
  139.     if(PEN_X(vw) < vw->vw_XEndPix)
  140.     {
  141.     int rectblocks = vw->vw_Flags & VWFF_RECTBLOCKS;
  142.     if(useBEC || rectblocks)
  143.     {
  144.         int xblkend = ((blockEndCol - vw->vw_StartCol)
  145.                * vw->vw_FontX) + vw->vw_XStartPix;
  146.         if(rectblocks)
  147.         {
  148.         if((((PEN_X(vw) - vw->vw_XStartPix) / vw->vw_FontX)
  149.             + vw->vw_StartCol) < blockStartCol)
  150.         {
  151.             PEN_X(vw) = ((blockStartCol - vw->vw_StartCol)
  152.                  * vw->vw_FontX) + vw->vw_XStartPix;
  153.         }
  154.         }
  155.         if(xblkend >= xend)
  156.         xblkend = xend;
  157.         if(xblkend > PEN_X(vw))
  158.         {
  159.         SET_AREA(vw, PEN_X(vw), PEN_Y(vw) - FONT_ASCENT(vw),
  160.              xblkend - PEN_X(vw), vw->vw_FontY);
  161.         }
  162.     }
  163.     else
  164.     {
  165.         SET_AREA(vw, PEN_X(vw), PEN_Y(vw) - FONT_ASCENT(vw),
  166.                xend - PEN_X(vw), vw->vw_FontY);
  167.     }
  168.     }
  169. }
  170.  
  171. /*
  172.  * pen should be at start of line to draw (line should be cleared first)
  173.  */
  174. void
  175. drawline(VW *vw, LINE *line, long lineNum)
  176. {
  177.     long llen = line->ln_Strlen;
  178.     long slen = llen - 1;
  179.     if(vw->vw_BlockStatus != 0)
  180.     {
  181.     drawbit(vw, P_TEXT, line->ln_Line, slen, 0, llen);
  182.     }
  183.     else
  184.     {
  185.     long block0col = vw->vw_BlockS.pos_Col;
  186.     long block1col = vw->vw_BlockE.pos_Col;
  187.     if(vw->vw_Flags & VWFF_RECTBLOCKS)
  188.     {
  189.         if(block0col > block1col)
  190.         {
  191.         long tmp;
  192.         tmp = block0col;
  193.         block0col = block1col;
  194.         block1col = tmp;
  195.         }
  196.         block1col++;
  197.     }
  198.     switch(lineinblock(vw, lineNum))
  199.     {
  200.     case 0: /* none of line in block */
  201.         drawbit(vw, P_TEXT, line->ln_Line, slen, 0, llen);
  202.         break;
  203.     case 1: /* whole of line in block */
  204.         drawbit(vw, P_BLOCK, line->ln_Line, slen, 0, llen);
  205.         drawblockline(vw, block0col, block1col,
  206.               vw->vw_StartCol + vw->vw_MaxX, FALSE);
  207.         break;
  208.     case 2: /* start of line in block */
  209.         drawbit(vw, P_BLOCK, line->ln_Line, slen, 0, block1col + 1);
  210.         drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, llen);
  211.         drawblockline(vw, block0col, block1col,
  212.               vw->vw_StartCol + vw->vw_MaxX, TRUE);
  213.         break;
  214.     case 3: /* end of line in block */
  215.         drawbit(vw, P_TEXT, line->ln_Line, slen, 0, block0col + 1);
  216.         drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col, llen);
  217.         drawblockline(vw, block0col, block1col,
  218.               vw->vw_StartCol + vw->vw_MaxX, FALSE);
  219.         break;
  220.     case 4: /* middle of line in block */
  221.         drawbit(vw, P_TEXT, line->ln_Line, slen, 0, block0col + 1);
  222.         drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col,
  223.             block1col + 1);
  224.         drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, llen);
  225.         drawblockline(vw, block0col, block1col,
  226.               vw->vw_StartCol + vw->vw_MaxX, TRUE);
  227.         break;
  228.     }
  229.     }
  230. }
  231.  
  232. /*
  233.  * pen should be at first draw position
  234.  * xEnd is *ex*clusive (ie, line->ln_Line[xEnd] isn't drawn)
  235.  */
  236. void
  237. drawlinelength(VW *vw, LINE *line, long lineNum, long xStart, long xEnd)
  238. {
  239.     int slen = line->ln_Strlen - 1;
  240.     if(vw->vw_BlockStatus)
  241.     {
  242.     drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, xEnd);
  243.     }
  244.     else
  245.     {
  246.     long block0col = vw->vw_BlockS.pos_Col;
  247.     long block1col = vw->vw_BlockE.pos_Col;
  248.     if(vw->vw_Flags & VWFF_RECTBLOCKS)
  249.     {
  250.         if(block0col > block1col)
  251.         {
  252.         long tmp;
  253.         tmp = block0col;
  254.         block0col = block1col;
  255.         block1col = tmp;
  256.         }
  257.         block1col++;
  258.     }
  259.     switch(lineinblock(vw, lineNum))
  260.     {
  261.     case 0: /* none of line in block */
  262.         drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, xEnd);
  263.         break;
  264.     case 1: /* whole of line in block */
  265.         drawbit(vw, P_BLOCK, line->ln_Line, slen, xStart, xEnd);
  266.         drawblockline(vw, block0col, block1col, xEnd, FALSE);
  267.         break;
  268.     case 2: /* start of line in block */
  269.         if(xStart < block1col)
  270.         drawbit(vw, P_BLOCK, line->ln_Line, slen, xStart, block1col+1);
  271.         else
  272.         block1col = xStart;
  273.         drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, xEnd);
  274.         drawblockline(vw, block0col, block1col, xEnd, TRUE);
  275.         break;
  276.     case 3: /* end of line in block */
  277.         if(xStart < block0col)
  278.         drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, block0col+1);
  279.         else
  280.         block0col = xStart;
  281.         drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col, xEnd);
  282.         drawblockline(vw, block0col, block1col, xEnd, FALSE);
  283.         break;
  284.     case 4: /* middle of line in block */
  285.         if(xStart < block0col)
  286.         drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, block0col+1);
  287.         else
  288.         block0col = xStart;
  289.         if(block0col < block1col)
  290.         drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col,
  291.             block1col + 1);
  292.         else
  293.         block1col = block0col;
  294.         drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, xEnd);
  295.         drawblockline(vw, block0col, block1col, xEnd, TRUE);
  296.         break;
  297.     }
  298.     }
  299. }
  300.  
  301. #define drawlinepart(vw, line,