summaryrefslogtreecommitdiff
path: root/pico
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2016-12-16 19:36:54 -0700
committerEduardo Chappa <chappa@washington.edu>2016-12-16 19:36:54 -0700
commitc1cf2264281c606455009ef1f63b2a35dcf4f591 (patch)
treeeb399a85d151202217b130d1a27abadb23063887 /pico
parent4638db18b0a2ebc5e631886e7d89218641be819f (diff)
downloadalpine-c1cf2264281c606455009ef1f63b2a35dcf4f591.tar.xz
* Separate updateline into two functions, one does updateline without
colors, the other one does updateline with colors.
Diffstat (limited to 'pico')
-rw-r--r--pico/display.c232
1 files changed, 170 insertions, 62 deletions
diff --git a/pico/display.c b/pico/display.c
index ed9e7f80..4763b50f 100644
--- a/pico/display.c
+++ b/pico/display.c
@@ -44,6 +44,7 @@ void vtmove(int, int);
void vtputc(CELL);
void vteeol(void);
void updateline(int, CELL *, CELL *, short *, int);
+void updatelinecolor(int, CELL *, CELL *, short *, int);
void updext(void);
void mlputi(int, int);
void pprints(int, int);
@@ -984,6 +985,164 @@ updext(void)
}
}
+/* update line color, to be executed to update lines when color is on */
+void
+updatelinecolor (int row, CELL vline[], CELL pline[], short *flags, int len)
+{
+ CELL *cp1, *cp2, *cp3, *cp4, *cp5, *cp6, *cp7;
+ int nbflag; /* non-blanks to the right flag? */
+ int cleartoeol = 0;
+ int in_quote, quote_found = 0, level;
+ PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors;
+ COLOR_PAIR *qcolor = NULL, *lastc = NULL, *pcolor = NULL;
+ int first = 1, lastattr = -1, change = 0;
+
+ if(pcolors == NULL){
+ updateline(row, vline, pline, flags, len);
+ return;
+ }
+
+ nbflag = FALSE;
+ lastc = pico_get_cur_color();
+
+ /* set up pointers to virtual and physical lines */
+ cp1 = &vline[0];
+ cp2 = &pline[0];
+ cp3 = &vline[term.t_ncol];
+ cp4 = &pline[term.t_ncol];
+
+ if(cellwidth_ptr_to_ptr(cp1, cp3) == cellwidth_ptr_to_ptr(cp2, cp4))
+ while (cp3 != cp1 && cp3[-1].c == cp4[-1].c && cp3[-1].a == cp4[-1].a) {
+ --cp3;
+ --cp4;
+ if (cp3[0].c != ' ' || cp3[0].a != 0) /* Note if any nonblank */
+ nbflag = TRUE; /* in right match. */
+ }
+
+ cp5 = cp3;
+
+ if (nbflag == FALSE && TERM_EOLEXIST) { /* Erase to EOL ? */
+ while (cp5 != cp1 && cp5[-1].c == ' ' && cp5[-1].a == 0)
+ --cp5;
+
+ if (cp3-cp5 <= 3) /* Use only if erase is */
+ cp5 = cp3; /* fewer characters. */
+ }
+
+ /* go to start of line */
+ movecursor(row, 0);
+
+ if(cp1 != cp5){
+ int w1, w2;
+
+ w1 = cellwidth_ptr_to_ptr(cp1, cp3);
+ w2 = cellwidth_ptr_to_ptr(cp2, cp2 + (cp3-cp1));
+
+ if(w1 < w2 || (nbflag && w1 != w2)){
+ if(TERM_EOLEXIST){
+ if(nbflag){
+ /*
+ * Draw all of the characters starting with cp1
+ * until we get to all spaces, then clear to the end of
+ * line from there. Watch out we don't run over the
+ * right hand edge, which shouldn't happen.
+ *
+ * Set cp5 to the first of the repeating spaces.
+ */
+ cp5 = &vline[term.t_ncol];
+ while (cp5 != cp1 && cp5[-1].c == ' ' && cp5[-1].a == 0)
+ --cp5;
+ }
+
+ /*
+ * In the !nbflag case we want spaces from cp5 on.
+ * Setting cp3 to something different from cp5 triggers
+ * the clear to end of line below.
+ */
+ if(cellwidth_ptr_to_ptr(&vline[0], cp5) < term.t_ncol)
+ cleartoeol++;
+ }
+ else{
+ int w;
+
+ /*
+ * No peeol so draw all the way to the edge whether they
+ * are spaces or not.
+ */
+ cp3 = &vline[0];
+ for(w = 0; w < term.t_ncol; cp3++){
+ int ww;
+
+ ww = wcellwidth((UCS) cp3->c);
+ w += (ww >= 0 ? ww : 1);
+ }
+
+ cp5 = cp3;
+ }
+ }
+ }
+
+ if(row != 0 && len < term.t_ncol)
+ cp5 = cp1 + len;
+
+ in_quote = 1;
+ level = -1;
+ while (cp1 != cp5){ /* Ordinary. */
+ int ww;
+
+ if(lastattr < 0){
+ lastattr = cp1->a;
+ change = 0;
+ }
+ else
+ change = lastattr != cp1->a;
+ if(first != 0){
+ first = 0;
+ if(row == 0)
+ pico_set_colorp(pcolors->tbcp, PSC_NONE);
+ else if(row < term.t_nrow - 2)
+ pcolor = (*flags & VFSIG) ? pcolors->sbcp : pcolors->ntcp;
+ }
+ if(cp1->c != '>' && cp1->c != ' ')
+ in_quote = 0;
+ else if (in_quote && cp1->c == '>' && pcolors != NULL)
+ level = (level + 1) % 3;
+ if(level >= 0){
+ if(level == 0) pcolor = pcolors->qlcp;
+ else if(level == 1) pcolor = pcolors->qllcp;
+ else if(level == 2) pcolor = pcolors->qlllcp;
+ }
+ if(cp1->a == 1)
+ pcolor = pcolors->rtcp; /* pcolor = proposed color */
+ if(change == 0)
+ pico_set_colorp(pcolor, PSC_NONE);
+ else
+ (*term.t_rev)(cp1->a); /* set inverse for this char */
+
+ if(change == 0)
+ (*term.t_rev)(cp1->a); /* set inverse for this char */
+ (*term.t_putchar)(cp1->c);
+
+ ww = wcellwidth((UCS) cp1->c);
+ ttcol += (ww >= 0 ? ww : 1);
+
+ *cp2++ = *cp1++;
+ }
+
+ if (lastc){
+ (void)pico_set_colorp(lastc, PSC_NONE);
+ free_color_pair(&lastc);
+ }
+
+ (*term.t_rev)(0); /* turn off inverse anyway! */
+
+ if (cp5 != cp3 || cleartoeol) /* Erase. */
+ peeol();
+
+ *flags &= ~(VFCHG|VFSIG); /* flag this line is changed */
+}
+
+
/*
* Update a single line. This does not know how to use insert or delete
@@ -1001,17 +1160,14 @@ updateline(int row, /* row on screen */
int display = TRUE;
int nbflag; /* non-blanks to the right flag? */
int cleartoeol = 0;
- int in_quote, quote_found = 0, level;
- PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors;
- COLOR_PAIR *qcolor = NULL, *lastc = NULL, *pcolor = NULL;
- int first = 1, lastattr = -1, change = 0;
- int x; /* bit to indicate if we should eXecute a block below */
if(row < 0 || row > term.t_nrow)
return;
- if(pcolors)
- lastc = pico_get_cur_color();
+ if((Pmaster && Pmaster->colors) || Pcolors){
+ updatelinecolor(row, vline, pline, flags, len);
+ return;
+ }
/* set up pointers to virtual and physical lines */
cp1 = &vline[0];
@@ -1019,11 +1175,10 @@ updateline(int row, /* row on screen */
cp3 = &vline[term.t_ncol];
/* advance past any common chars at the left */
- if(pcolors == NULL)
- while (cp1 != cp3 && cp1[0].c == cp2[0].c && cp1[0].a == cp2[0].a) {
+ while (cp1 != cp3 && cp1[0].c == cp2[0].c && cp1[0].a == cp2[0].a) {
++cp1;
++cp2;
- }
+ }
/* This can still happen, even though we only call this routine on changed
* lines. A hard update is always done when a line splits, a massive
@@ -1033,7 +1188,7 @@ updateline(int row, /* row on screen */
*/
/* if both lines are the same, no update needs to be done */
if (cp1 == cp3){
- *flags &= ~(VFCHG|VFSIG); /* mark it clean */
+ *flags &= ~VFCHG; /* mark it clean */
return;
}
@@ -1043,7 +1198,7 @@ updateline(int row, /* row on screen */
cp4 = &pline[term.t_ncol];
if(cellwidth_ptr_to_ptr(cp1, cp3) == cellwidth_ptr_to_ptr(cp2, cp4))
- while (cp3 != cp1 && cp3[-1].c == cp4[-1].c && cp3[-1].a == cp4[-1].a) {
+ while (cp3[-1].c == cp4[-1].c && cp3[-1].a == cp4[-1].a) {
--cp3;
--cp4;
if (cp3[0].c != ' ' || cp3[0].a != 0) /* Note if any nonblank */
@@ -1063,13 +1218,7 @@ updateline(int row, /* row on screen */
/* go to start of differences */
movecursor(row, cellwidth_ptr_to_ptr(&vline[0], cp1));
- /* the next code inserts a character or deletes one in the middle
- * of a line. However, we do not need this code to work when we
- * are using colors that depend on what is inserted/deleted, so
- * we defer this work to the code below
- */
- x = pcolors && (pcolors->qlcp || pcolors->qllcp || pcolors->qlllcp);
- if (!nbflag && x == 0){ /* use insert or del char? */
+ if (!nbflag) { /* use insert or del char? */
cp6 = cp3;
cp7 = cp4;
@@ -1173,47 +1322,11 @@ updateline(int row, /* row on screen */
}
}
- if(row != 0 && pcolors && len < term.t_ncol)
- cp5 = cp1 + len;
-
- in_quote = 1;
- level = -1;
while (cp1 != cp5) { /* Ordinary. */
int ww;
if(display){
- if(pcolors){
- if(lastattr < 0){
- lastattr = cp1->a;
- change = 0;
- }
- else change = lastattr != cp1->a;
- if(first != 0){
- first = 0;
- if(row == 0)
- pico_set_colorp(pcolors->tbcp, PSC_NONE);
- else if(row < term.t_nrow - 2)
- pcolor = (*flags & VFSIG) ? pcolors->sbcp : pcolors->ntcp;
- }
- if(cp1->c != '>' && cp1->c != ' ')
- in_quote = 0;
- else if (in_quote && cp1->c == '>' && pcolors != NULL)
- level = (level + 1) % 3;
- if(level >= 0){
- if(level == 0) pcolor = pcolors->qlcp;
- else if(level == 1) pcolor = pcolors->qllcp;
- else if(level == 2) pcolor = pcolors->qlllcp;
- }
- if(cp1->a == 1)
- pcolor = pcolors->rtcp; /* pcolor = proposed color */
- if(change == 0)
- pico_set_colorp(pcolor, PSC_NONE);
- else
- (*term.t_rev)(cp1->a); /* set inverse for this char */
- }
-
- if(change == 0)
- (*term.t_rev)(cp1->a); /* set inverse for this char */
+ (*term.t_rev)(cp1->a); /* set inverse for this char */
(*term.t_putchar)(cp1->c);
}
@@ -1223,11 +1336,6 @@ updateline(int row, /* row on screen */
*cp2++ = *cp1++;
}
- if (lastc){
- (void)pico_set_colorp(lastc, PSC_NONE);
- free_color_pair(&lastc);
- }
-
(*term.t_rev)(0); /* turn off inverse anyway! */
if (cp5 != cp3 || cleartoeol) { /* Erase. */
@@ -1238,7 +1346,7 @@ updateline(int row, /* row on screen */
*cp2++ = *cp1++;
}
- *flags &= ~(VFCHG|VFSIG); /* flag this line is changed */
+ *flags &= ~VFCHG; /* flag this line is changed */
}