From 9282b9f214b363429fd566c117cba8b445099da5 Mon Sep 17 00:00:00 2001
From: Nanako <469449812@qq.com>
Date: Fri, 4 Apr 2025 12:58:58 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=AD=97=E5=8F=B7=E8=80=8C?=
 =?UTF-8?q?=E4=B8=8D=E6=98=AF=E5=83=8F=E7=B4=A0=E9=AB=98=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 example/src/main.cpp                           |  4 ++--
 src/mirage_core/geometry/dpi_helper.h          | 18 ++++++++++++++++--
 .../freetype_font/src/freetype_interface.cpp   | 16 +++++++++-------
 .../stb_truetype_interface.cpp                 | 12 ++++++++----
 .../src/render/render_elements.cpp             |  6 +++---
 .../widget/leaf_widget/mtext_block.h           |  2 +-
 src/mirage_widget/window/mwindow_impl.cpp      |  2 +-
 7 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/example/src/main.cpp b/example/src/main.cpp
index 6afd5a1..17ac21e 100644
--- a/example/src/main.cpp
+++ b/example/src/main.cpp
@@ -12,13 +12,13 @@ int main(int argc, char* argv[]) {
 	mirage_app::get().init();
 
 	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"D:/Projects/noto-emoji-2.047/fonts/Noto-COLRv1.ttf");
 	manager.add_font(L"C:/Windows/Fonts/seguiemj.ttf");
 
 	const auto& text_block = std::make_shared<mtext_block>();
-	text_block->set_text(U"Hello, World! 你好,世界!\n换行测试1111测试测试测试测试测试测试");
+	text_block->set_text(U"Hello, World! 你好,世界!\n换行测试1111测试测试测试测试测试测试😀🐵🙏");
 
 	const auto& text_block2 = std::make_shared<mtext_block>();
 	text_block2->set_text(U"Hello, World!");
