优化文本渲染效果

This commit is contained in:
daiqingshuang 2025-04-02 13:25:34 +08:00
parent 9be39399d9
commit e0c0648221
7 changed files with 67 additions and 33 deletions

View File

@ -12,7 +12,7 @@ int main(int argc, char* argv[]) {
mirage_app::get().init(); mirage_app::get().init();
auto& manager = font_manager::instance(); auto& manager = font_manager::instance();
// manager.add_font(L"C:/Users/46944/AppData/Local/Microsoft/Windows/Fonts/MapleMono-NF-CN-Regular.ttf"); manager.add_font(L"C:/Users/46944/AppData/Local/Microsoft/Windows/Fonts/MapleMono-NF-CN-Regular.ttf");
manager.add_font(L"C:/Windows/Fonts/msyh.ttc"); manager.add_font(L"C:/Windows/Fonts/msyh.ttc");
// manager.add_font(L"D:/Projects/noto-emoji-2.047/fonts/Noto-COLRv1.ttf"); // manager.add_font(L"D:/Projects/noto-emoji-2.047/fonts/Noto-COLRv1.ttf");
manager.add_font(L"C:/Windows/Fonts/seguiemj.ttf"); manager.add_font(L"C:/Windows/Fonts/seguiemj.ttf");

View File

@ -7,6 +7,7 @@
#include "pixel.h" #include "pixel.h"
#include "freetype/ftcolor.h" #include "freetype/ftcolor.h"
#include "freetype/ftglyph.h" #include "freetype/ftglyph.h"
#include "freetype/ftlcdfil.h"
#include "interface/image_interface.h" #include "interface/image_interface.h"
FT_Library library_; FT_Library library_;
@ -88,7 +89,7 @@ std::shared_ptr<image_heap_t> freetype_interface::get_emoji_image(int32_t in_gly
} }
// 加载字形 // 加载字形
FT_Load_Glyph(face_, in_glyph_id, FT_LOAD_RENDER | FT_LOAD_COLOR); FT_Load_Glyph(face_, in_glyph_id, FT_LOAD_RENDER | FT_LOAD_COLOR | FT_LOAD_NO_HINTING);
if (face_->glyph->format != FT_GLYPH_FORMAT_BITMAP) { if (face_->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
return nullptr; return nullptr;
} }
@ -201,6 +202,7 @@ bool init_font_system() {
if (FT_Init_FreeType(&library_)) { if (FT_Init_FreeType(&library_)) {
return false; return false;
} }
FT_Library_SetLcdFilter(library_, FT_LCD_FILTER_DEFAULT);
return true; return true;
} }

View File

