@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user