first finished TileFont and test program.

This commit is contained in:
2020-08-03 21:22:02 +08:00
parent 8305602995
commit 2ae2228546
5 changed files with 157 additions and 158 deletions

View File

@@ -48,13 +48,11 @@ private:
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);
}
@@ -69,33 +67,6 @@ private:
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"),
@@ -108,7 +79,7 @@ private:
sampler=db->CreateSampler();
material_instance->BindSampler("tex",tile_data->GetTexture(),sampler);
material_instance->BindSampler("tex",tile_font->GetTexture(),sampler);
material_instance->BindUBO("world",ubo_world_matrix);
material_instance->Update();
@@ -134,21 +105,6 @@ private:
return(true);
}
void InitVBO()
{
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()
{
AutoDelete<vulkan::PipelineCreater>
@@ -162,6 +118,39 @@ private:
return pipeline;
}
bool InitTextRenderable()
{
CharLayoutAttr cla;
TextLayoutAttributes tla;
cla.CharColor=Color4f(COLOR::White);
cla.BackgroundColor=Color4f(COLOR::Black);
tla.char_layout_attr=&cla;
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("道可道,非常道。名可名,非常名。无名天地之始。有名万物之母。故常无欲以观其妙。常有欲以观其徼。此两者同出而异名,同谓之玄。玄之又玄,众妙之门。");
if(tl_engine.SimpleLayout(tile_font,str)>0)
{
render_obj=text_rc->Finish();
return(true);
}
return(false);
}
public:
bool Init()
@@ -169,9 +158,6 @@ public:
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitTileData())
return(false);
if(!InitTileFont())
return(false);
@@ -181,11 +167,12 @@ public:
if(!InitMaterial())
return(false);
InitVBO();
if(!InitPipeline())
return(false);
if(!InitTextRenderable())
return(false);
BuildCommandBuffer(pipeline,material_instance,render_obj);
return(true);

View File

