修改测试用例
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user