diff --git a/src/mirage_core/geometry/dpi_helper.h b/src/mirage_core/geometry/dpi_helper.h
index 6a69a5b..f9f405a 100644
--- a/src/mirage_core/geometry/dpi_helper.h
+++ b/src/mirage_core/geometry/dpi_helper.h
@@ -5,12 +5,24 @@
 
 class dpi_helper {
 public:
-	static void set_global_scale(float in_scale) {
+	static void global_scale(float in_scale) {
 		global_scale_ = in_scale;
 	}
-	static auto get_global_scale() {
+	static auto global_scale() {
 		return global_scale_;
 	}
+	static auto dpi_x() {
+		return dpi_x_;
+	}
+	static auto dpi_y() {
+		return dpi_y_;
+	}
+	static void dpi_x(uint32_t in_dpi_x) {
+		dpi_x_ = in_dpi_x;
+	}
+	static void dpi_y(uint32_t in_dpi_y) {
+		dpi_y_ = in_dpi_y;
+	}
 
 	static auto physical_to_logical(float in_physical) {
 		return in_physical / global_scale_;
@@ -47,4 +59,6 @@ public:
 	}
 private:
 	inline static float global_scale_ = 1.f;
+	inline static uint32_t dpi_x_ = 96;
+	inline static uint32_t dpi_y_ = 96;
 };
diff --git a/src/mirage_render/font/freetype_font/src/freetype_interface.cpp b/src/mirage_render/font/freetype_font/src/freetype_interface.cpp
index 6e3bd62..a52ab59 100644
--- a/src/mirage_render/font/freetype_font/src/freetype_interface.cpp
+++ b/src/mirage_render/font/freetype_font/src/freetype_interface.cpp
@@ -9,6 +9,7 @@
 #include "freetype/ftcolor.h"
 #include "freetype/ftglyph.h"
 #include "freetype/ftlcdfil.h"
+#include "geometry/dpi_helper.h"
 #include "interface/image_interface.h"
 
 FT_Library library_;
@@ -46,9 +47,9 @@ bool freetype_interface::supports_color_emoji() const {
 font_v_metrics_t freetype_interface::get_metrics() const {
 	font_v_metrics_t metrics{};
 	// 使用当前字体大小下的度量信息
-	metrics.ascent = face_->size->metrics.ascender / 64.0f;
-	metrics.descent = -face_->size->metrics.descender / 64.0f; // FreeType中descent为负值
-	metrics.line_height = face_->size->metrics.height / 64.0f;
+	metrics.ascent = face_->size->metrics.ascender >> 6;
+	metrics.descent = -face_->size->metrics.descender >> 6; // FreeType中descent为负值
+	metrics.line_height = face_->size->metrics.height >> 6;
 	return metrics;
 }
 
@@ -84,7 +85,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_NO_HINTING);
+	FT_Load_Glyph(face_, in_glyph_id, FT_LOAD_RENDER | FT_LOAD_COLOR | FT_LOAD_FORCE_AUTOHINT);
 	if (face_->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
 		return nullptr;
 	}
@@ -96,10 +97,10 @@ std::shared_ptr<image_heap_t> freetype_interface::get_emoji_image(int32_t in_gly
 	std::shared_ptr<image_heap_t> image(new image_heap_t(), freetype_bitmap_deleter);
 	image->width        = bitmap.width;
 	image->height       = bitmap.rows;
-	image->pixel_format = SG_PIXELFORMAT_RGBA8;
+	image->pixel_format = SG_PIXELFORMAT_BGRA8;
 	image->data         = new uint8_t[image->width * image->height * 4];
 
-	// 其他格式,初始化为透明
+	// 初始化为透明
 	clear_bitmap(image.get());
 	attach_bitmap(bitmap, image.get());
 
@@ -186,7 +187,8 @@ bool freetype_interface::on_load() {
 
 void freetype_interface::on_set_font_size(float in_size) {
 	font_face_interface::on_set_font_size(in_size);
-	FT_Set_Pixel_Sizes(face_, 0, static_cast<FT_UInt>(in_size));
+	const FT_F26Dot6 font_size = static_cast<FT_F26Dot6>(in_size * 64);
+	FT_Set_Char_Size(face_, 0, font_size, dpi_helper::dpi_x(), dpi_helper::dpi_y());
 }
 
 void freetype_interface::clear_bitmap(image_heap_t* in_image) {
diff --git a/src/mirage_render/font/stb_truetype_font/stb_truetype_interface.cpp b/src/mirage_render/font/stb_truetype_font/stb_truetype_interface.cpp
index f4ca7e6..d182e6a 100644
--- a/src/mirage_render/font/stb_truetype_font/stb_truetype_interface.cpp
+++ b/src/mirage_render/font/stb_truetype_font/stb_truetype_interface.cpp
@@ -4,6 +4,7 @@
 #include "stb_truetype.h"
 
 #include "font/font_utils.h"
+#include "geometry/dpi_helper.h"
 #include "interface/image_interface.h"
 
 void stb_truetype_deleter(image_heap_t* in_data) {
@@ -92,11 +93,12 @@ font_v_metrics_t stb_font_face_t::get_metrics() const {
         // 如果失败,使用默认的VMetrics
         stbtt_GetFontVMetrics(&font_info_, &ascent, &descent, &line_gap);
     }
+	line_gap = line_gap * scale_ + 0.5f;
 
 	font_v_metrics_t metrics{};
-	metrics.ascent      = static_cast<float>(ascent) * scale_;
-	metrics.descent     = static_cast<float>(descent) * scale_;
-	metrics.line_height = (ascent - descent + line_gap) * scale_;
+	metrics.ascent      = static_cast<int>(ascent * scale_ + 0.5f);
+	metrics.descent     = static_cast<int>(descent * scale_ - 0.5f);
+	metrics.line_height = static_cast<int>(metrics.ascent - metrics.descent + line_gap);
     return metrics;
 }
 
@@ -162,7 +164,9 @@ bool stb_font_face_t::on_load() {
 
 void stb_font_face_t::on_set_font_size(float in_size) {
 	font_face_interface::on_set_font_size(in_size);
-	scale_ = get_scale_for_pixel_height(in_size);
+	float desired_pixel_height = static_cast<float>(in_size * dpi_helper::dpi_y() / 72.0);
+	desired_pixel_height       = std::floorf(desired_pixel_height);
+	scale_                     = get_scale_for_pixel_height(desired_pixel_height);
 }
 
 bool init_font_system() {
diff --git a/src/mirage_render/src/render/render_elements.cpp b/src/mirage_render/src/render/render_elements.cpp
index 52ecf3a..47f71a8 100644
--- a/src/mirage_render/src/render/render_elements.cpp
+++ b/src/mirage_render/src/render/render_elements.cpp
@@ -1,6 +1,7 @@
 #include "render_elements.h"
 
 #include "font/font_system.h"
+#include "geometry/dpi_helper.h"
 #include "shaders/mirage_rounded_rect.hlsl.h"
 #include "shaders/mirage_image.hlsl.h"
 #include "shaders/mirage_text.hlsl.h"
@@ -196,8 +197,7 @@ void render_elements::make_rect(
 		return;
 	}
 	if (has_any_flag(in_effect, draw_effect::pixel_snap)) {
-		pos.x() = std::round(pos.x());
-		pos.y() = std::round(pos.y());
+		pos = dpi_helper::snap_to_pixel(pos);
 	}
 	add_rect_to_batch(pos,
 	                  in_size,
@@ -274,7 +274,7 @@ void render_elements::make_text(const text_layout_t& in_layout, const Eigen::Vec
 		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) {
 	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::anisotropic);
 
 	for (const auto& position : in_layout.glyphs) {
 		const auto& p      = position;
diff --git a/src/mirage_widget/widget/leaf_widget/mtext_block.h b/src/mirage_widget/widget/leaf_widget/mtext_block.h
index 62708e7..5268266 100644
--- a/src/mirage_widget/widget/leaf_widget/mtext_block.h
+++ b/src/mirage_widget/widget/leaf_widget/mtext_block.h
@@ -45,7 +45,7 @@ private:
 
 	std::u32string text_;
 	text_layout_t layout_{};
-	float font_size_ = 48.0f;
+	float font_size_ = 24.0f;
 	float line_spacing_ = 1.f;
 	float max_width_ = 0.0f;
 	std::shared_ptr<font_face_interface> font_;
diff --git a/src/mirage_widget/window/mwindow_impl.cpp b/src/mirage_widget/window/mwindow_impl.cpp
index 4e11507..1f30a1e 100644
--- a/src/mirage_widget/window/mwindow_impl.cpp
+++ b/src/mirage_widget/window/mwindow_impl.cpp
@@ -142,7 +142,7 @@ public:
 
     // 几何与变换
     float get_dpi_scale() const {
-        return dpi_helper::get_global_scale() * platform_window_->get_window_dpi_scale();
+        return dpi_helper::global_scale() * platform_window_->get_window_dpi_scale();
     }
 
     transform2d get_local_to_screen_transform() const {