@@ -4,6 +4,7 @@
#include<hgl/type/StringList.h>
#include<hgl/graph/font/FontSource.h>
#include<hgl/graph/RenderableCreater.h>
#include<hgl/graph/TileData.h>
namespace hgl
{
namespace graph
@@ -13,7 +14,7 @@ namespace hgl
/**
* 字符属性,可精确到字也可精确到段落或是全文
*/
struct CharAttributes
struct CharLayoutAttr
{
bool bold =false; ///<加粗
bool italic =false; ///<右斜
@@ -21,7 +22,7 @@ namespace hgl
Color4f CharColor; ///<字符颜色
Color4f BackgroundColor; ///<背影颜色
};//struct CharAttributes
};//struct CharLayoutAttr
/**
* 文本排列方向
@@ -57,7 +58,7 @@ namespace hgl
struct TextLayoutAttributes
{
FontSource * font_source =nullptr; ///<字符源
CharAttributes *char_attributes =nullptr; ///<缺省字符属性
CharLayoutAttr *char_layout_attr =nullptr; ///<缺省字符排版属性
uint8 text_direction =0; ///<文本排列方向
TextAlign align =TextAlign::Left; ///<段落对齐
@@ -94,25 +95,30 @@ namespace hgl
bool endless;
float splite_line_max_limit;
int max_chars; ///<总字符数量
int draw_chars_count; ///<要绘制字符列表
Set<u32char> alone_chars; ///<不重复字符统计缓冲区
TileUVFloatMap alone_chars_uv; ///<所有要绘制字符的uv
List<CLA *> cla_list; ///<所有字符属性列表
struct CharDrawAttr
{
CLA *cla;
TileUVFloat uv;
};
ObjectList<CharDrawAttr> draw_chars_list; ///<所有字符属性列表
template<typename T> int preprocess(const T *,const int);
protected:
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);
int pl_h_l2r();
int pl_h_r2l();
int pl_v_r2l();
int pl_v_l2r();
int sl_h_l2r();
int sl_h_r2l();
int sl_v_r2l();
int sl_v_l2r();
protected:
@@ -138,7 +144,7 @@ namespace hgl
rc=nullptr;
direction.text_direction=0;
max_chars =0;
draw_chars_count=0;
vertex =nullptr;
tex_coord =nullptr;
@@ -146,20 +152,20 @@ namespace hgl
virtual ~TextLayout()=default;
bool Set (RenderableCreater *_rc) {if(_rc)rc=_rc;}
bool Set (const TextLayoutAttributes *_tla) {if(_tla)memcpy(&tla,_tla,sizeof(TextLayoutAttributes));}
bool Set (FontSource *fs) {if(fs)tla.font_source=fs;}
bool SetTextDirection (const uint8 &td) {tla.text_direction=td;}
bool Set (const TextAlign &ta) {tla.align=ta;}
bool SetMaxWidth (const float mw) {tla.max_width=mw;}
bool SetMaxHeight (const float mh) {tla.max_height=mh;}
void Set (RenderableCreater *_rc) {if(_rc)rc=_rc;}
void Set (const TextLayoutAttributes *_tla) {if(_tla)memcpy(&tla,_tla,sizeof(TextLayoutAttributes));}
void Set (FontSource *fs) {if(fs)tla.font_source=fs;}
void SetTextDirection (const uint8 &td) {tla.text_direction=td;}
void Set (const TextAlign &ta) {tla.align=ta;}
void SetMaxWidth (const float mw) {tla.max_width=mw;}
void SetMaxHeight (const float mh) {tla.max_height=mh;}
virtual bool Init (); ///<初始化排版
// virtual int Layout (const int max_chars,const BaseString<T> &)=0; ///<排版
template<typename T>
int PlaneLayout (TileFont *,const int max_chars,const BaseString<T> &); ///<简易排版
int SimpleLayout (TileFont *,const BaseString<T> &); ///<简易排版
};//class TextLayout
}//namespace graph
}//namespace hgl

View File

@@ -26,13 +26,14 @@ namespace hgl
FontSource *GetFontSource (){return source;}
TileData * GetTileData (){return tile_data;}
Texture2D * GetTexture (){return tile_data->GetTexture();}
public:
TileFont(TileData *td,FontSource *fs);
virtual ~TileFont();
bool Registry(List<TileUVFloat> &,const List<u32char> &); ///<注册要使用的字符
bool Registry(TileUVFloatMap &,const u32char *ch_list,const int ch_count); ///<注册要使用的字符
void Unregistry(const List<u32char> &); ///<注销要使用的字符
};//class TileFont
}//namespace graph

View File

@@ -41,46 +41,54 @@ namespace hgl
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 T *str,const int str_length)
{
const int count=hgl_min(max_chars,str_length);
if(count<=0)
if(!str||!*str||str_length<=0)
return 0;
cla_list.ClearData();
cla_list.SetCount(count);
draw_chars_count=0;
alone_chars.ClearData();
CLA **cla=cla.GetData();
draw_chars_list.ClearData();
draw_chars_list.SetCount(str_length);
CharDrawAttr **cda=draw_chars_list.GetData();
const T *cp=str;
for(int i=0;i<count;i++)
{
*cla=tla->font_source.GetCLA(*cp);
(*cda)->cla=tla->font_source.GetCLA(*cp);
if((*cda)->cla->visible)
{
alone_chars.Add(*cp); //统计所有不重复字符
++draw_chars_count;
}
++cp;
++cla;
++cda;
}
//注册不重复字符给tile font系统获取所有字符的UV
if(!tf->Registry(alone_chars_uv,alone_chars.GetData(),alone_chars.GetCount()))
{
draw_chars_list.ClearData();
alone_chars.ClearData();
return(false);
}
//为可绘制字符列表中的字符获取UV
cda=draw_chars_list.GetData();
for(int i=0;i<count;i++)
{
alone_chars_uv.Get((*cda)->cla->ch,(*cda)->uv);
++cda;
}
return count;
@@ -91,14 +99,14 @@ namespace hgl
*/
bool TextLayout::h_splite_to_lines(float view_limit)
{
const int count=cla_list.GetCount();
const CLA **cla=cla_list.GetData();
//const int count=cla_list.GetCount();
//const CLA **cla=cla_list.GetData();
int cur_size=0;
//int cur_size=0;
for(int i=0;i<count;i++)
{
}
//for(int i=0;i<count;i++)
//{
//}
return(true);
}
@@ -145,54 +153,66 @@ namespace hgl
// return 0;
//}
int TextLayout::pl_h_l2r()
int TextLayout::sl_h_l2r()
{
const int count=cla_list.GetCount();
const CLA **cla=cla_list.GetData();
const int count=draw_chars_list.GetCount();
CharDrawAttr **cda=draw_chars_list.GetData();
int cur_size=0;
int left=0,top=0;
float *tp=vertex->Begin();
float *tcp=tex_coord->Begin();
for(int i=0;i<count;i++)
{
*tp=left; ++tp;
*tp=top; ++tp;
*tp=left+(*cla)->adv_info.w;++tp;
*tp=top +(*cla)->adv_info.h;++tp;
if((*cda)->cla->visible)
{
tp=WriteRect( tp,
left,
top,
(*cda)->cla->metrics.w,
(*cda)->cla->metrics.h);
tcp=WriteRect(tcp,(*cda)->uv);
}
else
{
}
left+=(*cda)->cla->metrics.adv_x;
++cda;
}
tex_coord->End();
vertex->End();
return 0;
return count;
}
int TextLayout::pl_h_r2l(){return 0;}
int TextLayout::pl_v_r2l(){return 0;}
int TextLayout::pl_v_l2r(){return 0;}
int TextLayout::sl_h_r2l(){return 0;}
int TextLayout::sl_v_r2l(){return 0;}
int TextLayout::sl_v_l2r(){return 0;}
/**
* 平面文本排版<br>
* 不处理自动换行,仅支持\r\n换行。无任何特殊处理
* 简易文本排版。无任何特殊处理,不支持任何转义符,不支持\r\n
*/
template<typename T>
int TextLayout::PlaneLayout(TileFont *tf,const int mc,const BaseString<T> &str)
int TextLayout::SimpleLayout(TileFont *tf,const BaseString<T> &str)
{
if(mc<=0||str.IsEmpty())
if(!tf||str.IsEmpty())
return(-1);
max_chars=hgl_min(mc,str.Length());
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))
if(draw_chars_count<=0) //可绘制字符为0这是全空格
return(-4);
if(!rc->Init(draw_chars_count)) //创建
return(-5);
vertex =rc->CreateVADA<VB4f>(VAN::Vertex);
tex_coord =rc->CreateVADA<VB4f>(VAN::TexCoord);

