[779] in BarnOwl Developers
[D-O-H] r784 - branches/barnowl_unicode/owl
daemon@ATHENA.MIT.EDU (asedeno@MIT.EDU)
Thu Oct 29 18:09:38 2009
Resent-From: nelhage@mit.edu
Resent-To: barnowl-dev-mtg@charon.mit.edu
To: dirty-owl-hackers@mit.edu
From: asedeno@MIT.EDU
Reply-to: dirty-owl-hackers@MIT.EDU
Date: Thu, 27 Dec 2007 11:01:03 -0500 (EST)
Author: asedeno
Date: 2007-12-27 11:01:03 -0500 (Thu, 27 Dec 2007)
New Revision: 784
Modified:
branches/barnowl_unicode/owl/fmtext.c
branches/barnowl_unicode/owl/message.c
branches/barnowl_unicode/owl/owl.h
branches/barnowl_unicode/owl/viewwin.c
Log:
Unicode / glib branch
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.
Modified: branches/barnowl_unicode/owl/fmtext.c
===================================================================
--- branches/barnowl_unicode/owl/fmtext.c 2007-12-27 15:55:12 UTC (rev 783)
+++ branches/barnowl_unicode/owl/fmtext.c 2007-12-27 16:01:03 UTC (rev 784)
@@ -7,94 +7,79 @@
/* initialize an fmtext with no data */
void owl_fmtext_init_null(owl_fmtext *f)
{
- f->textlen=0;
- f->bufflen=5;
- f->textbuff=owl_malloc(5);
- f->fmbuff=owl_malloc(5);
- f->fgcolorbuff=owl_malloc(5 * sizeof(short));
- f->bgcolorbuff=owl_malloc(5 * sizeof(short));
- f->textbuff[0]=0;
- f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
- f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
- f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
+ f->textlen = 0;
+ f->bufflen = 5;
+ f->textbuff = owl_malloc(5);
+ f->textbuff[0] = 0;
+ f->default_attrs = OWL_FMTEXT_ATTR_NONE;
+ f->default_fgcolor = OWL_COLOR_DEFAULT;
+ f->default_fgcolor = OWL_COLOR_DEFAULT;
}
/* Clear the data from an fmtext, but don't deallocate memory. This
fmtext can then be appended to again. */
void owl_fmtext_clear(owl_fmtext *f)
{
- f->textlen = 0;
- f->textbuff[0] = 0;
- f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
- f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
- f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
+ f->textlen = 0;
+ f->textbuff[0] = 0;
+ f->default_attrs = OWL_FMTEXT_ATTR_NONE;
+ f->default_fgcolor = OWL_COLOR_DEFAULT;
+ f->default_fgcolor = OWL_COLOR_DEFAULT;
}
-/* Internal function. Set the attribute 'attr' from index 'first' to
- * index 'last'
- */
-void _owl_fmtext_set_attr(owl_fmtext *f, int attr, int first, int last)
-{
- int i;
- for (i=first; i<=last; i++) {
- f->fmbuff[i]=(unsigned char) attr;
- }
-}
-
-/* Internal function. Add the attribute 'attr' to the existing
- * attributes from index 'first' to index 'last'
- */
-void _owl_fmtext_add_attr(owl_fmtext *f, int attr, int first, int last)
-{
- int i;
- for (i=first; i<=last; i++) {
- f->fmbuff[i]|=(unsigned char) attr;
- }
-}
-
-/* Internal function. Set the color to be 'color' from index 'first'
- * to index 'last
- */
-void _owl_fmtext_set_fgcolor(owl_fmtext *f, int color, int first, int last)
-{
- int i;
- for (i=first; i<=last; i++) {
- f->fgcolorbuff[i]=(short)color;
- }
-}
-
-void _owl_fmtext_set_bgcolor(owl_fmtext *f, int color, int first, int last)
-{
- int i;
- for (i=first; i<=last; i++) {
- f->bgcolorbuff[i]=(short)color;
- }
-}
-
void _owl_fmtext_realloc(owl_fmtext *f, int newlen) /*noproto*/
{
if(newlen + 1 > f->bufflen) {
- f->textbuff=owl_realloc(f->textbuff, newlen+1);
- f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
- f->fgcolorbuff=owl_realloc(f->fgcolorbuff, (newlen+1) * sizeof(short));
- f->bgcolorbuff=owl_realloc(f->bgcolorbuff, (newlen+1) * sizeof(short));
+ f->textbuff = owl_realloc(f->textbuff, newlen + 1);
f->bufflen = newlen+1;
}
}
+int _owl_fmtext_is_format_char(gunichar c) /*noproto*/
+{
+ if ((c & ~OWL_FMTEXT_UC_ATTR_MASK) == OWL_FMTEXT_UC_ATTR) return 1;
+ if ((c & ~(OWL_FMTEXT_UC_ALLCOLOR_MASK)) == OWL_FMTEXT_UC_COLOR_BASE) return 1;
+ return 0;
+}
/* append text to the end of 'f' with attribute 'attr' and color
* 'color'
*/
-void owl_fmtext_append_attr(owl_fmtext *f, char *text, int attr, int fgcolor, int bgcolor)
+void owl_fmtext_append_attr(owl_fmtext *f, char *text, char attr, short fgcolor, short bgcolor)
{
- int newlen;
- newlen=strlen(f->textbuff)+strlen(text);
+ char attrbuff[6];
+ int newlen, a = 0, fg = 0, bg = 0;
+
+ if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
+ if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
+ if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
+
+ /* Plane-16 characters in UTF-8 are 4 bytes long. */
+ newlen = strlen(f->textbuff) + strlen(text) + (8 * (a + fg + bg));
_owl_fmtext_realloc(f, newlen);
+
+ /* Set attributes */
+ if (a) {
+ memset(attrbuff,0,6);
+ g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
+ strcat(f->textbuff, attrbuff);
+ }
+ if (fg) {
+ memset(attrbuff,0,6);
+ g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
+ strcat(f->textbuff, attrbuff);
+ }
+ if (bg) {
+ memset(attrbuff,0,6);
+ g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
+ strcat(f->textbuff, attrbuff);
+ }
strcat(f->textbuff, text);
- _owl_fmtext_set_attr(f, attr, f->textlen, newlen);
- _owl_fmtext_set_fgcolor(f, fgcolor, f->textlen, newlen);
- _owl_fmtext_set_bgcolor(f, bgcolor, f->textlen, newlen);
+
+ /* Reset attributes */
+ if (bg) strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
+ if (fg) strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
+ if (a) strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
f->textlen=newlen;
}
@@ -128,60 +113,103 @@
owl_fmtext_append_attr(f, text, OWL_FMTEXT_ATTR_REVERSE | OWL_FMTEXT_ATTR_BOLD, OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
}
-/* Add the attribute 'attr' to all text in 'f' */
-void owl_fmtext_addattr(owl_fmtext *f, int attr)
+/* Add the attribute 'attr' to the default atts for the text in 'f' */
+void owl_fmtext_addattr(owl_fmtext *f, char attr)
{
/* add the attribute to all text */
- int i, j;
-
- j=f->textlen;
- for (i=0; i<j; i++) {
- f->fmbuff[i] |= attr;
- }
+ f->default_attrs |= attr;
}
-/* Anywhere the color is NOT ALREDY SET, set the color to 'color'.
- * Other colors are left unchanged
+/* Set the default foreground color for this fmtext to 'color'.
+ * Only affects text that is colored default.
*/
void owl_fmtext_colorize(owl_fmtext *f, int color)
{
- /* everywhere the fgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
- int i, j;
-
- j=f->textlen;
- for(i=0; i<j; i++) {
- if (f->fgcolorbuff[i]==OWL_COLOR_DEFAULT) f->fgcolorbuff[i] = (short)color;
- }
+ f->default_fgcolor = color;
}
+/* Set the default foreground color for this fmtext to 'color'.
+ * Only affects text that is colored default.
+ */
void owl_fmtext_colorizebg(owl_fmtext *f, int color)
{
- /* everywhere the bgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
- int i, j;
+ f->default_bgcolor = color;
+}
- j=f->textlen;
- for(i=0; i<j; i++) {
- if (f->bgcolorbuff[i]==OWL_COLOR_DEFAULT) f->bgcolorbuff[i] = (short)color;
+/* Internal function. Parse attrbute character. */
+void _owl_fmtext_update_attributes(gunichar c, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
+{
+ if ((c & OWL_FMTEXT_UC_ATTR) == OWL_FMTEXT_UC_ATTR) {
+ *attr = c & OWL_FMTEXT_UC_ATTR_MASK;
}
+ else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
+ *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
+ ? OWL_COLOR_DEFAULT
+ : c & OWL_FMTEXT_UC_COLOR_MASK);
+ }
+ else if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
+ *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
+ ? OWL_COLOR_DEFAULT
+ : c & OWL_FMTEXT_UC_COLOR_MASK);
+ }
}
+/* Internal function. Scan for attribute characters. */
+void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
+{
+ char *p;
+ p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ while (p && p < f->textbuff + start) {
+ _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
+ p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ }
+}
+
/* Internal function. Append text from 'in' between index 'start' and
* 'stop' to the end of 'f'
*/
-void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
+void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
{
- int newlen, i;
+ char attrbuff[6];
+ int newlen, a = 0, fg = 0, bg = 0;
+ char attr = 0;
+ short fgcolor = OWL_COLOR_DEFAULT;
+ short bgcolor = OWL_COLOR_DEFAULT;
- newlen=strlen(f->textbuff)+(stop-start+1);
+ _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
+ if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
+ if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
+ if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
+
+ /* We will reset to defaults after appending the text. We may need
+ to set initial attributes. */
+ newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
_owl_fmtext_realloc(f, newlen);
+ if (a) {
+ memset(attrbuff,0,6);
+ g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
+ strcat(f->textbuff, attrbuff);
+ }
+ if (fg) {
+ memset(attrbuff,0,6);
+ g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
+ strcat(f->textbuff, attrbuff);
+ }
+ if (bg) {
+ memset(attrbuff,0,6);
+ g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
+ strcat(f->textbuff, attrbuff);
+ }
+
strncat(f->textbuff, in->textbuff+start, stop-start+1);
+
+ /* Reset attributes */
+ strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
+ strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
+ strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
+
f->textbuff[newlen]='\0';
- for (i=start; i<=stop; i++) {
- f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
- f->fgcolorbuff[f->textlen+(i-start)]=in->fgcolorbuff[i];
- f->bgcolorbuff[f->textlen+(i-start)]=in->bgcolorbuff[i];
- }
f->textlen=newlen;
}
@@ -206,69 +234,142 @@
*/
char *owl_fmtext_print_plain(owl_fmtext *f)
{
- return(owl_strdup(f->textbuff));
+ char *r, *s, *p;
+ r = owl_malloc(f->bufflen);
+ r[0] = '\0';
+ s = f->textbuff;
+ /* Find next possible format character. */
+ p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ while(p) {
+ /* If it's a format character, copy up to it, and skip all
+ immediately following format characters. */
+ if (_owl_fmtext_is_format_char(g_utf8_get_char(p))) {
+ strncat(r, s, p-s);
+ p = g_utf8_next_char(p);
+ while (p && _owl_fmtext_is_format_char(g_utf8_get_char(p))) {
+ p = g_utf8_next_char(p);
+ }
+ s = p;
+ p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ }
+ else {
+ p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ }
+ }
+ if (s) strcat(r,s);
+ return(r);
}
+void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
+{
+ wattrset(w, A_NORMAL);
+ if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
+ if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
+ if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
+}
/* add the formatted text to the curses window 'w'. The window 'w'
* must already be initiatlized with curses
*/
-void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
+void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search)
{
- char *tmpbuff;
- int position, trans1, trans2, trans3, len, lastsame;
-
+ /* char *tmpbuff; */
+ /* int position, trans1, trans2, trans3, len, lastsame; */
+ char *s, *p;
+ char attr;
+ short fg, bg;
+ int search_results, search_len;
+
if (w==NULL) {
owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
return;
}
- tmpbuff=owl_malloc(f->textlen+10);
+ search_results = (do_search
+ ? owl_fmtext_search(f, owl_global_get_search_string(&g))
+ : NULL);
+ if (search_results) search_len = strlen(owl_global_get_search_string(&g));
+ s = f->textbuff;
+ /* Set default attributes. */
+ attr = f->default_attrs;
+ fg = f->default_fgcolor;
+ bg = f->default_bgcolor;
+ _owl_fmtext_wattrset(w, attr);
+ if (owl_global_get_hascolors(&g)) {
+ short pair;
+ pair = owl_fmtext_get_colorpair(fg, bg);
+ if (pair != -1) {
+ wcolor_set(w,pair,NULL);
+ }
+ }
- position=0;
- len=f->textlen;
- while (position<=len) {
- /* find the last char with the current format and color */
- trans1=owl_util_find_trans(f->fmbuff+position, len-position);
- trans2=owl_util_find_trans_short(f->fgcolorbuff+position, len-position);
- trans3=owl_util_find_trans_short(f->bgcolorbuff+position, len-position);
+ /* Find next possible format character. */
+ p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ while(p) {
+ if (_owl_fmtext_is_format_char(g_utf8_get_char(p))) {
+ /* Deal with all text from last insert to here. */
+ char tmp;
+
+ tmp = p[0];
+ p[0] = '\0';
+ if (search_results) {
+ /* Search is active, so highlight search results. */
+ char tmp2, *ss;
+ ss = stristr(s, owl_global_get_search_string(&g));
+ while (ss) {
+ /* Found search string, highlight it. */
- lastsame = (trans1 < trans2) ? trans1 : trans2;
- lastsame = (lastsame < trans3) ? lastsame : trans3;
- lastsame += position;
+ tmp2 = ss[0];
+ ss[0] = '\0';
+ waddstr(w, s);
+ ss[0] = tmp2;
- /* set the format */
- wattrset(w, A_NORMAL);
- if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
- wattron(w, A_BOLD);
- }
- if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
- wattron(w, A_REVERSE);
- }
- if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
- wattron(w, A_UNDERLINE);
- }
+ _owl_fmtext_wattrset(w,attr ^ A_REVERSE);
- /* set the color */
- /* warning, this is sort of a hack */
- if (owl_global_get_hascolors(&g)) {
- short fg, bg, pair;
- fg = f->fgcolorbuff[position];
- bg = f->bgcolorbuff[position];
+ tmp2 = ss[search_len];
+ ss[search_len] = '\0';
+ waddstr(w, ss);
+ ss[search_len] = tmp2;
- pair = owl_fmtext_get_colorpair(fg, bg);
- if (pair != -1) {
- wcolor_set(w,pair,NULL);
+ _owl_fmtext_wattrset(w,attr);
+
+ s = ss + search_len;
+ ss = stristr(s, owl_global_get_search_string(&g));
+ }
}
+ /* Deal with remaining part of string. */
+ waddstr(w, s);
+ p[0] = tmp;
+
+ /* Deal with new attributes. Initialize to defaults, then
+ process all consecutive formatting characters. */
+ attr = f->default_attrs;
+ fg = f->default_fgcolor;
+ bg = f->default_bgcolor;
+ while (p && _owl_fmtext_is_format_char(g_utf8_get_char(p))) {
+ _owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
+ p = g_utf8_next_char(p);
+ }
+ _owl_fmtext_wattrset(w, attr | f->default_attrs);
+ if (owl_global_get_hascolors(&g)) {
+ if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
+ if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
+ short pair;
+ pair = owl_fmtext_get_colorpair(fg, bg);
+ if (pair != -1) {
+ wcolor_set(w,pair,NULL);
+ }
+ }
+ /* Advance to next non-formatting character. */
+ s = p;
+ p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
}
-
- /* add the text */
- strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
- tmpbuff[lastsame-position+1]='\0';
- waddstr(w, tmpbuff);
-
- position=lastsame+1;
+ else {
+ p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
+ }
}
- owl_free(tmpbuff);
+ if (s) {
+ waddstr(w, s);
+ }
}
@@ -281,28 +382,27 @@
int i, offset;
/* find the starting line */
- ptr1=in->textbuff;
- if (aline!=0) {
- for (i=0; i<aline; i++) {
- ptr1=strchr(ptr1, '\n');
- if (!ptr1) return(-1);
- ptr1++;
- }
+ ptr1 = in->textbuff;
+ for (i = 0; i < aline; i++) {
+ ptr1 = strchr(ptr1, '\n');
+ if (!ptr1) return(-1);
+ ptr1++;
}
+
/* ptr1 now holds the starting point */
/* copy in the next 'lines' lines */
- if (lines<1) return(-1);
+ if (lines < 1) return(-1);
- for (i=0; i<lines; i++) {
- offset=ptr1-in->textbuff;
- ptr2=strchr(ptr1, '\n');
+ for (i = 0; i < lines; i++) {
+ offset = ptr1 - in->textbuff;
+ ptr2 = strchr(ptr1, '\n');
if (!ptr2) {
- _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
+ _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
return(-1);
}
- _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
- ptr1=ptr2+1;
+ _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
+ ptr1 = ptr2 + 1;
}
return(0);
}
@@ -315,74 +415,63 @@
void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
{
char *ptr_s, *ptr_e, *ptr_c, *last;
- int col, cnt, padding;
+ int col, st, padding, chwidth;
last=in->textbuff+in->textlen-1;
ptr_s=in->textbuff;
- while (ptr_s<=last) {
+ while (ptr_s <= last) {
ptr_e=strchr(ptr_s, '\n');
if (!ptr_e) {
/* but this shouldn't happen if we end in a \n */
break;
}
- if (ptr_e==ptr_s) {
+ if (ptr_e == ptr_s) {
owl_fmtext_append_normal(out, "\n");
- ptr_s++;
+ ++ptr_s;
continue;
}
col = 0;
- cnt = 0;
+ st = 0;
padding = 0;
ptr_c = ptr_s;
- while(col < bcol && ptr_c < ptr_e) {
+ while(col <= bcol && ptr_c < ptr_e) {
gunichar c = g_utf8_get_char(ptr_c);
- if (col + wcwidth(c) > bcol) break;
- col += wcwidth(c);
- ptr_c = g_utf8_next_char(ptr_c);
- if (col >= acol) {
- if (cnt == 0) {
- ptr_s = ptr_c;
- padding = col - acol;
+ if (!_owl_fmtext_is_format_char(c)) {
+ chwidth = wcwidth(c);
+
+ if (col + chwidth > bcol)
+ break;
+ if (col >= acol) {
+ if (st == 0) {
+ ptr_s = ptr_c;
+ padding = col - acol;
+ ++st;
+ }
}
- ++cnt;
+ col += chwidth;
+ chwidth = 0;
}
+ ptr_c = g_utf8_next_char(ptr_c);
}
- if (cnt) {
- while(padding-- > 0) {
- owl_fmtext_append_normal(out, " ");
+ if (st) {
+ /* lead padding */
+ owl_fmtext_append_spaces(out, padding);
+ if (ptr_c[0] & 0x80) {
+ if (col + chwidth == bcol)
+ ptr_c = g_utf8_next_char(ptr_c);
+ _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - 1 - in->textbuff);
+ owl_fmtext_append_normal(out, "\n");
}
- _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
+ else {
+ _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
+ }
}
else {
owl_fmtext_append_normal(out, "\n");
}
- ptr_s=ptr_e+1;
-
-#if 0
- /* we need to check that we won't run over here */
- len=bcol-acol;
- if (len > (ptr_e-(ptr_s+acol))) {
- /* the whole line fits with room to spare, don't take a full 'len' */
- len=ptr_e-(ptr_s+acol);
- }
- if (len>last-ptr_s) {
- /* the whole rest of the text fits with room to spare, adjust for it */
- len-=(last-ptr_s);
- }
- if (len<=0) {
- /* saftey check */
- owl_fmtext_append_normal(out, "\n");
- ptr_s=ptr_e+1;
- continue;
- }
-
- offset = ptr_s - in->textbuff;
- _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
-
- ptr_s=ptr_e+1;
-#endif
+ ptr_s = g_utf8_next_char(ptr_e);
}
}
@@ -410,10 +499,13 @@
}
/* set the charater at 'index' to be 'char'. If index is out of
- * bounds don't do anything */
-void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
+ * bounds don't do anything. If c or char at index is not ASCII, don't
+ * do anything because it's not UTF-8 safe. */
+void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
{
if ((index < 0) || (index > f->textlen-1)) return;
+ /* NOT ASCII*/
+ if (f->textbuff[index] & 0x80 || ch & 0x80) return;
f->textbuff[index]=ch;
}
@@ -429,47 +521,17 @@
}
dst->textlen=src->textlen;
dst->textbuff=owl_malloc(mallocsize);
- dst->fmbuff=owl_malloc(mallocsize);
- dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
- dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
memcpy(dst->textbuff, src->textbuff, src->textlen+1);
- memcpy(dst->fmbuff, src->fmbuff, src->textlen);
- memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
- memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
+ dst->default_attrs = src->default_attrs;
+ dst->default_fgcolor = src->default_fgcolor;
+ dst->default_bgcolor = src->default_bgcolor;
}
-/* highlight all instances of "string". Return the number of
- * instances found. This is a case insensitive search.
- */
-int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
-{
-
- int found, len;
- char *ptr1, *ptr2;
-
- len=strlen(string);
- found=0;
- ptr1=f->textbuff;
- while (ptr1-f->textbuff <= f->textlen) {
- ptr2=stristr(ptr1, string);
- if (!ptr2) return(found);
-
- found++;
- _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
- ptr2 - f->textbuff,
- ptr2 - f->textbuff + len - 1);
-
- ptr1=ptr2+len;
- }
- return(found);
-}
-
/* return 1 if the string is found, 0 if not. This is a case
* insensitive search.
*/
int owl_fmtext_search(owl_fmtext *f, char *string)
{
-
if (stristr(f->textbuff, string)) return(1);
return(0);
}
@@ -710,9 +772,6 @@
void owl_fmtext_free(owl_fmtext *f)
{
if (f->textbuff) owl_free(f->textbuff);
- if (f->fmbuff) owl_free(f->fmbuff);
- if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
- if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
}
/*** Color Pair manager ***/
Modified: branches/barnowl_unicode/owl/message.c
===================================================================
--- branches/barnowl_unicode/owl/message.c 2007-12-27 15:55:12 UTC (rev 783)
+++ branches/barnowl_unicode/owl/message.c 2007-12-27 16:01:03 UTC (rev 784)
@@ -536,18 +536,10 @@
owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline+1, &a);
owl_fmtext_truncate_cols(&a, acol, bcol, &b);
- if (fgcolor!=OWL_COLOR_DEFAULT) {
- owl_fmtext_colorize(&b, fgcolor);
- }
- if (bgcolor!=OWL_COLOR_DEFAULT) {
- owl_fmtext_colorizebg(&b, bgcolor);
- }
+ owl_fmtext_colorize(&b, fgcolor);
+ owl_fmtext_colorizebg(&b, bgcolor);
- if (owl_global_is_search_active(&g)) {
- owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
- }
-
- owl_fmtext_curs_waddstr(&b, win);
+ owl_fmtext_curs_waddstr(&b, win, owl_global_is_search_active(&g));
owl_fmtext_free(&a);
owl_fmtext_free(&b);
Modified: branches/barnowl_unicode/owl/owl.h
===================================================================
--- branches/barnowl_unicode/owl/owl.h 2007-12-27 15:55:12 UTC (rev 783)
+++ branches/barnowl_unicode/owl/owl.h 2007-12-27 16:01:03 UTC (rev 784)
@@ -100,6 +100,26 @@
#define OWL_FMTEXT_ATTR_REVERSE 2
#define OWL_FMTEXT_ATTR_UNDERLINE 4
+#define OWL_FMTEXT_UC_BASE 0x100000 /* Unicode Plane 16 - Supplementary Private Use Area-B*/
+#define OWL_FMTEXT_UC_ATTR ( OWL_FMTEXT_UC_BASE | 0x800 )
+#define OWL_FMTEXT_UC_ATTR_MASK 0x7
+#define OWL_FMTEXT_UC_COLOR_BASE ( OWL_FMTEXT_UC_BASE | 0x400 )
+#define OWL_FMTEXT_UC_FGCOLOR OWL_FMTEXT_UC_COLOR_BASE
+#define OWL_FMTEXT_UC_BGCOLOR ( OWL_FMTEXT_UC_COLOR_BASE | 0x200 )
+#define OWL_FMTEXT_UC_DEFAULT_COLOR 0x100
+#define OWL_FMTEXT_UC_FGDEFAULT ( OWL_FMTEXT_UC_FGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
+#define OWL_FMTEXT_UC_BGDEFAULT ( OWL_FMTEXT_UC_BGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
+#define OWL_FMTEXT_UC_COLOR_MASK 0xFF
+#define OWL_FMTEXT_UC_ALLCOLOR_MASK ( OWL_FMTEXT_UC_COLOR_MASK | OWL_FMTEXT_UC_DEFAULT_COLOR | 0x200)
+#define OWL_FMTEXT_UC_STARTBYTE_UTF8 '\xf4'
+
+#define OWL_FMTEXT_UTF8_ATTR_NONE "\xf4\x80\xa0\x80"
+#define OWL_FMTEXT_UTF8_FGDEFAULT "\xf4\x80\x94\x80"
+#define OWL_FMTEXT_UTF8_BGDEFAULT "\xf4\x80\x96\x80"
+
+
+
+
#define OWL_COLOR_BLACK 0
#define OWL_COLOR_RED 1
#define OWL_COLOR_GREEN 2
@@ -255,9 +275,9 @@
int textlen;
int bufflen;
char *textbuff;
- char *fmbuff;
- short *fgcolorbuff;
- short *bgcolorbuff;
+ char default_attrs;
+ short default_fgcolor;
+ short default_bgcolor;
} owl_fmtext;
typedef struct _owl_list {
Modified: branches/barnowl_unicode/owl/viewwin.c
===================================================================
--- branches/barnowl_unicode/owl/viewwin.c 2007-12-27 15:55:12 UTC (rev 783)
+++ branches/barnowl_unicode/owl/viewwin.c 2007-12-27 16:01:03 UTC (rev 784)
@@ -72,7 +72,7 @@
owl_fmtext_truncate_lines(&(v->fmtext), v->topline, v->winlines-BOTTOM_OFFSET, &fm1);
owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
- owl_fmtext_curs_waddstr(&fm2, v->curswin);
+ owl_fmtext_curs_waddstr(&fm2, v->curswin, 0);
/* print the message at the bottom */
wmove(v->curswin, v->winlines-1, 0);