home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / util / jade-3.0.lha / Jade / src / render.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-19  |  15.6 KB  |  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, lineNum, xStart) \
  302.     drawlinelength(vw, line, lineNum, xStart, vw->vw_StartCol + vw->vw_MaxX+1)
  303.  
  304. void
  305. redrawall(VW *vw)
  306. {
  307.     long linenum = vw->vw_StartLine;
  308.     LINE *line = vw->vw_Tx->tx_Lines + linenum;
  309.     short y = 0;
  310.     CLR_RECT(vw, vw->vw_XStartPix, vw->vw_YStartPix,
  311.          vw->vw_XEndPix, vw->vw_YEndPix);
  312.     while((y < vw->vw_MaxY) && (linenum < vw->vw_Tx->tx_NumLines))
  313.     {
  314.     pentoline(vw, y);
  315.     drawline(vw, line, linenum);
  316.     y++;
  317.     linenum++;
  318.     line++;
  319.     }
  320. }
  321.  
  322. void
  323. redrawallfrom(VW *vw, long col, long lineNum)
  324. {
  325.     LINE *line = vw->vw_Tx->tx_Lines + lineNum;
  326.     short y = lineNum - vw->vw_StartLine;
  327.     int yord = (y * vw->vw_FontY) + vw->vw_YStartPix;
  328.     if(col < vw->vw_StartCol)
  329.     col = vw->vw_StartCol;
  330.     if((y >= 0) && (y < vw->vw_MaxY))
  331.     {
  332.     CLR_RECT(vw, ((col-vw->vw_StartCol)*vw->vw_FontX) + vw->vw_XStartPix,
  333.           yord, vw->vw_XEndPix, yord + vw->vw_FontY);
  334.     pentopos(vw, col - vw->vw_StartCol, y);
  335.     drawlinepart(vw, line, lineNum, col);
  336.     line++;
  337.     lineNum++;
  338.     y++;
  339.     yord += vw->vw_FontY;
  340.     }
  341.     else
  342.     {
  343.     y = 0;
  344.     yord = vw->vw_YStartPix;
  345.     lineNum = vw->vw_StartLine;
  346.     line = vw->vw_Tx->tx_Lines + lineNum;
  347.     }
  348.     if(y < vw->vw_MaxY)
  349.     {
  350.     CLR_RECT(vw, vw->vw_XStartPix, yord, vw->vw_XEndPix, vw->vw_YEndPix);
  351.     while((y < vw->vw_MaxY) && (lineNum < vw->vw_Tx->tx_NumLines))
  352.     {
  353.         pentoline(vw, y);
  354.         drawline(vw, line, lineNum);
  355.         y++;
  356.         lineNum++;
  357.         line++;
  358.     }
  359.     }
  360. }
  361.  
  362. void
  363. redrawregion(VW *vw, POS *start, POS *end)
  364. {
  365.     long col = start->pos_Col;
  366.     long linenum = start->pos_Line;
  367.     LINE *line = vw->vw_Tx->tx_Lines + linenum;
  368.     short y = linenum - vw->vw_StartLine;
  369.     short yend = end->pos_Line - vw->vw_StartLine + 1;
  370.     int yord = (y * vw->vw_FontY) + vw->vw_YStartPix;
  371.     if(col < vw->vw_StartCol)
  372.     col = vw->vw_StartCol;
  373.     if(yend > vw->vw_MaxY)
  374.     yend = vw->vw_MaxY;
  375.     if((y >= 0) && (y < yend))
  376.     {
  377.     CLR_RECT(vw, ((col-vw->vw_StartCol)*vw->vw_FontX) + vw->vw_XStartPix,
  378.           yord, vw->vw_XEndPix, yord + vw->vw_FontY);
  379.     pentopos(vw, col - vw->vw_StartCol, y);
  380.     if(linenum < vw->vw_Tx->tx_NumLines)
  381.         drawlinepart(vw, line, linenum, col);
  382.     line++;
  383.     linenum++;
  384.     y++;
  385.     yord += vw->vw_FontY;
  386.     }
  387.     else
  388.     {
  389.     y = 0;
  390.     yord = vw->vw_YStartPix;
  391.     linenum = vw->vw_StartLine;
  392.     line = vw->vw_Tx->tx_Lines + linenum;
  393.     }
  394.     if(y < yend)
  395.     {
  396.     CLR_RECT(vw, vw->vw_XStartPix, yord, vw->vw_XEndPix,
  397.           vw->vw_YStartPix + (yend * vw->vw_FontY));
  398.     while((y < yend) && (linenum < vw->vw_Tx->tx_NumLines))
  399.     {
  400.         pentoline(vw, y);
  401.         drawline(vw, line, linenum);
  402.         y++;
  403.         linenum++;
  404.         line++;
  405.     }
  406.     }
  407. }
  408.  
  409. void
  410. redrawline(VW *vw, long lineNum)
  411. {
  412.     int yord = ((lineNum-vw->vw_StartLine) * vw->vw_FontY) + vw->vw_YStartPix;
  413.     CLR_RECT(vw, vw->vw_XStartPix, yord, vw->vw_XEndPix, yord + vw->vw_FontY);
  414.     pentoline(vw, lineNum - vw->vw_StartLine);
  415.     drawline(vw, vw->vw_Tx->tx_Lines + lineNum, lineNum);
  416. }
  417.  
  418. /*
  419.  * DOES NOT clear the drawing area
  420.  */
  421. void
  422. redrawlines(VW *vw, long startLine, long endLine)
  423. {
  424.     LINE *line = vw->vw_Tx->tx_Lines;
  425.     short y;
  426.     if(startLine < vw->vw_StartLine)
  427.     startLine = vw->vw_StartLine;
  428.     y = startLine - vw->vw_StartLine;
  429.     line += startLine;
  430.     if(endLine > vw->vw_Tx->tx_NumLines)
  431.     endLine = vw->vw_Tx->tx_NumLines;
  432.     endLine -= vw->vw_StartLine;
  433.     if(endLine > vw->vw_MaxY)
  434.     endLine = vw->vw_MaxY;
  435.     while(y < endLine)
  436.     {
  437.     pentoline(vw, y);
  438.     drawline(vw, line, startLine);
  439.     startLine++;
  440.     y++;
  441.     line++;
  442.     }
  443. }
  444.  
  445. void
  446. redrawlinesclr(VW *vw, long startLine, long endLine)
  447. {
  448.     LINE *line = vw->vw_Tx->tx_Lines;
  449.     short y;
  450.     endLine++;
  451.     if((endLine <= vw->vw_StartLine)
  452.        || (startLine > (vw->vw_StartLine + vw->vw_MaxY)))
  453.     {
  454.     return;
  455.     }
  456.     if(startLine < vw->vw_StartLine)
  457.     startLine = vw->vw_StartLine;
  458.     y = startLine - vw->vw_StartLine;
  459.     line += startLine;
  460.     if(endLine > vw->vw_Tx->tx_NumLines)
  461.     endLine = vw->vw_Tx->tx_NumLines;
  462.     endLine -= vw->vw_StartLine;
  463.     if(endLine > vw->vw_MaxY)
  464.     endLine = vw->vw_MaxY;
  465.     CLR_RECT(vw, vw->vw_XStartPix, (y * vw->vw_FontY) + vw->vw_YStartPix,
  466.           vw->vw_XEndPix, (endLine * vw->vw_FontY) + vw->vw_YStartPix);
  467.     while(y < endLine)
  468.     {
  469.     pentoline(vw, y);
  470.     drawline(vw, line, startLine);
  471.     startLine++;
  472.     y++;
  473.     line++;
  474.     }
  475. }
  476.  
  477. void
  478. redrawlinefrom(VW *vw, long col, long lineNum)
  479. {
  480.     if(col < vw->vw_StartCol)
  481.     col = vw->vw_StartCol;
  482.     if((lineNum >= vw->vw_StartLine)
  483.        && (lineNum < vw->vw_StartLine + vw->vw_MaxY))
  484.     {
  485.     int yord = ((lineNum - vw->vw_StartLine) * vw->vw_FontY)
  486.            + vw->vw_YStartPix;
  487.     CLR_RECT(vw, vw->vw_XStartPix +((col-vw->vw_StartCol) * vw->vw_FontX),
  488.           yord, vw->vw_XEndPix, yord + vw->vw_FontY);
  489.     pentopos(vw, col - vw->vw_StartCol, lineNum - vw->vw_StartLine);
  490.     drawlinepart(vw, vw->vw_Tx->tx_Lines + lineNum, lineNum, col);
  491.     }
  492. }
  493.  
  494. /*
  495.  * Assumes (start, end) is valid AND totally viewable (ie, no checks, no
  496.  * clipping). Should be ok since this is meant for Expose type events
  497.  * start is probably trashed
  498.  * `gapBlank' says whether or not I need to clear the space I'm drawing into.
  499.  */
  500. void
  501. redrawrect(VW *vw, POS *start, POS *end, bool gapBlank)
  502. {
  503.     TX *tx = vw->vw_Tx;
  504.     LINE *line = tx->tx_Lines + start->pos_Line;
  505.     int yord = ((start->pos_Line - vw->vw_StartLine) * vw->vw_FontY)
  506.            + vw->vw_YStartPix;
  507.     end->pos_Col++;
  508.     end->pos_Line++;
  509.     if(!gapBlank)
  510.     {
  511.     CLR_RECT(vw,
  512.           vw->vw_XStartPix + ((start->pos_Col - vw->vw_StartCol)
  513.                       * vw->vw_FontX),
  514.           yord,
  515.           vw->vw_XStartPix + ((end->pos_Col - vw->vw_StartCol)
  516.                       * vw->vw_FontX),
  517.           ((end->pos_Line - vw->vw_StartLine)
  518.            * vw->vw_FontY) + vw->vw_YStartPix);
  519.     }
  520.     if(end->pos_Line > tx->tx_NumLines)
  521.     end->pos_Line = tx->tx_NumLines;
  522.     while(end->pos_Line > start->pos_Line)
  523.     {
  524.     pentopos(vw, start->pos_Col - vw->vw_StartCol,
  525.          start->pos_Line - vw->vw_StartLine);
  526.     drawlinelength(vw, line, start->pos_Line, start->pos_Col,
  527.                end->pos_Col + 1);
  528.     line++;
  529.     start->pos_Line++;
  530.     }
  531. }
  532.  
  533.  
  534. /*
  535.  * Copies from srcLine to bottom of screen to dstLine
  536.  */
  537. void
  538. cutpastelines(VW *vw, long srcLine, long dstLine)
  539. {
  540.     int xsrc, ysrc, xwth, yht, xdst, ydst;
  541.     long lastline = vw->vw_StartLine + vw->vw_MaxY;
  542.     /* number of lines which are not blank. */
  543.     int lastdisp = (vw->vw_Tx->tx_NumLines - vw->vw_Tx->tx_ModDelta)
  544.            - vw->vw_LastDisplayOrigin.pos_Line;
  545.     if(srcLine < vw->vw_StartLine)
  546.     srcLine = vw->vw_StartLine;
  547.     if(dstLine < vw->vw_StartLine)
  548.     dstLine = vw->vw_StartLine;
  549.     if(srcLine >= lastline)
  550.     srcLine = lastline - 1;
  551.     if(dstLine >= lastline)
  552.     return;
  553.     if(srcLine == dstLine)
  554.     return;
  555.     xsrc = vw->vw_XStartPix;
  556.     xwth = vw->vw_XWidthPix;
  557.     xdst = vw->vw_XStartPix;
  558.     ysrc = vw->vw_YStartPix + ((srcLine - vw->vw_StartLine) * vw->vw_FontY);
  559.     ydst = vw->vw_YStartPix + ((dstLine - vw->vw_StartLine) * vw->vw_FontY);
  560.     if(ysrc > ydst)
  561.     {
  562.     if(lastdisp >= vw->vw_MaxY)
  563.         yht = vw->vw_YEndPix - ysrc;
  564.     else
  565.     {
  566.         yht = (vw->vw_YStartPix + (lastdisp * vw->vw_FontY)) - ydst;
  567.         if((yht + ydst) > vw->vw_YEndPix)
  568.         yht = vw->vw_YEndPix - ydst;
  569.     }
  570.     }
  571.     else
  572.     {
  573.     if(lastdisp >= vw->vw_MaxY)
  574.         yht = vw->vw_YEndPix - ydst;
  575.     else
  576.     {
  577.         yht = (vw->vw_YStartPix + (lastdisp * vw->vw_FontY)) - ysrc;
  578.         if((yht + ysrc) > vw->vw_YEndPix)
  579.         yht = vw->vw_YEndPix - ysrc;
  580.     }
  581.     }
  582.     if((xwth > 0) && (yht > 0))
  583.     COPY_AREA(vw, xsrc, ysrc, xwth, yht, xdst, ydst);
  584.     if(ysrc > ydst)
  585.     {
  586.     /* stuff we weren't able to blit.  */
  587.     long firstline = lastline - (srcLine - dstLine);
  588.     if(firstline < vw->vw_Tx->tx_NumLines)
  589.         redrawlinesclr(vw, firstline, lastline);
  590.     else
  591.         CLR_RECT(vw, vw->vw_XStartPix, vw->vw_YStartPix + (vw->vw_FontY * (firstline - vw->vw_StartLine)),
  592.               vw->vw_XEndPix, vw->vw_YEndPix);
  593.     }
  594. }
  595.