Extra2D/include/resource/font.h

175 lines
5.1 KiB
C
Raw Normal View History

#pragma once
#include <resource/resource.h>
#include <resource/font_atlas.h>
#include <types/math/vec2.h>
#include <types/base/types.h>
#include <string>
#include <vector>
// FreeType 头文件
#include <ft2build.h>
#include FT_FREETYPE_H
namespace extra2d {
/**
* @brief
*/
namespace CommonCharset {
// ASCII 可打印字符
constexpr const char* ASCII =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";
// 常用中文前100个高频字
constexpr const char* CHINESE_COMMON =
"的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成"
"会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着"
"等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把";
// 英文标点
constexpr const char* PUNCTUATION_EN = ".,;:!?-'\"()[]{}/|\\@#$%&*+-_=<>~`";
// 中文标点
constexpr const char* PUNCTUATION_CN = ",。、;:!?\"\"''()【】《》";
}
/**
* @brief
*/
struct FontConfig {
uint32 fontSize = 16; // 字体大小(像素)
bool useSDF = false; // 是否使用 SDF有向距离场
uint32 sdfPadding = 4; // SDF 边距
bool preloadCommon = true; // 是否预加载常用字符
bool hinting = true; // 是否使用字体 hinting
};
/**
* @brief
*
* 使 FreeType
*/
class Font : public Resource {
public:
Font();
~Font() override;
/**
* @brief
*/
ResourceType getType() const override { return ResourceType::Font; }
/**
* @brief
* @param path
* @param config
* @return
*/
bool loadFromFile(const std::string& path, const FontConfig& config);
/**
* @brief
* @param data
* @param config
* @return
*/
bool loadFromMemory(const std::vector<uint8>& data, const FontConfig& config);
/**
* @brief
* @param codepoint Unicode
* @return nullptr
*/
const GlyphInfo* getGlyph(uint32 codepoint);
/**
* @brief
* @param text
* @param fontSize 0 使
* @return
*/
Vec2 measureText(const std::string& text, float fontSize = 0.0f);
/**
* @brief
* @param codepoint1
* @param codepoint2
* @return
*/
float getKerning(uint32 codepoint1, uint32 codepoint2);
/**
* @brief
* @param fontSize 0 使
* @return
*/
float getLineHeight(float fontSize = 0.0f) const;
/**
* @brief
*/
FontAtlas* getAtlas() const { return atlas_.get(); }
/**
* @brief
* @param charset
*/
void preloadCharset(const std::string& charset);
/**
* @brief
*/
const FontConfig& getConfig() const { return config_; }
/**
* @brief
* @param outAscender
* @param outDescender
* @param outLineHeight
*/
void getMetrics(float& outAscender, float& outDescender, float& outLineHeight) const;
private:
FT_Face face_ = nullptr; // FreeType 字体面
FontConfig config_; // 字体配置
Ptr<FontAtlas> atlas_; // 字体图集
float baseScale_ = 1.0f; // 基础缩放比例
std::vector<uint8> fontData_; // 字体数据(保持内存中)
// FreeType 库静态实例
static FT_Library ftLibrary_;
static bool ftInitialized_;
/**
* @brief FreeType
*/
static bool initFreeType();
/**
* @brief
* @param codepoint Unicode
* @param outWidth
* @param outHeight
* @param outBearingX 线
* @param outBearingY 线
* @param outAdvance
* @param outBitmap
* @return
*/
bool renderGlyph(uint32 codepoint, uint32& outWidth, uint32& outHeight,
float& outBearingX, float& outBearingY, float& outAdvance,
std::vector<uint8>& outBitmap);
/**
* @brief UTF-8 Unicode
* @param text UTF-8
* @return Unicode
*/
static std::vector<uint32> utf8ToCodepoints(const std::string& text);
};
} // namespace extra2d