diff --git a/src/TextRenderer.cpp b/src/TextRenderer.cpp index 695d027..c15bf72 100644 --- a/src/TextRenderer.cpp +++ b/src/TextRenderer.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -13,7 +14,6 @@ #include #include #include -#include #include @@ -86,8 +86,8 @@ auto decode_utf8(std::string_view text) -> std::vector if (i + 1 < text.size()) { u8 const b1 = static_cast(text[i + 1]); if ((b1 & 0xC0) == 0x80) { - uint32_t t - = ((byte & 0x1F) << 6) | (static_cast(b1) & 0x3F); + uint32_t t = ((byte & 0x1F) << 6) + | (static_cast(b1) & 0x3F); if (t >= 0x80) { cp = t; length = 2; @@ -128,9 +128,9 @@ auto decode_utf8(std::string_view text) -> std::vector } 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 buffer(static_cast(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(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(dst_y) * bmp_w + x] - // = Color { r, g, b, 255 }; - buffer[static_cast(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(dst_y) * bmp_w + x] = Color { 255, + 255, 255, static_cast(255 - r) }; + } else { + buffer[static_cast(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(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 fallback_fonts) - -> std::optional + -> std::optional { 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; }