first finished TileFont and test program.
This commit is contained in:
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user