Fixes glyph-size calculation.
This commit is contained in:
parent
59d84172c5
commit
7b5bc58246
64
src/Font.cc
64
src/Font.cc
@ -1,4 +1,62 @@
|
|||||||
/* Because an implementation of stb_truetype is huge, compiles it separately. */
|
|
||||||
|
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
#include "Font.h"
|
#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);
|
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;
|
Colorbuffer RenderGlyphs(const std::wstring& str, uint32_t fontsize = 32);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
iAllocator* alloc_;
|
iAllocator* alloc_;
|
||||||
|
@ -41,7 +41,6 @@ public:
|
|||||||
const double c = std::cos(rota);
|
const double c = std::cos(rota);
|
||||||
const double s = std::sin(rota);
|
const double s = std::sin(rota);
|
||||||
|
|
||||||
const double aspect = frame.w*1./frame.h;
|
|
||||||
auto Ms = mat3{
|
auto Ms = mat3{
|
||||||
{ scaleX, 0, 0 },
|
{ scaleX, 0, 0 },
|
||||||
{ 0, scaleY, 0 },
|
{ 0, scaleY, 0 },
|
||||||
@ -52,17 +51,11 @@ public:
|
|||||||
{ s, c, 0, },
|
{ s, c, 0, },
|
||||||
{ 0, 0, 1, },
|
{ 0, 0, 1, },
|
||||||
};
|
};
|
||||||
auto Mm = mat3{
|
auto M = mat3{
|
||||||
{ 1, 0, 0 },
|
{ 1, 0, 0 },
|
||||||
{ 0, 1, 0 },
|
{ 0, 1, 0 },
|
||||||
{ posX, posY, 1},
|
{ 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, Mr);
|
||||||
M = ::linalg::mul(M, Ms);
|
M = ::linalg::mul(M, Ms);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user