AxWin3 - Adding RichText rendering, no sscanf so doesn't compile
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / renderers / richtext.c
1 /*
2  * Acess2 Window Manager v3
3  * - By John Hodge (thePowersGang)
4  *
5  * render/richtext.c
6  * - Formatted Line Editor
7  */
8 #include <common.h>
9 #include <wm_renderer.h>
10 #include <richtext_messages.h>
11
12 #define LINES_PER_BLOCK 30
13
14 // === TYPES ===
15 typedef struct sRichText_LineBlock
16 {
17         struct sRichText_LineBlock      *Next;
18          int    FirstLine;
19         char    *Lines[LINES_PER_BLOCK];
20 } tRichText_LineBlock;
21 typedef struct sRichText_Window
22 {
23          int    DispLines, DispCols;
24          int    FirstVisRow, FirstVisCol;
25          int    nLines, nCols;
26          int    CursorRow, CursorCol;
27         tRichText_LineBlock     FirstBlock;
28         tColour DefaultFG;
29         tColour DefaultBG;
30         tFont   *Font;
31         
32         short   LineHeight;
33 } tRichText_Window;
34
35 // === PROTOTYPES ===
36  int    Renderer_RichText_Init(void);
37 tWindow *Renderer_RichText_Create(int Flags);
38 void    Renderer_RichText_Redraw(tWindow *Window);
39  int    Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data);
40
41 // === GLOBALS ===
42 tWMRenderer     gRenderer_RichText = {
43         .Name = "RichText",
44         .CreateWindow   = Renderer_RichText_Create,
45         .Redraw         = Renderer_RichText_Redraw,
46         .HandleMessage  = Renderer_RichText_HandleMessage
47 };
48
49 // === CODE ===
50 int Renderer_RichText_Init(void)
51 {
52         WM_RegisterRenderer(&gRenderer_RichText);       
53         return 0;
54 }
55
56 tWindow *Renderer_RichText_Create(int Flags)
57 {
58         tRichText_Window        *info;
59         tWindow *ret = WM_CreateWindowStruct( sizeof(*info) );
60         if(!ret)        return NULL;
61         info = ret->RendererInfo;
62         // Everything starts at zero?
63         return ret;
64 }
65
66 inline int Renderer_RichText_RenderText_Act(tWindow *Window, tRichText_Window *info, int X, int Row, const char *Text, int Bytes, tColour FG, tColour BG)
67 {
68          int    rwidth;
69         // TODO: Fill only what is needed
70         WM_Render_DrawRect(Window, X, Row*info->LineHeight,
71                 Window->W - X, info->LineHeight,
72                 BG
73                 );
74         rwidth = WM_Render_DrawText(Window,
75                 X, Row*info->LineHeight,
76                 Window->W - X, info->LineHeight,
77                 info->Font, FG,
78                 Text, Bytes
79                 );
80         return rwidth;
81 }
82
83 void Renderer_RichText_RenderText(tWindow *Window, int Line, const char *Text)
84 {
85         tRichText_Window        *info = Window->RendererInfo;
86         tColour fg = info->DefaultFG;
87         tColour bg = info->DefaultBG;
88          int    bBold = 0;
89          int    bULine = 0;
90          int    bItalic = 0;
91          int    bRender = 0;
92          int    curx = 0;
93         const char      *oldtext = Text;
94         
95         for( int i = 0; i < info->FirstVisCol + info->DispCols; i ++ )
96         {
97                 char    ch, flags;
98                  int    len;
99
100                 if( i == info->FirstVisCol )
101                         bRender = 1;
102
103                 ch = *Text++;
104                 if( ch == 0 )   break;
105                 if( ch <=3 && bRender ) {
106                         // Render previous characters
107                         curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line, oldtext, Text - oldtext, fg, bg);
108                         oldtext = Text;
109                 }
110                 switch(ch)
111                 {
112                 case 1: // FG Select (\1 RRGGBB)
113                         len = sscanf(Text, "%6x", &fg);
114                         if( len != 6 ) {
115                                 // Bad client
116                         }
117                         Text += len;
118                         break ;
119                 case 2: // BG Select (\2 RRGGBB)
120                         len = sscanf(Text, "%6x", &bg);
121                         if( len != 6 ) {
122                                 // Bad client
123                         }
124                         Text += len;
125                         break ;
126                 case 3: // Flagset (0,it,uline,bold)
127                         len = sscanf(Text, "%1x", &flags);
128                         if( len != 1 ) {
129                                 // Bad client
130                         }
131                         Text += len;
132                         bItalic = !!(flags & (1 << 2));
133                         bULine = !!(flags & (1 << 1));
134                         bBold = !!(flags & (1 << 0));
135                         break ;
136                 default: // Any char, nop
137                         break;
138                 }
139         }
140         curx += Renderer_RichText_RenderText_Act(Window, info, curx, Line, oldtext, Text - oldtext, fg, bg);
141         WM_Render_DrawRect(Window, curx, Line * info->LineHeight, Window->W - curx, info->LineHeight, info->DefaultBG);
142 }
143
144 void Renderer_RichText_Redraw(tWindow *Window)
145 {
146         tRichText_Window        *info = Window->RendererInfo;
147          int    i;
148         tRichText_LineBlock     *lines = &info->FirstBlock;
149         
150         // Locate the first line block
151         for( i = info->FirstVisRow; i > LINES_PER_BLOCK && lines; i -= LINES_PER_BLOCK )
152                 lines = lines->Next;
153
154         for( i = 0; i < info->DispLines && lines; i ++ )
155         {
156                 if( i >= info->nLines - info->FirstVisRow )
157                         break;
158                 // TODO: Dirty rectangles?
159                 WM_Render_DrawRect(Window,
160                         0, i*info->LineHeight,
161                         Window->W, info->LineHeight,
162                         info->DefaultBG
163                         );
164                 // TODO: Horizontal scrolling?
165                 // TODO: Formatting
166                 //Renderer_RichText_RenderText(Window, i, lines->Lines[i % LINES_PER_BLOCK]);
167                 WM_Render_DrawText(Window,
168                         0, i*info->LineHeight,
169                         Window->W, info->LineHeight,
170                         info->Font, info->DefaultFG,
171                         lines->Lines[i % LINES_PER_BLOCK],
172                         -1);
173         
174                 if( (i + 1) % LINES_PER_BLOCK == 0 )
175                         lines = lines->Next;
176         }
177         // Clear out i -- info->DispLines
178         WM_Render_DrawRect(Window,
179                 0, i*info->LineHeight,
180                 Window->W, (info->DispLines-i)*info->LineHeight,
181                 info->DefaultBG
182                 );
183 }
184
185 int Renderer_RichText_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data)
186 {
187         switch(Msg)
188         {
189         case MSG_RICHTEXT_SETATTR:
190                 break;
191         }
192         return 0;
193 }

UCC git Repository :: git.ucc.asn.au