Merge branch 'master' of git://github.com/thepowersgang/acess2
[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);
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                 // NOTE: uses the same code as the upscale blit (probably not correct, need to replace)
68                 for( unsigned int row = 0; row < out_h; row ++ )
69                 {
70                         unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h;
71                         for( unsigned int col = 0; col < out_w; col ++ )
72                         {
73                                 unsigned int xf16 = col * FONT_WIDTH * 0x10000 / out_w;
74                                 uint8_t alpha = getValueAtPt(char_ptr, xf16, yf16);
75                                 //_SysDebug("row %i (%05x), col %i (%05x): alpha = %02x", row, yf16, col, xf16, alpha);
76                                 char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF);
77                         }
78                         dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data);
79                 }
80         }
81         else {
82                 // up-scaled blit
83                 for( unsigned int row = 0; row < out_h; row ++ )
84                 {
85                         unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h;
86                         for( unsigned int col = 0; col < out_w; col ++ )
87                         {
88                                 unsigned int xf16 = col * FONT_WIDTH * 0x10000 / out_w;
89                                 uint8_t alpha = getValueAtPt(char_ptr, xf16, yf16);
90                                 //_SysDebug("row %i (%05x), col %i (%05x): alpha = %02x", row, yf16, col, xf16, alpha);
91                                 char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF);
92                         }
93                         dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data);
94                 }
95         }
96 }
97 // X and Y are fixed-point 16.16 values
98 uint8_t CFontFallback::getValueAtPt(const uint8_t* char_ptr, unsigned int xf16, unsigned int yf16)
99 {
100         unsigned int ix = xf16 >> 16;
101         unsigned int iy = yf16 >> 16;
102         unsigned int fx = xf16 & 0xFFFF;
103         unsigned int fy = yf16 & 0xFFFF;
104         
105         if( fx == 0 && fy == 0 ) {
106                 return getValueAtRaw(char_ptr, ix, iy);
107         }
108         else if( fx == 0 ) {
109                 float y = (float)fy / 0x10000;
110                 uint8_t v0 = getValueAtRaw(char_ptr, ix, iy  );
111                 uint8_t v1 = getValueAtRaw(char_ptr, ix, iy+1);
112                 return v0 * (1 - y) + v1 * y;
113         }
114         else if( fy == 0 ) {
115                 float x = (float)fx / 0x10000;
116                 uint8_t v0 = getValueAtRaw(char_ptr, ix  , iy);
117                 uint8_t v1 = getValueAtRaw(char_ptr, ix+1, iy);
118                 return v0 * (1 - x) + v1 * x;
119         }
120         else {
121                 float x = (float)fx / 0x10000;
122                 float y = (float)fx / 0x10000;
123                 // [0,0](1 - x)(1 - y) + [1,0]x(1-y) + [0,1](1-x)y + [1,1]xy
124                 uint8_t v00 = getValueAtRaw(char_ptr, ix, iy);
125                 uint8_t v01 = getValueAtRaw(char_ptr, ix, iy+1);
126                 uint8_t v10 = getValueAtRaw(char_ptr, ix+1, iy);
127                 uint8_t v11 = getValueAtRaw(char_ptr, ix+1, iy+1);
128                 //_SysDebug("x,y = %04x %04x", (unsigned)(x * 0x10000), (unsigned)(y * 0x10000));
129                 //_SysDebug("v = %02x %02x %02x %02x", v00, v01, v10, v11);
130                 float val1 = v00 * (1 - x) * (1 - y);
131                 float val2 = v10 * x * (1 - y);
132                 float val3 = v01 * (1 - x) * y;
133                 float val4 = v11 * x * y;
134                 //_SysDebug("vals = %04x %04x %04x %04x",
135                 //      (unsigned)(val1 * 0x10000),
136                 //      (unsigned)(val2 * 0x10000),
137                 //      (unsigned)(val3 * 0x10000),
138                 //      (unsigned)(val4 * 0x10000)
139                 //      );
140                 
141                 return (uint8_t)(val1 + val2 + val3 + val4);
142         }
143 }
144
145 uint8_t CFontFallback::getValueAtRaw(const uint8_t* char_ptr, unsigned int x, unsigned int y)
146 {
147         //if( x == 0 || y == 0 )
148         //      return 0;
149         //x --; y --;
150         if(x >= FONT_WIDTH || y >= FONT_HEIGHT)
151                 return 0;
152         return (char_ptr[y] & (1 << (7-x))) ? 255 : 0;
153 }
154
155 unsigned int CFontFallback::unicodeToCharmap(uint32_t cp) const
156 {
157         if(cp >= ' ' && cp < 0x7F)
158                 return cp;
159         switch(cp)
160         {
161         default:
162                 return 0;
163         }
164 }
165
166 };      // namespace AxWin
167

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