mirror of
https://github.com/zhenyan121/SporeBG-Conid.git
synced 2026-04-10 06:14:08 +08:00
168 lines
6.5 KiB
C++
168 lines
6.5 KiB
C++
/**
|
||
* @file TextRenderer.h
|
||
* @brief 文本渲染器类,用于将带有特定样式的文本渲染到屏幕上
|
||
* @details 该类使用 SDL3 TTF 库进行文字渲染,并实现了纹理缓存机制以提高性能。
|
||
* 支持获取文本尺寸和渲染文本到指定位置。
|
||
* @author zhenyan121
|
||
* @date 2025-12-12
|
||
*/
|
||
|
||
#pragma once
|
||
#include <string>
|
||
#include <unordered_map>
|
||
#include <list>
|
||
#include <ctime>
|
||
#include <SDL3/SDL.h>
|
||
#include <SDL3_ttf/SDL_ttf.h>
|
||
#include "Textstyle.h"
|
||
#include "FontManager.h"
|
||
|
||
/**
|
||
* @class TextRenderer
|
||
* @brief 文本渲染器
|
||
* @details 负责管理文本渲染的生命周期,包括:
|
||
* - 文本纹理的创建和缓存
|
||
* - 文本尺寸的计算
|
||
* - 文本到指定屏幕位置的渲染
|
||
*
|
||
* 使用哈希缓存机制存储已渲染的文本纹理,避免重复创建相同的纹理。
|
||
*/
|
||
class TextRenderer {
|
||
|
||
public:
|
||
/**
|
||
* @brief 构造函数
|
||
* @param renderer SDL 渲染器指针,用于创建纹理和执行渲染操作。不可为 nullptr
|
||
* @param fontManager 字体管理器指针,用于获取指定字体 ID 和大小的字体对象。不可为 nullptr
|
||
* @details 初始化文本渲染器,设置必要的 SDL 渲染器和字体管理器引用
|
||
*/
|
||
TextRenderer(SDL_Renderer* renderer, FontManager* fontManager);
|
||
|
||
/**
|
||
* @brief 析构函数
|
||
* @details 自动释放所有缓存中的 SDL 纹理资源,防止内存泄漏
|
||
*/
|
||
~TextRenderer();
|
||
|
||
/**
|
||
* @brief 获取文本渲染后的尺寸
|
||
* @param text 要计算尺寸的文本内容。支持任意 UTF-8 字符串
|
||
* @param style 文本样式,包含字体 ID、大小、颜色等信息
|
||
* @return 返回一个 pair,first 为宽度(像素),second 为高度(像素);
|
||
* 如果渲染失败,返回 {0, 0}
|
||
* @details 该函数会检查缓存,如果文本纹理已存在则直接返回其尺寸;
|
||
* 否则创建新的纹理并缓存,然后返回尺寸。
|
||
* 这样可以避免重复渲染相同的文本。
|
||
* @note 返回的尺寸是矩形的宽和高
|
||
*/
|
||
std::pair<int, int> getTextSize(const std::string& text, TextStyle style);
|
||
|
||
/**
|
||
* @brief 将文本渲染到指定位置
|
||
* @param text 要渲染的文本内容。支持任意 UTF-8 字符串
|
||
* @param style 文本样式,包含字体 ID、大小、颜色等信息
|
||
* @param x 文本左上角的 X 坐标(像素)
|
||
* @param y 文本左上角的 Y 坐标(像素)
|
||
* @details 该函数会检查缓存,如果文本纹理已存在则直接使用;
|
||
* 否则创建新的纹理、缓存并渲染。
|
||
* 使用浮点数坐标进行渲染,支持亚像素精度。
|
||
* @note (x, y) 为文本左上角的顶点坐标
|
||
*/
|
||
void renderText(const std::string& text, TextStyle style, int x, int y);
|
||
|
||
/**
|
||
* @brief 为文本和样式生成哈希值
|
||
* @param text 文本内容
|
||
* @param style 文本样式
|
||
* @return 返回组合哈希值,用于缓存键的生成
|
||
* @details 利用文本内容、字体 ID、字体大小和颜色信息生成唯一的哈希值,
|
||
* 用于在缓存中快速查找已渲染的文本纹理
|
||
* @see m_cache
|
||
*/
|
||
size_t makeHash(const std::string& text, TextStyle style) const;
|
||
|
||
/**
|
||
* @brief 手动清理所有缓存
|
||
* @details 释放所有缓存中的纹理资源,完全清空缓存表
|
||
* @note 清理后任何文本都需要重新渲染
|
||
*/
|
||
void clearCache();
|
||
|
||
private:
|
||
/** @brief SDL 渲染器指针,用于创建纹理和执行 2D 渲染操作 */
|
||
SDL_Renderer* m_renderer;
|
||
|
||
/** @brief 字体管理器指针,用于管理和获取字体资源 */
|
||
FontManager* m_fontManager;
|
||
|
||
/**
|
||
* @struct CachedText
|
||
* @brief 缓存的文本纹理信息
|
||
* @details 存储已渲染文本的纹理及其尺寸信息,用于快速重用
|
||
*/
|
||
struct CachedText {
|
||
/** @brief 文本渲染后生成的 SDL 纹理指针 */
|
||
SDL_Texture* texture;
|
||
|
||
/** @brief 文本纹理的宽度(像素) */
|
||
int width;
|
||
|
||
/** @brief 文本纹理的高度(像素) */
|
||
int height;
|
||
|
||
/** @brief 该缓存项的最后访问时间戳(秒) */
|
||
time_t lastAccessTime;
|
||
};
|
||
|
||
/**
|
||
* @brief 文本纹理缓存容器
|
||
* @details 使用无序哈希表存储已渲染的文本纹理。
|
||
* 键是由文本内容、字体信息等生成的哈希值(通过 makeHash 生成);
|
||
* 值是对应的 CachedText 结构体,包含纹理指针和尺寸信息。
|
||
*
|
||
* 缓存机制的优势:
|
||
* - 避免重复渲染相同的文本
|
||
* - 提高渲染性能
|
||
* - 加速尺寸查询
|
||
* @see CachedText, makeHash()
|
||
*/
|
||
std::unordered_map<size_t, CachedText> m_cache;
|
||
|
||
/** @brief 最大缓存条目数,超过此数量会触发自动清理 */
|
||
static constexpr size_t MAX_CACHE_SIZE = 256;
|
||
|
||
/** @brief 缓存清理时保留的最少条目数(清理时会保留最常用的条目) */
|
||
static constexpr size_t MIN_CACHE_SIZE = 128;
|
||
|
||
/** @brief 自动清理缓存(当缓存超过最大限制时调用) */
|
||
void autoCleanCache();
|
||
|
||
/**
|
||
* @brief 创建文本纹理(暂未使用)
|
||
* @param text 文本内容
|
||
* @param fontID 字体 ID
|
||
* @param color 文本颜色
|
||
* @return 返回创建的纹理指针,创建失败时返回 nullptr
|
||
* @deprecated 该函数已被 createAndCacheTexture() 取代
|
||
*/
|
||
//SDL_Texture* createTextTexture(const std::string& text, const std::string& fontID, SDL_Color color);
|
||
|
||
/**
|
||
* @brief 创建并缓存文本纹理
|
||
* @param text 文本内容
|
||
* @param style 文本样式
|
||
* @return 返回 CachedText 结构体,包含创建的纹理和尺寸信息;
|
||
* 创建失败时返回空结构体(texture 为 nullptr)
|
||
* @details 该函数执行以下步骤:
|
||
* 1. 从字体管理器获取指定字体
|
||
* 2. 使用 TTF 库将文本渲染为表面(Surface)
|
||
* 3. 将表面转换为 SDL 纹理
|
||
* 4. 立即释放表面以节省内存
|
||
* 5. 将纹理和尺寸信息存储到缓存中
|
||
* 6. 返回结果
|
||
* @see CachedText, m_cache
|
||
*/
|
||
CachedText createAndCacheTexture(const std::string& text, TextStyle style);
|
||
|
||
};
|