mirror of
https://github.com/m1ngsama/TUT.git
synced 2025-12-26 12:04:11 +00:00
Major features: - New modular architecture with Terminal, FrameBuffer, Renderer layers - True Color (24-bit) support with warm, eye-friendly color scheme - Unicode support with proper CJK character width handling - Differential rendering for improved performance - Page caching (LRU, 20 pages, 5-minute expiry) - Search functionality with highlighting (/, n/N) - Form rendering (input, button, checkbox, radio, select) - Image placeholder support ([alt text] or [Image: filename]) - Binary data download via fetch_binary() - Loading state indicators New files: - src/browser_v2.cpp/h - Browser with new rendering system - src/main_v2.cpp - Entry point for tut2 - src/render/* - Terminal, FrameBuffer, Renderer, Layout, Image modules - src/utils/unicode.cpp/h - Unicode handling utilities - tests/* - Test programs for each module Build with: cmake --build build_v2 Run: ./build_v2/tut2 [URL]
156 lines
4.8 KiB
C++
156 lines
4.8 KiB
C++
/**
|
|
* test_renderer.cpp - FrameBuffer 和 Renderer 测试
|
|
*
|
|
* 测试内容:
|
|
* 1. Unicode字符宽度计算
|
|
* 2. FrameBuffer操作
|
|
* 3. 差分渲染演示
|
|
*/
|
|
|
|
#include "render/terminal.h"
|
|
#include "render/renderer.h"
|
|
#include "render/colors.h"
|
|
#include "render/decorations.h"
|
|
#include "utils/unicode.h"
|
|
#include <iostream>
|
|
#include <thread>
|
|
#include <chrono>
|
|
|
|
using namespace tut;
|
|
|
|
void test_unicode() {
|
|
std::cout << "=== Unicode 测试 ===\n";
|
|
|
|
// 测试用例
|
|
struct TestCase {
|
|
std::string text;
|
|
size_t expected_width;
|
|
const char* description;
|
|
};
|
|
|
|
TestCase tests[] = {
|
|
{"Hello", 5, "ASCII"},
|
|
{"你好", 4, "中文(2字符,宽度4)"},
|
|
{"Hello世界", 9, "混合ASCII+中文"},
|
|
{"🎉", 2, "Emoji"},
|
|
{"café", 4, "带重音符号"},
|
|
};
|
|
|
|
bool all_passed = true;
|
|
for (const auto& tc : tests) {
|
|
size_t width = Unicode::display_width(tc.text);
|
|
bool pass = (width == tc.expected_width);
|
|
std::cout << (pass ? "[OK] " : "[FAIL] ")
|
|
<< tc.description << ": \"" << tc.text << "\" "
|
|
<< "width=" << width
|
|
<< " (expected " << tc.expected_width << ")\n";
|
|
if (!pass) all_passed = false;
|
|
}
|
|
|
|
std::cout << (all_passed ? "\n所有Unicode测试通过!\n" : "\n部分测试失败!\n");
|
|
}
|
|
|
|
void test_framebuffer() {
|
|
std::cout << "\n=== FrameBuffer 测试 ===\n";
|
|
|
|
FrameBuffer fb(80, 24);
|
|
std::cout << "创建 80x24 FrameBuffer: OK\n";
|
|
|
|
// 测试set_text
|
|
fb.set_text(0, 0, "Hello World", colors::FG_PRIMARY, colors::BG_PRIMARY);
|
|
std::cout << "set_text ASCII: OK\n";
|
|
|
|
fb.set_text(0, 1, "你好世界", colors::H1_FG, colors::BG_PRIMARY);
|
|
std::cout << "set_text 中文: OK\n";
|
|
|
|
// 验证单元格
|
|
const Cell& cell = fb.get_cell(0, 0);
|
|
if (cell.content == "H" && cell.fg == colors::FG_PRIMARY) {
|
|
std::cout << "get_cell 验证: OK\n";
|
|
} else {
|
|
std::cout << "get_cell 验证: FAIL\n";
|
|
}
|
|
|
|
std::cout << "FrameBuffer 测试完成!\n";
|
|
}
|
|
|
|
void demo_renderer(Terminal& term) {
|
|
int w, h;
|
|
term.get_size(w, h);
|
|
|
|
FrameBuffer fb(w, h);
|
|
Renderer renderer(term);
|
|
|
|
// 清屏并显示标题
|
|
fb.clear_with_color(colors::BG_PRIMARY);
|
|
|
|
// 标题
|
|
std::string title = "TUT 2.0 - Renderer Demo";
|
|
int title_x = (w - Unicode::display_width(title)) / 2;
|
|
fb.set_text(title_x, 1, title, colors::H1_FG, colors::BG_PRIMARY, ATTR_BOLD);
|
|
|
|
// 分隔线
|
|
std::string line = make_horizontal_line(w - 4, chars::SGL_HORIZONTAL);
|
|
fb.set_text(2, 2, line, colors::BORDER, colors::BG_PRIMARY);
|
|
|
|
// 颜色示例
|
|
fb.set_text(2, 4, "颜色示例:", colors::FG_PRIMARY, colors::BG_PRIMARY, ATTR_BOLD);
|
|
fb.set_text(4, 5, chars::BULLET + std::string(" H1标题色"), colors::H1_FG, colors::BG_PRIMARY);
|
|
fb.set_text(4, 6, chars::BULLET + std::string(" H2标题色"), colors::H2_FG, colors::BG_PRIMARY);
|
|
fb.set_text(4, 7, chars::BULLET + std::string(" H3标题色"), colors::H3_FG, colors::BG_PRIMARY);
|
|
fb.set_text(4, 8, chars::BULLET + std::string(" 链接色"), colors::LINK_FG, colors::BG_PRIMARY);
|
|
|
|
// 装饰字符示例
|
|
fb.set_text(2, 10, "装饰字符:", colors::FG_PRIMARY, colors::BG_PRIMARY, ATTR_BOLD);
|
|
fb.set_text(4, 11, std::string(chars::DBL_TOP_LEFT) + make_horizontal_line(20, chars::DBL_HORIZONTAL) + chars::DBL_TOP_RIGHT,
|
|
colors::BORDER, colors::BG_PRIMARY);
|
|
fb.set_text(4, 12, std::string(chars::DBL_VERTICAL) + " 双线边框示例 " + chars::DBL_VERTICAL,
|
|
colors::BORDER, colors::BG_PRIMARY);
|
|
fb.set_text(4, 13, std::string(chars::DBL_BOTTOM_LEFT) + make_horizontal_line(20, chars::DBL_HORIZONTAL) + chars::DBL_BOTTOM_RIGHT,
|
|
colors::BORDER, colors::BG_PRIMARY);
|
|
|
|
// Unicode宽度示例
|
|
fb.set_text(2, 15, "Unicode宽度:", colors::FG_PRIMARY, colors::BG_PRIMARY, ATTR_BOLD);
|
|
fb.set_text(4, 16, "ASCII: Hello (5)", colors::FG_SECONDARY, colors::BG_PRIMARY);
|
|
fb.set_text(4, 17, "中文: 你好世界 (8)", colors::FG_SECONDARY, colors::BG_PRIMARY);
|
|
|
|
// 提示
|
|
fb.set_text(2, h - 2, "按 'q' 退出", colors::FG_DIM, colors::BG_PRIMARY);
|
|
|
|
// 渲染
|
|
renderer.render(fb);
|
|
|
|
// 等待退出
|
|
while (true) {
|
|
int key = term.get_key(100);
|
|
if (key == 'q' || key == 'Q') break;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
// 先运行非终端测试
|
|
test_unicode();
|
|
test_framebuffer();
|
|
|
|
std::cout << "\n按回车键进入交互演示 (或 Ctrl+C 退出)...\n";
|
|
std::cin.get();
|
|
|
|
// 交互演示
|
|
Terminal term;
|
|
if (!term.init()) {
|
|
std::cerr << "终端初始化失败!\n";
|
|
return 1;
|
|
}
|
|
|
|
term.use_alternate_screen(true);
|
|
term.hide_cursor();
|
|
|
|
demo_renderer(term);
|
|
|
|
term.show_cursor();
|
|
term.use_alternate_screen(false);
|
|
term.cleanup();
|
|
|
|
std::cout << "Renderer 测试完成!\n";
|
|
return 0;
|
|
}
|