3 * - By John Hodge (thePowersGang)
8 * Handles font selection and drawing of text to windows
10 #include <draw_text.hpp>
11 #include <axwin4/definitions.h>
12 #include <unicode.h> // libunicode (acess)
14 #include <assert.h> // assert... and _SysDebug
16 #include "resources/font_8x16.h"
21 // -- Primitive fallback font
22 CFontFallback::CFontFallback()
26 CRect CFontFallback::Size(const ::std::string& text, unsigned int Size) const
28 return CRect(0,0, text.size() * Size * FONT_WIDTH / FONT_HEIGHT, Size);
32 * \param Text height in pixels (not in points)
34 void CFontFallback::Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size)
36 unsigned int font_step = Size * FONT_WIDTH / FONT_HEIGHT;
38 for( auto codepoint : ::libunicode::utf8string(text) )
40 renderAtRes(dest, pos, codepoint, Size, 0x000000);
41 pos.Translate(font_step, 0);
45 void CFontFallback::renderAtRes(CSurface& dest, const CRect& rect, uint32_t cp, unsigned int Size, uint32_t FGC)
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 ) {
55 for( unsigned int row = 0; row < out_h; row ++ )
57 for( unsigned int col = 0; col < out_w; col ++ )
59 uint8_t alpha = getValueAtRaw(char_ptr, col, row);
60 char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF);
62 dest.BlendScanline(rect.m_y + row, rect.m_x, FONT_WIDTH, char_data);
65 else if( Size < FONT_HEIGHT ) {
70 for( unsigned int row = 0; row < out_h; row ++ )
72 unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h;
73 for( unsigned int col = 0; col < out_w; col ++ )
75 unsigned int xf16 = col * FONT_WIDTH * 0x10000 / out_w;
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);
80 dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data);
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)
87 unsigned int ix = xf16 >> 16;
88 unsigned int iy = yf16 >> 16;
89 unsigned int fx = xf16 & 0xFFFF;
90 unsigned int fy = yf16 & 0xFFFF;
92 if( fx == 0 && fy == 0 ) {
93 return getValueAtRaw(char_ptr, ix, iy);
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;
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;
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)
128 return (uint8_t)(val1 + val2 + val3 + val4);
132 uint8_t CFontFallback::getValueAtRaw(const uint8_t* char_ptr, unsigned int x, unsigned int y)
134 //if( x == 0 || y == 0 )
137 if(x >= FONT_WIDTH || y >= FONT_HEIGHT)
139 return (char_ptr[y] & (1 << (7-x))) ? 255 : 0;
142 unsigned int CFontFallback::unicodeToCharmap(uint32_t cp) const
144 if(cp >= ' ' && cp < 0x7F)
153 }; // namespace AxWin