Merge branch 'rr1-maint'
Conflicts: manual.lyx manual.txt
This commit is contained in:
commit
531c0d0635
6 changed files with 491 additions and 0 deletions
BIN
data/verysmall.font
Normal file
BIN
data/verysmall.font
Normal file
Binary file not shown.
56
include/library/customfont.hpp
Normal file
56
include/library/customfont.hpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef _customfont__hpp__included__
|
||||||
|
#define _customfont__hpp__included__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <map>
|
||||||
|
#include "framebuffer.hpp"
|
||||||
|
|
||||||
|
class ligature_key
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ligature_key(const std::vector<uint32_t>& key) throw(std::bad_alloc);
|
||||||
|
const std::vector<uint32_t>& get() const throw() { return ikey; }
|
||||||
|
size_t length() const throw() { return ikey.size(); }
|
||||||
|
bool operator<(const ligature_key& key) const throw();
|
||||||
|
bool operator<=(const ligature_key& key) const throw() { return !(key < *this); }
|
||||||
|
bool operator==(const ligature_key& key) const throw();
|
||||||
|
bool operator!=(const ligature_key& key) const throw() { return !(key == *this); }
|
||||||
|
bool operator>=(const ligature_key& key) const throw() { return !(*this < key); }
|
||||||
|
bool operator>(const ligature_key& key) const throw() { return key < *this; }
|
||||||
|
private:
|
||||||
|
std::vector<uint32_t> ikey;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct font_glyph_data
|
||||||
|
{
|
||||||
|
font_glyph_data();
|
||||||
|
font_glyph_data(std::istream& s);
|
||||||
|
unsigned width;
|
||||||
|
unsigned height;
|
||||||
|
unsigned stride;
|
||||||
|
std::vector<uint32_t> glyph; //Bitpacked, element breaks between rows.
|
||||||
|
void render(framebuffer<false>& fb, int32_t x, int32_t y, premultiplied_color fg, premultiplied_color bg)
|
||||||
|
const;
|
||||||
|
void render(framebuffer<true>& fb, int32_t x, int32_t y, premultiplied_color fg, premultiplied_color bg) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct custom_font
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
custom_font();
|
||||||
|
custom_font(const std::string& file);
|
||||||
|
void add(const ligature_key& key, const font_glyph_data& glyph) throw(std::bad_alloc);
|
||||||
|
ligature_key best_ligature_match(const std::vector<uint32_t>& codepoints, size_t start) const
|
||||||
|
throw(std::bad_alloc);
|
||||||
|
const font_glyph_data& lookup_glyph(const ligature_key& key) const throw();
|
||||||
|
unsigned get_rowadvance() const throw() { return rowadvance; }
|
||||||
|
private:
|
||||||
|
std::map<ligature_key, font_glyph_data> glyphs;
|
||||||
|
unsigned rowadvance;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
17
manual.lyx
17
manual.lyx
|
@ -2099,6 +2099,23 @@ Run specified render queue, copying the objects to current render queue.
|
||||||
Warning: Don't try to run the current render queue.
|
Warning: Don't try to run the current render queue.
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Subsubsection
|
||||||
|
gui.loadfont(string filename)
|
||||||
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Standard
|
||||||
|
Loads font from specified file (CUSTOMFONT object).
|
||||||
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Subsubsection
|
||||||
|
CUSTOMFONT(number x, number y, string text[, number fgc[, number bgc]])
|
||||||
|
\end_layout
|
||||||
|
|
||||||
|
\begin_layout Standard
|
||||||
|
Draw string with custom font to screen.
|
||||||
|
The parameters are the same as in gui.text.
|
||||||
|
\end_layout
|
||||||
|
|
||||||
\begin_layout Subsection
|
\begin_layout Subsection
|
||||||
table input
|
table input
|
||||||
\end_layout
|
\end_layout
|
||||||
|
|
10
manual.txt
10
manual.txt
|
@ -1051,6 +1051,16 @@ queue.
|
||||||
|
|
||||||
• Warning: Don't try to run the current render queue.
|
• Warning: Don't try to run the current render queue.
|
||||||
|
|
||||||
|
8.3.33 gui.loadfont(string filename)
|
||||||
|
|
||||||
|
Loads font from specified file (CUSTOMFONT object).
|
||||||
|
|
||||||
|
8.3.34 CUSTOMFONT(number x, number y, string text[, number fgc[,
|
||||||
|
number bgc]])
|
||||||
|
|
||||||
|
Draw string with custom font to screen. The parameters are the
|
||||||
|
same as in gui.text.
|
||||||
|
|
||||||
8.4 table input
|
8.4 table input
|
||||||
|
|
||||||
Input handling. Only available in on_input callback.
|
Input handling. Only available in on_input callback.
|
||||||
|
|
278
src/library/customfont.cpp
Normal file
278
src/library/customfont.cpp
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
#include "customfont.hpp"
|
||||||
|
#include "serialization.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#include "zip.hpp"
|
||||||
|
#include "string.hpp"
|
||||||
|
|
||||||
|
ligature_key::ligature_key(const std::vector<uint32_t>& key) throw(std::bad_alloc)
|
||||||
|
{
|
||||||
|
ikey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ligature_key::operator<(const ligature_key& key) const throw()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < ikey.size() && i < key.ikey.size(); i++)
|
||||||
|
if(ikey[i] < key.ikey[i])
|
||||||
|
return true;
|
||||||
|
else if(ikey[i] > key.ikey[i])
|
||||||
|
return false;
|
||||||
|
return (ikey.size() < key.ikey.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ligature_key::operator==(const ligature_key& key) const throw()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < ikey.size() && i < key.ikey.size(); i++)
|
||||||
|
if(ikey[i] != key.ikey[i])
|
||||||
|
return false;
|
||||||
|
return (ikey.size() == key.ikey.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void bound(int32_t c, uint32_t odim, uint32_t dim, uint32_t& dc, uint32_t& off, uint32_t& size)
|
||||||
|
{
|
||||||
|
if(c >= dim || c + odim <= 0) {
|
||||||
|
//Outside the screen.
|
||||||
|
dc = 0;
|
||||||
|
off = 0;
|
||||||
|
size = 0;
|
||||||
|
} else if(c >= 0) {
|
||||||
|
dc = c;
|
||||||
|
off = 0;
|
||||||
|
size = odim;
|
||||||
|
} else {
|
||||||
|
dc = 0;
|
||||||
|
off = -c;
|
||||||
|
size = odim + c;
|
||||||
|
}
|
||||||
|
if(dc + size > dim)
|
||||||
|
size = dim - dc;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool T> void _render(const font_glyph_data& glyph, framebuffer<T>& fb, int32_t x, int32_t y,
|
||||||
|
premultiplied_color fg, premultiplied_color bg)
|
||||||
|
{
|
||||||
|
uint32_t xdc, xoff, xsize;
|
||||||
|
uint32_t ydc, yoff, ysize;
|
||||||
|
bound(x, glyph.width, fb.get_width(), xdc, xoff, xsize);
|
||||||
|
bound(y, glyph.height, fb.get_height(), ydc, yoff, ysize);
|
||||||
|
if(!xsize || !ysize)
|
||||||
|
return;
|
||||||
|
for(unsigned i = 0; i < ysize; i++) {
|
||||||
|
auto p = fb.rowptr(i + ydc);
|
||||||
|
for(unsigned j = 0; j < xsize; j++) {
|
||||||
|
size_t ge = (i + yoff) * glyph.stride + ((j + xoff) / 32);
|
||||||
|
size_t gb = 31 - (j + xoff) % 32;
|
||||||
|
if((glyph.glyph[ge] >> gb) & 1)
|
||||||
|
fg.apply(p[j + xdc]);
|
||||||
|
else
|
||||||
|
bg.apply(p[j + xdc]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
font_glyph_data::font_glyph_data()
|
||||||
|
{
|
||||||
|
stride = width = height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_glyph_data::font_glyph_data(std::istream& s)
|
||||||
|
{
|
||||||
|
char header[40];
|
||||||
|
bool old = true;
|
||||||
|
bool upside_down = true;
|
||||||
|
size_t rcount = 26;
|
||||||
|
s.read(header, 26);
|
||||||
|
if(!s)
|
||||||
|
throw std::runtime_error("Can't read glyph bitmap header");
|
||||||
|
if(read16ule(header + 0) != 0x4D42)
|
||||||
|
throw std::runtime_error("Bad glyph BMP magic");
|
||||||
|
if(read16ule(header + 14) != 12) {
|
||||||
|
//Not OS/2 format.
|
||||||
|
old = false;
|
||||||
|
rcount = 40;
|
||||||
|
s.read(header + 26, 14);
|
||||||
|
if(!s)
|
||||||
|
throw std::runtime_error("Can't read glyph bitmap header");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t startoff = read32ule(header + 10);
|
||||||
|
if(old) {
|
||||||
|
width = read16ule(header + 18);
|
||||||
|
height = read16ule(header + 20);
|
||||||
|
if(read16ule(header + 22) != 1)
|
||||||
|
throw std::runtime_error("Bad glyph BMP planecount");
|
||||||
|
if(read16ule(header + 24) != 1)
|
||||||
|
throw std::runtime_error("Bad glyph BMP bitdepth");
|
||||||
|
if(startoff < 26)
|
||||||
|
throw std::runtime_error("Glyph BMP data can't overlap header");
|
||||||
|
} else {
|
||||||
|
long _width = read32sle(header + 18);
|
||||||
|
long _height = read32sle(header + 22);
|
||||||
|
if(_width < 0)
|
||||||
|
throw std::runtime_error("Bad glyph BMP size");
|
||||||
|
if(_height < 0)
|
||||||
|
upside_down = false;
|
||||||
|
width = _width;
|
||||||
|
height = (_height >= 0) ? height : -height;
|
||||||
|
|
||||||
|
if(read16ule(header + 26) != 1)
|
||||||
|
throw std::runtime_error("Bad glyph BMP planecount");
|
||||||
|
if(read16ule(header + 28) != 1)
|
||||||
|
throw std::runtime_error("Bad glyph BMP bitdepth");
|
||||||
|
if(read32ule(header + 30) != 0)
|
||||||
|
throw std::runtime_error("Bad glyph BMP compression method");
|
||||||
|
if(startoff < 40)
|
||||||
|
throw std::runtime_error("Glyph BMP data can't overlap header");
|
||||||
|
}
|
||||||
|
//Discard data until start of bitmap.
|
||||||
|
while(rcount < startoff) {
|
||||||
|
s.get();
|
||||||
|
if(!s)
|
||||||
|
throw std::runtime_error("EOF while skipping to BMP data");
|
||||||
|
rcount++;
|
||||||
|
}
|
||||||
|
stride = (width + 31) / 32;
|
||||||
|
glyph.resize(stride * height);
|
||||||
|
memset(&glyph[0], 0, sizeof(uint32_t) * glyph.size());
|
||||||
|
size_t toskip = (4 - ((width + 7) / 8) % 4) % 4;
|
||||||
|
for(size_t i = 0; i < height; i++) {
|
||||||
|
size_t y = upside_down ? (height - i - 1) : i;
|
||||||
|
size_t bpos = y * stride * 32;
|
||||||
|
for(size_t j = 0; j < width; j += 8) {
|
||||||
|
size_t e = (bpos + j) / 32;
|
||||||
|
size_t b = (bpos + j) % 32;
|
||||||
|
int c = s.get();
|
||||||
|
if(!s)
|
||||||
|
throw std::runtime_error("EOF while reading BMP data");
|
||||||
|
glyph[e] |= ((uint32_t)c << (24 - b));
|
||||||
|
}
|
||||||
|
for(size_t j = 0; j < toskip; j++) {
|
||||||
|
s.get();
|
||||||
|
if(!s)
|
||||||
|
throw std::runtime_error("EOF while reading BMP data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_glyph_data::render(framebuffer<false>& fb, int32_t x, int32_t y, premultiplied_color fg,
|
||||||
|
premultiplied_color bg) const
|
||||||
|
{
|
||||||
|
_render(*this, fb, x, y, fg, bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_glyph_data::render(framebuffer<true>& fb, int32_t x, int32_t y, premultiplied_color fg,
|
||||||
|
premultiplied_color bg) const
|
||||||
|
{
|
||||||
|
_render(*this, fb, x, y, fg, bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
custom_font::custom_font()
|
||||||
|
{
|
||||||
|
rowadvance = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_font::custom_font(const std::string& file)
|
||||||
|
{
|
||||||
|
std::istream* toclose = NULL;
|
||||||
|
rowadvance = 0;
|
||||||
|
try {
|
||||||
|
zip_reader r(file);
|
||||||
|
for(auto member : r) {
|
||||||
|
//Parse the key out of filename.
|
||||||
|
std::vector<uint32_t> k;
|
||||||
|
std::string tname = member;
|
||||||
|
std::string tmp;
|
||||||
|
if(tname == "bad") {
|
||||||
|
//Special, no key.
|
||||||
|
} else if(regex_match("[0-9]+(-[0-9]+)*", tname))
|
||||||
|
while(tname != "") {
|
||||||
|
extract_token(tname, tmp, "-");
|
||||||
|
k.push_back(parse_value<uint32_t>(tmp));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete toclose;
|
||||||
|
toclose = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ligature_key key(k);
|
||||||
|
std::istream& s = r[member];
|
||||||
|
toclose = &s;
|
||||||
|
try {
|
||||||
|
add(key, font_glyph_data(s));
|
||||||
|
} catch(std::bad_alloc& e) {
|
||||||
|
throw;
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
throw std::runtime_error(tname + std::string(": ") + e.what());
|
||||||
|
}
|
||||||
|
delete toclose;
|
||||||
|
toclose = NULL;
|
||||||
|
}
|
||||||
|
} catch(std::bad_alloc& e) {
|
||||||
|
if(toclose)
|
||||||
|
delete toclose;
|
||||||
|
throw;
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
if(toclose)
|
||||||
|
delete toclose;
|
||||||
|
throw std::runtime_error(std::string("Error reading font: ") + e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const ligature_key& lkey)
|
||||||
|
{
|
||||||
|
if(!lkey.length())
|
||||||
|
return (os << "bad");
|
||||||
|
for(size_t i = 0; i < lkey.length(); i++) {
|
||||||
|
if(i)
|
||||||
|
os << "-";
|
||||||
|
os << lkey.get()[i];
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
void custom_font::add(const ligature_key& key, const font_glyph_data& glyph) throw(std::bad_alloc)
|
||||||
|
{
|
||||||
|
glyphs[key] = glyph;
|
||||||
|
if(glyph.height > rowadvance)
|
||||||
|
rowadvance = glyph.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
ligature_key custom_font::best_ligature_match(const std::vector<uint32_t>& codepoints, size_t start) const
|
||||||
|
throw(std::bad_alloc)
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> tmp;
|
||||||
|
if(start >= codepoints.size())
|
||||||
|
return ligature_key(tmp); //Bad.
|
||||||
|
ligature_key best(tmp);
|
||||||
|
for(size_t i = 1; i <= codepoints.size() - start; i++) {
|
||||||
|
tmp.push_back(codepoints[start + i - 1]);
|
||||||
|
ligature_key lkey(tmp);
|
||||||
|
if(glyphs.count(lkey))
|
||||||
|
best = lkey;
|
||||||
|
auto j = glyphs.lower_bound(lkey);
|
||||||
|
//If lower_bound is greater than equivalent length of string, there can be no better match.
|
||||||
|
if(j == glyphs.end())
|
||||||
|
break;
|
||||||
|
const std::vector<uint32_t>& tmp2 = j->first.get();
|
||||||
|
bool best_found = false;
|
||||||
|
for(size_t k = 0; k < tmp2.size() && start + k < codepoints.size(); k++)
|
||||||
|
if(tmp2[k] > codepoints[start + k]) {
|
||||||
|
best_found = true;
|
||||||
|
break;
|
||||||
|
} else if(tmp2[k] < codepoints[start + k])
|
||||||
|
break;
|
||||||
|
if(best_found)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
const font_glyph_data& custom_font::lookup_glyph(const ligature_key& key) const throw()
|
||||||
|
{
|
||||||
|
static font_glyph_data empty_glyph;
|
||||||
|
auto i = glyphs.find(key);
|
||||||
|
return (i == glyphs.end()) ? empty_glyph : i->second;
|
||||||
|
}
|
130
src/lua/gui-text-cf.cpp
Normal file
130
src/lua/gui-text-cf.cpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
#include "lua/internal.hpp"
|
||||||
|
#include "fonts/wrapper.hpp"
|
||||||
|
#include "library/framebuffer.hpp"
|
||||||
|
#include "library/customfont.hpp"
|
||||||
|
#include "library/utf8.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct lua_customfont
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lua_customfont(lua_State* LS, const std::string& filename);
|
||||||
|
~lua_customfont() throw();
|
||||||
|
int draw(lua_State* LS);
|
||||||
|
const custom_font& get_font() { return font; }
|
||||||
|
private:
|
||||||
|
custom_font font;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_LUACLASS(lua_customfont, "CUSTOMFONT");
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> decode_utf8(const std::string& t)
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> x;
|
||||||
|
size_t ts = t.length();
|
||||||
|
uint16_t s = utf8_initial_state;
|
||||||
|
for(size_t i = 0; i <= ts; i++) {
|
||||||
|
int ch = (i < ts) ? (int)(unsigned char)t[i] : -1;
|
||||||
|
int32_t cp = utf8_parse_byte(ch, s);
|
||||||
|
if(cp >= 0)
|
||||||
|
x.push_back(cp);
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct render_object_text_cf : public render_object
|
||||||
|
{
|
||||||
|
render_object_text_cf(int32_t _x, int32_t _y, const std::string& _text, premultiplied_color _fg,
|
||||||
|
premultiplied_color _bg, lua_obj_pin<lua_customfont>* _font) throw()
|
||||||
|
: x(_x), y(_y), text(_text), fg(_fg), bg(_bg), font(_font) {}
|
||||||
|
~render_object_text_cf() throw() {}
|
||||||
|
template<bool X> void op(struct framebuffer<X>& scr) throw()
|
||||||
|
{
|
||||||
|
fg.set_palette(scr);
|
||||||
|
bg.set_palette(scr);
|
||||||
|
const custom_font& fdata = font->object()->get_font();
|
||||||
|
std::vector<uint32_t> _text = decode_utf8(text);
|
||||||
|
int32_t orig_x = x;
|
||||||
|
int32_t drawx = x;
|
||||||
|
int32_t drawy = y;
|
||||||
|
for(size_t i = 0; i < _text.size();) {
|
||||||
|
uint32_t cp = _text[i];
|
||||||
|
ligature_key k = fdata.best_ligature_match(_text, i);
|
||||||
|
const font_glyph_data& glyph = fdata.lookup_glyph(k);
|
||||||
|
if(k.length())
|
||||||
|
i += k.length();
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
if(cp == 9) {
|
||||||
|
drawx = (drawx + 64) >> 6 << 6;
|
||||||
|
} else if(cp == 10) {
|
||||||
|
drawx = orig_x;
|
||||||
|
drawy += fdata.get_rowadvance();
|
||||||
|
} else {
|
||||||
|
glyph.render(scr, drawx, drawy, fg, bg);
|
||||||
|
drawx += glyph.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void operator()(struct framebuffer<true>& scr) throw() { op(scr); }
|
||||||
|
void operator()(struct framebuffer<false>& scr) throw() { op(scr); }
|
||||||
|
private:
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
premultiplied_color fg;
|
||||||
|
premultiplied_color bg;
|
||||||
|
std::string text;
|
||||||
|
lua_obj_pin<lua_customfont>* font;
|
||||||
|
};
|
||||||
|
|
||||||
|
lua_customfont::lua_customfont(lua_State* LS, const std::string& filename)
|
||||||
|
: font(filename)
|
||||||
|
{
|
||||||
|
static bool done = false;
|
||||||
|
if(!done) {
|
||||||
|
objclass<lua_customfont>().bind(LS, "__call", &lua_customfont::draw);
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_customfont::~lua_customfont() throw() {}
|
||||||
|
|
||||||
|
int lua_customfont::draw(lua_State* LS)
|
||||||
|
{
|
||||||
|
std::string fname = "CUSTOMFONT::__call";
|
||||||
|
if(!lua_render_ctx)
|
||||||
|
return 0;
|
||||||
|
int64_t fgc = 0xFFFFFFU;
|
||||||
|
int64_t bgc = -1;
|
||||||
|
int32_t _x = get_numeric_argument<int32_t>(LS, 2, fname.c_str());
|
||||||
|
int32_t _y = get_numeric_argument<int32_t>(LS, 3, fname.c_str());
|
||||||
|
get_numeric_argument<int64_t>(LS, 5, fgc, fname.c_str());
|
||||||
|
get_numeric_argument<int64_t>(LS, 6, bgc, fname.c_str());
|
||||||
|
std::string text = get_string_argument(LS, 4, fname.c_str());
|
||||||
|
auto f = lua_class<lua_customfont>::pin(LS, 1, fname.c_str());
|
||||||
|
premultiplied_color fg(fgc);
|
||||||
|
premultiplied_color bg(bgc);
|
||||||
|
lua_render_ctx->queue->create_add<render_object_text_cf>(_x, _y, text, fg, bg, f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function_ptr_luafun gui_text_cf("gui.loadfont", [](lua_State* LS, const std::string& fname) -> int {
|
||||||
|
std::string filename = get_string_argument(LS, 1, fname.c_str());
|
||||||
|
try {
|
||||||
|
lua_customfont* b = lua_class<lua_customfont>::create(LS, LS, filename);
|
||||||
|
return 1;
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
lua_pushstring(LS, e.what());
|
||||||
|
lua_error(LS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue