修改为filesystem作为路径参数类型
This commit is contained in:
parent
7206c04a71
commit
4036ee2ded
@ -16,7 +16,7 @@ int main(int argc, char* argv[]) {
|
||||
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! 你好,世界!🥶😅😎");
|
||||
text_block->set_text(U"Hello, World! 你好,世界!🥶");
|
||||
|
||||
const auto& text_block2 = std::make_shared<mtext_block>();
|
||||
text_block2->set_text(U"Hello, World!");
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <filesystem>
|
||||
|
||||
class mapped_file {
|
||||
public:
|
||||
@ -12,7 +13,7 @@ public:
|
||||
mapped_file(const mapped_file&) = delete;
|
||||
mapped_file& operator=(const mapped_file&) = delete;
|
||||
|
||||
virtual bool map_file(const std::wstring& filename) = 0;
|
||||
virtual bool map_file(const std::filesystem::path& filename) = 0;
|
||||
virtual void unmap() = 0;
|
||||
|
||||
[[nodiscard]] virtual const void* get_data() const = 0;
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
mapped_file_unix(mapped_file_unix&& other) noexcept;
|
||||
mapped_file_unix& operator=(mapped_file_unix&& other) noexcept;
|
||||
|
||||
bool map_file(const std::wstring& filename);
|
||||
bool map_file(const std::filesystem::path& filename);
|
||||
void unmap();
|
||||
|
||||
[[nodiscard]] const void* get_data() const { return data; }
|
||||
@ -61,7 +61,7 @@ mapped_file_unix& mapped_file_unix::operator=(mapped_file_unix&& other) noexcept
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool mapped_file_unix::map_file(const std::wstring& filename) {
|
||||
bool mapped_file_unix::map_file(const std::filesystem::path& filename) {
|
||||
cleanup();
|
||||
|
||||
std::string utf8_filename(filename.begin(), filename.end());
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
mapped_file_win(mapped_file_win&& other) noexcept;
|
||||
mapped_file_win& operator=(mapped_file_win&& other) noexcept;
|
||||
|
||||
bool map_file(const std::wstring& filename) override;
|
||||
bool map_file(const std::filesystem::path& filename) override;
|
||||
void unmap() override;
|
||||
|
||||
[[nodiscard]] const void* get_data() const override { return data_; }
|
||||
@ -68,7 +68,7 @@ mapped_file_win& mapped_file_win::operator=(mapped_file_win&& other) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool mapped_file_win::map_file(const std::wstring& filename) {
|
||||
bool mapped_file_win::map_file(const std::filesystem::path& filename) {
|
||||
cleanup();
|
||||
|
||||
file_handle_ = CreateFileW(
|
||||
|
@ -12,7 +12,7 @@ font_face_t::font_face_t() {
|
||||
// 延迟初始化渲染器,直到加载字体
|
||||
}
|
||||
|
||||
bool font_face_t::load_from_file(const std::wstring& font_path) {
|
||||
bool font_face_t::load_from_file(const std::filesystem::path& font_path) {
|
||||
// 读取字体文件数据
|
||||
if (!load_font_data(font_path)) {
|
||||
return false;
|
||||
@ -260,7 +260,7 @@ void font_face_t::init_renderers() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool font_face_t::load_font_data(const std::wstring& font_path) {
|
||||
bool font_face_t::load_font_data(const std::filesystem::path& font_path) {
|
||||
// 创建内存映射文件
|
||||
font_data_ = mapped_file::create();
|
||||
if (!font_data_ || !font_data_->map_file(font_path)) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "stb_truetype.h"
|
||||
#include "misc/mapped_file/mapped_file.h"
|
||||
#include "font_renderer/font_renderer.h"
|
||||
#include <filesystem>
|
||||
|
||||
/**
|
||||
* @class font_face_t
|
||||
@ -43,7 +44,7 @@ public:
|
||||
* @param font_path 字体文件路径
|
||||
* @return 是否成功加载
|
||||
*/
|
||||
bool load_from_file(const std::wstring& font_path);
|
||||
bool load_from_file(const std::filesystem::path& font_path);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 字体度量信息
|
||||
@ -227,7 +228,7 @@ private:
|
||||
* @param font_path 字体文件路径
|
||||
* @return 是否成功
|
||||
*/
|
||||
bool load_font_data(const std::wstring& font_path);
|
||||
bool load_font_data(const std::filesystem::path& font_path);
|
||||
|
||||
/**
|
||||
* @brief 从字体数据中提取字体名称
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "colr_renderer.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "font/font_utils.h"
|
||||
#include "font/stb_truetype.h"
|
||||
|
||||
@ -8,6 +10,125 @@ bool colr_renderer_t::supports_font(const uint8_t* font_data, int font_offset) c
|
||||
font::find_table_offset(font_data, font_offset, "CPAL") != 0;
|
||||
}
|
||||
|
||||
void save_bitmap(const std::string& filename, const color_emoji_bitmap_t& bitmap) {
|
||||
// 检查输入有效性
|
||||
if (bitmap.width <= 0 || bitmap.height <= 0 || bitmap.data.empty()) {
|
||||
throw std::invalid_argument("Invalid bitmap data");
|
||||
}
|
||||
|
||||
if (bitmap.data.size() < static_cast<size_t>(bitmap.width * bitmap.height * 4)) {
|
||||
throw std::invalid_argument("Bitmap data size doesn't match dimensions");
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
// BMP文件头结构
|
||||
struct BITMAPFILEHEADER {
|
||||
uint16_t bfType; // 文件类型,必须是"BM"(0x4D42)
|
||||
uint32_t bfSize; // 文件大小
|
||||
uint16_t bfReserved1; // 保留,必须为0
|
||||
uint16_t bfReserved2; // 保留,必须为0
|
||||
uint32_t bfOffBits; // 从文件开始到像素数据的偏移量
|
||||
};
|
||||
|
||||
// BMP V4信息头结构,**支持Alpha通道**
|
||||
struct BITMAPV4HEADER {
|
||||
uint32_t biSize; // 信息头大小
|
||||
int32_t biWidth; // 图像宽度
|
||||
int32_t biHeight; // 图像高度
|
||||
uint16_t biPlanes; // 颜色平面数,必须为1
|
||||
uint16_t biBitCount; // 每个像素的位数
|
||||
uint32_t biCompression; // 压缩方式
|
||||
uint32_t biSizeImage; // 图像大小
|
||||
int32_t biXPelsPerMeter; // 水平分辨率
|
||||
int32_t biYPelsPerMeter; // 垂直分辨率
|
||||
uint32_t biClrUsed; // 使用的颜色索引数
|
||||
uint32_t biClrImportant; // 重要的颜色索引数
|
||||
uint32_t bV4RedMask; // 红色掩码
|
||||
uint32_t bV4GreenMask; // 绿色掩码
|
||||
uint32_t bV4BlueMask; // 蓝色掩码
|
||||
uint32_t bV4AlphaMask; // Alpha掩码
|
||||
uint32_t bV4CSType; // 颜色空间类型
|
||||
uint8_t bV4Endpoints[36]; // 端点
|
||||
uint32_t bV4GammaRed; // 红色Gamma
|
||||
uint32_t bV4GammaGreen; // 绿色Gamma
|
||||
uint32_t bV4GammaBlue; // 蓝色Gamma
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// 常量定义
|
||||
const uint32_t BI_BITFIELDS = 3; // 位域压缩
|
||||
const uint16_t BMP_SIGNATURE = 0x4D42; // "BM"
|
||||
|
||||
// 计算文件大小
|
||||
int rowSize = ((bitmap.width * 32 + 31) / 32) * 4; // 每行字节数(必须是4的倍数)
|
||||
int dataSize = rowSize * bitmap.height;
|
||||
int fileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPV4HEADER) + dataSize;
|
||||
|
||||
// 准备文件头
|
||||
BITMAPFILEHEADER fileHeader = {0};
|
||||
fileHeader.bfType = BMP_SIGNATURE;
|
||||
fileHeader.bfSize = fileSize;
|
||||
fileHeader.bfReserved1 = 0;
|
||||
fileHeader.bfReserved2 = 0;
|
||||
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPV4HEADER);
|
||||
|
||||
// 准备信息头
|
||||
BITMAPV4HEADER infoHeader = {0};
|
||||
infoHeader.biSize = sizeof(BITMAPV4HEADER);
|
||||
infoHeader.biWidth = bitmap.width;
|
||||
infoHeader.biHeight = bitmap.height; // **正值表示图像从下到上存储**
|
||||
infoHeader.biPlanes = 1;
|
||||
infoHeader.biBitCount = 32; // 32位每像素(BGRA)
|
||||
infoHeader.biCompression = BI_BITFIELDS;
|
||||
infoHeader.biSizeImage = dataSize;
|
||||
infoHeader.biXPelsPerMeter = 0;
|
||||
infoHeader.biYPelsPerMeter = 0;
|
||||
infoHeader.biClrUsed = 0;
|
||||
infoHeader.biClrImportant = 0;
|
||||
infoHeader.bV4RedMask = 0x00FF0000; // R在第3字节
|
||||
infoHeader.bV4GreenMask = 0x0000FF00; // G在第2字节
|
||||
infoHeader.bV4BlueMask = 0x000000FF; // B在第1字节
|
||||
infoHeader.bV4AlphaMask = 0xFF000000; // A在第4字节
|
||||
infoHeader.bV4CSType = 0; // LCS_CALIBRATED_RGB
|
||||
|
||||
// 打开文件
|
||||
std::ofstream file(filename, std::ios::binary);
|
||||
if (!file) {
|
||||
throw std::runtime_error("Failed to open file for writing: " + filename);
|
||||
}
|
||||
|
||||
// 写入文件头
|
||||
file.write(reinterpret_cast<const char*>(&fileHeader), sizeof(fileHeader));
|
||||
|
||||
// 写入信息头
|
||||
file.write(reinterpret_cast<const char*>(&infoHeader), sizeof(infoHeader));
|
||||
|
||||
// 转换并写入像素数据
|
||||
// **BMP存储顺序是从下到上,从左到右,且是BGRA而不是RGBA**
|
||||
std::vector<uint8_t> bmpData(dataSize, 0); // 初始化为0
|
||||
|
||||
for (int y = 0; y < bitmap.height; y++) {
|
||||
for (int x = 0; x < bitmap.width; x++) {
|
||||
// 计算源数据和目标数据的索引
|
||||
size_t srcIndex = (y * bitmap.width + x) * 4; // RGBA
|
||||
size_t destIndex = ((bitmap.height - 1 - y) * rowSize) + (x * 4); // BGRA, 从下到上
|
||||
|
||||
// RGBA -> BGRA
|
||||
bmpData[destIndex + 0] = bitmap.data[srcIndex + 2]; // B <- R
|
||||
bmpData[destIndex + 1] = bitmap.data[srcIndex + 1]; // G <- G
|
||||
bmpData[destIndex + 2] = bitmap.data[srcIndex + 0]; // R <- B
|
||||
bmpData[destIndex + 3] = bitmap.data[srcIndex + 3]; // A <- A
|
||||
}
|
||||
}
|
||||
|
||||
// 写入像素数据
|
||||
file.write(reinterpret_cast<const char*>(bmpData.data()), dataSize);
|
||||
|
||||
if (!file.good()) {
|
||||
throw std::runtime_error("Error occurred while writing to file: " + filename);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<color_emoji_bitmap_t> colr_renderer_t::render_emoji(
|
||||
const stbtt_fontinfo& font_info,
|
||||
const uint8_t* font_data,
|
||||
@ -160,6 +281,10 @@ std::optional<color_emoji_bitmap_t> colr_renderer_t::render_emoji(
|
||||
layer_width, layer_height, layer_width,
|
||||
scale, scale, layer_glyph_id);
|
||||
|
||||
// 测试,保存BMP
|
||||
save_bitmap(std::to_string(i) + ".bmp", bitmap);
|
||||
|
||||
|
||||
// 计算图层在最终位图中的位置
|
||||
const int offset_x = layer_x0 - x0;
|
||||
const int offset_y = layer_y0 - y0;
|
||||
@ -189,9 +314,9 @@ std::optional<color_emoji_bitmap_t> colr_renderer_t::render_emoji(
|
||||
|
||||
// 对于细节图层(如眼睛),增强其影响
|
||||
float enhanced_alpha = src_alpha;
|
||||
if (palette_entry_index > 0 && src_alpha > 0) { // 非底色图层且有透明度
|
||||
enhanced_alpha = std::min(src_alpha * 1.2f, 1.0f); // 稍微增强
|
||||
}
|
||||
// if (palette_entry_index > 0 && src_alpha > 0) { // 非底色图层且有透明度
|
||||
// enhanced_alpha = std::min(src_alpha * 1.2f, 1.0f); // 稍微增强
|
||||
// }
|
||||
|
||||
const float dst_alpha = bitmap.data[dst_idx + 3] / 255.0f;
|
||||
const float out_alpha = enhanced_alpha + dst_alpha * (1.0f - enhanced_alpha);
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "font_system.h"
|
||||
|
||||
#include "emoji_detector.h"
|
||||
|
||||
void font_manager::destroy() {
|
||||
fonts_.clear();
|
||||
emoji_font_ids_.clear();
|
||||
@ -8,7 +10,7 @@ void font_manager::destroy() {
|
||||
next_font_id_ = 0;
|
||||
}
|
||||
|
||||
int font_manager::add_font(const std::wstring& in_font_path, const std::string& in_font_type) {
|
||||
int font_manager::add_font(const std::filesystem::path& in_font_path, const std::string& in_font_type) {
|
||||
auto font = std::make_shared<font_face_t>();
|
||||
if (!font->load_from_file(in_font_path)) {
|
||||
return -1;
|
||||
|
@ -5,12 +5,10 @@
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
|
||||
#include "emoji_detector.h"
|
||||
#include "font_face.h"
|
||||
#include "atlas/bitmap_glyph_atlas.h"
|
||||
#include "atlas/color_emoji_atlas.h"
|
||||
#include "atlas/font_atlas.h"
|
||||
#include "atlas/font_atlas_manager.h"
|
||||
#include <filesystem>
|
||||
|
||||
/**
|
||||
* @class font_manager
|
||||
@ -48,7 +46,7 @@ public:
|
||||
* @param in_font_type 字体类型(regular, bold, italic, emoji等)
|
||||
* @return 添加成功返回字体ID,失败返回-1
|
||||
*/
|
||||
int add_font(const std::wstring& in_font_path, const std::string& in_font_type = "regular");
|
||||
int add_font(const std::filesystem::path& in_font_path, const std::string& in_font_type = "regular");
|
||||
|
||||
/**
|
||||
* @brief 设置主字体
|
||||
|
@ -142,10 +142,10 @@ struct text_layout_t {
|
||||
atlas_region_t region; // 纹理图集区域
|
||||
};
|
||||
|
||||
std::vector<glyph_position_t> glyphs; // 所有字形位置
|
||||
Eigen::Vector2f total_size; // 文本总尺寸
|
||||
float ascent; // 上升高度
|
||||
float baseline = 0.0f; // 基线位置
|
||||
std::vector<glyph_position_t> glyphs; // 所有字形位置
|
||||
Eigen::Vector2f total_size; // 文本总尺寸
|
||||
float ascent; // 上升高度
|
||||
float baseline; // 基线位置
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -42,8 +42,8 @@ private:
|
||||
void update_layout();
|
||||
|
||||
std::u32string text_;
|
||||
text_layout_t layout_;
|
||||
float font_size_ = 24.0f * 1.5f;
|
||||
text_layout_t layout_{};
|
||||
float font_size_ = 15.0f;
|
||||
float line_spacing_ = 1.2f;
|
||||
float max_width_ = 0.0f;
|
||||
std::shared_ptr<font_face_t> font_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user