+ tRichText_Window *info;
+ tWindow *ret = WM_CreateWindowStruct( sizeof(*info) );
+ if(!ret) return NULL;
+ info = ret->RendererInfo;
+
+ // Initialise font (get an idea of dimensions)
+ int h;
+ WM_Render_GetTextDims(NULL, "yY!", 3, NULL, &h);
+ info->LineHeight = h;
+
+ return ret;
+}
+
+static inline int Renderer_RichText_RenderText_Act(tWindow *Window, tRichText_Window *info, int X, int Row, const char *Text, int Bytes, tColour FG, tColour BG, int Flags)
+{
+ int rwidth;
+ // TODO: Fill only what is needed? What about the rest of the line?
+ WM_Render_DrawRect(Window, X, Row*info->LineHeight,
+ Window->W - X, info->LineHeight,
+ BG
+ );
+ // TODO: Bold, Italic, Underline
+ rwidth = WM_Render_DrawText(Window,
+ X, Row*info->LineHeight,
+ Window->W - X, info->LineHeight,
+ info->Font, FG,
+ Text, Bytes
+ );
+ return rwidth;
+}
+
+void Renderer_RichText_RenderText(tWindow *Window, int Line, const char *Text)
+{
+ tRichText_Window *info = Window->RendererInfo;
+ tColour fg = info->DefaultFG;
+ tColour bg = info->DefaultBG;
+ int flagset = 0;
+ int bRender = 0;
+ int curx = 0;
+ const char *oldtext = Text;
+
+ for( int i = 0; curx < Window->W; i ++ )
+ {
+ char ch, flags;
+ int len;
+
+ if( i == info->FirstVisCol )
+ bRender = 1;
+
+ ch = *Text++;
+ if( ch == 0 ) break;
+
+ // Not an escape - move along
+ if( ch > 4 )
+ continue ;
+
+ if( bRender ) {
+ // Render previous characters
+ curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line,
+ oldtext, Text - oldtext - 1, fg, bg, flagset);
+ if( curx >= Window->W )
+ break;
+ }
+ oldtext = Text;
+ switch(ch)
+ {
+ case 1: // FG Select (\1 RRGGBB)
+ if( sscanf(Text, "%6x%n", &fg, &len) != 1 || len != 6 ) {
+ // Bad client
+ _SysDebug("foreground scanf failed - len=%i", len);
+ len = 0;
+ }
+ Text += len;
+ oldtext = Text;
+ _SysDebug("FG update to %x", fg);
+ break ;
+ case 2: // BG Select (\2 RRGGBB)
+ if( sscanf(Text, "%6x%n", &bg, &len) != 1 || len != 6 ) {
+ // Bad client
+ _SysDebug("background scanf failed - len=%i", len);
+ len = 0;
+ }
+ Text += len;
+ oldtext = Text;
+ _SysDebug("BG update to %x", bg);
+ break ;
+ case 3: // Flagset (0,it,uline,bold)
+ if( sscanf(Text, "%1hhx%n", &flags, &len) != 1 || len != 1 ) {
+ // Bad client
+ _SysDebug("Flagset scanf failed - len=%i", len);
+ }
+ flagset = flags & 7;
+ Text += len;
+ oldtext = Text;
+ break ;
+ case 4: // Escape (do nothing)
+ Text ++;
+ // NOTE: No update to oldtext
+ break;
+ default: // Error.
+ break;
+ }
+ }
+ curx += Renderer_RichText_RenderText_Act(Window, info, curx,
+ Line, oldtext, Text - oldtext + 1, fg, bg, flagset);
+ WM_Render_DrawRect(Window, curx, Line * info->LineHeight,
+ Window->W - curx, info->LineHeight, info->DefaultBG);