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 ) {
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 ++ )
70 unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h;
71 for( unsigned int col = 0; col < out_w; col ++ )
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);
78 dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data);
83 for( unsigned int row = 0; row < out_h; row ++ )
85 unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h;
86 for( unsigned int col = 0; col < out_w; col ++ )
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);
93 dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data);
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)
100 unsigned int ix = xf16 >> 16;
101 unsigned int iy = yf16 >> 16;
102 unsigned int fx = xf16 & 0xFFFF;
103 unsigned int fy = yf16 & 0xFFFF;
105 if( fx == 0 && fy == 0 ) {
106 return getValueAtRaw(char_ptr, ix, iy);
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;
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;
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)
141 return (uint8_t)(val1 + val2 + val3 + val4);
145 uint8_t CFontFallback::getValueAtRaw(const uint8_t* char_ptr, unsigned int x, unsigned int y)
147 //if( x == 0 || y == 0 )
150 if(x >= FONT_WIDTH || y >= FONT_HEIGHT)
152 return (char_ptr[y] & (1 << (7-x))) ? 255 : 0;
155 unsigned int CFontFallback::unicodeToCharmap(uint32_t cp) const
157 if(cp >= ' ' && cp < 0x7F)
166 }; // namespace AxWin