Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • fmtext.c

    rc1522ec rfa3290d  
    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->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;
     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;
    1720}
    1821
     
    2124void owl_fmtext_clear(owl_fmtext *f)
    2225{
    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;
     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 */
     36void _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 */
     47void _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 */
     58void _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
     66void _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  }
    2872}
    2973
     
    3175{
    3276    if(newlen + 1 > f->bufflen) {
    33       f->textbuff = owl_realloc(f->textbuff, newlen + 1);
     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));
    3481      f->bufflen = newlen+1;
    3582  }
    3683}
    3784
    38 int 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 }
    4485/* append text to the end of 'f' with attribute 'attr' and color
    4586 * 'color'
    4687 */
    47 void 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));
     88void 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);
    5892  _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   }
    7693 
    7794  strcat(f->textbuff, text);
    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);
     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);
    8398  f->textlen=newlen;
    8499}
     
    114129}
    115130
    116 /* Add the attribute 'attr' to the default atts for the text in 'f' */
    117 void owl_fmtext_addattr(owl_fmtext *f, char attr)
     131/* Add the attribute 'attr' to all text in 'f' */
     132void owl_fmtext_addattr(owl_fmtext *f, int attr)
    118133{
    119134  /* add the attribute to all text */
    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.
     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
    125145 */
    126146void owl_fmtext_colorize(owl_fmtext *f, int color)
    127147{
    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  */
     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
    134157void owl_fmtext_colorizebg(owl_fmtext *f, int color)
    135158{
    136   f->default_bgcolor = color;
    137 }
    138 
    139 /* Internal function. Parse attrbute character. */
    140 void _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. */
    158 void _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 
     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}
    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) /*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;
     171void _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);
    187176  _owl_fmtext_realloc(f, newlen);
    188177
    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 
    205178  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 
    212179  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  }
    213185  f->textlen=newlen;
    214186}
     
    235207char *owl_fmtext_print_plain(owl_fmtext *f)
    236208{
    237   return owl_strip_format_chars(f->textbuff);
    238 }
    239 
    240 void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
    241 {
    242   wattrset(w, A_NORMAL);
    243   if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
    244   if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
    245   if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
    246 }
    247 
    248 void _owl_fmtext_update_colorpair(short fg, short bg, short *pair) /*noproto*/
    249 {
    250   if (owl_global_get_hascolors(&g)) {
    251     *pair = owl_fmtext_get_colorpair(fg, bg);
    252   }
    253 }
    254 
    255 void _owl_fmtext_wcolor_set(WINDOW *w, short pair) /*noproto*/
    256 {
    257   if (owl_global_get_hascolors(&g)) {
    258       wcolor_set(w,pair,NULL);
    259   }
     209  return(owl_strdup(f->textbuff));
    260210}
    261211
     
    263213 * must already be initiatlized with curses
    264214 */
    265 void _owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search) /*noproto*/
    266 {
    267   /* char *tmpbuff; */
    268   /* int position, trans1, trans2, trans3, len, lastsame; */
    269   char *s, *p;
    270   char attr;
    271   short fg, bg, pair;
    272   int search_results, search_len;
    273  
     215void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
     216{
     217  char *tmpbuff;
     218  int position, trans1, trans2, trans3, len, lastsame;
     219
    274220  if (w==NULL) {
    275221    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
     
    277223  }
    278224
    279   search_results = (do_search
    280                     ? owl_fmtext_search(f, owl_global_get_search_string(&g))
    281                     : 0);
    282   search_len = (search_results
    283                 ? strlen(owl_global_get_search_string(&g))
    284                 : 0);
    285   s = f->textbuff;
    286   /* Set default attributes. */
    287   attr = f->default_attrs;
    288   fg = f->default_fgcolor;
    289   bg = f->default_bgcolor;
    290   _owl_fmtext_wattrset(w, attr);
    291   _owl_fmtext_update_colorpair(fg, bg, &pair);
    292   _owl_fmtext_wcolor_set(w, pair);
    293 
    294   /* Find next possible format character. */
    295   p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
    296   while(p) {
    297     if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
    298       /* Deal with all text from last insert to here. */
    299       char tmp;
    300    
    301       tmp = p[0];
    302       p[0] = '\0';
    303       if (search_results) {
    304         /* Search is active, so highlight search results. */
    305         char tmp2, *ss;
    306         ss = stristr(s, owl_global_get_search_string(&g));
    307         while (ss) {
    308           /* Found search string, highlight it. */
    309 
    310           tmp2 = ss[0];
    311           ss[0] = '\0';
    312           waddstr(w, s);
    313           ss[0] = tmp2;
    314 
    315           _owl_fmtext_wattrset(w, attr ^ OWL_FMTEXT_ATTR_REVERSE);
    316           _owl_fmtext_wcolor_set(w, pair);
    317          
    318           tmp2 = ss[search_len];
    319           ss[search_len] = '\0';
    320           waddstr(w, ss);
    321           ss[search_len] = tmp2;
    322 
    323           _owl_fmtext_wattrset(w, attr);
    324           _owl_fmtext_wcolor_set(w, pair);
    325 
    326           s = ss + search_len;
    327           ss = stristr(s, owl_global_get_search_string(&g));
    328         }
    329       }
    330       /* Deal with remaining part of string. */
    331       waddstr(w, s);
    332       p[0] = tmp;
    333 
    334       /* Deal with new attributes. Initialize to defaults, then
    335          process all consecutive formatting characters. */
    336       attr = f->default_attrs;
    337       fg = f->default_fgcolor;
    338       bg = f->default_bgcolor;
    339       while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
    340         _owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
    341         p = g_utf8_next_char(p);
    342       }
    343       _owl_fmtext_wattrset(w, attr | f->default_attrs);
    344       if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
    345       if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
    346       _owl_fmtext_update_colorpair(fg, bg, &pair);
    347       _owl_fmtext_wcolor_set(w, pair);
    348 
    349       /* Advance to next non-formatting character. */
    350       s = p;
    351       p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
    352     }
    353     else {
    354       p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
    355     }
    356   }
    357   if (s) {
    358     waddstr(w, s);
    359   }
    360 }
    361 
    362 void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
    363 {
    364   _owl_fmtext_curs_waddstr(f, w, owl_global_is_search_active(&g));
    365 }
    366 
    367 void owl_fmtext_curs_waddstr_without_search(owl_fmtext *f, WINDOW *w)
    368 {
    369   _owl_fmtext_curs_waddstr(f, w, 0);
    370 }
     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
    371274
    372275/* start with line 'aline' (where the first line is 0) and print
     
    379282 
    380283  /* find the starting line */
    381   ptr1 = in->textbuff;
    382   for (i = 0; i < aline; i++) {
    383     ptr1 = strchr(ptr1, '\n');
    384     if (!ptr1) return(-1);
    385     ptr1++;
    386   }
    387  
     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  }
    388292  /* ptr1 now holds the starting point */
    389293
    390294  /* copy in the next 'lines' lines */
    391   if (lines < 1) return(-1);
    392 
    393   for (i = 0; i < lines; i++) {
    394     offset = ptr1 - in->textbuff;
    395     ptr2 = strchr(ptr1, '\n');
     295  if (lines<1) return(-1);
     296
     297  for (i=0; i<lines; i++) {
     298    offset=ptr1-in->textbuff;
     299    ptr2=strchr(ptr1, '\n');
    396300    if (!ptr2) {
    397       _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
     301      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
    398302      return(-1);
    399303    }
    400     _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
    401     ptr1 = ptr2 + 1;
     304    _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
     305    ptr1=ptr2+1;
    402306  }
    403307  return(0);
     
    407311 * ends at 'bcol' or sooner.  The first column is number 0.  The new
    408312 * message is placed in 'out'.  The message is * expected to end in a
    409  * new line for now. NOTE: This needs to be modified to deal with
    410  * backing up if we find a SPACING COMBINING MARK at the end of a
    411  * line. If that happens, we should back up to the last non-mark
    412  * character and stop there.
     313 * new line for now
    413314 */
    414315void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
    415316{
    416   char *ptr_s, *ptr_e, *ptr_c, *last;
    417   int col, st, padding, chwidth;
     317  char *ptr1, *ptr2, *last;
     318  int len, offset;
    418319
    419320  last=in->textbuff+in->textlen-1;
    420   ptr_s=in->textbuff;
    421   while (ptr_s <= last) {
    422     ptr_e=strchr(ptr_s, '\n');
    423     if (!ptr_e) {
     321  ptr1=in->textbuff;
     322  while (ptr1<=last) {
     323    ptr2=strchr(ptr1, '\n');
     324    if (!ptr2) {
    424325      /* but this shouldn't happen if we end in a \n */
    425326      break;
    426327    }
    427328   
    428     if (ptr_e == ptr_s) {
     329    if (ptr2==ptr1) {
    429330      owl_fmtext_append_normal(out, "\n");
    430       ++ptr_s;
     331      ptr1++;
    431332      continue;
    432333    }
    433334
    434     col = 0;
    435     st = 0;
    436     padding = 0;
    437     chwidth = 0;
    438     ptr_c = ptr_s;
    439     while(ptr_c < ptr_e) {
    440       gunichar c = g_utf8_get_char(ptr_c);
    441       if (!owl_fmtext_is_format_char(c)) {
    442         chwidth = mk_wcwidth(c);
    443         if (col + chwidth > bcol) break;
    444        
    445         if (col >= acol) {
    446           if (st == 0) {
    447             ptr_s = ptr_c;
    448             padding = col - acol;
    449             ++st;
    450           }
    451         }
    452         col += chwidth;
    453         chwidth = 0;
    454       }
    455       ptr_c = g_utf8_next_char(ptr_c);
    456     }
    457     if (st) {
    458       /* lead padding */
    459       owl_fmtext_append_spaces(out, padding);
    460       if (ptr_c == ptr_e) {
    461         /* We made it to the newline. */
    462         _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
    463       }
    464       else {
    465         if (chwidth > 1) {
    466           /* Last char is wide, truncate. */
    467           _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
    468           owl_fmtext_append_normal(out, "\n");
    469         }
    470         else {
    471           /* Last char fits perfectly, leave alone.*/
    472           _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
    473         }
    474       }
    475     }
    476     else {
     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 */
    477347      owl_fmtext_append_normal(out, "\n");
    478     }
    479     ptr_s = g_utf8_next_char(ptr_e);
     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;
    480356  }
    481357}
     
    505381
    506382/* set the charater at 'index' to be 'char'.  If index is out of
    507  * bounds don't do anything. If c or char at index is not ASCII, don't
    508  * do anything because it's not UTF-8 safe. */
    509 void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
     383 * bounds don't do anything */
     384void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
    510385{
    511386  if ((index < 0) || (index > f->textlen-1)) return;
    512   /* NOT ASCII*/
    513   if (f->textbuff[index] & 0x80 || ch & 0x80) return;
    514387  f->textbuff[index]=ch;
    515388}
     
    527400  dst->textlen=src->textlen;
    528401  dst->textbuff=owl_malloc(mallocsize);
     402  dst->fmbuff=owl_malloc(mallocsize);
     403  dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
     404  dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    529405  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
    530   dst->default_attrs = src->default_attrs;
    531   dst->default_fgcolor = src->default_fgcolor;
    532   dst->default_bgcolor = src->default_bgcolor;
     406  memcpy(dst->fmbuff, src->fmbuff, src->textlen);
     407  memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
     408  memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
     409}
     410
     411/* highlight all instances of "string".  Return the number of
     412 * instances found.  This is a case insensitive search.
     413 */
     414int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
     415{
     416
     417  int found, len;
     418  char *ptr1, *ptr2;
     419
     420  len=strlen(string);
     421  found=0;
     422  ptr1=f->textbuff;
     423  while (ptr1-f->textbuff <= f->textlen) {
     424    ptr2=stristr(ptr1, string);
     425    if (!ptr2) return(found);
     426
     427    found++;
     428    _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
     429                         ptr2 - f->textbuff,
     430                         ptr2 - f->textbuff + len - 1);
     431
     432    ptr1=ptr2+len;
     433  }
     434  return(found);
    533435}
    534436
     
    538440int owl_fmtext_search(owl_fmtext *f, char *string)
    539441{
     442
    540443  if (stristr(f->textbuff, string)) return(1);
    541444  return(0);
     
    778681{
    779682  if (f->textbuff) owl_free(f->textbuff);
     683  if (f->fmbuff) owl_free(f->fmbuff);
     684  if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
     685  if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
    780686}
    781687
Note: See TracChangeset for help on using the changeset viewer.