Changeset 9866c3a


Ignore:
Timestamp:
Dec 27, 2007, 11:01:03 AM (16 years ago)
Author:
Alejandro R. Sedeño <asedeno@mit.edu>
Branches:
master, barnowl_perlaim, debian, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
925e122
Parents:
dd24b6a
Message:
Reworked the fmtext format to use in-line formatting.  Characters used
for formatting are part of Unicode Supplemental Private Area-B, or
Plane 16.

fmtext no longer need 5x the text space to store formatting
information, though they are harder to change at arbitrary
points. This was something we hardly ever did anyhow, and we can still
do everything we need to do.

fmtext keeps a pair of colors and a char for default attributes to be
applied when necessary.

Searching is now done inline at owl_fmtext_waddstr() rather than
specifying a section of the string to be reversed.

This probably still needs some cleanup and more comments, but it
works.
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • fmtext.c

    rdd24b6a r9866c3a  
    88void owl_fmtext_init_null(owl_fmtext *f)
    99{
    10   f->textlen=0;
    11   f->bufflen=5;
    12   f->textbuff=owl_malloc(5);
    13   f->fmbuff=owl_malloc(5);
    14   f->fgcolorbuff=owl_malloc(5 * sizeof(short));
    15   f->bgcolorbuff=owl_malloc(5 * sizeof(short));
    16   f->textbuff[0]=0;
    17   f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
    18   f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
    19   f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
     10  f->textlen = 0;
     11  f->bufflen = 5;
     12  f->textbuff = owl_malloc(5);
     13  f->textbuff[0] = 0;
     14  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
     15  f->default_fgcolor = OWL_COLOR_DEFAULT;
     16  f->default_fgcolor = OWL_COLOR_DEFAULT;
    2017}
    2118
     
    2421void owl_fmtext_clear(owl_fmtext *f)
    2522{
    26     f->textlen = 0;
    27     f->textbuff[0] = 0;
    28     f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
    29     f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
    30     f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
    31 }
    32 
    33 /* Internal function.  Set the attribute 'attr' from index 'first' to
    34  * index 'last'
    35  */
    36 void _owl_fmtext_set_attr(owl_fmtext *f, int attr, int first, int last)
    37 {
    38   int i;
    39   for (i=first; i<=last; i++) {
    40     f->fmbuff[i]=(unsigned char) attr;
    41   }
    42 }
    43 
    44 /* Internal function.  Add the attribute 'attr' to the existing
    45  * attributes from index 'first' to index 'last'
    46  */
    47 void _owl_fmtext_add_attr(owl_fmtext *f, int attr, int first, int last)
    48 {
    49   int i;
    50   for (i=first; i<=last; i++) {
    51     f->fmbuff[i]|=(unsigned char) attr;
    52   }
    53 }
    54 
    55 /* Internal function.  Set the color to be 'color' from index 'first'
    56  * to index 'last
    57  */
    58 void _owl_fmtext_set_fgcolor(owl_fmtext *f, int color, int first, int last)
    59 {
    60   int i;
    61   for (i=first; i<=last; i++) {
    62     f->fgcolorbuff[i]=(short)color;
    63   }
    64 }
    65 
    66 void _owl_fmtext_set_bgcolor(owl_fmtext *f, int color, int first, int last)
    67 {
    68   int i;
    69   for (i=first; i<=last; i++) {
    70     f->bgcolorbuff[i]=(short)color;
    71   }
     23  f->textlen = 0;
     24  f->textbuff[0] = 0;
     25  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
     26  f->default_fgcolor = OWL_COLOR_DEFAULT;
     27  f->default_fgcolor = OWL_COLOR_DEFAULT;
    7228}
    7329
     
    7531{
    7632    if(newlen + 1 > f->bufflen) {
    77       f->textbuff=owl_realloc(f->textbuff, newlen+1);
    78       f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
    79       f->fgcolorbuff=owl_realloc(f->fgcolorbuff, (newlen+1) * sizeof(short));
    80       f->bgcolorbuff=owl_realloc(f->bgcolorbuff, (newlen+1) * sizeof(short));
     33      f->textbuff = owl_realloc(f->textbuff, newlen + 1);
    8134      f->bufflen = newlen+1;
    8235  }
    8336}
    8437
     38int _owl_fmtext_is_format_char(gunichar c) /*noproto*/
     39{
     40  if ((c & ~OWL_FMTEXT_UC_ATTR_MASK) == OWL_FMTEXT_UC_ATTR) return 1;
     41  if ((c & ~(OWL_FMTEXT_UC_ALLCOLOR_MASK)) == OWL_FMTEXT_UC_COLOR_BASE) return 1;
     42  return 0;
     43}
    8544/* append text to the end of 'f' with attribute 'attr' and color
    8645 * 'color'
    8746 */
    88 void owl_fmtext_append_attr(owl_fmtext *f, char *text, int attr, int fgcolor, int bgcolor)
    89 {
    90   int newlen;
    91   newlen=strlen(f->textbuff)+strlen(text);
     47void owl_fmtext_append_attr(owl_fmtext *f, char *text, char attr, short fgcolor, short bgcolor)
     48{
     49  char attrbuff[6];
     50  int newlen, a = 0, fg = 0, bg = 0;
     51 
     52  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     53  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     54  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     55
     56  /* Plane-16 characters in UTF-8 are 4 bytes long. */
     57  newlen = strlen(f->textbuff) + strlen(text) + (8 * (a + fg + bg));
    9258  _owl_fmtext_realloc(f, newlen);
     59
     60  /* Set attributes */
     61  if (a) {
     62    memset(attrbuff,0,6);
     63    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     64    strcat(f->textbuff, attrbuff);     
     65  }
     66  if (fg) {
     67    memset(attrbuff,0,6);
     68    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     69    strcat(f->textbuff, attrbuff);     
     70  }
     71  if (bg) {
     72    memset(attrbuff,0,6);
     73    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     74    strcat(f->textbuff, attrbuff);     
     75  }
    9376 
    9477  strcat(f->textbuff, text);
    95   _owl_fmtext_set_attr(f, attr, f->textlen, newlen);
    96   _owl_fmtext_set_fgcolor(f, fgcolor, f->textlen, newlen);
    97   _owl_fmtext_set_bgcolor(f, bgcolor, f->textlen, newlen);
     78
     79  /* Reset attributes */
     80  if (bg) strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     81  if (fg) strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     82  if (a)  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
    9883  f->textlen=newlen;
    9984}
     
    129114}
    130115
    131 /* Add the attribute 'attr' to all text in 'f' */
    132 void owl_fmtext_addattr(owl_fmtext *f, int attr)
     116/* Add the attribute 'attr' to the default atts for the text in 'f' */
     117void owl_fmtext_addattr(owl_fmtext *f, char attr)
    133118{
    134119  /* add the attribute to all text */
    135   int i, j;
    136 
    137   j=f->textlen;
    138   for (i=0; i<j; i++) {
    139     f->fmbuff[i] |= attr;
    140   }
    141 }
    142 
    143 /* Anywhere the color is NOT ALREDY SET, set the color to 'color'.
    144  * Other colors are left unchanged
     120  f->default_attrs |= attr;
     121}
     122
     123/* Set the default foreground color for this fmtext to 'color'.
     124 * Only affects text that is colored default.
    145125 */
    146126void owl_fmtext_colorize(owl_fmtext *f, int color)
    147127{
    148   /* everywhere the fgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
    149   int i, j;
    150 
    151   j=f->textlen;
    152   for(i=0; i<j; i++) {
    153     if (f->fgcolorbuff[i]==OWL_COLOR_DEFAULT) f->fgcolorbuff[i] = (short)color;
    154   }
    155 }
    156 
     128  f->default_fgcolor = color;
     129}
     130
     131/* Set the default foreground color for this fmtext to 'color'.
     132 * Only affects text that is colored default.
     133 */
    157134void owl_fmtext_colorizebg(owl_fmtext *f, int color)
    158135{
    159   /* everywhere the bgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
    160   int i, j;
    161 
    162   j=f->textlen;
    163   for(i=0; i<j; i++) {
    164     if (f->bgcolorbuff[i]==OWL_COLOR_DEFAULT) f->bgcolorbuff[i] = (short)color;
    165   }
    166 }
     136  f->default_bgcolor = color;
     137}
     138
     139/* Internal function. Parse attrbute character. */
     140void _owl_fmtext_update_attributes(gunichar c, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     141{
     142  if ((c & OWL_FMTEXT_UC_ATTR) == OWL_FMTEXT_UC_ATTR) {
     143    *attr = c & OWL_FMTEXT_UC_ATTR_MASK;
     144  }
     145  else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
     146    *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
     147                ? OWL_COLOR_DEFAULT
     148                : c & OWL_FMTEXT_UC_COLOR_MASK);
     149  }
     150  else if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
     151    *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
     152                ? OWL_COLOR_DEFAULT
     153                : c & OWL_FMTEXT_UC_COLOR_MASK);
     154  }
     155}
     156
     157/* Internal function. Scan for attribute characters. */
     158void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     159{
     160  char *p;
     161  p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     162  while (p && p < f->textbuff + start) {
     163    _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
     164    p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     165  }
     166
    167167
    168168/* Internal function.  Append text from 'in' between index 'start' and
    169169 * 'stop' to the end of 'f'
    170170 */
    171 void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
    172 {
    173   int newlen, i;
    174 
    175   newlen=strlen(f->textbuff)+(stop-start+1);
     171void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
     172{
     173  char attrbuff[6];
     174  int newlen, a = 0, fg = 0, bg = 0;
     175  char attr = 0;
     176  short fgcolor = OWL_COLOR_DEFAULT;
     177  short bgcolor = OWL_COLOR_DEFAULT;
     178
     179  _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
     180  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     181  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     182  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     183
     184  /* We will reset to defaults after appending the text. We may need
     185     to set initial attributes. */
     186  newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
    176187  _owl_fmtext_realloc(f, newlen);
    177188
     189  if (a) {
     190    memset(attrbuff,0,6);
     191    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     192    strcat(f->textbuff, attrbuff);     
     193  }
     194  if (fg) {
     195    memset(attrbuff,0,6);
     196    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     197    strcat(f->textbuff, attrbuff);     
     198  }
     199  if (bg) {
     200    memset(attrbuff,0,6);
     201    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     202    strcat(f->textbuff, attrbuff);     
     203  }
     204
    178205  strncat(f->textbuff, in->textbuff+start, stop-start+1);
     206
     207  /* Reset attributes */
     208  strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     209  strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     210  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
     211
    179212  f->textbuff[newlen]='\0';
    180   for (i=start; i<=stop; i++) {
    181     f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
    182     f->fgcolorbuff[f->textlen+(i-start)]=in->fgcolorbuff[i];
    183     f->bgcolorbuff[f->textlen+(i-start)]=in->bgcolorbuff[i];
    184   }
    185213  f->textlen=newlen;
    186214}
     
    207235char *owl_fmtext_print_plain(owl_fmtext *f)
    208236{
    209   return(owl_strdup(f->textbuff));
    210 }
    211 
     237  char *r, *s, *p;
     238  r = owl_malloc(f->bufflen);
     239  r[0] = '\0';
     240  s = f->textbuff;
     241  /* Find next possible format character. */
     242  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     243  while(p) {
     244    /* If it's a format character, copy up to it, and skip all
     245       immediately following format characters. */
     246    if (_owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     247      strncat(r, s, p-s);
     248      p = g_utf8_next_char(p);
     249      while (p && _owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     250        p = g_utf8_next_char(p);
     251      }
     252      s = p;
     253      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     254    }
     255    else {
     256      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     257    }
     258  }
     259  if (s) strcat(r,s);
     260  return(r);
     261}
     262
     263void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
     264{
     265  wattrset(w, A_NORMAL);
     266  if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
     267  if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
     268  if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
     269}
    212270/* add the formatted text to the curses window 'w'.  The window 'w'
    213271 * must already be initiatlized with curses
    214272 */
    215 void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
    216 {
    217   char *tmpbuff;
    218   int position, trans1, trans2, trans3, len, lastsame;
    219 
     273void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search)
     274{
     275  /* char *tmpbuff; */
     276  /* int position, trans1, trans2, trans3, len, lastsame; */
     277  char *s, *p;
     278  char attr;
     279  short fg, bg;
     280  int search_results, search_len;
     281 
    220282  if (w==NULL) {
    221283    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
     
    223285  }
    224286
    225   tmpbuff=owl_malloc(f->textlen+10);
    226 
    227   position=0;
    228   len=f->textlen;
    229   while (position<=len) {
    230     /* find the last char with the current format and color */
    231     trans1=owl_util_find_trans(f->fmbuff+position, len-position);
    232     trans2=owl_util_find_trans_short(f->fgcolorbuff+position, len-position);
    233     trans3=owl_util_find_trans_short(f->bgcolorbuff+position, len-position);
    234 
    235     lastsame = (trans1 < trans2) ? trans1 : trans2;
    236     lastsame = (lastsame < trans3) ? lastsame : trans3;
    237     lastsame += position;
    238 
    239     /* set the format */
    240     wattrset(w, A_NORMAL);
    241     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
    242       wattron(w, A_BOLD);
    243     }
    244     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
    245       wattron(w, A_REVERSE);
    246     }
    247     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
    248       wattron(w, A_UNDERLINE);
    249     }
    250 
    251     /* set the color */
    252     /* warning, this is sort of a hack */
    253     if (owl_global_get_hascolors(&g)) {
    254       short fg, bg, pair;
    255       fg = f->fgcolorbuff[position];
    256       bg = f->bgcolorbuff[position];
    257 
    258       pair = owl_fmtext_get_colorpair(fg, bg);
    259       if (pair != -1) {
    260         wcolor_set(w,pair,NULL);
    261       }
    262     }
    263 
    264     /* add the text */
    265     strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
    266     tmpbuff[lastsame-position+1]='\0';
    267     waddstr(w, tmpbuff);
    268 
    269     position=lastsame+1;
    270   }
    271   owl_free(tmpbuff);
     287  search_results = (do_search
     288                    ? owl_fmtext_search(f, owl_global_get_search_string(&g))
     289                    : NULL);
     290  if (search_results) search_len = strlen(owl_global_get_search_string(&g));
     291  s = f->textbuff;
     292  /* Set default attributes. */
     293  attr = f->default_attrs;
     294  fg = f->default_fgcolor;
     295  bg = f->default_bgcolor;
     296  _owl_fmtext_wattrset(w, attr);
     297  if (owl_global_get_hascolors(&g)) {
     298    short pair;
     299    pair = owl_fmtext_get_colorpair(fg, bg);
     300    if (pair != -1) {
     301      wcolor_set(w,pair,NULL);
     302    }
     303  }
     304
     305  /* Find next possible format character. */
     306  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     307  while(p) {
     308    if (_owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     309      /* Deal with all text from last insert to here. */
     310      char tmp;
     311   
     312      tmp = p[0];
     313      p[0] = '\0';
     314      if (search_results) {
     315        /* Search is active, so highlight search results. */
     316        char tmp2, *ss;
     317        ss = stristr(s, owl_global_get_search_string(&g));
     318        while (ss) {
     319          /* Found search string, highlight it. */
     320
     321          tmp2 = ss[0];
     322          ss[0] = '\0';
     323          waddstr(w, s);
     324          ss[0] = tmp2;
     325
     326          _owl_fmtext_wattrset(w,attr ^ A_REVERSE);
     327
     328          tmp2 = ss[search_len];
     329          ss[search_len] = '\0';
     330          waddstr(w, ss);
     331          ss[search_len] = tmp2;
     332
     333          _owl_fmtext_wattrset(w,attr);
     334
     335          s = ss + search_len;
     336          ss = stristr(s, owl_global_get_search_string(&g));
     337        }
     338      }
     339      /* Deal with remaining part of string. */
     340      waddstr(w, s);
     341      p[0] = tmp;
     342
     343      /* Deal with new attributes. Initialize to defaults, then
     344         process all consecutive formatting characters. */
     345      attr = f->default_attrs;
     346      fg = f->default_fgcolor;
     347      bg = f->default_bgcolor;
     348      while (p && _owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     349        _owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
     350        p = g_utf8_next_char(p);
     351      }
     352      _owl_fmtext_wattrset(w, attr | f->default_attrs);
     353      if (owl_global_get_hascolors(&g)) {
     354        if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
     355        if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
     356        short pair;
     357        pair = owl_fmtext_get_colorpair(fg, bg);
     358        if (pair != -1) {
     359          wcolor_set(w,pair,NULL);
     360        }
     361      }
     362      /* Advance to next non-formatting character. */
     363      s = p;
     364      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     365    }
     366    else {
     367      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     368    }
     369  }
     370  if (s) {
     371    waddstr(w, s);
     372  }
    272373}
    273374
     
    282383 
    283384  /* find the starting line */
    284   ptr1=in->textbuff;
    285   if (aline!=0) {
    286     for (i=0; i<aline; i++) {
    287       ptr1=strchr(ptr1, '\n');
    288       if (!ptr1) return(-1);
    289       ptr1++;
    290     }
    291   }
     385  ptr1 = in->textbuff;
     386  for (i = 0; i < aline; i++) {
     387    ptr1 = strchr(ptr1, '\n');
     388    if (!ptr1) return(-1);
     389    ptr1++;
     390  }
     391 
    292392  /* ptr1 now holds the starting point */
    293393
    294394  /* copy in the next 'lines' lines */
    295   if (lines<1) return(-1);
    296 
    297   for (i=0; i<lines; i++) {
    298     offset=ptr1-in->textbuff;
    299     ptr2=strchr(ptr1, '\n');
     395  if (lines < 1) return(-1);
     396
     397  for (i = 0; i < lines; i++) {
     398    offset = ptr1 - in->textbuff;
     399    ptr2 = strchr(ptr1, '\n');
    300400    if (!ptr2) {
    301       _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
     401      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
    302402      return(-1);
    303403    }
    304     _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
    305     ptr1=ptr2+1;
     404    _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
     405    ptr1 = ptr2 + 1;
    306406  }
    307407  return(0);
     
    316416{
    317417  char *ptr_s, *ptr_e, *ptr_c, *last;
    318   int col, cnt, padding;
     418  int col, st, padding, chwidth;
    319419
    320420  last=in->textbuff+in->textlen-1;
    321421  ptr_s=in->textbuff;
    322   while (ptr_s<=last) {
     422  while (ptr_s <= last) {
    323423    ptr_e=strchr(ptr_s, '\n');
    324424    if (!ptr_e) {
     
    327427    }
    328428   
    329     if (ptr_e==ptr_s) {
     429    if (ptr_e == ptr_s) {
    330430      owl_fmtext_append_normal(out, "\n");
    331       ptr_s++;
     431      ++ptr_s;
    332432      continue;
    333433    }
    334434
    335435    col = 0;
    336     cnt = 0;
     436    st = 0;
    337437    padding = 0;
    338438    ptr_c = ptr_s;
    339     while(col < bcol && ptr_c < ptr_e) {
     439    while(col <= bcol && ptr_c < ptr_e) {
    340440      gunichar c = g_utf8_get_char(ptr_c);
    341       if (col + wcwidth(c) > bcol) break;
    342       col += wcwidth(c);
     441      if (!_owl_fmtext_is_format_char(c)) {
     442        chwidth = wcwidth(c);
     443     
     444        if (col + chwidth > bcol)
     445          break;
     446        if (col >= acol) {
     447          if (st == 0) {
     448            ptr_s = ptr_c;
     449            padding = col - acol;
     450            ++st;
     451          }
     452        }
     453        col += chwidth;
     454        chwidth = 0;
     455      }
    343456      ptr_c = g_utf8_next_char(ptr_c);
    344       if (col >= acol) {
    345         if (cnt == 0) {
    346           ptr_s = ptr_c;
    347           padding = col - acol;
    348         }
    349         ++cnt;
    350       }
    351     }
    352     if (cnt) {
    353       while(padding-- > 0) {
    354         owl_fmtext_append_normal(out, " ");
    355       }
    356       _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     457    }
     458    if (st) {
     459      /* lead padding */
     460      owl_fmtext_append_spaces(out, padding);
     461      if (ptr_c[0] & 0x80) {
     462        if (col + chwidth == bcol)
     463          ptr_c = g_utf8_next_char(ptr_c);
     464        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - 1 - in->textbuff);     
     465        owl_fmtext_append_normal(out, "\n");
     466      }
     467      else {
     468        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     469      }
    357470    }
    358471    else {
    359472      owl_fmtext_append_normal(out, "\n");
    360473    }
    361     ptr_s=ptr_e+1;
    362      
    363 #if 0
    364     /* we need to check that we won't run over here */
    365     len=bcol-acol;
    366     if (len > (ptr_e-(ptr_s+acol))) {
    367       /* the whole line fits with room to spare, don't take a full 'len' */
    368       len=ptr_e-(ptr_s+acol);
    369     }
    370     if (len>last-ptr_s) {
    371       /* the whole rest of the text fits with room to spare, adjust for it */
    372       len-=(last-ptr_s);
    373     }
    374     if (len<=0) {
    375       /* saftey check */
    376       owl_fmtext_append_normal(out, "\n");
    377       ptr_s=ptr_e+1;
    378       continue;
    379     }
    380 
    381     offset = ptr_s - in->textbuff;
    382     _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
    383 
    384     ptr_s=ptr_e+1;
    385 #endif
     474    ptr_s = g_utf8_next_char(ptr_e);
    386475  }
    387476}
     
    411500
    412501/* set the charater at 'index' to be 'char'.  If index is out of
    413  * bounds don't do anything */
    414 void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
     502 * bounds don't do anything. If c or char at index is not ASCII, don't
     503 * do anything because it's not UTF-8 safe. */
     504void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
    415505{
    416506  if ((index < 0) || (index > f->textlen-1)) return;
     507  /* NOT ASCII*/
     508  if (f->textbuff[index] & 0x80 || ch & 0x80) return;
    417509  f->textbuff[index]=ch;
    418510}
     
    430522  dst->textlen=src->textlen;
    431523  dst->textbuff=owl_malloc(mallocsize);
    432   dst->fmbuff=owl_malloc(mallocsize);
    433   dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    434   dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    435524  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
    436   memcpy(dst->fmbuff, src->fmbuff, src->textlen);
    437   memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
    438   memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
    439 }
    440 
    441 /* highlight all instances of "string".  Return the number of
    442  * instances found.  This is a case insensitive search.
    443  */
    444 int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
    445 {
    446 
    447   int found, len;
    448   char *ptr1, *ptr2;
    449 
    450   len=strlen(string);
    451   found=0;
    452   ptr1=f->textbuff;
    453   while (ptr1-f->textbuff <= f->textlen) {
    454     ptr2=stristr(ptr1, string);
    455     if (!ptr2) return(found);
    456 
    457     found++;
    458     _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
    459                          ptr2 - f->textbuff,
    460                          ptr2 - f->textbuff + len - 1);
    461 
    462     ptr1=ptr2+len;
    463   }
    464   return(found);
     525  dst->default_attrs = src->default_attrs;
     526  dst->default_fgcolor = src->default_fgcolor;
     527  dst->default_bgcolor = src->default_bgcolor;
    465528}
    466529
     
    470533int owl_fmtext_search(owl_fmtext *f, char *string)
    471534{
    472 
    473535  if (stristr(f->textbuff, string)) return(1);
    474536  return(0);
     
    711773{
    712774  if (f->textbuff) owl_free(f->textbuff);
    713   if (f->fmbuff) owl_free(f->fmbuff);
    714   if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
    715   if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
    716775}
    717776
  • message.c

    r93ee554 r9866c3a  
    537537  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline+1, &a);
    538538  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
    539   if (fgcolor!=OWL_COLOR_DEFAULT) {
    540     owl_fmtext_colorize(&b, fgcolor);
    541   }
    542   if (bgcolor!=OWL_COLOR_DEFAULT) {
    543     owl_fmtext_colorizebg(&b, bgcolor);
    544   }
    545 
    546   if (owl_global_is_search_active(&g)) {
    547     owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
    548   }
    549      
    550   owl_fmtext_curs_waddstr(&b, win);
     539  owl_fmtext_colorize(&b, fgcolor);
     540  owl_fmtext_colorizebg(&b, bgcolor);
     541
     542  owl_fmtext_curs_waddstr(&b, win, owl_global_is_search_active(&g));
    551543
    552544  owl_fmtext_free(&a);
  • owl.h

    rdd24b6a r9866c3a  
    101101#define OWL_FMTEXT_ATTR_UNDERLINE 4
    102102
     103#define OWL_FMTEXT_UC_BASE 0x100000 /* Unicode Plane 16 - Supplementary Private Use Area-B*/
     104#define OWL_FMTEXT_UC_ATTR ( OWL_FMTEXT_UC_BASE | 0x800 )
     105#define OWL_FMTEXT_UC_ATTR_MASK 0x7
     106#define OWL_FMTEXT_UC_COLOR_BASE ( OWL_FMTEXT_UC_BASE | 0x400 )
     107#define OWL_FMTEXT_UC_FGCOLOR OWL_FMTEXT_UC_COLOR_BASE
     108#define OWL_FMTEXT_UC_BGCOLOR ( OWL_FMTEXT_UC_COLOR_BASE | 0x200 )
     109#define OWL_FMTEXT_UC_DEFAULT_COLOR 0x100
     110#define OWL_FMTEXT_UC_FGDEFAULT ( OWL_FMTEXT_UC_FGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
     111#define OWL_FMTEXT_UC_BGDEFAULT ( OWL_FMTEXT_UC_BGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
     112#define OWL_FMTEXT_UC_COLOR_MASK 0xFF
     113#define OWL_FMTEXT_UC_ALLCOLOR_MASK ( OWL_FMTEXT_UC_COLOR_MASK | OWL_FMTEXT_UC_DEFAULT_COLOR | 0x200)
     114#define OWL_FMTEXT_UC_STARTBYTE_UTF8 '\xf4'
     115
     116#define OWL_FMTEXT_UTF8_ATTR_NONE "\xf4\x80\xa0\x80"
     117#define OWL_FMTEXT_UTF8_FGDEFAULT "\xf4\x80\x94\x80"
     118#define OWL_FMTEXT_UTF8_BGDEFAULT "\xf4\x80\x96\x80"
     119
     120
     121
     122
    103123#define OWL_COLOR_BLACK     0
    104124#define OWL_COLOR_RED       1
     
    256276  int bufflen;
    257277  char *textbuff;
    258   char *fmbuff;
    259   short *fgcolorbuff;
    260   short *bgcolorbuff;
     278  char default_attrs;
     279  short default_fgcolor;
     280  short default_bgcolor;
    261281} owl_fmtext;
    262282
  • viewwin.c

    r8721756 r9866c3a  
    7373  owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
    7474
    75   owl_fmtext_curs_waddstr(&fm2, v->curswin);
     75  owl_fmtext_curs_waddstr(&fm2, v->curswin, 0);
    7676
    7777  /* print the message at the bottom */
Note: See TracChangeset for help on using the changeset viewer.