fuck it close enough

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-10-07 04:45:41 +03:00
parent 64979c6e5c
commit 2b8bc31fc7

View File

@@ -6,6 +6,7 @@
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <limits>
#include <mutex>
#include <optional>
#include <string>
@@ -13,7 +14,6 @@
#include <unordered_map>
#include <utility>
#include <vector>
#include <limits>
#include <fontconfig/fontconfig.h>
@@ -86,8 +86,8 @@ auto decode_utf8(std::string_view text) -> std::vector<CodepointSpan>
if (i + 1 < text.size()) {
u8 const b1 = static_cast<u8>(text[i + 1]);
if ((b1 & 0xC0) == 0x80) {
uint32_t t
= ((byte & 0x1F) << 6) | (static_cast<uint32_t>(b1) & 0x3F);
uint32_t t = ((byte & 0x1F) << 6)
| (static_cast<uint32_t>(b1) & 0x3F);
if (t >= 0x80) {
cp = t;
length = 2;
@@ -128,9 +128,9 @@ auto decode_utf8(std::string_view text) -> std::vector<CodepointSpan>
}
spans.push_back(CodepointSpan {
.codepoint = cp,
.start = start,
.end = std::min(text.size(), start + length),
.codepoint = cp,
.start = start,
.end = std::min(text.size(), start + length),
});
i += length;
}
@@ -240,18 +240,44 @@ auto TextRenderer::generate_glyph(FontRuntime &rt, FontData &fd,
msdf_bitmap, shape, rt.px_range, scale_vec, translate);
std::vector<Color> buffer(static_cast<size_t>(bmp_w) * bmp_h);
// FIXME: Figure out shader
// for (int y = 0; y < bmp_h; ++y) {
// int const dst_y = bmp_h - 1 - y;
// for (int x = 0; x < bmp_w; ++x) {
// float const *px = msdf_bitmap(x, y);
// auto const r = msdfgen::pixelFloatToByte(px[0]);
// auto const g = msdfgen::pixelFloatToByte(px[1]);
// auto const b = msdfgen::pixelFloatToByte(px[2]);
// buffer[static_cast<size_t>(dst_y) * bmp_w + x]
// = Color { r, g, b, 255 };
// }
//}
auto sum_white = 0;
auto sum_black = 0;
for (int y = 0; y < bmp_h; ++y) {
for (int x = 0; x < bmp_w; ++x) {
float const *px = msdf_bitmap(x, y);
auto const r = msdfgen::pixelFloatToByte(px[0]);
if (r > 127) {
sum_white++;
} else {
sum_black++;
}
}
}
for (int y = 0; y < bmp_h; ++y) {
int const dst_y = bmp_h - 1 - y;
for (int x = 0; x < bmp_w; ++x) {
float const *px = msdf_bitmap(x, y);
auto const r = msdfgen::pixelFloatToByte(px[0]);
// FIXME: Figure out shader
// auto const g = msdfgen::pixelFloatToByte(px[1]);
// auto const b = msdfgen::pixelFloatToByte(px[2]);
// buffer[static_cast<size_t>(dst_y) * bmp_w + x]
// = Color { r, g, b, 255 };
buffer[static_cast<size_t>(dst_y) * bmp_w + x]
= Color { 255, 255, 255, r };
if (sum_white > sum_black && (float)bmp_w / (float)bmp_h > 0.6) {
buffer[static_cast<size_t>(dst_y) * bmp_w + x] = Color { 255,
255, 255, static_cast<unsigned char>(255 - r) };
} else {
buffer[static_cast<size_t>(dst_y) * bmp_w + x]
= Color { 255, 255, 255, r };
}
}
}
@@ -324,12 +350,13 @@ TextRenderer::TextRenderer()
TextRenderer::~TextRenderer()
{
for (usize i = 0; i < m_font_sets.size(); ++i) {
FontHandle handle;
handle.id = i;
unload_font(handle);
}
// Not unloading the shader... I have no clue why, but there's some sort of double free. I love C interop!!!!
for (usize i = 0; i < m_font_sets.size(); ++i) {
FontHandle handle;
handle.id = i;
unload_font(handle);
}
// Not unloading the shader... I have no clue why, but there's some sort of
// double free. I love C interop!!!!
}
auto TextRenderer::measure_text(FontHandle const font,
@@ -369,12 +396,10 @@ auto TextRenderer::measure_text(FontHandle const font,
continue;
auto &rt = *m_font_runtime[runtime_index];
auto &fd = m_font_data[runtime_index];
auto *entry
= ensure_glyph(rt, fd, placement.glyph_index, false);
auto *entry = ensure_glyph(rt, fd, placement.glyph_index, false);
if (!entry || entry->width == 0 || entry->height == 0)
continue;
float const x_offset_em
= hb_to_em(placement.x_offset, rt.units_per_em);
float const x_offset_em = hb_to_em(placement.x_offset, rt.units_per_em);
float const left
= advance_em + x_offset_em + entry->glyph.plane_bounds.left;
float const right
@@ -457,17 +482,13 @@ auto TextRenderer::draw_text(FontHandle const font, std::string_view const text,
updated_stamp.push_back(runtime_index);
}
auto *entry
= ensure_glyph(rt, fd, placement.glyph_index, true);
auto *entry = ensure_glyph(rt, fd, placement.glyph_index, true);
if (!entry || entry->width == 0 || entry->height == 0)
continue;
float const advance_em
= hb_to_em(placement.x_advance, rt.units_per_em);
float const x_offset_em
= hb_to_em(placement.x_offset, rt.units_per_em);
float const y_offset_em
= hb_to_em(placement.y_offset, rt.units_per_em);
float const advance_em = hb_to_em(placement.x_advance, rt.units_per_em);
float const x_offset_em = hb_to_em(placement.x_offset, rt.units_per_em);
float const y_offset_em = hb_to_em(placement.y_offset, rt.units_per_em);
float const x_base_em = pen_x_em + x_offset_em;
float const y_base_em = pen_y_em + y_offset_em;
float const scale_px = size_f / static_cast<float>(rt.em_scale);
@@ -593,7 +614,7 @@ auto TextRenderer::load_single_font(std::filesystem::path const &path)
auto TextRenderer::load_font(std::filesystem::path const &path,
std::span<std::filesystem::path const> fallback_fonts)
-> std::optional<FontHandle>
-> std::optional<FontHandle>
{
auto primary_index = load_single_font(path);
if (!primary_index)
@@ -641,15 +662,15 @@ auto TextRenderer::shape_text(FontHandle const font,
for (size_t i = 0; i < codepoints.size(); ++i) {
bool matched = false;
for (size_t candidate = 0; candidate < font_set.font_indices.size();
++candidate) {
++candidate) {
usize runtime_index = font_set.font_indices[candidate];
if (runtime_index >= m_font_runtime.size())
continue;
auto const &runtime_ptr = m_font_runtime[runtime_index];
if (!runtime_ptr || !runtime_ptr->face)
continue;
FT_UInt glyph = FT_Get_Char_Index(
runtime_ptr->face, codepoints[i].codepoint);
FT_UInt glyph
= FT_Get_Char_Index(runtime_ptr->face, codepoints[i].codepoint);
if (glyph != 0) {
selections[i] = candidate;
matched = true;
@@ -680,8 +701,8 @@ auto TextRenderer::shape_text(FontHandle const font,
size_t segment_start = codepoints[idx].start;
size_t segment_end = codepoints[idx].end;
size_t end_idx = idx + 1;
while (end_idx < codepoints.size()
&& selections[end_idx] == font_choice) {
while (
end_idx < codepoints.size() && selections[end_idx] == font_choice) {
segment_end = codepoints[end_idx].end;
++end_idx;
}