2022-03-28 16:54:03 +01:00
|
|
|
#include "hershey_fonts.hpp"
|
2022-03-31 16:13:28 +01:00
|
|
|
#include "common/unicode_sorta.hpp"
|
2022-03-28 16:54:03 +01:00
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
namespace hershey {
|
|
|
|
std::map<std::string, const font_t*> fonts = {
|
|
|
|
{ "sans", &futural },
|
|
|
|
//{ "sans_bold", &futuram },
|
|
|
|
{ "gothic", &gothgbt },
|
|
|
|
//{ "cursive_bold", &scriptc },
|
|
|
|
{ "cursive", &scripts },
|
|
|
|
{ "serif_italic", ×i },
|
|
|
|
{ "serif", ×r },
|
|
|
|
//{ "serif_bold", ×rb }
|
|
|
|
};
|
|
|
|
|
|
|
|
inline float deg2rad(float degrees) {
|
|
|
|
return (degrees * M_PI) / 180.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
const font_glyph_t* glyph_data(const font_t* font, unsigned char c) {
|
2022-03-31 16:13:28 +01:00
|
|
|
if(c < 32 || c > 127 + 64) { // + 64 char remappings defined in unicode_sorta.hpp
|
2022-03-28 16:54:03 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-03-31 16:13:28 +01:00
|
|
|
if(c > 127) {
|
2022-04-01 15:21:08 +01:00
|
|
|
c = unicode_sorta::char_base_195[c - 128];
|
2022-03-31 16:13:28 +01:00
|
|
|
}
|
|
|
|
|
2022-03-28 16:54:03 +01:00
|
|
|
return &font->chars[c - 32];
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t measure_glyph(const font_t* font, unsigned char c, float s) {
|
|
|
|
const font_glyph_t *gd = glyph_data(font, c);
|
|
|
|
|
|
|
|
// if glyph data not found (id too great) then skip
|
|
|
|
if(!gd) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gd->width * s;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t measure_text(const font_t* font, std::string message, float s) {
|
|
|
|
int32_t width = 0;
|
|
|
|
for(auto &c : message) {
|
|
|
|
width += measure_glyph(font, c, s);
|
|
|
|
}
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t glyph(const font_t* font, line_func line, unsigned char c, int32_t x, int32_t y, float s, float a) {
|
|
|
|
const font_glyph_t *gd = glyph_data(font, c);
|
|
|
|
|
|
|
|
// if glyph data not found (id too great) then skip
|
|
|
|
if(!gd) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
a = deg2rad(a);
|
|
|
|
float as = sin(a);
|
|
|
|
float ac = cos(a);
|
|
|
|
|
|
|
|
const int8_t *pv = gd->vertices;
|
|
|
|
int8_t cx = (*pv++) * s;
|
|
|
|
int8_t cy = (*pv++) * s;
|
|
|
|
bool pen_down = true;
|
|
|
|
|
|
|
|
for(uint32_t i = 1; i < gd->vertex_count; i++) {
|
|
|
|
if(pv[0] == -128 && pv[1] == -128) {
|
|
|
|
pen_down = false;
|
|
|
|
pv += 2;
|
|
|
|
}else{
|
|
|
|
int8_t nx = (*pv++) * s;
|
|
|
|
int8_t ny = (*pv++) * s;
|
|
|
|
|
|
|
|
int rcx = (cx * ac - cy * as) + 0.5f;
|
|
|
|
int rcy = (cx * as + cy * ac) + 0.5f;
|
|
|
|
|
|
|
|
int rnx = (nx * ac - ny * as) + 0.5f;
|
|
|
|
int rny = (nx * as + ny * ac) + 0.5f;
|
|
|
|
|
|
|
|
if(pen_down) {
|
|
|
|
line(rcx + x, rcy + y, rnx + x, rny + y);
|
|
|
|
}
|
|
|
|
|
|
|
|
cx = nx;
|
|
|
|
cy = ny;
|
|
|
|
pen_down = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return gd->width * s;
|
|
|
|
}
|
|
|
|
|
|
|
|
void text(const font_t* font, line_func line, std::string message, int32_t x, int32_t y, float s, float a) {
|
|
|
|
int32_t cx = x;
|
|
|
|
int32_t cy = y;
|
|
|
|
|
|
|
|
int32_t ox = 0;
|
|
|
|
|
|
|
|
float as = sin(deg2rad(a));
|
|
|
|
float ac = cos(deg2rad(a));
|
|
|
|
|
|
|
|
for(auto &c : message) {
|
|
|
|
int rcx = (ox * ac) + 0.5f;
|
|
|
|
int rcy = (ox * as) + 0.5f;
|
|
|
|
|
|
|
|
ox += glyph(font, line, c, cx + rcx, cy + rcy, s, a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|