Fixes glyph-size calculation.
This commit is contained in:
parent
59d84172c5
commit
7b5bc58246
62
src/Font.cc
62
src/Font.cc
@ -1,4 +1,62 @@
|
||||
/* Because an implementation of stb_truetype is huge, compiles it separately. */
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "Font.h"
|
||||
|
||||
gj::Colorbuffer gj::Font::RenderGlyphs(const std::wstring& str, uint32_t fontsize) {
|
||||
const float s = stbtt_ScaleForPixelHeight(&stb_, fontsize * 1.f);
|
||||
|
||||
int ascent;
|
||||
stbtt_GetFontVMetrics(&stb_, &ascent, 0, 0);
|
||||
|
||||
const int baseline = static_cast<int>(ascent * s);
|
||||
|
||||
/* calculate bitmap size */
|
||||
float h = 0, w = 2;
|
||||
for (auto c : str) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&stb_, c, &advance, &lsb);
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
const float x_shift = w - (int)w;
|
||||
stbtt_GetCodepointBitmapBoxSubpixel(&stb_, c, s, s, x_shift, 0, &x0, &y0, &x1, &y1);
|
||||
|
||||
const int ch = baseline + y1;
|
||||
if (h < ch) h = static_cast<float>(ch);
|
||||
|
||||
w += advance * s;
|
||||
}
|
||||
w += 1;
|
||||
h += 1;
|
||||
|
||||
Colorbuffer buf(alloc_, static_cast<uint32_t>(w), static_cast<uint32_t>(h));
|
||||
buf.Clear();
|
||||
|
||||
float* dst = buf.ptr();
|
||||
|
||||
float x = 2;
|
||||
for (auto c : str) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&stb_, c, &advance, &lsb);
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
const float x_shift = x - (int)x;
|
||||
stbtt_GetCodepointBitmapBoxSubpixel(&stb_, c, s, s, x_shift, 0, &x0, &y0, &x1, &y1);
|
||||
if (x1 - x0 > 64 || y1 - y0 > 64) {
|
||||
gj::Abort("font size is too huge");
|
||||
}
|
||||
|
||||
uint8_t ptr[64][64] = { 0 };
|
||||
stbtt_MakeCodepointBitmapSubpixel(&stb_, &ptr[0][0], x1 - x0, y1 - y0, 64, s, s, x_shift, 0, c);
|
||||
|
||||
const int l = static_cast<int>(x) + x0;
|
||||
const int r = static_cast<int>(x) + x1;
|
||||
const int u = baseline + y0;
|
||||
const int b = baseline + y1;
|
||||
for (int y = 0; y < b - u; ++y) {
|
||||
for (int x = 0; x < r - l; ++x) {
|
||||
dst[(u + y) * static_cast<int>(w) + l + x] = static_cast<float>(ptr[y][x] * 1. / UINT8_MAX);
|
||||
}
|
||||
}
|
||||
x += advance * s;
|
||||
}
|
||||
return std::move(buf);
|
||||
}
|
57
src/Font.h
57
src/Font.h
@ -60,63 +60,8 @@ namespace gj {
|
||||
}
|
||||
return std::move(ret);
|
||||
}
|
||||
Colorbuffer RenderGlyphs(const std::wstring& str, uint32_t fontsize = 32) {
|
||||
const float s = stbtt_ScaleForPixelHeight(&stb_, fontsize * 1.f);
|
||||
|
||||
int ascent;
|
||||
stbtt_GetFontVMetrics(&stb_, &ascent, 0, 0);
|
||||
|
||||
const int baseline = static_cast<int>(ascent * s);
|
||||
|
||||
/* calculate bitmap size */
|
||||
float h = 0, w = 2;
|
||||
for (auto c : str) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&stb_, c, &advance, &lsb);
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
const float x_shift = w - (int) w;
|
||||
stbtt_GetCodepointBitmapBoxSubpixel(&stb_, c, s, s, x_shift, 0, &x0, &y0, &x1, &y1);
|
||||
|
||||
const int ch = baseline+1;
|
||||
if (h < ch) h = static_cast<float>(ch);
|
||||
|
||||
w += advance * s;
|
||||
}
|
||||
|
||||
Colorbuffer buf(alloc_, static_cast<uint32_t>(w), static_cast<uint32_t>(h));
|
||||
buf.Clear();
|
||||
|
||||
float* dst = buf.ptr();
|
||||
|
||||
float x = 2;
|
||||
for (auto c : str) {
|
||||
int advance, lsb;
|
||||
stbtt_GetCodepointHMetrics(&stb_, c, &advance, &lsb);
|
||||
|
||||
int x0, y0, x1, y1;
|
||||
const float x_shift = x - (int)x;
|
||||
stbtt_GetCodepointBitmapBoxSubpixel(&stb_, c, s, s, x_shift, 0, &x0, &y0, &x1, &y1);
|
||||
if (x1 - x0 > 64 || y1 - y0 > 64) {
|
||||
gj::Abort("font size is too huge");
|
||||
}
|
||||
|
||||
uint8_t ptr[64][64] = {0};
|
||||
stbtt_MakeCodepointBitmapSubpixel(&stb_, &ptr[0][0], x1-x0, y1-y0, 64, s, s, x_shift, 0, c);
|
||||
|
||||
const int l = static_cast<int>(x) + x0;
|
||||
const int r = static_cast<int>(x) + x1;
|
||||
const int u = baseline + y0;
|
||||
const int b = baseline + y1;
|
||||
for (int y = 0; y < b-u; ++y) {
|
||||
for (int x = 0; x < r-l; ++x) {
|
||||
dst[(u+y)*static_cast<int>(w) + l+x] = static_cast<float>(ptr[y][x]*1. / UINT8_MAX);
|
||||
}
|
||||
}
|
||||
x += advance * s;
|
||||
}
|
||||
return std::move(buf);
|
||||
}
|
||||
Colorbuffer RenderGlyphs(const std::wstring& str, uint32_t fontsize = 32);
|
||||
|
||||
private:
|
||||
iAllocator* alloc_;
|
||||
|
@ -41,7 +41,6 @@ public:
|
||||
const double c = std::cos(rota);
|
||||
const double s = std::sin(rota);
|
||||
|
||||
const double aspect = frame.w*1./frame.h;
|
||||
auto Ms = mat3{
|
||||
{ scaleX, 0, 0 },
|
||||
{ 0, scaleY, 0 },
|
||||
@ -52,17 +51,11 @@ public:
|
||||
{ s, c, 0, },
|
||||
{ 0, 0, 1, },
|
||||
};
|
||||
auto Mm = mat3{
|
||||
auto M = mat3{
|
||||
{ 1, 0, 0 },
|
||||
{ 0, 1, 0 },
|
||||
{ posX, posY, 1},
|
||||
};
|
||||
auto M = mat3{
|
||||
{ 1, 0, 0 },
|
||||
{ 0, aspect/2, 0 },
|
||||
{ 0, 0, 1},
|
||||
};
|
||||
M = ::linalg::mul(M, Mm);
|
||||
M = ::linalg::mul(M, Mr);
|
||||
M = ::linalg::mul(M, Ms);
|
||||
|
||||
|
Reference in New Issue
Block a user