完成垂直方向布局

This commit is contained in:
Nanako 2024-12-27 22:19:19 +08:00
parent b50d7e46a7
commit 9b6527f2da
5 changed files with 55 additions and 35 deletions

View File

@ -113,9 +113,12 @@ 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"你好,世界!\nТест по русскому языку\nテスト", 32, {0, 0, 0, 1});
float font_height = 64;
context.draw_string({0, 100}, U"你好,世界!\nТест по русскому языку\nテスト", font_height, {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.draw_rectangle({ 0, 100 + font_height }, { 2048, 1 }, { 1, 0, 1, 1 });
context.draw_rectangle({ 0, 100 + font_height * 2 }, { 2048, 1 }, { 1, 0, 1, 1 });
context.draw_rectangle({ 0, 100 + font_height * 3 }, { 2048, 1 }, { 1, 0, 1, 1 });
context.flush();

View File

@ -8,7 +8,7 @@ aorii_text* text = nullptr;
void renderer_context::init() {
text = new aorii_text();
// D:\Projects\aorii\JetBrainsMono-Regular.ttf
text->initialize(LR"(C:\Windows\Fonts\simhei.ttf)");
text->initialize(LR"(HarmonyOS_Sans_SC_Regular.ttf)");
text->add_font(LR"(C:\Windows\Fonts\seguiemj.ttf)");
// text->precache_common_characters();
}

View File

@ -184,7 +184,7 @@ 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 float line_gap = primary_font.line_gap * scale;
const int32_t line_height = height;
const float line_height = height;
const float space_width = primary_font.space_width * scale;
const float tab_width = primary_font.tab_width * scale;
@ -209,29 +209,39 @@ std::vector<measured_ch> aorii_text::measure_text(const std::u32string& text, fl
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;
int32_t max_top = 0;
int32_t max_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);
max_top = std::max(max_top, item->top);
max_bottom = std::max(max_bottom, item->bottom);
}
data.max_top = max_top;
data.min_top = min_top;
data.max_bottom = max_bottom;
data.min_bottom = min_bottom;
data.max_top = max_top;
data.max_bottom = max_bottom;
// 如果min_top小于0, 则将max_bottom减去min_top
// if (min_top < 0) {
// data.max_bottom -= min_top;
// data.min_bottom -= min_top;
// data.max_top -= min_top;
// data.min_top = 0;
// }
}
std::vector<measured_ch> result;
Eigen::Vector2f pos{0, 0};
for (const auto& line : lines) {
// 计算这一行顶部和底部的最大和最小值,然后进行垂直居中
const float top_offset = (line_height - (line.max_bottom - line.min_top) * scale) / 2;
for (const auto& ch : line.text) {
if (ch == U' ') {
pos.x() += space_width;
@ -253,14 +263,17 @@ std::vector<measured_ch> aorii_text::measure_text(const std::u32string& text, fl
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;
}
// 将字符底部对齐到行底部
const float bottom_offset = item->bottom - line.max_bottom;
mch.offset.y() -= bottom_offset * mch.size_scale;
// mch.offset.y() += line_height;
pos.x() += (item->right - item->left) * mch.size_scale;
mch.offset.y() += top_offset;
// mch.offset.x() += item->left * mch.size_scale;
pos.x() += item->x_advance * mch.size_scale;
// pos.x() -= item->left * mch.size_scale;
}
result.push_back(mch);
}
@ -268,7 +281,7 @@ std::vector<measured_ch> aorii_text::measure_text(const std::u32string& text, fl
pos.x() = 0;
pos.y() += line_height;
pos.y() += line_gap;
pos.y() -= scale_padding * 2;
// pos.y() -= scale_padding * 2;
}
return result;
}
@ -344,7 +357,11 @@ ch_atlas_item const* aorii_text::cache_ch_to_atlas(char32_t ch) {
stbtt_GetGlyphHMetrics(font, glyph_index, &advance_width, &left_side_bearing);
int ch_x0, ch_y0, ch_x1, ch_y1;
stbtt_GetGlyphBox(font, glyph_index, &ch_x0, &ch_y0, &ch_x1, &ch_y1);
spdlog::info("left: {}, right: {}, top: {}, bottom: {}", ch_x0, ch_x1, ch_y0, ch_y1);
int width_log = ch_x1 - ch_x0;
int height_log = ch_y1 - ch_y0;
spdlog::info("left: {}, right: {}, top: {}, bottom: {}, width: {}, height: {}, x_advance: {}, left_side_bearing: {}",
ch_x0, ch_x1, ch_y0, ch_y1, width_log, height_log, advance_width, left_side_bearing);
// 将x_offset和y_offset转换到字体空间
x_offset = x_offset / scale;

View File

@ -7,24 +7,24 @@ class renderer_texture_array;
struct stbtt_fontinfo;
struct ch_atlas_item {
float tex_u; // U position in atlas
float tex_v; // V position in atlas
uint8_t tex_z; // Z position in texture array
float u_size; // Texture width
float v_size; // Texture height
float tex_u; // 图集中的U位置
float tex_v; // 图集中的V位置
uint8_t tex_z; // 图集索引
float u_size; // U方向尺寸
float v_size; // V方向尺寸
int32_t x_offset; // X offset from baseline
int32_t y_offset; // Y offset from baseline
int32_t x_offset; // SDF纹理的X偏移量
int32_t y_offset; // SDF纹理的Y偏移量
int32_t left;
int32_t right;
int32_t top;
int32_t bottom;
int32_t get_width() const { return right - left; }
int32_t get_height() const { return bottom - top; }
int32_t left; // 字形的左边界
int32_t right; // 字形的右边界
int32_t top; // 字形的顶部
int32_t bottom; // 字形的底部
[[nodiscard]] int32_t get_width() const { return right - left; }
[[nodiscard]] int32_t get_height() const { return bottom - top; }
int32_t x_advance;
int32_t left_side_bearing;
int32_t x_advance; // 字形的X进度
int32_t left_side_bearing; // 字形的左侧轴承
};
struct measured_ch {

View File

@ -42,9 +42,9 @@ SamplerState sampler_state : register(s0);
float4 pixel_main(PSInput input) : SV_Target {
float2 uv = input.altas_uv + input.char_size * input.uv;
float distance = atlas_texture.Sample(sampler_state, float3(uv, input.altas_index)).r;
return float4(distance, distance, distance, 1.0);
// return float4(distance, distance, distance, 1.0);
float range = 0.2;
float alpha = smoothstep(0.4, 0.5, distance);
float alpha = smoothstep(0.3, 0.6, distance);
float4 color = input.color;
color.a *= alpha;