home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
SOURCE
/
CSSRC
/
SDPLOAT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-04
|
16KB
|
645 lines
/*
sdploat.c
% sed_Ploat
C-scape 3.2
Copyright (c) 1988 by Oakland Group, Inc.
ALL RIGHTS RESERVED.
Revision History
---------------------
8/22/88 jmd is now called tbdraw
9/15/88 jmd changed winptd_struct to ptd_struct, preened phlush_s
made phlush static, removed viddecl.h
1/25/89 jdc fixed trailing color bug
3/24/89 jmd added sed_ macros, removed sed back attr
3/29/89 jmd Added CSPRIV modifier
5/19/89 jmd renamed exp to expan to shut up lint
5/26/89 jmd Sped up by using ptd_Clear
5/27/89 jmd added field painting
5/29/89 jmd added shadows
6/11/89 jmd added field only paint mode
6/12/89 jmd is now called sdploat
7/21/89 jmd/gam fixed attr problem with FIELDS only
8/08/89 jmd added some NULL tests
8/16/89 jdc Fixed field marking
8/24/89 jdc Fixed call to opbox_clip
9/10/89 jmd Fixed initialization problem in field only case
9/12/89 jmd Fixed last bug in sed_Ploat
3/28/90 jmd ansi-fied
5/01/90 jdc removed trailing '\n' requirement
6/01/90 jmd changed flag to flagg to avoid DG conflict
6/05/90 jmd moved prototype of phlush to after the struct
8/09/90 jdc added wrap_char
12/04/90 jdc fixed wrap past window width problem
*/
#include "sed.h" /* these routines need access to the dmgr */
#include "tbpriv.h" /* For tb_FindLine() */
#define SAVE_HINTS
#define TEXT 1
#define CHR 2
#define DONE 3
#define FIELDS 4 /* ploat fields only */
struct phlush_s {
sed_type sed;
ptd_struct *ptd;
bblock_type b, phlushb;
char *t, *phlusht;
char phlushs;
unsigned int phlusho, off, blen;
int col, phlushc, flen, mark, done;
ocbox paintbox, markbox;
opcoord ytext;
opcoord fwid, fhgt;
int blankrow;
int fldno; /* field hints */
int fldrow;
byte attr;
};
OSTATIC void CSPRIV phlush(struct phlush_s *f, int flagg);
#define f_reset(f) { f.phlushb = f.b; f.phlusht = f.t;\
f.phlushc = (f.paintbox.leftcol > f.col) ? f.paintbox.leftcol : f.col;}
void sed_Ploat(sed_type sed, ptd_struct *ptd, int blankrow)
/*
Ploats text and fields within the region of the sed specified by the ptd.
This is only called by sedwin_Class
*/
{
struct phlush_s f;
tb_type tb;
bblock_type b;
unsigned int off;
long offset, space, boff;
int scol, width, back, tab_size, dif, expan;
tb = sed_GetTextbuf(sed);
cs_Assert(tb_Ok(tb), CS_TB_DL_TB, 0);
f.sed = sed;
f.ptd = ptd;
opbox_charcoords(ptd->relboxp, win_GetFont(sed), &(f.paintbox));
f.fhgt = win_GetFontHeight(sed);
f.fwid = win_GetFontWidth(sed);
f.ytext = (f.paintbox.toprow + 1) * f.fhgt;
f.paintbox.toprow += sed_GetYoffset(sed);
f.paintbox.botrow += sed_GetYoffset(sed);
f.paintbox.leftcol += sed_GetXoffset(sed);
f.paintbox.rightcol += sed_GetXoffset(sed);
/* initialize field hints */
f.fldrow = f.paintbox.toprow;
f.fldno = menu_GetGRow(sed_GetMenu(sed), f.fldrow) - 1;
f.blankrow = blankrow;
if (sed_GetPaintFlag(sed) == SDPF_FIELDS) {
/* only ploat the fields */
for (; f.paintbox.toprow <= f.paintbox.botrow;
f.paintbox.toprow++, f.ytext += f.fhgt) {
f.phlushc = f.paintbox.leftcol;
f.col = f.paintbox.rightcol;
phlush(&f, FIELDS);
}
return;
}
b = tb->bbc->b; /* save current hints */
off = b->off;
space = b->row;
boff = tb->offset;
scol = tb->exp_len;
dif = tb->len;
back = tb->nend;
f.done = FALSE;
if (tb_FindLine(tb, f.paintbox.toprow) <= 0) {
f.done = TRUE;
f.b = tb->bbc->b;
while (f.b->next != NULL) {
f.b = f.b->next;
}
}
else {
f.b = tb->bbc->b;
}
offset = tb->offset; /* initialize */
f.t = f.b->start;
f.off = f.b->off;
f.blen = f.b->len;
tab_size = tb->tab_size;
width = tb->width;
if ((f.mark = tb->mark) != TED_NOMARK) {
box_sort(&(f.markbox), &(tb->markbox), (f.mark == TED_MARK) ? BOXSORT_ROW:BOXSORT_COL);
}
tb->bbc->b = b; /* reset hints */
b->off = off;
b->row = space;
tb->offset = boff;
tb->exp_len = scol;
tb->len = dif;
tb->nend = back;
/* loop through all the rows */
for (; f.paintbox.toprow <= f.paintbox.botrow;
f.paintbox.toprow++, f.ytext += f.fhgt) {
f.col = 0;
space = -1L;
f.phlushb = f.b;
f.phlusht = f.t;
f.phlusho = f.off;
f.phlushc = f.paintbox.leftcol;
f.attr = f.b->attr;
while (!f.done) {
if (f.t[f.off] == '\t') {
if (f.col >= width + WRAP_CUTOFF) {
space = -1L;
break;
}
expan = tab_size - (f.col % tab_size);
phlush(&f, TEXT);
if ((dif = f.paintbox.leftcol - f.col) >= expan) {
f.col += expan;
dif = expan;
f.flen = 0;
}
else if (dif <= 0) {
dif = 1;
f.flen = 1;
}
else {
f.col += dif;
f.flen = 0;
}
f.phlushs = tb->tab_char;
phlush(&f, CHR);
f.flen = expan - dif;
phlush(&f, DONE);
offset++;
space = offset;
scol = f.col;
}
else if (f.t[f.off] == '\n') {
phlush(&f, TEXT);
if (f.col < f.paintbox.leftcol) {
f.col++;
f.flen = 0;
}
else {
f.flen = 1;
}
f.phlushs = tb->newline_char;
phlush(&f, CHR);
offset++;
space = -1L;
break;
}
else {
if (f.t[f.off] == ' ' || f.t[f.off] == tb->wrap_char) {
if (f.col >= width + WRAP_CUTOFF) {
space = -1L;
break;
}
f.col++;
offset++;
space = offset; /* parms for char after space */
scol = f.col;
}
else if (f.col >= width) {
break;
}
else {
f.col++;
offset++;
}
(f.off)++;
if (f.off >= f.blen) {
if (f.b->next == NULL) {
f.done = TRUE;
break;
}
f.b = f.b->next;
f.t = f.b->start;
f.off = 0;
f.blen = f.b->len;
f.attr = f.b->attr;
}
}
if (f.col <= f.phlushc) {
f.phlushb = f.b;
f.phlusht = f.t;
f.phlusho = f.off;
}
}
if (!f.done && space != -1L) { /* do wrap */
back = (int)(offset - space); /* walk back bblocks */
while (back > f.off) {
back -= (f.off + 1);
f.b = f.b->prev;
f.off = f.b->len - 1;
}
f.t = f.b->start;
f.off -= back;
f.blen = f.b->len;
offset = space;
f.col = scol;
f.attr = f.b->attr;
}
phlush(&f, TEXT);
f.flen = f.paintbox.rightcol - f.col + 1;
phlush(&f, DONE);
}
}
static void CSPRIV phlush(struct phlush_s *f, int flagg)
/*
Ploat a strip of text/fields as requested by sed_Ploat
flag can be:
FIELDS paint only fields.
TEXT paint text and fields.
CHR paint a single characters, repeated (with fields also).
DONE paint trailing spaces (with fields).
*/
{
int len, len2, len3, dif;
byte attr;
ocbox pbox, mbox;
opbox *relboxp, clrbox;
ptd_struct *ptd;
int pcol; /* current paint column */
int endcol; /* current last paint column */
int fcol; /* firct column of current field */
int fldno; /* current field number */
opcoord xcol;
field_type field;
sed_type sed;
menu_type menu;
int tlen;
boolean painting, fpaint;
boolean pclear = FALSE;
boolean mark = FALSE;
/* save repeated indirections */
pbox.toprow = f->paintbox.toprow;
pbox.botrow = f->paintbox.botrow;
pbox.leftcol = f->paintbox.leftcol;
pbox.rightcol = f->paintbox.rightcol;
mbox.toprow = f->markbox.toprow;
mbox.botrow = f->markbox.botrow;
mbox.leftcol = f->markbox.leftcol;
mbox.rightcol = f->markbox.rightcol;
ptd = f->ptd;
sed = f->sed;
menu = sed_GetMenu(f->sed);
/** figure out how much we have to flush **/
/* len is the total number of characters to paint */
/* len3 is the amount to paint during one pass */
/* phlushc is the starting column */
if (f->phlushc > pbox.rightcol) { /* nothing to display */
len = 0;
if (flagg != TEXT) {
f->col += f->flen;
}
}
else if (flagg == TEXT || flagg == FIELDS) {
len = f->col - f->phlushc;
}
else { /* flagg == CHR || DONE */
len = f->flen - (f->phlushc - f->col); /* those fields! */
f->col += f->flen;
}
/* clip against endcol */
if ((dif = f->phlushc + len - 1 - pbox.rightcol) > 0) {
len = len - dif;
}
/** Loop until everything is painted **/
while (len > 0) {
if (flagg == FIELDS) {
len3 = len;
attr = win_GetAttr(sed);
}
else {
/* clip against bblock */
if (flagg != TEXT || (len2 = f->phlushb->len - f->phlusho) > len) {
len2 = len;
}
/* test for marking */
mark = FALSE;
len3 = len2;
if (pbox.toprow > mbox.botrow || pbox.toprow < mbox.toprow) {
/* skip marking tests */
;
}
else if (f->mark == TED_MARK) {
/* figure out how to handle the marked region */
if (pbox.toprow == mbox.toprow && pbox.toprow == mbox.botrow) {
if (f->phlushc < mbox.leftcol) {
len3 = mbox.leftcol - f->phlushc;
}
else if (f->phlushc <= mbox.rightcol) {
len3 = mbox.rightcol - f->phlushc + 1;
mark = TRUE;
}
}
else if (pbox.toprow == mbox.toprow) {
if (f->phlushc < mbox.leftcol) {
len3 = mbox.leftcol - f->phlushc;
}
else {
mark = TRUE;
}
}
else if (pbox.toprow == mbox.botrow) {
if (f->phlushc <= mbox.rightcol) {
len3 = mbox.rightcol - f->phlushc + 1;
mark = TRUE;
}
}
else {
mark = TRUE;
}
}
else if (f->mark == TED_COLMARK) {
/* figure out how to handle the column marked region */
if (f->phlushc > mbox.rightcol) {
;
}
else if (f->phlushc < mbox.leftcol) {
len3 = mbox.leftcol - f->phlushc;
}
else {
mark = TRUE;
len3 = mbox.rightcol - f->phlushc + 1;
}
}
/* compare plot length with block length */
if (len3 < 0 || len2 < len3) {
len3 = len2;
}
/* figure out the attribute to use */
if (sed_GetPaintFlag(sed) == SDPF_SHADOW) {
/* use the shadow color */
attr = win_GetShadowAttr(sed);
}
else if (mark) {
attr = sed_GetSelAttr(sed);
}
else if (flagg == DONE) {
attr = (f->attr == DEF_COLOR) ? win_GetAttr(sed) : f->attr;
}
else {
attr = (f->phlushb->attr == DEF_COLOR) ? win_GetAttr(sed) : f->phlushb->attr;
}
}
/** sit in a nasty loop and plot all the text and fields within len3 **/
if (f->fldrow != pbox.toprow) {
/* different row than last time */
fldno = menu_GetGRow(menu, pbox.toprow) - 1;
f->fldrow = pbox.toprow;
}
else {
fldno = f->fldno;
}
pcol = f->phlushc;
endcol = pcol + len3 - 1;
painting = TRUE;
/* paint a series of text/field slots (either of which can be 0 long) */
while (painting) {
/* reset flags */
fpaint = FALSE;
tlen = 0;
if (fldno < 0 ||
((fcol = field_GetCol(field = menu_GetField(menu, fldno))) > endcol)) {
/* paint rest of the text */
tlen = endcol - pcol + 1;
painting = FALSE;
/* remember what field we were on */
f->fldno = fldno;
}
else if (field_GetLastCol(field) >= pcol) {
/* a field lies within the slot */
fpaint = TRUE;
/* test for text before the field */
if (fcol > pcol) {
tlen = fcol - pcol;
}
}
/* text paint */
if (tlen > 0) {
if (flagg != FIELDS) {
/* set up paint data */
xcol = (pcol - sed_GetXoffset(f->sed)) * f->fwid;
/* plot the text */
if (flagg == TEXT) {
ptd_PlotText(ptd, xcol, f->ytext,
f->phlusht + f->phlusho + (pcol - f->phlushc),
0, attr, tlen);
}
else if (flagg == CHR) {
ptd_PlotText(ptd, xcol, f->ytext, NULL, f->phlushs, attr, tlen);
}
else {
/* Clear the region directly.
Set up coords for clear (handled below).
*/
pclear = TRUE;
clrbox.xmin = xcol;
clrbox.xmax = xcol + (tlen * f->fwid);
clrbox.ymin = f->ytext - f->fhgt;
clrbox.ymax = f->ytext;
}
}
/* advance pcol */
pcol += tlen;
}
/* field paint */
if (fpaint) {
/* Paint field, if it isn't blanked */
if (f->blankrow < 0 || field_GetRow(field) < f->blankrow) {
/** Paint the field **/
sd_plot_field(sed, field, fldno, ptd);
}
else {
/** paint a blank field **/
/* Clear the region directly.
Set up coords for clear (handled below).
If text is also cleared combine into one operation
*/
if (pclear) {
/* use the text clear coords */
clrbox.xmax = (field_GetLastCol(field) - sed_GetXoffset(sed) + 1) * f->fwid;
}
else {
pclear = TRUE;
clrbox.ymin = (field_GetRow(field) - sed_GetYoffset(sed)) * f->fhgt;
clrbox.ymax = (field_GetRow(field) - sed_GetYoffset(sed) + 1) * f->fhgt;
clrbox.xmin = (field_GetCol(field) - sed_GetXoffset(sed)) * f->fwid;
clrbox.xmax = (field_GetLastCol(field) - sed_GetXoffset(sed) + 1) * f->fwid;
}
}
/* advance pcol */
if (field_GetLastCol(field) >= pcol) {
pcol = field_GetLastCol(field) + 1;
}
}
if (pclear) {
/* a request to clear a region
temporarily substitute the ptd's relbox with a new
one so we can clear the field box with ptd_Clear
*/
pclear = FALSE;
/* clip against the ptd */
relboxp = ptd->relboxp;
if (opbox_clipbox(relboxp, &clrbox) != 0) {
ptd->relboxp = &clrbox;
ptd_Clear(ptd, disp_GetAttrBgColor(attr));
ptd->relboxp = relboxp;
}
}
/* get next field in row */
if (fldno >= 0) {
fldno = field_GetRight(field);
}
} /* while (painting) */
/* adjust len3 (we may have painted more than asked for) */
len3 = pcol - f->phlushc;
/* compute how much more there is to ploat */
len -= len3;
if (f->phlushc <= f->col) {
f->phlushc += len3;
}
/* test if we've crossed a block boudary */
if (flagg == TEXT) {
f->phlusho += len3;
while (f->phlusho >= f->phlushb->len) {
f->phlusho -= f->phlushb->len;
if ((f->phlushb = f->phlushb->next) == NULL) {
break;
}
f->phlusht = f->phlushb->start;
}
}
} /* while (len > 0) */
if (flagg == CHR) {
(f->off)++;
f->attr = f->b->attr;
while (f->off >= f->blen) {
if (f->b->next == NULL) {
f->done = TRUE;
break;
}
f->b = f->b->next;
f->t = f->b->start;
f->off = 0;
f->blen = f->b->len;
}
}
if (flagg != FIELDS) {
f->phlushb = f->b;
f->phlusht = f->t;
f->phlusho = f->off;
}
}
void box_sort(ocbox *dbox, mcbox *sbox, int mode)
/*
'mode' is either BOXSORT_ROW or BOXSORT_COL
*/
{
if (sbox->anchor_row <= sbox->cleat_row) {
dbox->toprow = sbox->anchor_row;
dbox->botrow = sbox->cleat_row;
if (mode == BOXSORT_ROW) {
if (sbox->anchor_row == sbox->cleat_row) {
dbox->leftcol = (sbox->anchor_col < sbox->cleat_col) ? sbox->anchor_col : sbox->cleat_col;
dbox->rightcol = (sbox->anchor_col > sbox->cleat_col) ? sbox->anchor_col : sbox->cleat_col;
}
else {
dbox->leftcol = sbox->anchor_col;
dbox->rightcol = sbox->cleat_col;
}
}
}
else {
dbox->toprow = sbox->cleat_row;
dbox->botrow = sbox->anchor_row;
if (mode == BOXSORT_ROW) {
dbox->leftcol = sbox->cleat_col;
dbox->rightcol = sbox->anchor_col;
}
}
if (mode == BOXSORT_COL) {
if (sbox->anchor_col < sbox->cleat_col) {
dbox->leftcol = sbox->anchor_col;
dbox->rightcol = sbox->cleat_col;
}
else {
dbox->leftcol = sbox->cleat_col;
dbox->rightcol = sbox->anchor_col;
}
}
}