1 #include "core/instance.hpp"
2 #include "lua/internal.hpp"
3 #include "lua/halo.hpp"
4 #include "lua/bitmap.hpp"
5 #include "fonts/wrapper.hpp"
6 #include "core/framebuffer.hpp"
7 #include "core/instance.hpp"
8 #include "library/framebuffer-font2.hpp"
9 #include "library/utf8.hpp"
10 #include "library/lua-framebuffer.hpp"
11 #include "library/zip.hpp"
20 struct empty_font_tag
{};
21 lua_customfont(lua::state
& L
, const std::string
& filename
, const std::string
& filename2
);
22 lua_customfont(lua::state
& L
);
23 lua_customfont(lua::state
& L
, empty_font_tag tag
);
24 static size_t overcommit() { return 0; }
25 static size_t overcommit(const std::string
& filename
, const std::string
& filename2
) { return 0; }
26 static size_t overcommit(empty_font_tag tag
) { return 0; }
27 ~lua_customfont() throw();
28 static int create(lua::state
& L
, lua::parameters
& P
);
29 static int load(lua::state
& L
, lua::parameters
& P
);
30 int draw(lua::state
& L
, lua::parameters
& P
);
31 int edit(lua::state
& L
, lua::parameters
& P
);
32 const framebuffer::font2
& get_font() { return font
; }
38 std::string orig_filename
;
39 framebuffer::font2 font
;
42 lua::_class
<lua_customfont
> LUA_class_customfont(lua_class_gui
, "CUSTOMFONT", {
43 {"new", lua_customfont::create
},
44 {"load", lua_customfont::load
},
46 {"__call", &lua_customfont::draw
},
47 {"edit", &lua_customfont::edit
},
48 }, &lua_customfont::print
);
50 struct render_object_text_cf
: public framebuffer::object
52 render_object_text_cf(int32_t _x
, int32_t _y
, const std::string
& _text
, framebuffer::color _fg
,
53 framebuffer::color _bg
, framebuffer::color _hl
, lua::objpin
<lua_customfont
>& _font
) throw()
54 : x(_x
), y(_y
), text(_text
), fg(_fg
), bg(_bg
), hl(_hl
), font(_font
) {}
55 ~render_object_text_cf() throw()
58 template<bool X
> void op(struct framebuffer::fb
<X
>& scr
) throw()
60 const framebuffer::font2
& fdata
= font
->get_font();
61 std::u32string _text
= utf8::to32(text
);
63 auto size
= fdata
.get_metrics(_text
, x
);
64 //Enlarge size by 2 in each dimension, in order to accomodiate halo, if any.
65 //Round up width to multiple of 32.
66 size
.first
= (size
.first
+ 33) >> 5 << 5;
68 size_t allocsize
= size
.first
* size
.second
+ 32;
70 if(allocsize
> 32768) {
71 std::vector
<uint8_t> memory
;
72 memory
.resize(allocsize
);
73 op_with(scr
, &memory
[0], size
, _text
, fdata
);
75 uint8_t memory
[allocsize
];
76 op_with(scr
, memory
, size
, _text
, fdata
);
79 template<bool X
> void op_with(struct framebuffer::fb
<X
>& scr
, unsigned char* mem
,
80 std::pair
<size_t, size_t> size
, const std::u32string
& _text
, const framebuffer::font2
& fdata
)
83 memset(mem
, 0, size
.first
* size
.second
);
84 int32_t rx
= x
+ scr
.get_origin_x();
85 int32_t ry
= y
+ scr
.get_origin_y();
86 fdata
.for_each_glyph(_text
, x
, [mem
, size
](uint32_t x
, uint32_t y
,
87 const framebuffer::font2::glyph
& glyph
) {
90 glyph
.render(mem
+ (y
* size
.first
+ x
), size
.first
, 0, 0, glyph
.width
, glyph
.height
);
92 halo_blit(scr
, mem
, size
.first
, size
.second
, rx
, ry
, bg
, fg
, hl
);
94 bool kill_request(void* obj
) throw()
96 return kill_request_ifeq(font
.object(), obj
);
98 void operator()(struct framebuffer::fb
<true>& scr
) throw() { op(scr
); }
99 void operator()(struct framebuffer::fb
<false>& scr
) throw() { op(scr
); }
100 void clone(framebuffer::queue
& q
) const throw(std::bad_alloc
) { q
.clone_helper(this); }
105 framebuffer::color fg
;
106 framebuffer::color bg
;
107 framebuffer::color hl
;
108 lua::objpin
<lua_customfont
> font
;
111 lua_customfont::lua_customfont(lua::state
& L
, const std::string
& filename
, const std::string
& filename2
)
112 : orig_filename(zip::resolverel(filename
, filename2
)), font(orig_filename
)
116 lua_customfont::lua_customfont(lua::state
& L
)
119 orig_filename
= "<builtin>";
122 lua_customfont::~lua_customfont() throw()
124 CORE().fbuf
->render_kill_request(this);
127 int lua_customfont::draw(lua::state
& L
, lua::parameters
& P
)
131 framebuffer::color fg
, bg
, hl
;
133 lua::objpin
<lua_customfont
> f
;
135 if(!core
.lua2
->render_ctx
)
138 P(f
, _x
, _y
, text
, P
.optional(fg
, 0xFFFFFFU
), P
.optional(bg
, -1), P
.optional(hl
, -1));
140 core
.lua2
->render_ctx
->queue
->create_add
<render_object_text_cf
>(_x
, _y
, text
, fg
, bg
, hl
, f
);
144 lua_customfont::lua_customfont(lua::state
& L
, lua_customfont::empty_font_tag tag
)
146 orig_filename
= "<empty>";
149 int lua_customfont::edit(lua::state
& L
, lua::parameters
& P
)
154 P(P
.skipped(), text
, _glyph
);
156 framebuffer::font2::glyph glyph
;
157 glyph
.width
= _glyph
->width
;
158 glyph
.height
= _glyph
->height
;
159 glyph
.stride
= (glyph
.width
+ 31) / 32;
160 glyph
.fglyph
.resize(glyph
.stride
* glyph
.height
);
161 memset(&glyph
.fglyph
[0], 0, sizeof(uint32_t) * glyph
.fglyph
.size());
162 for(size_t y
= 0; y
< glyph
.height
; y
++) {
163 size_t bpos
= y
* glyph
.stride
* 32;
164 for(size_t x
= 0; x
< glyph
.width
; x
++) {
165 size_t e
= (bpos
+ x
) / 32;
166 size_t b
= 31 - (bpos
+ x
) % 32;
167 if(_glyph
->pixels
[y
* _glyph
->width
+ x
])
168 glyph
.fglyph
[e
] |= (1UL << b
);
171 font
.add(utf8::to32(text
), glyph
);
175 int lua_customfont::create(lua::state
& L
, lua::parameters
& P
)
177 lua::_class
<lua_customfont
>::create(L
, lua_customfont::empty_font_tag());
181 int lua_customfont::load(lua::state
& L
, lua::parameters
& P
)
183 std::string filename
, filename2
;
185 lua::_class
<lua_customfont
>::create(L
);
189 P(filename
, P
.optional(filename2
, ""));
191 lua::_class
<lua_customfont
>::create(L
, filename
, filename2
);