feat(fairygui): FairyGUI 完整集成 (#314)
* feat(fairygui): FairyGUI ECS 集成核心架构 实现 FairyGUI 的 ECS 原生集成,完全替代旧 UI 系统: 核心类: - GObject: UI 对象基类,支持变换、可见性、关联、齿轮 - GComponent: 容器组件,管理子对象和控制器 - GRoot: 根容器,管理焦点、弹窗、输入分发 - GGroup: 组容器,支持水平/垂直布局 抽象层: - DisplayObject: 显示对象基类 - EventDispatcher: 事件分发 - Timer: 计时器 - Stage: 舞台,管理输入和缩放 布局系统: - Relations: 约束关联管理 - RelationItem: 24 种关联类型 基础设施: - Controller: 状态控制器 - Transition: 过渡动画 - ScrollPane: 滚动面板 - UIPackage: 包管理 - ByteBuffer: 二进制解析 * refactor(ui): 删除旧 UI 系统,使用 FairyGUI 替代 * feat(fairygui): 实现 UI 控件 - 添加显示类:Image、TextField、Graph - 添加基础控件:GImage、GTextField、GGraph - 添加交互控件:GButton、GProgressBar、GSlider - 更新 IRenderCollector 支持 Graph 渲染 - 扩展 Controller 添加 selectedPageId - 添加 STATE_CHANGED 事件类型 * feat(fairygui): 现代化架构重构 - 增强 EventDispatcher 支持类型安全、优先级和传播控制 - 添加 PropertyBinding 响应式属性绑定系统 - 添加 ServiceContainer 依赖注入容器 - 添加 UIConfig 全局配置系统 - 添加 UIObjectFactory 对象工厂 - 实现 RenderBridge 渲染桥接层 - 实现 Canvas2DBackend 作为默认渲染后端 - 扩展 IRenderCollector 支持更多图元类型 * feat(fairygui): 九宫格渲染和资源加载修复 - 修复 FGUIUpdateSystem 支持路径和 GUID 两种加载方式 - 修复 GTextInput 同时设置 _displayObject 和 _textField - 实现九宫格渲染展开为 9 个子图元 - 添加 sourceWidth/sourceHeight 用于九宫格计算 - 添加 DOMTextRenderer 文本渲染层(临时方案) * fix(fairygui): 修复 GGraph 颜色读取 * feat(fairygui): 虚拟节点 Inspector 和文本渲染支持 * fix(fairygui): 编辑器状态刷新和遗留引用修复 - 修复切换 FGUI 包后组件列表未刷新问题 - 修复切换组件后 viewport 未清理旧内容问题 - 修复虚拟节点在包加载后未刷新问题 - 重构为事件驱动架构,移除轮询机制 - 修复 @esengine/ui 遗留引用,统一使用 @esengine/fairygui * fix: 移除 tsconfig 中的 @esengine/ui 引用
This commit is contained in:
269
packages/fairygui/src/text/BitmapFont.ts
Normal file
269
packages/fairygui/src/text/BitmapFont.ts
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* BitmapFont
|
||||
*
|
||||
* Bitmap font support for FairyGUI.
|
||||
* Handles BMFont format from FairyGUI Editor exports.
|
||||
*
|
||||
* 位图字体支持
|
||||
* 处理 FairyGUI 编辑器导出的 BMFont 格式
|
||||
*/
|
||||
|
||||
import type { MSDFFont, IMSDFFontData, IMSDFGlyph } from './MSDFFont';
|
||||
|
||||
/**
|
||||
* FairyGUI bitmap font glyph
|
||||
* FairyGUI 位图字体字形
|
||||
*/
|
||||
export interface IBitmapGlyph {
|
||||
/** X offset in the glyph | 字形内 X 偏移 */
|
||||
x: number;
|
||||
/** Y offset in the glyph | 字形内 Y 偏移 */
|
||||
y: number;
|
||||
/** Glyph width | 字形宽度 */
|
||||
width: number;
|
||||
/** Glyph height | 字形高度 */
|
||||
height: number;
|
||||
/** Horizontal advance | 水平前进量 */
|
||||
advance: number;
|
||||
/** Source texture region (if from atlas) | 源纹理区域 */
|
||||
textureRegion?: {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
/** Texture ID for this glyph | 此字形的纹理 ID */
|
||||
textureId?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* FairyGUI bitmap font data (from UIPackage)
|
||||
* FairyGUI 位图字体数据(来自 UIPackage)
|
||||
*/
|
||||
export interface IBitmapFontData {
|
||||
/** Is TTF (dynamic font) | 是否是 TTF(动态字体) */
|
||||
ttf: boolean;
|
||||
/** Can be tinted | 可以着色 */
|
||||
tint: boolean;
|
||||
/** Font size | 字体大小 */
|
||||
fontSize: number;
|
||||
/** Line height | 行高 */
|
||||
lineHeight: number;
|
||||
/** Glyphs map (charCode -> glyph) | 字形映射 */
|
||||
glyphs: Map<number, IBitmapGlyph>;
|
||||
/** Texture ID for the font atlas | 字体图集纹理 ID */
|
||||
textureId?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* BitmapFont
|
||||
*
|
||||
* Adapter for FairyGUI bitmap fonts.
|
||||
* Can be used for rendering when MSDF fonts are not available.
|
||||
*
|
||||
* FairyGUI 位图字体适配器
|
||||
* 当 MSDF 字体不可用时可用于渲染
|
||||
*/
|
||||
export class BitmapFont {
|
||||
/** Font name | 字体名称 */
|
||||
public readonly name: string;
|
||||
|
||||
/** Texture ID | 纹理 ID */
|
||||
public textureId: number = 0;
|
||||
|
||||
/** Font data | 字体数据 */
|
||||
private _data: IBitmapFontData;
|
||||
|
||||
constructor(name: string, data: IBitmapFontData) {
|
||||
this.name = name;
|
||||
this._data = data;
|
||||
if (data.textureId !== undefined) {
|
||||
this.textureId = data.textureId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a TTF (dynamic) font
|
||||
* 是否是 TTF(动态)字体
|
||||
*/
|
||||
public get isTTF(): boolean {
|
||||
return this._data.ttf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the font be tinted
|
||||
* 字体是否可以着色
|
||||
*/
|
||||
public get canTint(): boolean {
|
||||
return this._data.tint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Font size | 字体大小
|
||||
*/
|
||||
public get fontSize(): number {
|
||||
return this._data.fontSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Line height | 行高
|
||||
*/
|
||||
public get lineHeight(): number {
|
||||
return this._data.lineHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get glyph for a character
|
||||
* 获取字符的字形
|
||||
*/
|
||||
public getGlyph(charCode: number): IBitmapGlyph | undefined {
|
||||
return this._data.glyphs.get(charCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if font has a glyph
|
||||
* 检查字体是否有字形
|
||||
*/
|
||||
public hasGlyph(charCode: number): boolean {
|
||||
return this._data.glyphs.has(charCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all glyphs
|
||||
* 获取所有字形
|
||||
*/
|
||||
public get glyphs(): Map<number, IBitmapGlyph> {
|
||||
return this._data.glyphs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitmap Font Manager
|
||||
* 位图字体管理器
|
||||
*/
|
||||
export class BitmapFontManager {
|
||||
/** Loaded fonts | 已加载的字体 */
|
||||
private _fonts: Map<string, BitmapFont> = new Map();
|
||||
|
||||
/**
|
||||
* Register a bitmap font
|
||||
* 注册位图字体
|
||||
*/
|
||||
public registerFont(font: BitmapFont): void {
|
||||
this._fonts.set(font.name, font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a font by name
|
||||
* 按名称获取字体
|
||||
*/
|
||||
public getFont(name: string): BitmapFont | undefined {
|
||||
return this._fonts.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a font is registered
|
||||
* 检查字体是否已注册
|
||||
*/
|
||||
public hasFont(name: string): boolean {
|
||||
return this._fonts.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload a font
|
||||
* 卸载字体
|
||||
*/
|
||||
public unloadFont(name: string): void {
|
||||
this._fonts.delete(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all fonts
|
||||
* 清除所有字体
|
||||
*/
|
||||
public clear(): void {
|
||||
this._fonts.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from FairyGUI package font data
|
||||
* 从 FairyGUI 包字体数据创建
|
||||
*/
|
||||
public createFromPackageData(name: string, data: IBitmapFontData): BitmapFont {
|
||||
const font = new BitmapFont(name, data);
|
||||
this.registerFont(font);
|
||||
return font;
|
||||
}
|
||||
}
|
||||
|
||||
/** Global bitmap font manager | 全局位图字体管理器 */
|
||||
let _bitmapFontManager: BitmapFontManager | null = null;
|
||||
|
||||
/**
|
||||
* Get global bitmap font manager
|
||||
* 获取全局位图字体管理器
|
||||
*/
|
||||
export function getBitmapFontManager(): BitmapFontManager {
|
||||
if (!_bitmapFontManager) {
|
||||
_bitmapFontManager = new BitmapFontManager();
|
||||
}
|
||||
return _bitmapFontManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert bitmap font to MSDF-compatible format
|
||||
* 将位图字体转换为 MSDF 兼容格式
|
||||
*
|
||||
* Note: This creates a "fake" MSDF font that uses bitmap rendering.
|
||||
* The pxRange is set to 0 to disable MSDF processing in the shader.
|
||||
*
|
||||
* 注意:这会创建一个使用位图渲染的"伪" MSDF 字体。
|
||||
* pxRange 设置为 0 以在着色器中禁用 MSDF 处理。
|
||||
*/
|
||||
export function convertBitmapToMSDFFormat(
|
||||
bitmapFont: BitmapFont,
|
||||
atlasWidth: number,
|
||||
atlasHeight: number
|
||||
): IMSDFFontData {
|
||||
const glyphs: IMSDFGlyph[] = [];
|
||||
|
||||
for (const [charCode, glyph] of bitmapFont.glyphs) {
|
||||
const region = glyph.textureRegion;
|
||||
if (!region) continue;
|
||||
|
||||
glyphs.push({
|
||||
unicode: charCode,
|
||||
advance: glyph.advance / bitmapFont.fontSize,
|
||||
planeBounds: {
|
||||
left: glyph.x / bitmapFont.fontSize,
|
||||
bottom: -(glyph.y + glyph.height) / bitmapFont.fontSize,
|
||||
right: (glyph.x + glyph.width) / bitmapFont.fontSize,
|
||||
top: -glyph.y / bitmapFont.fontSize
|
||||
},
|
||||
atlasBounds: {
|
||||
left: region.x,
|
||||
bottom: region.y,
|
||||
right: region.x + region.width,
|
||||
top: region.y + region.height
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
atlas: {
|
||||
type: 'sdf', // Use simple SDF mode for bitmap
|
||||
distanceRange: 0, // 0 = disable MSDF processing, use as regular texture
|
||||
size: bitmapFont.fontSize,
|
||||
width: atlasWidth,
|
||||
height: atlasHeight,
|
||||
yOrigin: 'top'
|
||||
},
|
||||
metrics: {
|
||||
emSize: bitmapFont.fontSize,
|
||||
lineHeight: bitmapFont.lineHeight / bitmapFont.fontSize,
|
||||
ascender: 1,
|
||||
descender: 0
|
||||
},
|
||||
glyphs
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user