@ -160,7 +160,6 @@ text_layout_t font_manager::layout_text(
// 计算字形坐标 // 计算字形坐标
float x = cursor_x + glyph_metrics.offset.x() + glyph_metrics.rect.left(); float x = cursor_x + glyph_metrics.offset.x() + glyph_metrics.rect.left();
// float y = cursor_y + font_ascent + glyph_metrics->rect.top() + font_descent;
float y = baseline + glyph_metrics.offset.y(); float y = baseline + glyph_metrics.offset.y();
// 添加字形位置信息到布局 // 添加字形位置信息到布局

View File

@ -182,6 +182,7 @@ void render_elements::make_rect(
const Eigen::Vector2f& in_size, const Eigen::Vector2f& in_size,
const rect_color& in_color, const rect_color& in_color,
const geometry_t& in_geometry, const geometry_t& in_geometry,
const draw_effect& in_effect,
const mirage_vertex_param_t& in_param_a, const mirage_vertex_param_t& in_param_a,
const mirage_vertex_param_t& in_param_b, const mirage_vertex_param_t& in_param_b,
const mirage_vertex_param_t& in_param_c, const mirage_vertex_param_t& in_param_c,
@ -190,7 +191,14 @@ void render_elements::make_rect(
const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_pivot,
const Eigen::Vector2f& in_scale) { const Eigen::Vector2f& in_scale) {
// 从几何体转换到窗口坐标 // 从几何体转换到窗口坐标
const auto& pos = in_geometry.local_to_window(in_pos); auto pos = in_geometry.local_to_window(in_pos);
if (pos.x() > window_size_.x() || pos.y() > window_size_.y()) {
return;
}
if (has_any_flag(in_effect, draw_effect::pixel_snap)) {
pos.x() = std::round(pos.x());
pos.y() = std::round(pos.y());
}
add_rect_to_batch(pos, add_rect_to_batch(pos,
in_size, in_size,
in_color, in_color,
@ -204,16 +212,18 @@ void render_elements::make_rect(
} }
void render_elements::make_rounded_rect(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, void render_elements::make_rounded_rect(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const rect_color& in_color, const rect_round& in_round, float in_rotation_radians, const geometry_t& in_geometry, const draw_effect& in_effect,
const rect_color& in_color, const rect_round& in_round,
float in_rotation_radians,
const Eigen::Vector2f& in_pivot, const rect_uv& in_uv, const Eigen::Vector2f& in_scale) { const Eigen::Vector2f& in_pivot, const rect_uv& in_uv, const Eigen::Vector2f& in_scale) {
set_pipeline(rounded_rect_pipeline_); set_pipeline(rounded_rect_pipeline_);
const mirage_vertex_param_t param_a{ in_size }; const mirage_vertex_param_t param_a{ in_size };
const mirage_vertex_param_t param_b{ in_round }; const mirage_vertex_param_t param_b{ in_round };
make_rect(in_pos, in_size, in_color, in_geometry, param_a, param_b, {}, in_uv, in_rotation_radians, in_pivot, in_scale); make_rect(in_pos, in_size, in_color, in_geometry, in_effect, param_a, param_b, {}, in_uv, in_rotation_radians, in_pivot, in_scale);
} }
void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const sg_image& in_image, sampler_type in_sampler_type, const geometry_t& in_geometry, const sg_image& in_image, sampler_type in_sampler_type, const draw_effect& in_effect,
const rect_color& in_color, const rect_uv& in_uv, float in_rotation_radians, const Eigen::Vector2f& in_pivot, const rect_color& in_color, const rect_uv& in_uv, float in_rotation_radians, const Eigen::Vector2f& in_pivot,
const Eigen::Vector2f& in_scale) { const Eigen::Vector2f& in_scale) {
const auto& sampler = texture_sampler_builder::get_sampler(in_sampler_type); const auto& sampler = texture_sampler_builder::get_sampler(in_sampler_type);
@ -222,6 +232,7 @@ void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vec
in_geometry, in_geometry,
in_image, in_image,
sampler, sampler,
in_effect,
in_color, in_color,
in_uv, in_uv,
in_rotation_radians, in_rotation_radians,
@ -230,7 +241,7 @@ void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vec
} }
void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const sg_image& in_image, const std::shared_ptr<texture_sampler>& in_sampler, const geometry_t& in_geometry, const sg_image& in_image, const std::shared_ptr<texture_sampler>& in_sampler, const draw_effect& in_effect,
const rect_color& in_color, const rect_uv& in_uv, float in_rotation_radians, const Eigen::Vector2f& in_pivot, const rect_color& in_color, const rect_uv& in_uv, float in_rotation_radians, const Eigen::Vector2f& in_pivot,
const Eigen::Vector2f& in_scale) { const Eigen::Vector2f& in_scale) {
if (!in_sampler) { if (!in_sampler) {
@ -245,11 +256,22 @@ void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vec
ensure_batch_compatibility(new_key); ensure_batch_compatibility(new_key);
make_rect(in_pos, in_size, { in_color }, in_geometry, {}, {}, {}, in_uv, in_rotation_radians, in_pivot, in_scale); make_rect(in_pos,
in_size,
{ in_color },
in_geometry,
in_effect,
{},
{},
{},
in_uv,
in_rotation_radians,
in_pivot,
in_scale);
} }
void render_elements::make_text(const text_layout_t& in_layout, const Eigen::Vector2f& in_pos, void render_elements::make_text(const text_layout_t& in_layout, const Eigen::Vector2f& in_pos,
const Eigen::Vector2f& in_size, const geometry_t& in_geometry, const rect_color& in_color, const Eigen::Vector2f& in_size, const geometry_t& in_geometry, const draw_effect& in_effect, const rect_color& in_color,
float in_rotation_radians, const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) { float in_rotation_radians, const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) {
const auto& glyph_sampler = texture_sampler_builder::get_sampler(sampler_type::pixel_art); const auto& glyph_sampler = texture_sampler_builder::get_sampler(sampler_type::pixel_art);
const auto& emoji_sampler = texture_sampler_builder::get_sampler(sampler_type::pixel_art); const auto& emoji_sampler = texture_sampler_builder::get_sampler(sampler_type::pixel_art);
@ -268,12 +290,9 @@ void render_elements::make_text(const text_layout_t& in_layout, const Eigen::Vec
new_key.sampler = position.is_emoji ? *emoji_sampler : *glyph_sampler; new_key.sampler = position.is_emoji ? *emoji_sampler : *glyph_sampler;
Eigen::Vector2f real_pos = p.position.array() + in_pos.array(); Eigen::Vector2f real_pos = p.position.array() + in_pos.array();
// snap to pixel grid
real_pos.x() = std::round(real_pos.x());
real_pos.y() = std::round(real_pos.y());
ensure_batch_compatibility(new_key); ensure_batch_compatibility(new_key);
make_rect(real_pos, size, in_color, in_geometry, {}, {}, {}, uv, in_rotation_radians, in_pivot, in_scale); make_rect(real_pos, size, in_color, in_geometry, in_effect, {}, {}, {}, uv, in_rotation_radians, in_pivot, in_scale);
// make_wireframe(real_pos, size, in_geometry, 1.0f, in_color, in_rotation_radians, in_pivot, in_scale); // make_wireframe(real_pos, size, in_geometry, 1.0f, in_color, in_rotation_radians, in_pivot, in_scale);
} }
} }
@ -283,13 +302,13 @@ void render_elements::make_text(const text_layout_t& in_layout, const Eigen::Vec
font_ascent_end.x() += in_layout.total_size.x(); font_ascent_end.x() += in_layout.total_size.x();
// 绘制文本的基线 // 绘制文本的基线
make_line(font_ascent_start, font_ascent_end, in_geometry, 1.0f, in_color, in_rotation_radians, in_pivot, in_scale); make_line(font_ascent_start, font_ascent_end, in_geometry, 1.0f, in_effect, in_color, in_rotation_radians, in_pivot, in_scale);
// 绘制文本的线框 // 绘制文本的线框
make_wireframe(in_pos, in_size, in_geometry, 1.0f, in_color, in_rotation_radians, in_pivot, in_scale); make_wireframe(in_pos, in_size, in_geometry, 1.0f, in_effect, in_color, in_rotation_radians, in_pivot, in_scale);
} }
void render_elements::make_wireframe(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size, void render_elements::make_wireframe(const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, float in_line_width, const rect_color& in_color, float in_rotation_radians, const geometry_t& in_geometry, float in_line_width, const draw_effect& in_effect, const rect_color& in_color, float in_rotation_radians,
const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) { const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) {
set_pipeline(wireframe_pipeline_); set_pipeline(wireframe_pipeline_);
mirage_vertex_param_t param_a{}; mirage_vertex_param_t param_a{};
@ -299,6 +318,7 @@ void render_elements::make_wireframe(const Eigen::Vector2f& in_pos, const Eigen:
in_size, in_size,
{ in_color }, { in_color },
in_geometry, in_geometry,
in_effect,
param_a, param_a,
{}, {},
{}, {},
@ -309,7 +329,7 @@ void render_elements::make_wireframe(const Eigen::Vector2f& in_pos, const Eigen:
} }
void render_elements::make_line(const Eigen::Vector2f& in_start, const Eigen::Vector2f& in_end, void render_elements::make_line(const Eigen::Vector2f& in_start, const Eigen::Vector2f& in_end,
const geometry_t& in_geometry, float in_thickness, const rect_color& in_color, float in_rotation_radians, const geometry_t& in_geometry, float in_thickness, const draw_effect& in_effect, const rect_color& in_color, float in_rotation_radians,
const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) { const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) {
set_pipeline(line_pipeline_); set_pipeline(line_pipeline_);
auto rect = rect_t<>::bounding_box<float>({in_start, in_end}); auto rect = rect_t<>::bounding_box<float>({in_start, in_end});
@ -340,6 +360,7 @@ void render_elements::make_line(const Eigen::Vector2f& in_start, const Eigen::Ve
rect.size(), rect.size(),
{ in_color }, { in_color },
in_geometry, in_geometry,
in_effect,
param_a, param_a,
param_b, param_b,
{}, {},

View File

@ -22,7 +22,10 @@
* *
*/ */
enum class draw_effect { enum class draw_effect {
none,
pixel_snap,
}; };
DEFINE_ENUM_FLAGS(draw_effect)
/** /**
* @struct batch_key * @struct batch_key
@ -208,6 +211,7 @@ public:
const Eigen::Vector2f& in_size, const Eigen::Vector2f& in_size,
const rect_color& in_color, const rect_color& in_color,
const geometry_t& in_geometry, const geometry_t& in_geometry,
const draw_effect& in_effect = draw_effect::none,
const mirage_vertex_param_t& in_param_a = {}, const mirage_vertex_param_t& in_param_a = {},
const mirage_vertex_param_t& in_param_b = {}, const mirage_vertex_param_t& in_param_b = {},
const mirage_vertex_param_t& in_param_c = {}, const mirage_vertex_param_t& in_param_c = {},
@ -231,6 +235,7 @@ public:
void make_rounded_rect(const Eigen::Vector2f& in_pos, void make_rounded_rect(const Eigen::Vector2f& in_pos,
const Eigen::Vector2f& in_size, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const geometry_t& in_geometry,
const draw_effect& in_effect = draw_effect::none,
const rect_color& in_color = { { 1, 1, 1, 1 } }, const rect_color& in_color = { { 1, 1, 1, 1 } },
const rect_round& in_round = {}, const rect_round& in_round = {},
float in_rotation_radians = 0.0f, float in_rotation_radians = 0.0f,
@ -243,28 +248,31 @@ public:
const geometry_t& in_geometry, const geometry_t& in_geometry,
const sg_image& in_image, const sg_image& in_image,
sampler_type in_sampler_type, sampler_type in_sampler_type,
const rect_color& in_color = { { 1, 1, 1, 1 } }, const draw_effect& in_effect = draw_effect::none,
const rect_color& in_color = { { 1, 1, 1, 1 } },
const rect_uv& in_uv = {}, const rect_uv& in_uv = {},
float in_rotation_radians = 0.0f, float in_rotation_radians = 0.0f,
const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f), const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f),
const Eigen::Vector2f& in_scale = Eigen::Vector2f(1.f, 1.f)); const Eigen::Vector2f& in_scale = Eigen::Vector2f(1.f, 1.f));
void make_image(const Eigen::Vector2f& in_pos, void make_image(const Eigen::Vector2f& in_pos,
const Eigen::Vector2f& in_size, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const geometry_t& in_geometry,
const sg_image& in_image, const sg_image& in_image,
const std::shared_ptr<texture_sampler>& in_sampler, const std::shared_ptr<texture_sampler>& in_sampler,
const rect_color& in_color = { { 1, 1, 1, 1 } }, const draw_effect& in_effect = draw_effect::none,
const rect_uv& in_uv = {}, const rect_color& in_color = { { 1, 1, 1, 1 } },
float in_rotation_radians = 0.0f, const rect_uv& in_uv = {},
const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f), float in_rotation_radians = 0.0f,
const Eigen::Vector2f& in_scale = Eigen::Vector2f(1.f, 1.f)); const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f),
const Eigen::Vector2f& in_scale = Eigen::Vector2f(1.f, 1.f));
void make_text(const text_layout_t& in_layout, void make_text(const text_layout_t& in_layout,
const Eigen::Vector2f& in_pos, const Eigen::Vector2f& in_pos,
const Eigen::Vector2f& in_size, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const geometry_t& in_geometry,
const rect_color& in_color = { { 1, 1, 1, 1 } }, const draw_effect& in_effect = draw_effect::pixel_snap,
const rect_color& in_color = { { 1, 1, 1, 1 } },
float in_rotation_radians = 0.0f, float in_rotation_radians = 0.0f,
const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f), const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f),
const Eigen::Vector2f& in_scale = Eigen::Vector2f(1.f, 1.f)); const Eigen::Vector2f& in_scale = Eigen::Vector2f(1.f, 1.f));
@ -272,7 +280,8 @@ public:
void make_wireframe(const Eigen::Vector2f& in_pos, void make_wireframe(const Eigen::Vector2f& in_pos,
const Eigen::Vector2f& in_size, const Eigen::Vector2f& in_size,
const geometry_t& in_geometry, const geometry_t& in_geometry,
float in_line_width, float in_line_width,
const draw_effect& in_effect = draw_effect::none,
const rect_color& in_color = { { 1, 1, 1, 1 } }, const rect_color& in_color = { { 1, 1, 1, 1 } },
float in_rotation_radians = 0.0f, float in_rotation_radians = 0.0f,
const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f), const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f),
@ -282,6 +291,7 @@ public:
const Eigen::Vector2f& in_end, const Eigen::Vector2f& in_end,
const geometry_t& in_geometry, const geometry_t& in_geometry,
float in_thickness, float in_thickness,
const draw_effect& in_effect = draw_effect::none,
const rect_color& in_color = { { 1, 1, 1, 1 } }, const rect_color& in_color = { { 1, 1, 1, 1 } },
float in_rotation_radians = 0.0f, float in_rotation_radians = 0.0f,
const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f), const Eigen::Vector2f& in_pivot = Eigen::Vector2f(0.5f, 0.5f),

View File

@ -6,7 +6,7 @@
#include "widget/panel_widget/mbox.h" #include "widget/panel_widget/mbox.h"
mbutton::mbutton() { mbutton::mbutton() {
color_ = {0.5, 0.5, 0.5, 1}; color_ = {0.1, 0.1, 0.1, 1};
slot_.h_alignment(horizontal_alignment_t::center); slot_.h_alignment(horizontal_alignment_t::center);
slot_.v_alignment(vertical_alignment_t::center); slot_.v_alignment(vertical_alignment_t::center);
} }
@ -21,6 +21,7 @@ void mbutton::on_paint(mirage_paint_context& in_context) {
{ 0, 0 }, { 0, 0 },
in_context.geo().get_local_size(), in_context.geo().get_local_size(),
in_context.geo(), in_context.geo(),
{},
{ color_ }, { color_ },
{ 10 } { 10 }
); );
@ -72,7 +73,7 @@ void mbutton::on_mouse_enter() {
void mbutton::on_mouse_leave() { void mbutton::on_mouse_leave() {
mborder::on_mouse_leave(); mborder::on_mouse_leave();
std::cout << this << ": Mouse left!" << std::endl; std::cout << this << ": Mouse left!" << std::endl;
color_ = {0.5, 0.5, 0.5, 1}; color_ = {0.1, 0.1, 0.1, 1};
invalidate(invalidate_reason::paint); invalidate(invalidate_reason::paint);
} }

View File

@ -13,6 +13,7 @@ void mimage::on_paint(mirage_paint_context& in_context) {
in_context.geo(), in_context.geo(),
image_->get_image(), image_->get_image(),
sampler_type::default_, sampler_type::default_,
{},
{ color_ } { color_ }
); );
} }