This adds ANSI escape sequence support to fltk-1.3. The files were originally found here: https://www.seriss.com/people/erco/fltk/ansi-patch/1.3.x/ansi-patch-1.3.x--r10037.cxx https://www.seriss.com/people/erco/fltk/ansi-patch/1.3.x/AnsiMode.H Changes Jan 28, 2023 by Rich Renamed file from ansi-patch-1.3.x--r10037.cxx to fltk-ansi-patch-1.3.x.patch Added a/src/ prefix to Fl_Browser.cxx, 2 places. Changed strtol to strtoul, 3 places. Rich Index: Fl_Browser.cxx =================================================================== --- a/src/Fl_Browser.cxx (revision 10037) +++ b/src/Fl_Browser.cxx (working copy) @@ -494,6 +494,8 @@ return textsize()+2; } +#include "AnsiMode.H" // ERCO: private class to handle ANSI font/color modes + /** Draws \p item at the position specified by \p X \p Y \p W \p H. The \p W and \p H values are used for clipping. @@ -526,6 +528,7 @@ int tsize = textsize(); Fl_Font font = textfont(); Fl_Color lcol = textcolor(); + Fl_Color bgcol = color(); // ERCO Fl_Align talign = FL_ALIGN_LEFT; // check for all the @-lines recognized by XForms: //#if defined(__GNUC__) @@ -542,8 +545,10 @@ case 'c': talign = FL_ALIGN_CENTER; break; case 'r': talign = FL_ALIGN_RIGHT; break; case 'B': + bgcol = (Fl_Color)strtoul(str,&str,10); // ERCO if (!(l->flags & SELECTED)) { - fl_color((Fl_Color)strtoul(str, &str, 10)); + fl_color((Fl_Color)bgcol); // ERCO + //fl_color((Fl_Color)strtoul(str, &str, 10)); // ERCO fl_rectf(X, Y, w1, H); } else while (isdigit(*str & 255)) str++; // skip digits break; @@ -577,12 +582,74 @@ } } BREAK: - fl_font(font, tsize); - if (l->flags & SELECTED) - lcol = fl_contrast(lcol, selection_color()); - if (!active_r()) lcol = fl_inactive(lcol); - fl_color(lcol); - fl_draw(str, X+3, Y, w1-6, H, e ? Fl_Align(talign|FL_ALIGN_CLIP) : talign, 0, 0); + { + // ANSI + AnsiMode ansi(lcol, bgcol, font, tsize); + int XX = X; + int WW = W; // entire browser + int ww1 = w1 - 4; // this field's width + char *start = str; + char *ss = start; + int done = 0; + int clipped = 0; + while ( ! done ) { + if ( *ss == 0 || *ss == 033 ) { + // Anything to print? + if ( start != ss ) { + // Print what we have so far + char ts = *ss; + *ss = 0; + fl_font(ansi.FontFace(), ansi.FontSize()); + WW = (int)fl_width(start); + if ( WW > ww1 ) { + WW = ww1; // field clipping + clipped = 1; // we clipped + } + if ( WW > 0 ) { + if (((FL_BLINE*)item)->flags & SELECTED) + ansi.Fg(fl_contrast(ansi.Fg(),selection_color())); + else if ( (Fl_Color)ansi.Bg() != bgcol) { + fl_color(ansi.Bg()); + fl_rectf(XX+3,Y,WW,H); + } + if (!active_r()) ansi.Fg(fl_inactive(textcolor())); + fl_color(ansi.Fg()); + Fl_Align a = Fl_Align(talign | (e ? FL_ALIGN_CLIP : 0)); + fl_draw(start, XX+3, Y, WW, H, a, 0, 0); + if ( ansi.Underscore() ) fl_line(XX+3,Y+H-1,XX+3+WW-1,Y+H-1); + } + XX += WW; + ww1 -= WW; + *ss = ts; // restore char + } + // Handle ANSI escape sequence + if ( *ss == 0 ) { done = 1; continue; } + ++ss; // skip ESC + if ( *ss != '[' ) { start = ss; continue; } + ++ss; // skip '[' + ss = ansi.ParseAnsi(ss); + if ( *ss == 0 ) { done = 1; continue; } + start = ss; + continue; + } + ++ss; + } + if ( clipped ) { + // Draw 'clipped' indicators + int XC = XX+1; + int YC = Y + (H/2); // center + fl_color(ansi.Bg()); + fl_pie(XC-8,Y+2,10,11,0.0,360.0); + fl_color(FL_BLACK); // arrow triangle black + fl_polygon(XC,YC, XC-5,YC-3, XC-5,YC+3); + } + } +//ERCO fl_font(font, tsize); +//ERCO if (l->flags & SELECTED) +//ERCO lcol = fl_contrast(lcol, selection_color()); +//ERCO if (!active_r()) lcol = fl_inactive(lcol); +//ERCO fl_color(lcol); +//ERCO fl_draw(str, X+3, Y, w1-6, H, e ? Fl_Align(talign|FL_ALIGN_CLIP) : talign, 0, 0); if (!e) break; // no more fields... *e = column_char(); // put the separator back X += w1;