1 #include "platform/wxwidgets/textrender.hpp"
2 #include "platform/wxwidgets/platform.hpp"
3 #include "fonts/wrapper.hpp"
4 #include "library/utf8.hpp"
5 #include "library/string.hpp"
7 #include <wx/dcclient.h>
10 extern const uint32_t text_framebuffer::element::white
= 0xFFFFFF;
11 extern const uint32_t text_framebuffer::element::black
= 0x000000;
13 text_framebuffer::text_framebuffer()
19 text_framebuffer::text_framebuffer(size_t w
, size_t h
)
26 void text_framebuffer::set_size(size_t w
, size_t h
)
28 if(w
== width
&& h
== height
)
30 std::vector
<element
> newfb
;
32 for(size_t i
= 0; i
< h
&& i
< height
; i
++)
33 for(size_t j
= 0; j
< w
&& j
< width
; j
++)
34 newfb
[i
* w
+ j
] = buffer
[i
* width
+ j
];
40 std::pair
<size_t, size_t> text_framebuffer::get_cell()
42 return std::make_pair(8, 16);
45 std::pair
<size_t, size_t> text_framebuffer::get_pixels()
48 return std::make_pair(x
.first
* width
, x
.second
* height
);
51 void text_framebuffer::render(char* tbuffer
)
53 size_t stride
= 24 * width
;
54 size_t cellstride
= 24;
55 for(size_t y
= 0; y
< height
; y
++) {
57 for(size_t x
= 0; x
< width
; x
++) {
59 break; //No more space in row.
60 char* cellbase
= tbuffer
+ y
* (16 * stride
) + xp
* cellstride
;
61 const element
& e
= buffer
[y
* width
+ x
];
62 const framebuffer::font::glyph
& g
= main_font
.get_glyph(e
.ch
);
63 char bgb
= (e
.bg
>> 16);
64 char bgg
= (e
.bg
>> 8);
65 char bgr
= (e
.bg
>> 0);
66 char fgb
= (e
.fg
>> 16);
67 char fgg
= (e
.fg
>> 8);
68 char fgr
= (e
.fg
>> 0);
70 uint32_t cells
= g
.get_width() / 8;
71 uint32_t drawc
= 8 * std::min(cells
, (uint32_t)((xp
< width
- 1) ? 2 : 1));
72 for(size_t y2
= 0; y2
< g
.get_height(); y2
++) {
73 for(size_t j
= 0; j
< drawc
; j
++) {
74 if(g
.read_pixel(j
, y2
)) {
75 cellbase
[3 * j
+ 0] = fgr
;
76 cellbase
[3 * j
+ 1] = fgg
;
77 cellbase
[3 * j
+ 2] = fgb
;
79 cellbase
[3 * j
+ 0] = bgr
;
80 cellbase
[3 * j
+ 1] = bgg
;
81 cellbase
[3 * j
+ 2] = bgb
;
91 size_t text_framebuffer::text_width(const std::string
& text
)
93 auto x
= main_font
.get_metrics(text
, 0, false, false);
97 size_t text_framebuffer::write(const std::string
& str
, size_t w
, size_t x
, size_t y
, uint32_t fg
, uint32_t bg
)
99 return write(utf8::to32(str
), w
, x
, y
, fg
, bg
);
102 size_t text_framebuffer::write(const std::u32string
& str
, size_t w
, size_t x
, size_t y
, uint32_t fg
, uint32_t bg
)
111 if(x
+ pused
< width
) {
112 element
& e
= buffer
[y
* width
+ x
+ pused
];
121 const framebuffer::font::glyph
& g
= main_font
.get_glyph(u
);
122 if(x
+ pused
< width
) {
123 element
& e
= buffer
[y
* width
+ x
+ pused
];
128 pused
+= g
.get_width() / 8;
132 if(x
+ pused
< width
) {
133 element
& e
= buffer
[y
* width
+ x
+ pused
];
143 text_framebuffer_panel::text_framebuffer_panel(wxWindow
* parent
, size_t w
, size_t h
, wxWindowID id
,
145 : wxPanel(parent
, id
), text_framebuffer(w
, h
)
148 redirect
= _redirect
;
149 auto psize
= get_pixels();
150 size_changed
= false;
152 paint_requested
= false;
153 SetMinSize(wxSize(psize
.first
, psize
.second
));
154 this->Connect(wxEVT_PAINT
, wxPaintEventHandler(text_framebuffer_panel::on_paint
), NULL
, this);
155 this->Connect(wxEVT_ERASE_BACKGROUND
, wxEraseEventHandler(text_framebuffer_panel::on_erase
), NULL
, this);
156 this->Connect(wxEVT_SET_FOCUS
, wxFocusEventHandler(text_framebuffer_panel::on_focus
), NULL
, this);
159 text_framebuffer_panel::~text_framebuffer_panel()
163 void text_framebuffer_panel::set_size(size_t _width
, size_t _height
)
166 text_framebuffer::set_size(_width
, _height
);
167 auto psize
= get_pixels();
168 buffer
.resize(psize
.first
* psize
.second
* 3);
170 SetMinSize(wxSize(psize
.first
, psize
.second
));
176 void text_framebuffer_panel::request_paint()
180 auto psize
= get_pixels();
181 SetMinSize(wxSize(psize
.first
, psize
.second
));
182 size_changed
= false;
183 paint_requested
= true;
185 } else if(!paint_requested
) {
186 paint_requested
= true;
191 void text_framebuffer_panel::on_erase(wxEraseEvent
& e
)
195 void text_framebuffer_panel::on_paint(wxPaintEvent
& e
)
199 auto size
= GetSize();
200 text_framebuffer::set_size((size
.x
+ 7) / 8, (size
.y
+ 15) / 16);
201 auto psize
= get_pixels();
202 buffer
.resize(psize
.first
* psize
.second
* 3);
205 psize
= get_pixels();
208 wxBitmap
bmp1(wxImage(psize
.first
, psize
.second
, reinterpret_cast<unsigned char*>(&buffer
[0]),
210 dc
.DrawBitmap(bmp1
, 0, 0, false);
211 paint_requested
= false;
214 void text_framebuffer_panel::on_focus(wxFocusEvent
& e
)
218 redirect
->SetFocus();