Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fmtext.c

    r005fc22 r6f6330b  
    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_bgcolor = 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_bgcolor = 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)
     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_COLOR_BASE) == OWL_FMTEXT_UC_COLOR_BASE) {
     146    if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
     147      *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
     148                  ? OWL_COLOR_DEFAULT
     149                  : c & OWL_FMTEXT_UC_COLOR_MASK);
     150    }
     151    else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
     152      *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
     153                  ? OWL_COLOR_DEFAULT
     154                  : c & OWL_FMTEXT_UC_COLOR_MASK);
     155    }
     156  }
     157}
     158
     159/* Internal function. Scan for attribute characters. */
     160void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     161{
     162  char *p;
     163  p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     164  while (p && p < f->textbuff + start) {
     165    _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
     166    p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     167  }
     168
    167169
    168170/* Internal function.  Append text from 'in' between index 'start' and
    169171 * 'stop' to the end of 'f'
    170172 */
    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);
     173void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
     174{
     175  char attrbuff[6];
     176  int newlen, a = 0, fg = 0, bg = 0;
     177  char attr = 0;
     178  short fgcolor = OWL_COLOR_DEFAULT;
     179  short bgcolor = OWL_COLOR_DEFAULT;
     180
     181  _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
     182  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     183  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     184  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     185
     186  /* We will reset to defaults after appending the text. We may need
     187     to set initial attributes. */
     188  newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
    176189  _owl_fmtext_realloc(f, newlen);
    177190
     191  if (a) {
     192    memset(attrbuff,0,6);
     193    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     194    strcat(f->textbuff, attrbuff);     
     195  }
     196  if (fg) {
     197    memset(attrbuff,0,6);
     198    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     199    strcat(f->textbuff, attrbuff);     
     200  }
     201  if (bg) {
     202    memset(attrbuff,0,6);
     203    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     204    strcat(f->textbuff, attrbuff);     
     205  }
     206
    178207  strncat(f->textbuff, in->textbuff+start, stop-start+1);
     208
     209  /* Reset attributes */
     210  strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     211  strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     212  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
     213
    179214  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   }
    185215  f->textlen=newlen;
    186216}
     
    207237char *owl_fmtext_print_plain(owl_fmtext *f)
    208238{
    209   return(owl_strdup(f->textbuff));
     239  return owl_strip_format_chars(f->textbuff);
     240}
     241
     242void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
     243{
     244  wattrset(w, A_NORMAL);
     245  if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
     246  if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
     247  if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
     248}
     249
     250void _owl_fmtext_update_colorpair(short fg, short bg, short *pair) /*noproto*/
     251{
     252  if (owl_global_get_hascolors(&g)) {
     253    *pair = owl_fmtext_get_colorpair(fg, bg);
     254  }
     255}
     256
     257void _owl_fmtext_wcolor_set(WINDOW *w, short pair) /*noproto*/
     258{
     259  if (owl_global_get_hascolors(&g)) {
     260      wcolor_set(w,pair,NULL);
     261  }
    210262}
    211263
     
    213265 * must already be initiatlized with curses
    214266 */
    215 void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
    216 {
    217   char *tmpbuff;
    218   int position, trans1, trans2, trans3, len, lastsame;
    219 
     267void _owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search) /*noproto*/
     268{
     269  /* char *tmpbuff; */
     270  /* int position, trans1, trans2, trans3, len, lastsame; */
     271  char *s, *p;
     272  char attr;
     273  short fg, bg, pair;
     274  int search_results, search_len;
     275 
    220276  if (w==NULL) {
    221277    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
     
    223279  }
    224280
    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);
    272 }
    273 
     281  search_results = (do_search
     282                    ? owl_fmtext_search(f, owl_global_get_search_string(&g))
     283                    : 0);
     284  search_len = (search_results
     285                ? strlen(owl_global_get_search_string(&g))
     286                : 0);
     287  s = f->textbuff;
     288  /* Set default attributes. */
     289  attr = f->default_attrs;
     290  fg = f->default_fgcolor;
     291  bg = f->default_bgcolor;
     292  _owl_fmtext_wattrset(w, attr);
     293  _owl_fmtext_update_colorpair(fg, bg, &pair);
     294  _owl_fmtext_wcolor_set(w, pair);
     295
     296  /* Find next possible format character. */
     297  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     298  while(p) {
     299    if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     300      /* Deal with all text from last insert to here. */
     301      char tmp;
     302   
     303      tmp = p[0];
     304      p[0] = '\0';
     305      if (search_results) {
     306        /* Search is active, so highlight search results. */
     307        char tmp2, *ss;
     308        ss = stristr(s, owl_global_get_search_string(&g));
     309        while (ss) {
     310          /* Found search string, highlight it. */
     311
     312          tmp2 = ss[0];
     313          ss[0] = '\0';
     314          waddstr(w, s);
     315          ss[0] = tmp2;
     316
     317          _owl_fmtext_wattrset(w, attr ^ OWL_FMTEXT_ATTR_REVERSE);
     318          _owl_fmtext_wcolor_set(w, pair);
     319         
     320          tmp2 = ss[search_len];
     321          ss[search_len] = '\0';
     322          waddstr(w, ss);
     323          ss[search_len] = tmp2;
     324
     325          _owl_fmtext_wattrset(w, attr);
     326          _owl_fmtext_wcolor_set(w, pair);
     327
     328          s = ss + search_len;
     329          ss = stristr(s, owl_global_get_search_string(&g));
     330        }
     331      }
     332      /* Deal with remaining part of string. */
     333      waddstr(w, s);
     334      p[0] = tmp;
     335
     336      /* Deal with new attributes. Initialize to defaults, then
     337         process all consecutive formatting characters. */
     338      attr = f->default_attrs;
     339      fg = f->default_fgcolor;
     340      bg = f->default_bgcolor;
     341      while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     342        _owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
     343        p = g_utf8_next_char(p);
     344      }
     345      _owl_fmtext_wattrset(w, attr | f->default_attrs);
     346      if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
     347      if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
     348      _owl_fmtext_update_colorpair(fg, bg, &pair);
     349      _owl_fmtext_wcolor_set(w, pair);
     350
     351      /* Advance to next non-formatting character. */
     352      s = p;
     353      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     354    }
     355    else {
     356      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     357    }
     358  }
     359  if (s) {
     360    waddstr(w, s);
     361  }
     362}
     363
     364void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
     365{
     366  _owl_fmtext_curs_waddstr(f, w, owl_global_is_search_active(&g));
     367}
     368
     369void owl_fmtext_curs_waddstr_without_search(owl_fmtext *f, WINDOW *w)
     370{
     371  _owl_fmtext_curs_waddstr(f, w, 0);
     372}
    274373
    275374/* start with line 'aline' (where the first line is 0) and print
     
    282381 
    283382  /* 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   }
     383  ptr1 = in->textbuff;
     384  for (i = 0; i < aline; i++) {
     385    ptr1 = strchr(ptr1, '\n');
     386    if (!ptr1) return(-1);
     387    ptr1++;
     388  }
     389 
    292390  /* ptr1 now holds the starting point */
    293391
     392  /* copy the default attributes */
     393  out->default_attrs = in->default_attrs;
     394  out->default_fgcolor = in->default_fgcolor;
     395  out->default_bgcolor = in->default_bgcolor;
     396   
    294397  /* 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');
     398  if (lines < 1) return(-1);
     399
     400  for (i = 0; i < lines; i++) {
     401    offset = ptr1 - in->textbuff;
     402    ptr2 = strchr(ptr1, '\n');
    300403    if (!ptr2) {
    301       _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
     404      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
    302405      return(-1);
    303406    }
    304     _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
    305     ptr1=ptr2+1;
     407    _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
     408    ptr1 = ptr2 + 1;
    306409  }
    307410  return(0);
     
    311414 * ends at 'bcol' or sooner.  The first column is number 0.  The new
    312415 * message is placed in 'out'.  The message is * expected to end in a
    313  * new line for now
     416 * new line for now. NOTE: This needs to be modified to deal with
     417 * backing up if we find a SPACING COMBINING MARK at the end of a
     418 * line. If that happens, we should back up to the last non-mark
     419 * character and stop there.
    314420 */
    315421void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
    316422{
    317   char *ptr1, *ptr2, *last;
    318   int len, offset;
     423  char *ptr_s, *ptr_e, *ptr_c, *last;
     424  int col, st, padding, chwidth;
     425
     426  /* copy the default attributes */
     427  out->default_attrs = in->default_attrs;
     428  out->default_fgcolor = in->default_fgcolor;
     429  out->default_bgcolor = in->default_bgcolor;
    319430
    320431  last=in->textbuff+in->textlen-1;
    321   ptr1=in->textbuff;
    322   while (ptr1<=last) {
    323     ptr2=strchr(ptr1, '\n');
    324     if (!ptr2) {
     432  ptr_s=in->textbuff;
     433  while (ptr_s <= last) {
     434    ptr_e=strchr(ptr_s, '\n');
     435    if (!ptr_e) {
    325436      /* but this shouldn't happen if we end in a \n */
    326437      break;
    327438    }
    328439   
    329     if (ptr2==ptr1) {
     440    if (ptr_e == ptr_s) {
    330441      owl_fmtext_append_normal(out, "\n");
    331       ptr1++;
     442      ++ptr_s;
    332443      continue;
    333444    }
    334445
    335     /* we need to check that we won't run over here */
    336     len=bcol-acol;
    337     if (len > (ptr2-(ptr1+acol))) {
    338       /* the whole line fits with room to spare, don't take a full 'len' */
    339       len=ptr2-(ptr1+acol);
    340     }
    341     if (len>last-ptr1) {
    342       /* the whole rest of the text fits with room to spare, adjust for it */
    343       len-=(last-ptr1);
    344     }
    345     if (len<=0) {
    346       /* saftey check */
     446    col = 0;
     447    st = 0;
     448    padding = 0;
     449    chwidth = 0;
     450    ptr_c = ptr_s;
     451    while(ptr_c < ptr_e) {
     452      gunichar c = g_utf8_get_char(ptr_c);
     453      if (!owl_fmtext_is_format_char(c)) {
     454        chwidth = mk_wcwidth(c);
     455        if (col + chwidth > bcol) break;
     456       
     457        if (col >= acol) {
     458          if (st == 0) {
     459            ptr_s = ptr_c;
     460            padding = col - acol;
     461            ++st;
     462          }
     463        }
     464        col += chwidth;
     465        chwidth = 0;
     466      }
     467      ptr_c = g_utf8_next_char(ptr_c);
     468    }
     469    if (st) {
     470      /* lead padding */
     471      owl_fmtext_append_spaces(out, padding);
     472      if (ptr_c == ptr_e) {
     473        /* We made it to the newline. */
     474        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     475      }
     476      else {
     477        if (chwidth > 1) {
     478          /* Last char is wide, truncate. */
     479          _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
     480          owl_fmtext_append_normal(out, "\n");
     481        }
     482        else {
     483          /* Last char fits perfectly, leave alone.*/
     484          _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     485        }
     486      }
     487    }
     488    else {
    347489      owl_fmtext_append_normal(out, "\n");
    348       ptr1=ptr2+1;
    349       continue;
    350     }
    351 
    352     offset=ptr1-in->textbuff;
    353     _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
    354 
    355     ptr1=ptr2+1;
     490    }
     491    ptr_s = g_utf8_next_char(ptr_e);
    356492  }
    357493}
     
    381517
    382518/* set the charater at 'index' to be 'char'.  If index is out of
    383  * bounds don't do anything */
    384 void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
     519 * bounds don't do anything. If c or char at index is not ASCII, don't
     520 * do anything because it's not UTF-8 safe. */
     521void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
    385522{
    386523  if ((index < 0) || (index > f->textlen-1)) return;
     524  /* NOT ASCII*/
     525  if (f->textbuff[index] & 0x80 || ch & 0x80) return;
    387526  f->textbuff[index]=ch;
    388527}
     
    401540  dst->bufflen=mallocsize;
    402541  dst->textbuff=owl_malloc(mallocsize);
    403   dst->fmbuff=owl_malloc(mallocsize);
    404   dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    405   dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    406542  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
    407   memcpy(dst->fmbuff, src->fmbuff, src->textlen);
    408   memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
    409   memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
    410 }
    411 
    412 /* highlight all instances of "string".  Return the number of
    413  * instances found.  This is a case insensitive search.
    414  */
    415 int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
    416 {
    417 
    418   int found, len;
    419   char *ptr1, *ptr2;
    420 
    421   len=strlen(string);
    422   found=0;
    423   ptr1=f->textbuff;
    424   while (ptr1-f->textbuff <= f->textlen) {
    425     ptr2=stristr(ptr1, string);
    426     if (!ptr2) return(found);
    427 
    428     found++;
    429     _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
    430                          ptr2 - f->textbuff,
    431                          ptr2 - f->textbuff + len - 1);
    432 
    433     ptr1=ptr2+len;
    434   }
    435   return(found);
     543  dst->default_attrs = src->default_attrs;
     544  dst->default_fgcolor = src->default_fgcolor;
     545  dst->default_bgcolor = src->default_bgcolor;
    436546}
    437547
     
    441551int owl_fmtext_search(owl_fmtext *f, char *string)
    442552{
    443 
    444553  if (stristr(f->textbuff, string)) return(1);
    445554  return(0);
     
    682791{
    683792  if (f->textbuff) owl_free(f->textbuff);
    684   if (f->fmbuff) owl_free(f->fmbuff);
    685   if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
    686   if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
    687793}
    688794
Note: See TracChangeset for help on using the changeset viewer.