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;
