update TileFont....
This commit is contained in:
parent
4dc060e05f
commit
1f80f793ac
2
CMCore
2
CMCore
@ -1 +1 @@
|
||||
Subproject commit c2d6f456f7c17fe2ab7905a7c4f5b2222b5b611b
|
||||
Subproject commit 5866f9238750b11ddd925d51201da788cb234d7e
|
@ -1,30 +1,40 @@
|
||||
// DrawTile
|
||||
// 该示例使用TileData,演示多个tile图片在一张纹理上
|
||||
|
||||
#include<hgl/type/StringList.h>
|
||||
#include<hgl/graph/TextureLoader.h>
|
||||
#include<hgl/graph/TileData.h>
|
||||
#include<hgl/graph/font/TileFont.h>
|
||||
#include<hgl/graph/font/TextLayout.h>
|
||||
|
||||
#include"VulkanAppFramework.h"
|
||||
#include<hgl/graph/vulkan/VKTexture.h>
|
||||
#include<hgl/graph/vulkan/VKSampler.h>
|
||||
#include<hgl/math/Math.h>
|
||||
#include<hgl/graph/font/TextLayout.h>
|
||||
|
||||
using namespace hgl;
|
||||
using namespace hgl::graph;
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
Texture2D *CreateTextureFromFile(Device *device,const OSString &filename);
|
||||
VK_NAMESPACE_END
|
||||
/**
|
||||
* 文本绘制技术流程:
|
||||
*
|
||||
* 1.由TextLayout模块排版所有的字符,并向FontSource获取所有字符的Bitmap。生成文本可渲染对象的vertex position数据
|
||||
* 2.由TextLayout向TileData提交需要渲染的所有字符的Bitmap,并得到每个Bitmap对应的UV数据。生成文本可渲染对象的uv数据
|
||||
*/
|
||||
|
||||
constexpr uint32_t SCREEN_SIZE=512;
|
||||
constexpr uint32_t SCREEN_WIDTH =1280;
|
||||
constexpr uint32_t SCREEN_HEIGHT=960;
|
||||
|
||||
constexpr uint CHAR_BITMAP_SIZE=16; //字符尺寸
|
||||
constexpr uint CHAR_BITMAP_BORDER=1; //边界象素尺寸
|
||||
|
||||
class TestApp:public VulkanApplicationFramework
|
||||
{
|
||||
Camera cam;
|
||||
|
||||
private:
|
||||
|
||||
TextLayout text_layout;
|
||||
|
||||
private:
|
||||
|
||||
vulkan::Material * material =nullptr;
|
||||
vulkan::Texture2D * texture =nullptr;
|
||||
vulkan::Sampler * sampler =nullptr;
|
||||
vulkan::MaterialInstance * material_instance =nullptr;
|
||||
vulkan::Renderable * render_obj =nullptr;
|
||||
@ -32,11 +42,60 @@ private:
|
||||
|
||||
vulkan::Pipeline * pipeline =nullptr;
|
||||
|
||||
vulkan::VertexAttribBuffer *vertex_buffer =nullptr;
|
||||
vulkan::VertexAttribBuffer *tex_coord_buffer =nullptr;
|
||||
private:
|
||||
|
||||
TileFont * tile_font;
|
||||
TextLayout tl_engine; ///<文本排版引擎
|
||||
|
||||
RenderableCreater * text_rc =nullptr;
|
||||
Renderable * text_renderable =nullptr; ///<文本渲染对象列表
|
||||
|
||||
public:
|
||||
|
||||
~TestApp()
|
||||
{
|
||||
SAFE_CLEAR(text_renderable);
|
||||
SAFE_CLEAR(text_rc);
|
||||
SAFE_CLEAR(tile_font);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool InitTileFont()
|
||||
{
|
||||
Font fnt(OS_TEXT("Consolas"),0,CHAR_BITMAP_SIZE);
|
||||
|
||||
tile_font=device->CreateTileFont(fnt);
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool InitTextRenderable()
|
||||
{
|
||||
CharAttributes ca;
|
||||
TextLayoutAttributes tla;
|
||||
|
||||
ca.CharColor=Color4f(COLOR::White);
|
||||
ca.BackgroundColor=Color4f(COLOR::Black);
|
||||
|
||||
tla.char_attributes=&ca;
|
||||
|
||||
text_rc=new RenderableCreater(db,material);
|
||||
|
||||
tl_engine.Set(text_rc);
|
||||
tl_engine.Set(&tla);
|
||||
tl_engine.SetTextDirection(0);
|
||||
tl_engine.Set(TextAlign::Left);
|
||||
tl_engine.SetMaxWidth(0);
|
||||
tl_engine.SetMaxHeight(0);
|
||||
|
||||
if(!tl_engine.Init())
|
||||
return(false);
|
||||
|
||||
UTF16String str=U16_TEXT("道可道,非常道。名可名,非常名。无名天地之始。有名万物之母。故常无欲以观其妙。常有欲以观其徼。此两者同出而异名,同谓之玄。玄之又玄,众妙之门。");
|
||||
|
||||
tl_engine.PlaneLayout(tile_font,0,str);
|
||||
}
|
||||
|
||||
bool InitMaterial()
|
||||
{
|
||||
material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"),
|
||||
@ -45,21 +104,16 @@ private:
|
||||
if(!material)
|
||||
return(false);
|
||||
|
||||
render_obj=material->CreateRenderable(VERTEX_COUNT);
|
||||
material_instance=material->CreateInstance();
|
||||
|
||||
texture=vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/lena.Tex2D"));
|
||||
|
||||
sampler=db->CreateSampler();
|
||||
|
||||
material_instance->BindSampler("tex",texture,sampler);
|
||||
material_instance->BindSampler("tex",tile_data->GetTexture(),sampler);
|
||||
material_instance->BindUBO("world",ubo_world_matrix);
|
||||
material_instance->Update();
|
||||
|
||||
db->Add(material);
|
||||
db->Add(material_instance);
|
||||
db->Add(texture);
|
||||
db->Add(render_obj);
|
||||
return(true);
|
||||
}
|
||||
|
||||
@ -82,11 +136,17 @@ private:
|
||||
|
||||
void InitVBO()
|
||||
{
|
||||
vertex_buffer =db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,vertex_data);
|
||||
tex_coord_buffer=db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,tex_coord_data);
|
||||
const int tile_count=tile_list.GetCount();
|
||||
|
||||
render_obj=material->CreateRenderable(tile_count);
|
||||
|
||||
vertex_buffer =db->CreateVAB(VAF_VEC4,tile_count,vertex_data);
|
||||
tex_coord_buffer=db->CreateVAB(VAF_VEC4,tile_count,tex_coord_data);
|
||||
|
||||
render_obj->Set("Vertex",vertex_buffer);
|
||||
render_obj->Set("TexCoord",tex_coord_buffer);
|
||||
|
||||
db->Add(render_obj);
|
||||
}
|
||||
|
||||
bool InitPipeline()
|
||||
@ -106,7 +166,13 @@ public:
|
||||
|
||||
bool Init()
|
||||
{
|
||||
if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE))
|
||||
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
|
||||
return(false);
|
||||
|
||||
if(!InitTileData())
|
||||
return(false);
|
||||
|
||||
if(!InitTileFont())
|
||||
return(false);
|
||||
|
||||
if(!InitUBO())
|
||||
@ -138,7 +204,7 @@ public:
|
||||
}
|
||||
};//class TestApp:public VulkanApplicationFramework
|
||||
|
||||
int os_main(int,os_char **)
|
||||
int main(int,char **)
|
||||
{
|
||||
TestApp app;
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace hgl
|
||||
public:
|
||||
|
||||
Font();
|
||||
Font(const os_char *,int,int,bool,bool,bool=true);
|
||||
Font(const os_char *,int,int,bool b=false,bool i=false,bool=true);
|
||||
|
||||
CompOperatorMemcmp(const Font &); ///<比较操作符重载
|
||||
};//struct Font
|
||||
|
@ -33,6 +33,31 @@ namespace hgl
|
||||
uint8 *data;
|
||||
};//struct FontBitmap
|
||||
|
||||
/**
|
||||
* 字符排版属性
|
||||
*/
|
||||
struct CharLayoutAttributes
|
||||
{
|
||||
u32char ch; ///<字符
|
||||
|
||||
bool visible; ///<是否可显示字符
|
||||
|
||||
int size; ///<字符排版尺寸(一般为宽)
|
||||
|
||||
bool is_cjk; ///<是否是中日韩文字
|
||||
bool is_emoji; ///<是否是表情符号
|
||||
|
||||
bool is_punctuation; ///<是否是标点符号
|
||||
|
||||
bool begin_disable; ///<是否行首禁用符号
|
||||
bool end_disable; ///<是否行尾禁用符号
|
||||
bool vrotate; ///<竖排时是否需要旋转
|
||||
|
||||
CharMetricsInfo adv_info; ///<字符绘制信息
|
||||
};//struct CharLayoutAttributes
|
||||
|
||||
using CLA=CharLayoutAttributes;
|
||||
|
||||
/**
|
||||
* 文字位图数据源
|
||||
*/
|
||||
@ -42,12 +67,15 @@ namespace hgl
|
||||
|
||||
Set<void *> ref_object;
|
||||
|
||||
MapObject<u32char,CLA> cla_cache;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~FontSource()=default;
|
||||
|
||||
virtual FontBitmap *GetCharBitmap (const u32char &)=0; ///<取得字符位图数据
|
||||
virtual const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息
|
||||
const CLA * GetCLA (const u32char &); ///<取得字符排版信息
|
||||
virtual int GetCharHeight ()const=0; ///<取得字符高度
|
||||
|
||||
void RefAcquire(void *); ///<引用请求
|
||||
@ -80,6 +108,8 @@ namespace hgl
|
||||
virtual int GetCharHeight ()const override{return fnt.height;} ///<取得字符高度
|
||||
};//class FontSourceSingle:public FontSource
|
||||
|
||||
FontSourceSingle *CreateFontSource(const Font &f);
|
||||
|
||||
/**
|
||||
* 文字位图多重数据源
|
||||
*/
|
||||
|
@ -82,30 +82,6 @@ namespace hgl
|
||||
|
||||
class TextLayout
|
||||
{
|
||||
protected:
|
||||
|
||||
struct CharLayoutAttributes
|
||||
{
|
||||
u32char ch; ///<字符
|
||||
|
||||
int size; ///<字符排版尺寸(一般为宽)
|
||||
|
||||
bool visible; ///<是否可显示字符
|
||||
|
||||
bool is_cjk; ///<是否是中日韩文字
|
||||
bool is_emoji; ///<是否是表情符号
|
||||
|
||||
bool is_punctuation; ///<是否是标点符号
|
||||
|
||||
bool begin_disable; ///<是否行首禁用符号
|
||||
bool end_disable; ///<是否行尾禁用符号
|
||||
bool vrotate; ///<竖排时是否需要旋转
|
||||
|
||||
CharMetricsInfo adv_info; ///<字符绘制信息
|
||||
};//struct CharLayoutAttributes
|
||||
|
||||
using CLA=CharLayoutAttributes;
|
||||
|
||||
protected:
|
||||
|
||||
RenderableCreater *rc;
|
||||
@ -119,14 +95,15 @@ namespace hgl
|
||||
float splite_line_max_limit;
|
||||
|
||||
int max_chars; ///<总字符数量
|
||||
int draw_chars_count; ///<可绘制字符数量
|
||||
|
||||
List<CLA> chars_attributes;
|
||||
Set<u32char> alone_chars; ///<不重复字符统计缓冲区
|
||||
|
||||
List<CLA *> cla_list; ///<所有字符属性列表
|
||||
|
||||
protected:
|
||||
|
||||
template<typename T> int preprocess(const BaseString<T> &origin_string);
|
||||
template<typename T> int plane_preprocess(const BaseString<T> &origin_string);
|
||||
template<typename T> int stat_chars(const T *,const int);
|
||||
template<typename T> int preprocess(const T *,const int);
|
||||
|
||||
bool h_splite_to_lines(float view_limit);
|
||||
bool v_splite_to_lines(float view_limit);
|
||||
@ -162,7 +139,6 @@ namespace hgl
|
||||
|
||||
direction.text_direction=0;
|
||||
max_chars =0;
|
||||
draw_chars_count =0;
|
||||
|
||||
vertex =nullptr;
|
||||
tex_coord =nullptr;
|
||||
|
@ -3,12 +3,28 @@
|
||||
|
||||
#include<hgl/graph/TileData.h>
|
||||
#include<hgl/graph/font/FontSource.h>
|
||||
#include<hgl/type/UnicodeBlocks.h>
|
||||
#include<hgl/type/ResPoolManage.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
class TileObjectPool
|
||||
{
|
||||
TileData *tile_data;
|
||||
|
||||
public:
|
||||
|
||||
TileObject *Acquire();
|
||||
void Release(TileObject *);
|
||||
|
||||
public:
|
||||
|
||||
TileObjectPool(TileData *td):tile_data(td);
|
||||
};
|
||||
|
||||
using TileObjectManage=_ResPoolManage<u32char,TileObject *,TileObjectPool>;
|
||||
|
||||
/**
|
||||
* Tile字符管理<br>
|
||||
* 本模块允许有多个字符数据来源,每个来源也可以对应多个unicode块, 但一个unicode块只能对应一个字体数据来源
|
||||
@ -18,10 +34,21 @@ namespace hgl
|
||||
FontSource *source;
|
||||
TileData *tile_data;
|
||||
|
||||
TileObjectPool *tile_pool;
|
||||
TileObjectManage *ch_tile_pool;
|
||||
|
||||
public:
|
||||
|
||||
FontSource *GetFontSource (){return source;}
|
||||
TileData * GetTileData (){return tile_data;}
|
||||
|
||||
public:
|
||||
|
||||
TileFont(TileData *td,FontSource *fs);
|
||||
virtual ~TileFont();
|
||||
|
||||
bool Registry(List<RectScope2f> &,const List<u32char> &); ///<注册要使用的字符
|
||||
void Unregistry(const List<u32char> &); ///<注销要使用的字符
|
||||
};//class TileFont
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include<hgl/type/RectScope.h>
|
||||
#include<hgl/platform/Window.h>
|
||||
#include<hgl/graph/Bitmap.h>
|
||||
#include<hgl/graph/font/Font.h>
|
||||
#include<hgl/graph/vulkan/VK.h>
|
||||
#include<hgl/graph/vulkan/VKDeviceAttribute.h>
|
||||
#include<hgl/graph/vulkan/VKSwapchain.h>
|
||||
@ -18,6 +19,7 @@ namespace hgl
|
||||
namespace graph
|
||||
{
|
||||
class TileData;
|
||||
class TileFont;
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
|
||||
@ -262,6 +264,8 @@ public:
|
||||
RenderTarget *CreateRenderTarget(Framebuffer *);
|
||||
|
||||
TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集
|
||||
|
||||
TileFont *CreateTileFont(const Font &f,int limit_count=-1); ///<创建一个Tile字体
|
||||
};//class Device
|
||||
|
||||
Device *CreateRenderDevice(Instance *inst,Window *win,const PhysicalDevice *physical_device=nullptr);
|
||||
|
2
res
2
res
@ -1 +1 @@
|
||||
Subproject commit c6eafccb4e3db9336cbfeef610c3a7f114016213
|
||||
Subproject commit 8e31af94c83e4114673e19db2ea7593522bae16e
|
@ -85,7 +85,8 @@ SET(VK_RENDERABLE_SOURCE ${RD_INCLUDE_PATH}/VKVertexAttributeBinding.h
|
||||
${RD_INCLUDE_PATH}/VKRenderable.h
|
||||
VKVertexAttributeBinding.cpp
|
||||
VKRenderable.cpp
|
||||
VKTileData.cpp)
|
||||
VKTileData.cpp
|
||||
VKTileFont.cpp)
|
||||
|
||||
SOURCE_GROUP("Renderable" FILES ${VK_RENDERABLE_SOURCE})
|
||||
|
||||
|
44
src/RenderDevice/Vulkan/VKTileFont.cpp
Normal file
44
src/RenderDevice/Vulkan/VKTileFont.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include<hgl/graph/font/TileFont.h>
|
||||
#include<hgl/graph/vulkan/VKDevice.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
FontSource *AcquireFontSource(const Font &f);
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
/**
|
||||
* 创建只使用一种字符的Tile字符管理对象
|
||||
* @param f 字体需求信息
|
||||
* @param limit_count 缓冲字符数量上限
|
||||
*/
|
||||
TileFont *Device::CreateTileFont(const Font &f,int limit_count)
|
||||
{
|
||||
int height=(f.height+3)>>2;
|
||||
|
||||
height<<=2; //保证可以被4整除
|
||||
height+=2; //上下左右各空一个象素
|
||||
|
||||
if(limit_count<=0)
|
||||
{
|
||||
const VkExtent2D &ext=GetSwapchainSize();
|
||||
|
||||
limit_count=(ext.width/height)*(ext.height/height); //按全屏幕放满不一样的字符为上限
|
||||
}
|
||||
|
||||
FontSource *fs=AcquireFontSource(f);
|
||||
|
||||
if(!fs)
|
||||
return(nullptr);
|
||||
|
||||
TileData *td=CreateTileData(UFMT_R8,height,height,limit_count);
|
||||
|
||||
if(!td)
|
||||
return nullptr;
|
||||
|
||||
return(new TileFont(td,fs));
|
||||
}
|
||||
VK_NAMESPACE_END
|
@ -21,6 +21,11 @@ SET(SG_VAD_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribData.h
|
||||
|
||||
SOURCE_GROUP("VertexAttribData" FILES ${SG_VAD_SOURCE})
|
||||
|
||||
SET(TILE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/TileData.h
|
||||
TileData.cpp)
|
||||
|
||||
SOURCE_GROUP("Tile" FILES ${TILE_SOURCE})
|
||||
|
||||
SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h
|
||||
${ROOT_INCLUDE_PATH}/hgl/graph/SceneDB.h
|
||||
${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h
|
||||
@ -28,7 +33,6 @@ SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h
|
||||
${ROOT_INCLUDE_PATH}/hgl/graph/RenderableInstance.h
|
||||
${ROOT_INCLUDE_PATH}/hgl/graph/RenderList.h
|
||||
${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h
|
||||
${ROOT_INCLUDE_PATH}/hgl/graph/TileData.h
|
||||
#${ROOT_INCLUDE_PATH}/hgl/graph/Mesh.h
|
||||
#${ROOT_INCLUDE_PATH}/hgl/graph/Material.h
|
||||
#${ROOT_INCLUDE_PATH}/hgl/graph/Spline.h
|
||||
@ -39,7 +43,6 @@ SET(SCENE_GRAPH_SOURCE RenderList.cpp
|
||||
SceneNode.cpp
|
||||
SceneOrient.cpp
|
||||
InlineGeometry.cpp
|
||||
TileData.cpp
|
||||
#InlinePipeline.cpp
|
||||
#Material.cpp
|
||||
#Mesh.cpp
|
||||
@ -90,7 +93,7 @@ add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER}
|
||||
${SG_TEXTURE_SOURCE}
|
||||
${SG_MATERIAL_HEADER}
|
||||
${SG_MATERIAL_SOURCE}
|
||||
|
||||
${TILE_SOURCE}
|
||||
${SG_VAD_SOURCE}
|
||||
|
||||
${RENDERABLE_FILES}
|
||||
|
@ -19,5 +19,63 @@ namespace hgl
|
||||
|
||||
ref_object.Delete(ptr);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr u16char BeginSymbols []=U16_TEXT("!),❟.:;?]}¨·ˇˉ―‖’❜”„❞…∶、。〃々❯〉》」』】〕〗!"'),.:;?]`|}~»›"); //行首禁用符号
|
||||
constexpr u16char EndSymbols []=U16_TEXT("([{·❛‘“‟❝❮〈《「『【〔〖(.[{«‹"); //行尾禁用符号
|
||||
constexpr u16char CurrencySymbols []=U16_TEXT("₳฿₿¢₡¢₢₵₫€££₤₣ƒ₲₭Ł₥₦₽₱$$₮ℳ₶₩₩¥¥₴₸¤₰៛₪₯₠₧﷼㍐원৳₹₨৲௹"); //货币符号
|
||||
constexpr u16char VRotateSymbols []=U16_TEXT("()[]{}〈〉《》「」『』【】〔〕〖〗()[]{}―‖…∶|~"); //竖排必须旋转的符号
|
||||
|
||||
constexpr int BeginSymbolsCount =(sizeof(BeginSymbols) /sizeof(u16char))-1;
|
||||
constexpr int EndSymbolsCount =(sizeof(EndSymbols) /sizeof(u16char))-1;
|
||||
constexpr int CurrencySymbolsCount=(sizeof(CurrencySymbols)/sizeof(u16char))-1;
|
||||
constexpr int VRotateSymbolsCount =(sizeof(VRotateSymbols) /sizeof(u16char))-1;
|
||||
}//namespace
|
||||
|
||||
const CLA *FontSource::GetCLA(const u32char &ch)
|
||||
{
|
||||
CLA *cla;
|
||||
|
||||
if(cla_cache.Get(ch,cla))
|
||||
return cla;
|
||||
|
||||
cla=new CLA;
|
||||
|
||||
cla->ch=ch;
|
||||
|
||||
if(hgl::isspace(ch))
|
||||
{
|
||||
cla->visible=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cla->visible=true;
|
||||
|
||||
cla->begin_disable =hgl::strchr(BeginSymbols, ch,BeginSymbolsCount );
|
||||
cla->end_disable =hgl::strchr(EndSymbols, ch,EndSymbolsCount );
|
||||
|
||||
if(!cla->end_disable) //货币符号同样行尾禁用
|
||||
cla->end_disable =hgl::strchr(CurrencySymbols, ch,CurrencySymbolsCount );
|
||||
|
||||
cla->vrotate =hgl::strchr(VRotateSymbols, ch,VRotateSymbolsCount );
|
||||
|
||||
cla->is_cjk =isCJK(ch);
|
||||
cla->is_emoji =isEmoji(ch);
|
||||
|
||||
cla->is_punctuation =isPunctuation(ch);
|
||||
|
||||
if(!GetCharMetrics(cla->adv_info,ch))
|
||||
hgl_zero(cla->adv_info);
|
||||
else
|
||||
if(cla->adv_info.w>0&&cla->adv_info.h>0)
|
||||
{
|
||||
cla->size=ceil(cla->adv_info.adv_x);
|
||||
}
|
||||
}
|
||||
|
||||
cla_cache.Add(ch,cla);
|
||||
return cla;
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
|
@ -139,7 +139,7 @@ namespace hgl
|
||||
return(true);
|
||||
}
|
||||
|
||||
FontSource *CreateFontSource(const Font &f)
|
||||
FontSourceSingle *CreateFontSource(const Font &f)
|
||||
{
|
||||
return(new WinBitmapFont(f));
|
||||
}
|
||||
|
@ -6,27 +6,6 @@ namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
namespace
|
||||
{
|
||||
constexpr u16char BeginSymbols []=U16_TEXT("!),❟.:;?]}¨·ˇˉ―‖’❜”„❞…∶、。〃々❯〉》」』】〕〗!"'),.:;?]`|}~»›"); //行首禁用符号
|
||||
constexpr u16char EndSymbols []=U16_TEXT("([{·❛‘“‟❝❮〈《「『【〔〖(.[{«‹"); //行尾禁用符号
|
||||
constexpr u16char CurrencySymbols []=U16_TEXT("₳฿₿¢₡¢₢₵₫€££₤₣ƒ₲₭Ł₥₦₽₱$$₮ℳ₶₩₩¥¥₴₸¤₰៛₪₯₠₧﷼㍐원৳₹₨৲௹"); //货币符号
|
||||
constexpr u16char VRotateSymbols []=U16_TEXT("()[]{}〈〉《》「」『』【】〔〕〖〗()[]{}―‖…∶|~"); //竖排必须旋转的符号
|
||||
|
||||
constexpr int BeginSymbolsCount =(sizeof(BeginSymbols) /sizeof(u16char))-1;
|
||||
constexpr int EndSymbolsCount =(sizeof(EndSymbols) /sizeof(u16char))-1;
|
||||
constexpr int CurrencySymbolsCount=(sizeof(CurrencySymbols)/sizeof(u16char))-1;
|
||||
constexpr int VRotateSymbolsCount =(sizeof(VRotateSymbols) /sizeof(u16char))-1;
|
||||
|
||||
/**
|
||||
* 4舍5入处理
|
||||
*/
|
||||
inline TEXT_COORD_TYPE out4in5(const double value)
|
||||
{
|
||||
return TEXT_COORD_TYPE(floor(value+0.5));
|
||||
}
|
||||
}//namespace
|
||||
|
||||
bool TextLayout::Init()
|
||||
{
|
||||
if(!rc
|
||||
@ -50,119 +29,55 @@ namespace hgl
|
||||
const float origin_char_height=tla.font_source->GetCharHeight();
|
||||
|
||||
x=y=0;
|
||||
char_height =out4in5(origin_char_height);
|
||||
space_size =out4in5(origin_char_height*tla.space_size);
|
||||
full_space_size =out4in5(origin_char_height*tla.full_space_size);
|
||||
tab_size =out4in5(origin_char_height*tla.tab_size);
|
||||
char_gap =out4in5(origin_char_height*tla.char_gap);
|
||||
line_gap =out4in5(origin_char_height*tla.line_gap);
|
||||
line_height =out4in5(origin_char_height+line_gap);
|
||||
paragraph_gap =out4in5(origin_char_height*tla.paragraph_gap);
|
||||
char_height =ceil(origin_char_height);
|
||||
space_size =ceil(origin_char_height*tla.space_size);
|
||||
full_space_size =ceil(origin_char_height*tla.full_space_size);
|
||||
tab_size =ceil(origin_char_height*tla.tab_size);
|
||||
char_gap =ceil(origin_char_height*tla.char_gap);
|
||||
line_gap =ceil(origin_char_height*tla.line_gap);
|
||||
line_height =ceil(origin_char_height+line_gap);
|
||||
paragraph_gap =ceil(origin_char_height*tla.paragraph_gap);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int TextLayout::stat_chars(const T *str,const int str_length)
|
||||
{
|
||||
if(!str||!*str||str_length<=0)
|
||||
return 0;
|
||||
|
||||
alone_chars.ClearData();
|
||||
|
||||
for(int i=0;i<str_length;i++)
|
||||
{
|
||||
alone_chars.Add(*str);
|
||||
++str;
|
||||
}
|
||||
|
||||
return alone_chars.GetCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 预处理所有的字符,获取所有字符的宽高,以及是否标点符号等信息
|
||||
*/
|
||||
template<typename T>
|
||||
int TextLayout::preprocess(const BaseString<T> &origin_string)
|
||||
int TextLayout::preprocess(const T *str,const int str_length)
|
||||
{
|
||||
const int count=hgl_min(max_chars,origin_string.Length());
|
||||
const int count=hgl_min(max_chars,str_length);
|
||||
|
||||
if(count<=0)
|
||||
return 0;
|
||||
|
||||
chars_attributes.SetCount(count);
|
||||
draw_chars_count=0;
|
||||
cla_list.ClearData();
|
||||
cla_list.SetCount(count);
|
||||
|
||||
CLA *cla=chars_attributes.GetData();
|
||||
const T *cp=origin_string.c_str();
|
||||
CLA **cla=cla.GetData();
|
||||
const T *cp=str;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
cla->ch=*cp;
|
||||
|
||||
if(hgl::isspace(*cp))
|
||||
{
|
||||
cla->visible=false;
|
||||
|
||||
if(*cp=='\t') cla->size=tab_size; else
|
||||
if(*cp==HGL_FULL_SPACE) cla->size=full_space_size; else
|
||||
cla->size=space_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
cla->visible=true; cla->size=out4in5(tla.font_source->GetCharAdvWidth(*cp));
|
||||
|
||||
cla->begin_disable =hgl::strchr(BeginSymbols, *cp,BeginSymbolsCount );
|
||||
cla->end_disable =hgl::strchr(EndSymbols, *cp,EndSymbolsCount );
|
||||
|
||||
if(!cla->end_disable) //货币符号同样行尾禁用
|
||||
cla->end_disable =hgl::strchr(CurrencySymbols,*cp,CurrencySymbolsCount );
|
||||
|
||||
cla->vrotate =hgl::strchr(VRotateSymbols,*cp,VRotateSymbolsCount );
|
||||
|
||||
cla->is_cjk =isCJK(*cp);
|
||||
cla->is_emoji =isEmoji(*cp);
|
||||
|
||||
cla->is_punctuation =isPunctuation(*cp);
|
||||
|
||||
if(!tla->font_source->GetCharMetrics(cla->adv_info,*cp))
|
||||
hgl_zero(cla->adv_info);
|
||||
else
|
||||
if(cla->adv_info.w>0&&cla->adv_info.h>0)
|
||||
++draw_chars_count;
|
||||
}
|
||||
|
||||
++cp;
|
||||
++cla;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 简易预处理所有的字符,获取所有字符的宽高,以及是否标点符号等信息
|
||||
*/
|
||||
template<typename T>
|
||||
int TextLayout::plane_preprocess(const BaseString<T> &origin_string)
|
||||
{
|
||||
const int count=hgl_min(max_chars,origin_string.Length());
|
||||
|
||||
if(count<=0)
|
||||
return 0;
|
||||
|
||||
chars_attributes.SetCount(count);
|
||||
draw_chars_count=0;
|
||||
|
||||
CLA *cla=chars_attributes.GetData();
|
||||
const T *cp=origin_string.c_str();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
cla->ch=*cp;
|
||||
|
||||
if(hgl::isspace(*cp))
|
||||
{
|
||||
cla->visible=false;
|
||||
|
||||
if(*cp=='\t') cla->size=tab_size; else
|
||||
if(*cp==HGL_FULL_SPACE) cla->size=full_space_size; else
|
||||
cla->size=space_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
cla->visible=true; cla->size=out4in5(tla.font_source->GetCharAdvWidth(*cp));
|
||||
|
||||
cla->vrotate =hgl::strchr(VRotateSymbols,*cp,VRotateSymbolsCount );
|
||||
|
||||
if(!tla->font_source->GetCharMetrics(cla->adv_info,*cp))
|
||||
hgl_zero(cla->adv_info);
|
||||
else
|
||||
if(cla->adv_info.w>0&&cla->adv_info.h>0)
|
||||
++draw_chars_count;
|
||||
}
|
||||
*cla=tla->font_source.GetCLA(*cp);
|
||||
|
||||
++cp;
|
||||
++cla;
|
||||
@ -176,8 +91,8 @@ namespace hgl
|
||||
*/
|
||||
bool TextLayout::h_splite_to_lines(float view_limit)
|
||||
{
|
||||
const int count=chars_attributes.GetCount();
|
||||
const CLA *cla=chars_attributes.GetData();
|
||||
const int count=cla_list.GetCount();
|
||||
const CLA **cla=cla_list.GetData();
|
||||
|
||||
int cur_size=0;
|
||||
|
||||
@ -232,17 +147,24 @@ namespace hgl
|
||||
|
||||
int TextLayout::pl_h_l2r()
|
||||
{
|
||||
const int count=chars_attributes.GetCount();
|
||||
const CLA *cla=chars_attributes.GetData();
|
||||
const int count=cla_list.GetCount();
|
||||
const CLA **cla=cla_list.GetData();
|
||||
|
||||
int cur_size=0;
|
||||
int left=0,top=0;
|
||||
|
||||
float *tp=vertex->Begin();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
//vertex->Write(
|
||||
*tp=left; ++tp;
|
||||
*tp=top; ++tp;
|
||||
*tp=left+(*cla)->adv_info.w;++tp;
|
||||
*tp=top +(*cla)->adv_info.h;++tp;
|
||||
}
|
||||
|
||||
vertex->End();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -262,7 +184,10 @@ namespace hgl
|
||||
|
||||
max_chars=hgl_min(mc,str.Length());
|
||||
|
||||
if(plane_preprocess<T>(str)<=0)
|
||||
if(stat_chars<T>(str.c_str(),str.Length())<=0)
|
||||
return(-2);
|
||||
|
||||
if(preprocess<T>(str.c_str(),str.Length())<=0)
|
||||
return(-3);
|
||||
|
||||
if(!rc->Init(draw_chars_count))
|
||||
|
@ -6,7 +6,13 @@ namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
FontSource *AcquireFontSource(const Font &f);
|
||||
TileObject *TileObjectPool::Acquire()
|
||||
{
|
||||
}
|
||||
|
||||
void TileObjectPool::Release(TileObject *)
|
||||
{
|
||||
}
|
||||
|
||||
TileFont::TileFont(TileData *td,FontSource *fs)
|
||||
{
|
||||
@ -17,10 +23,16 @@ namespace hgl
|
||||
source=fs;
|
||||
source->RefAcquire(this);
|
||||
}
|
||||
|
||||
tile_pool=new TileObjectPool(tile_data);
|
||||
ch_tile_pool=new TileObjectManage(tile_pool);
|
||||
}
|
||||
|
||||
TileFont::~TileFont()
|
||||
{
|
||||
delete ch_tile_pool;
|
||||
delete tile_pool;
|
||||
|
||||
if(source)
|
||||
source->RefRelease(this);
|
||||
|
||||
@ -28,35 +40,21 @@ namespace hgl
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建只使用一种字符的Tile字符管理对象
|
||||
* @param f 字体需求信息
|
||||
* @param limit_count 缓冲字符数量上限
|
||||
* 注册要使用的字符
|
||||
* @param rs 每个字符在纹理中的UV坐标
|
||||
* @param ch_list 要注册的字符列表
|
||||
*/
|
||||
TileFont *CreateTileFont(VK_NAMESPACE::Device *device,const Font &f,int limit_count=-1)
|
||||
bool TileFont::Registry(List<RectScope2f> &rs,const List<u32char> &ch_list)
|
||||
{
|
||||
int height=(f.height+3)>>2;
|
||||
|
||||
height<<=2; //保证可以被4整除
|
||||
height+=2; //上下左右各空一个象素
|
||||
|
||||
if(limit_count<=0)
|
||||
{
|
||||
const VkExtent2D &ext=device->GetSwapchainSize();
|
||||
|
||||
limit_count=(ext.width/height)*(ext.height/height); //按全屏幕放满不一样的字符为上限
|
||||
}
|
||||
|
||||
FontSource *fs=AcquireFontSource(f);
|
||||
|
||||
if(!fs)
|
||||
return(nullptr);
|
||||
|
||||
TileData *td=device->CreateTileData(UFMT_R8,height,height,limit_count);
|
||||
|
||||
if(!td)
|
||||
return nullptr;
|
||||
|
||||
return(new TileFont(td,fs));
|
||||
/**
|
||||
* 注销要使用的字符
|
||||
* @param ch_list 要注销的字符列表
|
||||
*/
|
||||
void TileFont::Unregistry(const List<u32char> &ch_list)
|
||||
{
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
|
Loading…
x
Reference in New Issue
Block a user