修改测试用例

This commit is contained in:
2024-12-27 19:45:20 +08:00
parent 4074f5d6e1
commit b50d7e46a7
4 changed files with 82 additions and 51 deletions

View File

@@ -113,8 +113,9 @@ void dx_window::begin_frame() {
// if (test_texture) context.draw_texture({ 0.f, 0.f }, test_texture->size().cast<float>(), test_texture);
// context.draw_string({0, 0}, U"你好,世界!全是水群大师\n测试换行\n测试Unicode: 😀\nТест по русскому языку\nテスト日本語", 32, {0, 0, 0, 1});
context.draw_string({0, 100}, U"Тест по русскому языку", 32, {0, 0, 0, 1});
context.draw_string({0, 100}, U"你好,世界!\nТест по русскому языку\nテスト", 32, {0, 0, 0, 1});
context.draw_rectangle({ 0, 100 }, { 2048, 1 }, { 1, 0, 1, 1 });
context.draw_rectangle({ 0, 132 }, { 2048, 1 }, { 1, 0, 1, 1 });
context.flush();

View File

@@ -44,22 +44,14 @@ void renderer_context::draw_texture(const Eigen::Vector2f& in_pos, const Eigen::
void renderer_context::draw_string(const Eigen::Vector2f& in_pos, const std::u32string& in_str, float in_height, const linear_color& in_color) {
to_text_pipeline(in_color);
float cursor_x = in_pos.x();
float cursor_y = in_pos.y();
Eigen::Vector2f cursor(cursor_x, cursor_y);
const auto& measure = text->measure_text(in_str, in_height);
for (const auto& mch: measure) {
const auto info = mch.item;
if (!info)
continue;
// 使用整形坐标, 避免出现模糊
Eigen::Vector2f pos{ info->left, info->right };
pos += cursor;
Eigen::Vector2f size{ info->get_width(), info->get_height() };
// const Eigen::Vector2f pos { cursor_x + mch.x_offset, cursor_y + mch.y_offset };
// const Eigen::Vector2f size { info->get_width() * mch.size_scale, info->get_height() * mch.size_scale };
const Eigen::Vector2f pos = mch.offset + in_pos;
const Eigen::Vector2f size = Eigen::Vector2f{ info->get_width(), info->get_height() } * mch.size_scale;
aorii_vertex_param param{};
param.param_a1 = info->tex_u;
@@ -69,7 +61,6 @@ void renderer_context::draw_string(const Eigen::Vector2f& in_pos, const std::u32
param.param_b2 = info->v_size;
make_rect(pos, size, in_color, 0, param);
cursor.x() += size.x();
}
}

View File

@@ -183,52 +183,92 @@ std::vector<measured_ch> aorii_text::measure_text(const std::u32string& text, fl
// 基线和行高信息
const int32_t ascent = primary_font.ascent;
const int32_t descent = primary_font.descent;
const int32_t line_gap = primary_font.line_gap * scale;
const float line_gap = primary_font.line_gap * scale;
const int32_t line_height = height;
const float space_width = primary_font.space_width * scale;
const float tab_width = primary_font.tab_width * scale;
struct line_data {
std::u32string text;
int32_t max_top{};
int32_t min_top{};
int32_t max_bottom{};
int32_t min_bottom{};
};
std::vector<line_data> lines;
// 按照\n分割文本
std::u32string text_copy = text;
for (size_t i = 0; i < text_copy.length(); i++) {
if (text_copy[i] == U'\n') {
lines.emplace_back(text_copy.substr(0, i));
text_copy = text_copy.substr(i + 1);
i = 0;
}
}
if (!text_copy.empty())
lines.emplace_back(text_copy);
for (auto& data: lines) {
int32_t max_top = 0;
int32_t min_top = 0;
int32_t max_bottom = 0;
int32_t min_bottom = 0;
for (const auto& ch: data.text) {
const auto item = get_atlas_item(ch);
if (!item)
continue;
max_top = std::max(max_top, item->top);
min_top = std::min(min_top, item->top);
max_bottom = std::max(max_bottom, item->bottom);
min_bottom = std::min(min_bottom, item->bottom);
}
data.max_top = max_top;
data.min_top = min_top;
data.max_bottom = max_bottom;
data.min_bottom = min_bottom;
}
std::vector<measured_ch> result;
float x = 0;
float y = 0;
Eigen::Vector2f pos{0, 0};
char32_t prev_char = 0;
for (const auto& ch : text) {
if (ch == U' ') {
x += space_width;
continue;
}
if (ch == U'\t') {
x += tab_width;
continue;
}
if (ch == U'\n') {
x = 0;
y += line_height;
y += line_gap;
y -= scale_padding * 2;
continue;
}
const auto item = get_atlas_item(ch);
measured_ch mch{};
mch.item = item;
mch.x_offset = x;
mch.y_offset = y;
mch.size_scale = scale;
if (item) {
// 如果字符高度大于行高, 则缩放
const float item_height = item->get_height() * scale;
if (item_height > line_height) {
mch.size_scale = line_height / item_height * scale;
for (const auto& line : lines) {
for (const auto& ch : line.text) {
if (ch == U' ') {
pos.x() += space_width;
continue;
}
if (ch == U'\t') {
pos.x() += tab_width;
continue;
}
float test = line_height - item->get_height() * mch.size_scale;
mch.y_offset += test;
x += item->get_width() * mch.size_scale;
prev_char = ch;
const auto item = get_atlas_item(ch);
measured_ch mch{};
mch.item = item;
mch.offset = pos;
mch.size_scale = scale;
if (item) {
// 如果字符高度大于行高, 则缩放
const float item_height = item->get_height() * scale;
if (item_height > line_height) {
mch.size_scale = line_height / item_height * scale;
}
// 注意字符坐标系的原点在左下角
// 如果字符的顶部高于行的顶部则将其对齐到min_top
if (item->top < 0) {
mch.offset.y() += (line.min_top - item->top) * mch.size_scale;
}
pos.x() += (item->right - item->left) * mch.size_scale;
}
result.push_back(mch);
}
result.push_back(mch);
pos.x() = 0;
pos.y() += line_height;
pos.y() += line_gap;
pos.y() -= scale_padding * 2;
}
return result;
}

View File

@@ -29,8 +29,7 @@ struct ch_atlas_item {
struct measured_ch {
ch_atlas_item const* item;
float x_offset;
float y_offset;
Eigen::Vector2f offset;
float size_scale;
};