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 >
Wrap
C/C++ Source or Header
|
1994-04-19
|
16KB
|
595 lines
/* render.c -- System-independant rendering
Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
This file is part of Jade.
Jade is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Jade is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jade; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "jade.h"
#include "jade_protos.h"
#ifdef HAVE_AMIGA
# ifdef _DCC
# define GfxBase_DECLARED
# endif
# include <clib/graphics_protos.h>
# include <graphics/gfxbase.h>
# include <graphics/gfxmacros.h>
extern struct GfxBase *GfxBase;
#endif
_PR void pentocursor(VW *);
_PR void pentoline(VW *, short);
_PR void pentopos(VW *, short, short);
_PR void cursor(VW *, bool);
_PR void drawbit(VW *, int, u_char *, int, long, long);
_PR void drawline(VW *, LINE *, long);
_PR void drawlinelength(VW *, LINE *, long, long, long);
_PR void redrawall(VW *);
_PR void redrawallfrom(VW *, long, long);
_PR void redrawregion(VW *, POS *, POS *);
_PR void redrawline(VW *, long);
_PR void redrawlines(VW *, long, long);
_PR void redrawlinesclr(VW *, long, long);
_PR void redrawlinefrom(VW *, long, long);
_PR void redrawrect(VW *, POS *, POS *, bool);
_PR void cutpastelines(VW *, long, long);
void
pentocursor(VW *vw)
{
int x, y;
x = vw->vw_XStartPix +
((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) * vw->vw_FontX);
if(x < vw->vw_XStartPix)
x = vw->vw_XStartPix;
y = vw->vw_FontStart +
((vw->vw_CursorPos.pos_Line - vw->vw_StartLine) * vw->vw_FontY);
MOVE(vw, x, y);
}
/*
* note actual y coordinate not line number
*/
void
pentoline(VW *vw, short yPos)
{
MOVE(vw, vw->vw_XStartPix, vw->vw_FontStart + (yPos * vw->vw_FontY));
}
/*
* this also takes coordinates...
*/
void
pentopos(VW *vw, short xPos, short yPos)
{
int x, y;
x = vw->vw_XStartPix + (xPos * vw->vw_FontX);
if(x < vw->vw_XStartPix)
x = vw->vw_XStartPix;
y = vw->vw_FontStart + (yPos * vw->vw_FontY);
MOVE(vw, x, y);
}
void
cursor(VW *vw, bool status)
{
if(!vw->vw_Sleeping
&& (vw->vw_CursorPos.pos_Line < vw->vw_StartLine + vw->vw_MaxY))
{
int pencol;
LINE *line = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
long cursoff = vw->vw_CursorPos.pos_Col;
int inblk = cursinblock(vw);
if((status && inblk) || (!status && !inblk))
pencol = P_TEXT;
else
pencol = P_BLOCK;
pentocursor(vw);
if((cursoff + 1) >= line->ln_Strlen)
TEXT(vw, pencol, " ", 1);
else
TEXT(vw, pencol, line->ln_Line + cursoff, 1);
}
}
/*
* draws a section of a line of text, beg and end are x ordinates
*/
void
drawbit(VW *vw, int colour, u_char *str, int slen, long beg, long end)
{
long startx = vw->vw_StartCol;
long endx = vw->vw_MaxX + startx + 1;
long length;
if(end <= startx)
return;
if(beg < startx)
beg = startx;
if(end > endx)
end = endx;
if((length = end - beg - 1) <= 0)
return;
slen -= beg;
if(slen <= 0)
return;
if(slen < length)
length = slen;
TEXT(vw, colour, str + beg, length);
}
static void
drawblockline(VW *vw, long blockStartCol, long blockEndCol,
long drawEndCol, bool useBEC)
{
int xend = ((drawEndCol - vw->vw_StartCol) * vw->vw_FontX)
+ vw->vw_XStartPix;
if(PEN_X(vw) < vw->vw_XEndPix)
{
int rectblocks = vw->vw_Flags & VWFF_RECTBLOCKS;
if(useBEC || rectblocks)
{
int xblkend = ((blockEndCol - vw->vw_StartCol)
* vw->vw_FontX) + vw->vw_XStartPix;
if(rectblocks)
{
if((((PEN_X(vw) - vw->vw_XStartPix) / vw->vw_FontX)
+ vw->vw_StartCol) < blockStartCol)
{
PEN_X(vw) = ((blockStartCol - vw->vw_StartCol)
* vw->vw_FontX) + vw->vw_XStartPix;
}
}
if(xblkend >= xend)
xblkend = xend;
if(xblkend > PEN_X(vw))
{
SET_AREA(vw, PEN_X(vw), PEN_Y(vw) - FONT_ASCENT(vw),
xblkend - PEN_X(vw), vw->vw_FontY);
}
}
else
{
SET_AREA(vw, PEN_X(vw), PEN_Y(vw) - FONT_ASCENT(vw),
xend - PEN_X(vw), vw->vw_FontY);
}
}
}
/*
* pen should be at start of line to draw (line should be cleared first)
*/
void
drawline(VW *vw, LINE *line, long lineNum)
{
long llen = line->ln_Strlen;
long slen = llen - 1;
if(vw->vw_BlockStatus != 0)
{
drawbit(vw, P_TEXT, line->ln_Line, slen, 0, llen);
}
else
{
long block0col = vw->vw_BlockS.pos_Col;
long block1col = vw->vw_BlockE.pos_Col;
if(vw->vw_Flags & VWFF_RECTBLOCKS)
{
if(block0col > block1col)
{
long tmp;
tmp = block0col;
block0col = block1col;
block1col = tmp;
}
block1col++;
}
switch(lineinblock(vw, lineNum))
{
case 0: /* none of line in block */
drawbit(vw, P_TEXT, line->ln_Line, slen, 0, llen);
break;
case 1: /* whole of line in block */
drawbit(vw, P_BLOCK, line->ln_Line, slen, 0, llen);
drawblockline(vw, block0col, block1col,
vw->vw_StartCol + vw->vw_MaxX, FALSE);
break;
case 2: /* start of line in block */
drawbit(vw, P_BLOCK, line->ln_Line, slen, 0, block1col + 1);
drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, llen);
drawblockline(vw, block0col, block1col,
vw->vw_StartCol + vw->vw_MaxX, TRUE);
break;
case 3: /* end of line in block */
drawbit(vw, P_TEXT, line->ln_Line, slen, 0, block0col + 1);
drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col, llen);
drawblockline(vw, block0col, block1col,
vw->vw_StartCol + vw->vw_MaxX, FALSE);
break;
case 4: /* middle of line in block */
drawbit(vw, P_TEXT, line->ln_Line, slen, 0, block0col + 1);
drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col,
block1col + 1);
drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, llen);
drawblockline(vw, block0col, block1col,
vw->vw_StartCol + vw->vw_MaxX, TRUE);
break;
}
}
}
/*
* pen should be at first draw position
* xEnd is *ex*clusive (ie, line->ln_Line[xEnd] isn't drawn)
*/
void
drawlinelength(VW *vw, LINE *line, long lineNum, long xStart, long xEnd)
{
int slen = line->ln_Strlen - 1;
if(vw->vw_BlockStatus)
{
drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, xEnd);
}
else
{
long block0col = vw->vw_BlockS.pos_Col;
long block1col = vw->vw_BlockE.pos_Col;
if(vw->vw_Flags & VWFF_RECTBLOCKS)
{
if(block0col > block1col)
{
long tmp;
tmp = block0col;
block0col = block1col;
block1col = tmp;
}
block1col++;
}
switch(lineinblock(vw, lineNum))
{
case 0: /* none of line in block */
drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, xEnd);
break;
case 1: /* whole of line in block */
drawbit(vw, P_BLOCK, line->ln_Line, slen, xStart, xEnd);
drawblockline(vw, block0col, block1col, xEnd, FALSE);
break;
case 2: /* start of line in block */
if(xStart < block1col)
drawbit(vw, P_BLOCK, line->ln_Line, slen, xStart, block1col+1);
else
block1col = xStart;
drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, xEnd);
drawblockline(vw, block0col, block1col, xEnd, TRUE);
break;
case 3: /* end of line in block */
if(xStart < block0col)
drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, block0col+1);
else
block0col = xStart;
drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col, xEnd);
drawblockline(vw, block0col, block1col, xEnd, FALSE);
break;
case 4: /* middle of line in block */
if(xStart < block0col)
drawbit(vw, P_TEXT, line->ln_Line, slen, xStart, block0col+1);
else
block0col = xStart;
if(block0col < block1col)
drawbit(vw, P_BLOCK, line->ln_Line, slen, block0col,
block1col + 1);
else
block1col = block0col;
drawbit(vw, P_TEXT, line->ln_Line, slen, block1col, xEnd);
drawblockline(vw, block0col, block1col, xEnd, TRUE);
break;
}
}
}
#define drawlinepart(vw, line,