#include #include #include #include namespace hgl { namespace graph { bool TextLayout::Init() { if((!tla.font_source&&!font_source) ||!tla.char_layout_attr) return(false); direction.text_direction=tla.text_direction; if(direction.vertical) { endless =(tla.max_width<=0.0f); splite_line_max_limit = tla.max_width; } else { endless =(tla.max_height<=0.0f); splite_line_max_limit = tla.max_height; } if(!font_source) font_source=tla.font_source; const float origin_char_height=font_source->GetCharHeight(); x=y=0; 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 bool TextLayout::preprocess(TextPrimitive *tr,TileFont *tile_font,const T *str,const int str_length) { if(!tr ||!tile_font ||!str||!*str||str_length<=0 ||!font_source) return(false); //遍历所有字符,取得每一个字符的基本绘制信息 { draw_chars_count=0; chars_sets.ClearData(); draw_chars_list.ClearData(); const T *cp=str; CharDrawAttr *cda; for(int i=0;icla=font_source->GetCLA(*cp); if(cda->cla->visible) { chars_sets.Add(*cp); //统计所有不重复字符 ++draw_chars_count; } draw_chars_list.Add(cda); ++cp; } } //释放不再使用的字符 { clear_chars_sets=tr->GetCharsSets(); //获取不再使用的字符合集 clear_chars_sets.Clear(chars_sets); //清除下一步要用的字符合集 if(clear_chars_sets.GetCount()>0) //可以彻底清除的字符 { tile_font->Unregistry(clear_chars_sets.GetList()); clear_chars_sets.ClearData(); } } //注册不重复字符给tile font系统,获取所有字符的UV if(!tile_font->Registry(chars_uv,chars_sets)) { draw_chars_list.ClearData(); chars_sets.ClearData(); return(false); } tr->SetCharsSets(chars_sets); //注册需要使用的字符合集 //为可绘制字符列表中的字符获取UV { CharDrawAttr **cda=draw_chars_list.GetData(); for(int i=0;icla->attr->ch,(*cda)->uv); ++cda; } } return(true); } /** * 将字符串断成多行,处理标点禁用,以及英文单词禁拆分 */ bool TextLayout::h_splite_to_lines(float view_limit) { //const int count=cla_list.GetCount(); //const CLA **cla=cla_list.GetData(); //int cur_size=0; //for(int i=0;i &str) //{ // if(mc<=0 // ||!str // ||!(*str)) // return(-1); // max_chars=mc; // origin_string=str; // if(preprocess()<=0) // return(-3); // // if(!rc->Init(draw_chars_count)) // return(-4); // vertex =rc->CreateVADA(VAN::Position); // tex_coord =rc->CreateVADA(VAN::TexCoord); // if(!vertex||!tex_coord) // return(-5); // if(direction.vertical) // { // if(!v_splite_to_lines(tla->max_height)) // return(-4); // } // else // { // if(!h_splite_to_lines(tla->max_width)) // return(-4); // } // return 0; //} int TextLayout::sl_h_l2r() { const int count=draw_chars_list.GetCount(); CharDrawAttr **cda=draw_chars_list.GetData(); int cur_size=0; int left=0,top=0; int16 *tp=vertex; float *tcp=tex_coord; for(int i=0;icla->visible) { tp=WriteRect( tp, left+(*cda)->cla->metrics.x, top -(*cda)->cla->metrics.y+font_source->GetCharHeight(), (*cda)->cla->metrics.w, (*cda)->cla->metrics.h); tcp=WriteRect(tcp,(*cda)->uv); left+=(*cda)->cla->metrics.adv_x; } else { if((*cda)->cla->attr->ch==' ') left+=space_size; else if((*cda)->cla->attr->ch==U32_FULL_WIDTH_SPACE) left+=full_space_size; else if((*cda)->cla->attr->ch=='\t') left+=tab_size; else if((*cda)->cla->attr->ch=='\n') { left=0; top+=font_source->GetCharHeight()+line_gap; } else { left+=(*cda)->cla->metrics.adv_x; } } ++cda; } return count; } int TextLayout::sl_h_r2l(){return 0;} int TextLayout::sl_v_r2l(){return 0;} int TextLayout::sl_v_l2r(){return 0;} /** * 简易文本排版。无任何特殊处理,不支持任何转义符,不支持\r\n */ template int TextLayout::SimpleLayout(TextPrimitive *tr,TileFont *tf,const String &str) { if(!tr) return(-1); if(!tf||str.IsEmpty()) return(-1); int max_chars=str.Length(); if(!preprocess(tr,tf,str.c_str(),max_chars)) return(-2); if(draw_chars_count<=0) //可绘制字符为0???这是全空格? return(-3); vertex .SetLength(max_chars*4); tex_coord .SetLength(max_chars*4); if(!vertex||!tex_coord) return(-5); int result; if(direction.vertical) { if(direction.right_to_left) result=sl_v_r2l(); else result=sl_v_l2r(); } else { if(direction.right_to_left) result=sl_h_r2l(); else result=sl_h_l2r(); } if(result>0) { tr->SetCharCount(result); tr->WriteVertex(vertex); tr->WriteTexCoord(tex_coord); } return result; } int TextLayout::SimpleLayout(TextPrimitive *tr,TileFont *tf,const UTF16String &str){return this->SimpleLayout(tr,tf,str);} int TextLayout::SimpleLayout(TextPrimitive *tr,TileFont *tf,const UTF32String &str){return this->SimpleLayout(tr,tf,str);} //template //int TextLayout::SimpleLayout(TileFont *tf,const StringList> &sl) //{ //} //int TextLayout::SimpleLayout(TileFont *tf,const UTF16StringList &sl){return this->SimpleLayout(tf,sl);} //int TextLayout::SimpleLayout(TileFont *tf,const UTF32StringList &sl){return this->SimpleLayout(tf,sl);} }//namespace graph }//namespace hgl