home *** CD-ROM | disk | FTP | other *** search
- /*
- 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;
- }
- }
- }
-