Usermode/AxWin4 - Added text rendering (very hacky using VGA font)
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / draw_text.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * draw_text.cpp
6  * - Text Drawing
7  *
8  * Handles font selection and drawing of text to windows
9  */
10 #include <draw_text.hpp>
11 #include <axwin4/definitions.h>
12 #include <unicode.h>    // libunicode (acess)
13 extern "C" {
14 #include <assert.h>     // assert... and _SysDebug
15 };
16 #include "resources/font_8x16.h"
17
18 // === CODE ===
19 namespace AxWin {
20
21 // -- Primitive fallback font
22 CFontFallback::CFontFallback()
23 {
24 }
25
26 CRect CFontFallback::Size(const ::std::string& text, unsigned int Size) const
27 {
28         return CRect(0,0, text.size() * Size * FONT_WIDTH / FONT_HEIGHT, Size);
29 }
30
31 /**
32  * \param Text height in pixels (not in points)
33  */
34 void CFontFallback::Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size)
35 {
36         unsigned int font_step = Size * FONT_WIDTH / FONT_HEIGHT;
37         CRect   pos = rect;
38         for( auto codepoint : ::libunicode::utf8string(text) )
39         {
40                 renderAtRes(dest, pos, codepoint, Size, 0x000000);
41                 pos.Translate(font_step, 0);
42         }
43 }
44
45 void CFontFallback::renderAtRes(CSurface& dest, const CRect& rect, uint32_t cp, unsigned int Size, uint32_t FGC)
46 {
47         unsigned int char_idx = unicodeToCharmap(cp);
48         assert(char_idx < 256);
49         const uint8_t*  char_ptr = &VTermFont[char_idx * FONT_HEIGHT];
50         unsigned int    out_h = Size;
51         unsigned int    out_w = (Size * FONT_WIDTH / FONT_HEIGHT) + 1;
52         uint32_t        char_data[out_w];
53         if( Size == FONT_HEIGHT ) {
54                 // Standard blit
55                 for( unsigned int row = 0; row < out_h; row ++ )
56                 {
57                         for( unsigned int col = 0; col < out_w; col ++ )
58                         {
59                                 uint8_t alpha = getValueAtRaw(char_ptr, col, row);
60                                 char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF);
61                         }
62                         dest.BlendScanline(rect.m_y + row, rect.m_x, FONT_WIDTH, char_data);
63                 }
64         }
65         else if( Size < FONT_HEIGHT ) {
66                 // Down-scaled blit
67         }
68         else {
69                 // up-scaled blit
70                 for( unsigned int row = 0; row < out_h; row ++ )
71                 {
72                         unsigned int yf16 = row * out_h * 0x10000 / Size;
73                         for( unsigned int col = 0; col < out_w; col ++ )
74                         {
75                                 unsigned int xf16 = col * out_w * 0x10000 / FONT_WIDTH;
76                                 uint8_t alpha = getValueAtPt(char_ptr, xf16, yf16);
77                                 //_SysDebug("row %i (%05x), col %i (%05x): alpha = %02x", row, yf16, col, xf16, alpha);
78                                 char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF);
79                         }
80                         dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data);
81                 }
82         }
83 }
84 // X and Y are fixed-point 16.16 values
85 uint8_t CFontFallback::getValueAtPt(const uint8_t* char_ptr, unsigned int xf16, unsigned int yf16)
86 {
87         unsigned int ix = xf16 >> 16;
88         unsigned int iy = yf16 >> 16;
89         unsigned int fx = xf16 & 0xFFFF;
90         unsigned int fy = yf16 & 0xFFFF;
91         
92         if( fx == 0 && fy == 0 ) {
93                 return getValueAtRaw(char_ptr, ix, iy);
94         }
95         else if( fx == 0 ) {
96                 float y = (float)fy / 0x10000;
97                 uint8_t v0 = getValueAtRaw(char_ptr, ix, iy  );
98                 uint8_t v1 = getValueAtRaw(char_ptr, ix, iy+1);
99                 return v0 * (1 - y) + v1 * y;
100         }
101         else if( fy == 0 ) {
102                 float x = (float)fx / 0x10000;
103                 uint8_t v0 = getValueAtRaw(char_ptr, ix  , iy);
104                 uint8_t v1 = getValueAtRaw(char_ptr, ix+1, iy);
105                 return v0 * (1 - x) + v1 * x;
106         }
107         else {
108                 float x = (float)fx / 0x10000;
109                 float y = (float)fx / 0x10000;
110                 // [0,0](1 - x)(1 - y) + [1,0]x(1-y) + [0,1](1-x)y + [1,1]xy
111                 uint8_t v00 = getValueAtRaw(char_ptr, ix, iy);
112                 uint8_t v01 = getValueAtRaw(char_ptr, ix, iy+1);
113                 uint8_t v10 = getValueAtRaw(char_ptr, ix+1, iy);
114                 uint8_t v11 = getValueAtRaw(char_ptr, ix+1, iy+1);
115                 //_SysDebug("x,y = %04x %04x", (unsigned)(x * 0x10000), (unsigned)(y * 0x10000));
116                 //_SysDebug("v = %02x %02x %02x %02x", v00, v01, v10, v11);
117                 float val1 = v00 * (1 - x) * (1 - y);
118                 float val2 = v10 * x * (1 - y);
119                 float val3 = v01 * (1 - x) * y;
120                 float val4 = v11 * x * y;
121                 //_SysDebug("vals = %04x %04x %04x %04x",
122                 //      (unsigned)(val1 * 0x10000),
123                 //      (unsigned)(val2 * 0x10000),
124                 //      (unsigned)(val3 * 0x10000),
125                 //      (unsigned)(val4 * 0x10000)
126                 //      );
127                 
128                 return (uint8_t)(val1 + val2 + val3 + val4);
129         }
130 }
131
132 uint8_t CFontFallback::getValueAtRaw(const uint8_t* char_ptr, unsigned int x, unsigned int y)
133 {
134         if( x == 0 || y == 0 )
135                 return 0;
136         x --;
137         y --;
138         if(x >= FONT_WIDTH || y >= FONT_HEIGHT)
139                 return 0;
140         return (char_ptr[y] & (1 << (8-x))) ? 255 : 0;
141 }
142
143 unsigned int CFontFallback::unicodeToCharmap(uint32_t cp) const
144 {
145         if(cp >= ' ' && cp < 0x7F)
146                 return cp;
147         switch(cp)
148         {
149         default:
150                 return 0;
151         }
152 }
153
154 };      // namespace AxWin
155

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