Import Geant4 11.0.0.beta source tree
This commit is contained in:
+576
@@ -0,0 +1,576 @@
|
||||
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
||||
// See the file tools.license for terms.
|
||||
|
||||
#ifndef tools_sg_text
|
||||
#define tools_sg_text
|
||||
|
||||
#include "nodekit"
|
||||
#include "back_area"
|
||||
|
||||
#include "matrix"
|
||||
#include "text_hershey"
|
||||
#include "base_freetype"
|
||||
|
||||
#include "enums"
|
||||
#include "rgba"
|
||||
#include "noderef"
|
||||
#include "mf"
|
||||
|
||||
#include "../colorf"
|
||||
#include "../S_STRING"
|
||||
|
||||
namespace tools {
|
||||
namespace sg {
|
||||
|
||||
class text : public back_area {
|
||||
TOOLS_NODE(text,tools::sg::text,back_area)
|
||||
public:
|
||||
mf_string strings;
|
||||
sf<bool> confine;
|
||||
|
||||
sf_vec<colorf,float> color;
|
||||
sf_string font;
|
||||
sf_enum<sg::font_modeling> font_modeling;
|
||||
|
||||
sf_string encoding;
|
||||
sf<float> line_width; // for text_hershey.
|
||||
sf_enum<winding_type> front_face; //no more used.
|
||||
|
||||
sf<bool> back_visible;
|
||||
|
||||
sf<bool> enforce_front_height;
|
||||
sf<float> front_height;
|
||||
sf<bool> enforce_front_width;
|
||||
sf<float> front_width;
|
||||
|
||||
sf<float> wmargin_factor;
|
||||
sf<float> hmargin_factor;
|
||||
sf_enum<sg::hjust> hjust;
|
||||
sf_enum<sg::vjust> vjust;
|
||||
public:
|
||||
virtual const desc_fields& node_desc_fields() const {
|
||||
TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::text)
|
||||
static const desc_fields s_v(parent::node_desc_fields(),17, //WARNING : have the right count.
|
||||
TOOLS_ARG_FIELD_DESC(strings),
|
||||
TOOLS_ARG_FIELD_DESC(confine),
|
||||
|
||||
TOOLS_ARG_FIELD_DESC(color),
|
||||
|
||||
TOOLS_ARG_FIELD_DESC_OPTS_BEG(font,10)
|
||||
font_hershey().c_str(),
|
||||
font_lato_regular_ttf().c_str(),
|
||||
font_roboto_bold_ttf().c_str(),
|
||||
font_arial_ttf().c_str(),
|
||||
font_arialbd_ttf().c_str(),
|
||||
font_timesbd_ttf().c_str(),
|
||||
font_symbol_ttf().c_str(),
|
||||
font_stixgeneral_otf().c_str(),
|
||||
font_helvetica_ttf().c_str(),
|
||||
font_times_roman_ttf().c_str()
|
||||
TOOLS_ARG_FIELD_DESC_OPTS_END,
|
||||
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_modeling,3)
|
||||
TOOLS_ARG_ENUM(font_outline),
|
||||
TOOLS_ARG_ENUM(font_filled),
|
||||
TOOLS_ARG_ENUM(font_pixmap)
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_END,
|
||||
|
||||
TOOLS_ARG_FIELD_DESC(encoding),
|
||||
TOOLS_ARG_FIELD_DESC(line_width),
|
||||
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_BEG(front_face,2)
|
||||
TOOLS_ARG_ENUM(winding_ccw),
|
||||
TOOLS_ARG_ENUM(winding_cw)
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_END,
|
||||
|
||||
TOOLS_ARG_FIELD_DESC(back_visible),
|
||||
|
||||
TOOLS_ARG_FIELD_DESC(enforce_front_height),
|
||||
TOOLS_ARG_FIELD_DESC(front_height),
|
||||
TOOLS_ARG_FIELD_DESC(enforce_front_width),
|
||||
TOOLS_ARG_FIELD_DESC(front_width),
|
||||
TOOLS_ARG_FIELD_DESC(wmargin_factor),
|
||||
TOOLS_ARG_FIELD_DESC(hmargin_factor),
|
||||
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_BEG(hjust,3)
|
||||
TOOLS_ARG_ENUM(left),
|
||||
TOOLS_ARG_ENUM(center),
|
||||
TOOLS_ARG_ENUM(right)
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_END,
|
||||
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_BEG(vjust,3)
|
||||
TOOLS_ARG_ENUM(bottom),
|
||||
TOOLS_ARG_ENUM(middle),
|
||||
TOOLS_ARG_ENUM(top)
|
||||
TOOLS_ARG_FIELD_DESC_ENUMS_END
|
||||
);
|
||||
return s_v;
|
||||
}
|
||||
private:
|
||||
void add_fields(){
|
||||
add_field(&strings);
|
||||
add_field(&confine);
|
||||
|
||||
add_field(&color);
|
||||
add_field(&font);
|
||||
add_field(&font_modeling);
|
||||
add_field(&encoding);
|
||||
add_field(&line_width);
|
||||
add_field(&front_face);
|
||||
|
||||
add_field(&back_visible);
|
||||
|
||||
add_field(&enforce_front_height);
|
||||
add_field(&front_height);
|
||||
add_field(&enforce_front_width);
|
||||
add_field(&front_width);
|
||||
|
||||
add_field(&wmargin_factor);
|
||||
add_field(&hmargin_factor);
|
||||
add_field(&hjust);
|
||||
add_field(&vjust);
|
||||
}
|
||||
public:
|
||||
virtual void render(render_action& a_action) {
|
||||
if(touched()) {
|
||||
update_sg();
|
||||
reset_touched();
|
||||
}
|
||||
if(back_visible.value()) m_back_sep.render(a_action);
|
||||
m_sep.render(a_action);
|
||||
}
|
||||
virtual void pick(pick_action& a_action) {
|
||||
if(touched()) {
|
||||
update_sg();
|
||||
reset_touched();
|
||||
}
|
||||
if(back_visible.value()) {
|
||||
nodekit_pick(a_action,m_back_sep,this);
|
||||
}
|
||||
//m_sep.pick(a_action);
|
||||
}
|
||||
virtual void search(search_action& a_action) {
|
||||
if(touched()) {
|
||||
update_sg();
|
||||
reset_touched();
|
||||
}
|
||||
parent::search(a_action);
|
||||
if(a_action.done()) return;
|
||||
if(a_action.do_path()) a_action.path_push(this);
|
||||
if(back_visible.value()) {
|
||||
m_back_sep.search(a_action);
|
||||
if(a_action.done()) return;
|
||||
}
|
||||
m_sep.search(a_action);
|
||||
if(a_action.done()) return;
|
||||
if(a_action.do_path()) a_action.path_pop();
|
||||
}
|
||||
virtual void bbox(bbox_action& a_action) {
|
||||
if(touched()) {
|
||||
update_sg();
|
||||
reset_touched();
|
||||
}
|
||||
if(back_visible.value()) m_back_sep.bbox(a_action);
|
||||
m_sep.bbox(a_action);
|
||||
}
|
||||
public:
|
||||
text(const base_freetype& a_ttf)
|
||||
:parent()
|
||||
,strings()
|
||||
,confine(false)
|
||||
|
||||
,color(colorf_black())
|
||||
,font(font_hershey())
|
||||
,font_modeling(font_filled)
|
||||
,encoding(encoding_PAW())
|
||||
,line_width(1)
|
||||
,front_face(winding_ccw)
|
||||
|
||||
,back_visible(true)
|
||||
|
||||
,enforce_front_height(false)
|
||||
,front_height(1)
|
||||
,enforce_front_width(false)
|
||||
,front_width(1)
|
||||
|
||||
,wmargin_factor(0.9f)
|
||||
,hmargin_factor(0.9f)
|
||||
,hjust(left) // same default as base_text.
|
||||
,vjust(middle) // not same default as base_text (which is bottom). We take middle for backcomp of confined text.
|
||||
// Note that text_hershey, text_freetype is (left,bottom) justified.
|
||||
|
||||
,m_base_text(0)
|
||||
,m_TT_text(base_freetype::create(a_ttf))
|
||||
{
|
||||
add_fields();
|
||||
}
|
||||
virtual ~text(){
|
||||
delete m_TT_text;
|
||||
}
|
||||
public:
|
||||
text(const text& a_from)
|
||||
:parent(a_from)
|
||||
,strings(a_from.strings)
|
||||
,confine(a_from.confine)
|
||||
|
||||
,color(a_from.color)
|
||||
,font(a_from.font)
|
||||
,font_modeling(a_from.font_modeling)
|
||||
,encoding(a_from.encoding)
|
||||
,line_width(a_from.line_width)
|
||||
,front_face(a_from.front_face)
|
||||
|
||||
,back_visible(a_from.back_visible)
|
||||
|
||||
,enforce_front_height(a_from.enforce_front_height)
|
||||
,front_height(a_from.front_height)
|
||||
,enforce_front_width(a_from.enforce_front_width)
|
||||
,front_width(a_from.front_width)
|
||||
|
||||
,wmargin_factor(a_from.wmargin_factor)
|
||||
,hmargin_factor(a_from.hmargin_factor)
|
||||
,hjust(a_from.hjust)
|
||||
,vjust(a_from.vjust)
|
||||
|
||||
,m_base_text(0)
|
||||
,m_TT_text(base_freetype::create(*a_from.m_TT_text))
|
||||
{
|
||||
add_fields();
|
||||
}
|
||||
text& operator=(const text& a_from){
|
||||
parent::operator=(a_from);
|
||||
if(&a_from==this) return *this;
|
||||
|
||||
strings = a_from.strings;
|
||||
confine = a_from.confine;
|
||||
|
||||
color = a_from.color;
|
||||
font = a_from.font;
|
||||
font_modeling = a_from.font_modeling;
|
||||
encoding = a_from.encoding;
|
||||
line_width = a_from.line_width;
|
||||
front_face = a_from.front_face;
|
||||
|
||||
back_visible = a_from.back_visible;
|
||||
|
||||
enforce_front_height = a_from.enforce_front_height;
|
||||
front_height = a_from.front_height;
|
||||
enforce_front_width = a_from.enforce_front_width;
|
||||
front_width = a_from.front_width;
|
||||
|
||||
wmargin_factor = a_from.wmargin_factor;
|
||||
hmargin_factor = a_from.hmargin_factor;
|
||||
hjust = a_from.hjust;
|
||||
vjust = a_from.vjust;
|
||||
|
||||
m_base_text = 0;
|
||||
|
||||
//delete m_TT_text;
|
||||
//m_TT_text = base_freetype::create(*a_from.m_TT_text);
|
||||
|
||||
return *this;
|
||||
}
|
||||
public:
|
||||
float text_height() const {
|
||||
if(!m_base_text) return 0;
|
||||
return m_base_text->height;
|
||||
}
|
||||
/*bool get_bounds(float a_height,
|
||||
float& a_mn_x,float& a_mn_y,float& a_mn_z,
|
||||
float& a_mx_x,float& a_mx_y,float& a_mx_z) const {
|
||||
if(!m_base_text) {
|
||||
a_mn_x = 0;
|
||||
a_mn_y = 0;
|
||||
a_mn_z = 0;
|
||||
a_mx_x = 0;
|
||||
a_mx_y = 0;
|
||||
a_mx_z = 0;
|
||||
return false;
|
||||
}
|
||||
m_base_text->get_bounds(m_base_text->height,a_mn_x,a_mn_y,a_mn_z,a_mx_x,a_mx_y,a_mx_z);
|
||||
return true;
|
||||
}*/
|
||||
bool is_empty() const {
|
||||
tools_vforcit(std::string,strings.values(),it) {
|
||||
const std::string& line = *it;
|
||||
if(line.size()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const separator& container() const {return m_back_sep;} //must be consistent with pick().
|
||||
public:
|
||||
void update_sg() {
|
||||
parent::update_sg();
|
||||
|
||||
m_sep.clear();
|
||||
m_base_text = 0;
|
||||
|
||||
if(width.value()<=0) return;
|
||||
if(height.value()<=0) return;
|
||||
if(is_empty()) return;
|
||||
|
||||
rgba* mat = new rgba();
|
||||
mat->color = color;
|
||||
m_sep.add(mat);
|
||||
|
||||
matrix* tsf = new matrix;
|
||||
m_sep.add(tsf);
|
||||
|
||||
float fw = width * wmargin_factor;
|
||||
float fh = height * hmargin_factor;
|
||||
|
||||
//sf<float> zfront ?
|
||||
float zz = back_visible.value()?0.01f:0;
|
||||
|
||||
if(font==font_hershey()) {
|
||||
|
||||
draw_style* ds = new draw_style;
|
||||
ds->style = draw_lines;
|
||||
ds->line_width = line_width;
|
||||
m_sep.add(ds);
|
||||
|
||||
text_hershey* _text = new text_hershey;
|
||||
m_base_text = _text;
|
||||
_text->encoding = encoding;
|
||||
_text->strings = strings;
|
||||
m_sep.add(_text);
|
||||
|
||||
} else {
|
||||
|
||||
m_base_text = m_TT_text;
|
||||
//ttf/arialbd 11
|
||||
//01234567890
|
||||
m_TT_text->font = font;
|
||||
m_TT_text->strings = strings;
|
||||
m_TT_text->modeling = font_modeling;
|
||||
|
||||
//_text->modeling.value(font_outline);
|
||||
|
||||
m_sep.add(new noderef(*m_TT_text));
|
||||
|
||||
}
|
||||
|
||||
if(enforce_front_height) {
|
||||
|
||||
m_base_text->height = front_height;
|
||||
|
||||
float mn_x,mn_y,mn_z;
|
||||
float mx_x,mx_y,mx_z;
|
||||
m_base_text->get_bounds(front_height,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
|
||||
float bxw = mx_x-mn_x;
|
||||
float xtrans = 0;
|
||||
if(hjust==center) {
|
||||
xtrans = 0;
|
||||
} else if(hjust==left) {
|
||||
xtrans = -fw*0.5f+bxw*0.5f;
|
||||
} else if(hjust==right) {
|
||||
xtrans = fw*0.5f-bxw*0.5f;
|
||||
}
|
||||
|
||||
float bxh = mx_y-mn_y;
|
||||
float ytrans = 0;
|
||||
if(vjust==middle) {
|
||||
ytrans = 0;
|
||||
} else if(vjust==bottom) {
|
||||
ytrans = -fh*0.5f+bxh*0.5f;
|
||||
} else if(vjust==top) {
|
||||
ytrans = fh*0.5f-bxh*0.5f;
|
||||
}
|
||||
|
||||
float xx = -(mn_x+mx_x)*0.5F+xtrans;
|
||||
float yy = -(mn_y+mx_y)*0.5F+ytrans;
|
||||
tsf->set_translate(xx,yy,zz);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(enforce_front_width) {
|
||||
|
||||
float th = fh;
|
||||
float mn_x,mn_y,mn_z;
|
||||
float mx_x,mx_y,mx_z;
|
||||
m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
float bxw = mx_x-mn_x;
|
||||
|
||||
// adjust box width :
|
||||
// th -> bxw then to have front_width:
|
||||
if(bxw>0) {
|
||||
th = th*front_width/bxw;
|
||||
m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
}
|
||||
|
||||
bxw = mx_x-mn_x;
|
||||
float xtrans = 0;
|
||||
if(hjust==center) {
|
||||
xtrans = 0;
|
||||
} else if(hjust==left) {
|
||||
xtrans = -fw*0.5f+bxw*0.5f;
|
||||
} else if(hjust==right) {
|
||||
xtrans = fw*0.5f-bxw*0.5f;
|
||||
}
|
||||
|
||||
float bxh = mx_y-mn_y;
|
||||
float ytrans = 0;
|
||||
if(vjust==middle) {
|
||||
ytrans = 0;
|
||||
} else if(vjust==bottom) {
|
||||
ytrans = -fh*0.5f+bxh*0.5f;
|
||||
} else if(vjust==top) {
|
||||
ytrans = fh*0.5f-bxw*0.5f;
|
||||
}
|
||||
|
||||
float xx = -(mn_x+mx_x)*0.5F+xtrans;
|
||||
float yy = -(mn_y+mx_y)*0.5F+ytrans;
|
||||
tsf->set_translate(xx,yy,zz);
|
||||
|
||||
m_base_text->height = bxh; //=th?
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//various automatic text height strategies :
|
||||
|
||||
if(confine) {
|
||||
// code common to freetype and hershey :
|
||||
|
||||
// try to adjust text within fw x fh (by attempting to be smart !).
|
||||
// the below assumes that text bounds are linear according
|
||||
// "text height".
|
||||
{float mn_x,mn_y,mn_z;
|
||||
float mx_x,mx_y,mx_z;
|
||||
|
||||
float th = fh;
|
||||
m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
float bxh = mx_y-mn_y;
|
||||
// adjust box height :
|
||||
// fh -> bxh then to have fh :
|
||||
if(bxh>0) {
|
||||
th = fh*fh/bxh;
|
||||
m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
}
|
||||
|
||||
//float bxw = box.mx()[0]-box.mn()[0];
|
||||
float bxw = mx_x-mn_x;
|
||||
bxh = mx_y-mn_y;
|
||||
if((fh>0)&&(bxh>0)){
|
||||
float fasp = fw/fh;
|
||||
float basp = bxw/bxh;
|
||||
if(fasp>=basp) {
|
||||
} else {
|
||||
// adjust box width :
|
||||
// th -> bxw then to have fw :
|
||||
if(bxw>0) {
|
||||
th = th*fw/bxw;
|
||||
m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_base_text->height = th;
|
||||
|
||||
//bxw = box.mx()[0]-box.mn()[0];
|
||||
bxw = mx_x-mn_x;
|
||||
float xtrans = 0;
|
||||
if(hjust==center) {
|
||||
xtrans = 0;
|
||||
} else if(hjust==left) {
|
||||
xtrans = -fw*0.5f+bxw*0.5f;
|
||||
} else if(hjust==right) {
|
||||
xtrans = fw*0.5f-bxw*0.5f;
|
||||
}
|
||||
|
||||
bxh = mx_y-mn_y;
|
||||
float ytrans = 0;
|
||||
if(vjust==middle) {
|
||||
ytrans = 0;
|
||||
} else if(vjust==bottom) {
|
||||
ytrans = -fh*0.5f+bxh*0.5f;
|
||||
} else if(vjust==top) {
|
||||
ytrans = fh*0.5f-bxw*0.5f;
|
||||
}
|
||||
|
||||
float xx = -(mn_x+mx_x)*0.5F+xtrans;
|
||||
float yy = -(mn_y+mx_y)*0.5F+ytrans;
|
||||
|
||||
tsf->set_translate(xx,yy,zz);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// we arrange yy so that two aside texts
|
||||
// with same height will have their text base lines aligned.
|
||||
// The max height is given by ascent+descent (with descent>0).
|
||||
float th = fh;
|
||||
|
||||
float mxh = m_base_text->ascent(th)+
|
||||
m_base_text->y_advance(th)*(strings.size()-1)+
|
||||
m_base_text->descent(th);
|
||||
|
||||
//{box3f box;
|
||||
// m_base_text->get_bounds(th,box);
|
||||
// float bxh = box.mx()[1]-box.mn()[1]; //should be idem mxh.
|
||||
// mxh = bxh;}
|
||||
|
||||
if(mxh) th = fh*fh/mxh; //end/final height.
|
||||
|
||||
m_base_text->height = th; //then all chars will fit into th.
|
||||
|
||||
mxh = m_base_text->ascent(th)+
|
||||
m_base_text->y_advance(th)*(strings.size()-1)+
|
||||
m_base_text->descent(th);
|
||||
|
||||
float yy = -fh*0.5f+m_base_text->descent(th)+
|
||||
m_base_text->y_advance(th)*(strings.size()-1);
|
||||
|
||||
//float xx = -fw*0.5F; //left justified.
|
||||
//tsf->set_translate(xx,yy,zz);
|
||||
{float mn_x,mn_y,mn_z;
|
||||
float mx_x,mx_y,mx_z;
|
||||
m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
|
||||
|
||||
float bxw = mx_x-mn_x;
|
||||
float xtrans = 0;
|
||||
if(hjust==center) {
|
||||
xtrans = 0;
|
||||
} else if(hjust==left) {
|
||||
xtrans = -fw*0.5f+bxw*0.5f;
|
||||
} else if(hjust==right) {
|
||||
xtrans = fw*0.5f-bxw*0.5f;
|
||||
}
|
||||
/*
|
||||
float bxh = mx_y-mn_y;
|
||||
float ytrans = 0;
|
||||
if(vjust==middle) {
|
||||
ytrans = 0;
|
||||
} else if(vjust==bottom) {
|
||||
ytrans = -fh*0.5f+bxh*0.5f;
|
||||
} else if(vjust==top) {
|
||||
ytrans = fh*0.5f-bxw*0.5f;
|
||||
}
|
||||
*/
|
||||
float xx = -(mn_x+mx_x)*0.5F+xtrans;
|
||||
tsf->set_translate(xx,yy,zz);}
|
||||
|
||||
// truncate text at right if out of border :
|
||||
{std::vector<std::string> labcut;
|
||||
tools_vforcit(std::string,strings.values(),it) {
|
||||
std::string scut;
|
||||
m_base_text->truncate(*it,th,fw,scut);
|
||||
labcut.push_back(scut);
|
||||
}
|
||||
m_base_text->strings = labcut;}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
separator m_sep;
|
||||
base_text* m_base_text;
|
||||
base_freetype* m_TT_text; //optimize : avoid too much freetype load font.
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user