@@ -6,6 +6,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -13,7 +14,6 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include <fontconfig/fontconfig.h>
|
#include <fontconfig/fontconfig.h>
|
||||||
|
|
||||||
@@ -86,8 +86,8 @@ auto decode_utf8(std::string_view text) -> std::vector<CodepointSpan>
|
|||||||
if (i + 1 < text.size()) {
|
if (i + 1 < text.size()) {
|
||||||
u8 const b1 = static_cast<u8>(text[i + 1]);
|
u8 const b1 = static_cast<u8>(text[i + 1]);
|
||||||
if ((b1 & 0xC0) == 0x80) {
|
if ((b1 & 0xC0) == 0x80) {
|
||||||
uint32_t t
|
uint32_t t = ((byte & 0x1F) << 6)
|
||||||
= ((byte & 0x1F) << 6) | (static_cast<uint32_t>(b1) & 0x3F);
|
| (static_cast<uint32_t>(b1) & 0x3F);
|
||||||
if (t >= 0x80) {
|
if (t >= 0x80) {
|
||||||
cp = t;
|
cp = t;
|
||||||
length = 2;
|
length = 2;
|
||||||
@@ -240,20 +240,46 @@ auto TextRenderer::generate_glyph(FontRuntime &rt, FontData &fd,
|
|||||||
msdf_bitmap, shape, rt.px_range, scale_vec, translate);
|
msdf_bitmap, shape, rt.px_range, scale_vec, translate);
|
||||||
|
|
||||||
std::vector<Color> buffer(static_cast<size_t>(bmp_w) * bmp_h);
|
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) {
|
for (int y = 0; y < bmp_h; ++y) {
|
||||||
int const dst_y = bmp_h - 1 - y;
|
int const dst_y = bmp_h - 1 - y;
|
||||||
for (int x = 0; x < bmp_w; ++x) {
|
for (int x = 0; x < bmp_w; ++x) {
|
||||||
float const *px = msdf_bitmap(x, y);
|
float const *px = msdf_bitmap(x, y);
|
||||||
auto const r = msdfgen::pixelFloatToByte(px[0]);
|
auto const r = msdfgen::pixelFloatToByte(px[0]);
|
||||||
// FIXME: Figure out shader
|
if (sum_white > sum_black && (float)bmp_w / (float)bmp_h > 0.6) {
|
||||||
// auto const g = msdfgen::pixelFloatToByte(px[1]);
|
buffer[static_cast<size_t>(dst_y) * bmp_w + x] = Color { 255,
|
||||||
// auto const b = msdfgen::pixelFloatToByte(px[2]);
|
255, 255, static_cast<unsigned char>(255 - r) };
|
||||||
// buffer[static_cast<size_t>(dst_y) * bmp_w + x]
|
} else {
|
||||||
// = Color { r, g, b, 255 };
|
|
||||||
buffer[static_cast<size_t>(dst_y) * bmp_w + x]
|
buffer[static_cast<size_t>(dst_y) * bmp_w + x]
|
||||||
= Color { 255, 255, 255, r };
|
= Color { 255, 255, 255, r };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
upload_region(fd, place->first, place->second, bmp_w, bmp_h, buffer);
|
upload_region(fd, place->first, place->second, bmp_w, bmp_h, buffer);
|
||||||
|
|
||||||
@@ -329,7 +355,8 @@ TextRenderer::~TextRenderer()
|
|||||||
handle.id = i;
|
handle.id = i;
|
||||||
unload_font(handle);
|
unload_font(handle);
|
||||||
}
|
}
|
||||||
// Not unloading the shader... I have no clue why, but there's some sort of double free. I love C interop!!!!
|
// 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,
|
auto TextRenderer::measure_text(FontHandle const font,
|
||||||
@@ -369,12 +396,10 @@ auto TextRenderer::measure_text(FontHandle const font,
|
|||||||
continue;
|
continue;
|
||||||
auto &rt = *m_font_runtime[runtime_index];
|
auto &rt = *m_font_runtime[runtime_index];
|
||||||
auto &fd = m_font_data[runtime_index];
|
auto &fd = m_font_data[runtime_index];
|
||||||
auto *entry
|
auto *entry = ensure_glyph(rt, fd, placement.glyph_index, false);
|
||||||
= ensure_glyph(rt, fd, placement.glyph_index, false);
|
|
||||||
if (!entry || entry->width == 0 || entry->height == 0)
|
if (!entry || entry->width == 0 || entry->height == 0)
|
||||||
continue;
|
continue;
|
||||||
float const x_offset_em
|
float const x_offset_em = hb_to_em(placement.x_offset, rt.units_per_em);
|
||||||
= hb_to_em(placement.x_offset, rt.units_per_em);
|
|
||||||
float const left
|
float const left
|
||||||
= advance_em + x_offset_em + entry->glyph.plane_bounds.left;
|
= advance_em + x_offset_em + entry->glyph.plane_bounds.left;
|
||||||
float const right
|
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);
|
updated_stamp.push_back(runtime_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *entry
|
auto *entry = ensure_glyph(rt, fd, placement.glyph_index, true);
|
||||||
= ensure_glyph(rt, fd, placement.glyph_index, true);
|
|
||||||
if (!entry || entry->width == 0 || entry->height == 0)
|
if (!entry || entry->width == 0 || entry->height == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float const advance_em
|
float const advance_em = hb_to_em(placement.x_advance, rt.units_per_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 x_offset_em
|
float const y_offset_em = hb_to_em(placement.y_offset, rt.units_per_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 x_base_em = pen_x_em + x_offset_em;
|
||||||
float const y_base_em = pen_y_em + y_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);
|
float const scale_px = size_f / static_cast<float>(rt.em_scale);
|
||||||
@@ -648,8 +669,8 @@ auto TextRenderer::shape_text(FontHandle const font,
|
|||||||
auto const &runtime_ptr = m_font_runtime[runtime_index];
|
auto const &runtime_ptr = m_font_runtime[runtime_index];
|
||||||
if (!runtime_ptr || !runtime_ptr->face)
|
if (!runtime_ptr || !runtime_ptr->face)
|
||||||
continue;
|
continue;
|
||||||
FT_UInt glyph = FT_Get_Char_Index(
|
FT_UInt glyph
|
||||||
runtime_ptr->face, codepoints[i].codepoint);
|
= FT_Get_Char_Index(runtime_ptr->face, codepoints[i].codepoint);
|
||||||
if (glyph != 0) {
|
if (glyph != 0) {
|
||||||
selections[i] = candidate;
|
selections[i] = candidate;
|
||||||
matched = true;
|
matched = true;
|
||||||
@@ -680,8 +701,8 @@ auto TextRenderer::shape_text(FontHandle const font,
|
|||||||
size_t segment_start = codepoints[idx].start;
|
size_t segment_start = codepoints[idx].start;
|
||||||
size_t segment_end = codepoints[idx].end;
|
size_t segment_end = codepoints[idx].end;
|
||||||
size_t end_idx = idx + 1;
|
size_t end_idx = idx + 1;
|
||||||
while (end_idx < codepoints.size()
|
while (
|
||||||
&& selections[end_idx] == font_choice) {
|
end_idx < codepoints.size() && selections[end_idx] == font_choice) {
|
||||||
segment_end = codepoints[end_idx].end;
|
segment_end = codepoints[end_idx].end;
|
||||||
++end_idx;
|
++end_idx;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user