View File

@@ -30,45 +30,32 @@ namespace hgl
* @param rs 每个字符在纹理中的UV坐标
* @param ch_list 要注册的字符列表
*/
bool TileFont::Registry(List<TileUVFloat> &rs,const List<u32char> &ch_list)
bool TileFont::Registry(TileUVFloatMap &uv_map,const u32char *ch_list,const int ch_count)
{
const u32char *cp=ch_list.GetData();
const u32char *cp=ch_list;
TileObject *to;
List<u32char> new_chars;
int in_active_count;
int in_idle_count;
int out_count;
int idle_left_count;
int in_active_count; //在活跃列表中的数量
int in_idle_count; //在闲置列表中的数量
int out_count; //不存在的字符数量
int idle_left_count; //闲置列表中可释放的数量
int exist_count;
to_res.Stats(ch_list,ch_count,&in_active_count,&in_idle_count,&out_count,&idle_left_count);
to_res.Stats(ch_list.GetData(),ch_list.GetCount(),&in_active_count,&in_idle_count,&out_count,&idle_left_count);
if(out_count>idle_left_count+tile_data->GetFreeCount()) //不存在的字符数量总量>剩余可释放的闲置项+剩余可用的空余tile
return(false);
exist_count=in_active_count+in_idle_count;
if(exist_count>tile_data->GetFreeCount()) //剩余空间不够了
{
int need=new_chars.GetCount()-tile_data->GetFreeCount(); //计算需要的tile数量差值
to_res.Get
if(need>to_res.GetIdleCount()) //闲置项都不够,那没戏了
return(false);
}
rs.ClearData();
rs.SetCount(ch_list.GetCount());
uv_map.ClearData();
FontBitmap *bmp;
TileUVFloat *tp=rs.GetData();
cp=ch_list.GetData();
cp=ch_list;
if(new_chars.GetCount())
{
tile_data->BeginCommit();
for(uint i=0;i<ch_list.GetCount();i++)
for(uint i=0;i<ch_count;i++)
{
if(!to_res.Get(*cp,to))
{
@@ -80,16 +67,14 @@ namespace hgl
to_res.Add(*cp,to);
}
uv_map.Add(*cp,to->uv_float);
++cp;
*tp=to->uv_float;
++tp;
}
tile_data->EndCommit();
}
else
{
for(uint i=0;i<ch_list.GetCount();i++)
for(uint i=0;i<ch_count;i++)
{
to_res.Get(*cp,to);
++cp;