Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_sg_text 4 #ifndef tools_sg_text 5 #define tools_sg_text 5 #define tools_sg_text 6 6 7 #include "nodekit" 7 #include "nodekit" 8 #include "back_area" 8 #include "back_area" 9 9 10 #include "matrix" 10 #include "matrix" 11 #include "text_hershey" 11 #include "text_hershey" 12 #include "base_freetype" 12 #include "base_freetype" 13 13 14 #include "enums" 14 #include "enums" 15 #include "rgba" 15 #include "rgba" 16 #include "noderef" 16 #include "noderef" 17 #include "mf" 17 #include "mf" 18 18 19 #include "../colorf" 19 #include "../colorf" 20 #include "../S_STRING" 20 #include "../S_STRING" 21 21 22 #include <utility> << 23 << 24 namespace tools { 22 namespace tools { 25 namespace sg { 23 namespace sg { 26 24 27 class text : public back_area { 25 class text : public back_area { 28 TOOLS_NODE(text,tools::sg::text,back_area) 26 TOOLS_NODE(text,tools::sg::text,back_area) 29 public: 27 public: 30 mf_string strings; 28 mf_string strings; 31 sf<bool> confine; 29 sf<bool> confine; 32 30 33 sf_vec<colorf,float> color; 31 sf_vec<colorf,float> color; 34 sf_string font; 32 sf_string font; 35 sf_enum<sg::font_modeling> font_modeling; 33 sf_enum<sg::font_modeling> font_modeling; 36 34 37 sf_string encoding; 35 sf_string encoding; 38 sf<float> line_width; // for text_hershey. 36 sf<float> line_width; // for text_hershey. 39 sf_enum<winding_type> front_face; //no more 37 sf_enum<winding_type> front_face; //no more used. 40 38 41 sf<bool> back_visible; 39 sf<bool> back_visible; 42 40 43 sf<bool> enforce_front_height; 41 sf<bool> enforce_front_height; 44 sf<float> front_height; 42 sf<float> front_height; 45 sf<bool> enforce_front_width; 43 sf<bool> enforce_front_width; 46 sf<float> front_width; 44 sf<float> front_width; 47 45 48 sf<float> wmargin_factor; 46 sf<float> wmargin_factor; 49 sf<float> hmargin_factor; 47 sf<float> hmargin_factor; 50 sf_enum<sg::hjust> hjust; 48 sf_enum<sg::hjust> hjust; 51 sf_enum<sg::vjust> vjust; 49 sf_enum<sg::vjust> vjust; 52 public: 50 public: 53 virtual const desc_fields& node_desc_fields( 51 virtual const desc_fields& node_desc_fields() const { 54 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::tex 52 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::text) 55 static const desc_fields s_v(parent::node_ 53 static const desc_fields s_v(parent::node_desc_fields(),17, //WARNING : have the right count. 56 TOOLS_ARG_FIELD_DESC(strings), 54 TOOLS_ARG_FIELD_DESC(strings), 57 TOOLS_ARG_FIELD_DESC(confine), 55 TOOLS_ARG_FIELD_DESC(confine), 58 56 59 TOOLS_ARG_FIELD_DESC(color), 57 TOOLS_ARG_FIELD_DESC(color), 60 58 61 TOOLS_ARG_FIELD_DESC_OPTS_BEG(font,10) 59 TOOLS_ARG_FIELD_DESC_OPTS_BEG(font,10) 62 font_hershey().c_str(), 60 font_hershey().c_str(), 63 font_lato_regular_ttf().c_str(), 61 font_lato_regular_ttf().c_str(), 64 font_roboto_bold_ttf().c_str(), 62 font_roboto_bold_ttf().c_str(), 65 font_arial_ttf().c_str(), 63 font_arial_ttf().c_str(), 66 font_arialbd_ttf().c_str(), 64 font_arialbd_ttf().c_str(), 67 font_timesbd_ttf().c_str(), 65 font_timesbd_ttf().c_str(), 68 font_symbol_ttf().c_str(), 66 font_symbol_ttf().c_str(), 69 font_stixgeneral_otf().c_str(), 67 font_stixgeneral_otf().c_str(), 70 font_helvetica_ttf().c_str(), 68 font_helvetica_ttf().c_str(), 71 font_times_roman_ttf().c_str() 69 font_times_roman_ttf().c_str() 72 TOOLS_ARG_FIELD_DESC_OPTS_END, 70 TOOLS_ARG_FIELD_DESC_OPTS_END, 73 71 74 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_mode 72 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_modeling,3) 75 TOOLS_ARG_ENUM(font_outline), 73 TOOLS_ARG_ENUM(font_outline), 76 TOOLS_ARG_ENUM(font_filled), 74 TOOLS_ARG_ENUM(font_filled), 77 TOOLS_ARG_ENUM(font_pixmap) 75 TOOLS_ARG_ENUM(font_pixmap) 78 TOOLS_ARG_FIELD_DESC_ENUMS_END, 76 TOOLS_ARG_FIELD_DESC_ENUMS_END, 79 77 80 TOOLS_ARG_FIELD_DESC(encoding), 78 TOOLS_ARG_FIELD_DESC(encoding), 81 TOOLS_ARG_FIELD_DESC(line_width), 79 TOOLS_ARG_FIELD_DESC(line_width), 82 80 83 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(front_fac 81 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(front_face,2) 84 TOOLS_ARG_ENUM(winding_ccw), 82 TOOLS_ARG_ENUM(winding_ccw), 85 TOOLS_ARG_ENUM(winding_cw) 83 TOOLS_ARG_ENUM(winding_cw) 86 TOOLS_ARG_FIELD_DESC_ENUMS_END, 84 TOOLS_ARG_FIELD_DESC_ENUMS_END, 87 85 88 TOOLS_ARG_FIELD_DESC(back_visible), 86 TOOLS_ARG_FIELD_DESC(back_visible), 89 87 90 TOOLS_ARG_FIELD_DESC(enforce_front_heigh 88 TOOLS_ARG_FIELD_DESC(enforce_front_height), 91 TOOLS_ARG_FIELD_DESC(front_height), 89 TOOLS_ARG_FIELD_DESC(front_height), 92 TOOLS_ARG_FIELD_DESC(enforce_front_width 90 TOOLS_ARG_FIELD_DESC(enforce_front_width), 93 TOOLS_ARG_FIELD_DESC(front_width), 91 TOOLS_ARG_FIELD_DESC(front_width), 94 TOOLS_ARG_FIELD_DESC(wmargin_factor), 92 TOOLS_ARG_FIELD_DESC(wmargin_factor), 95 TOOLS_ARG_FIELD_DESC(hmargin_factor), 93 TOOLS_ARG_FIELD_DESC(hmargin_factor), 96 94 97 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(hjust,3) 95 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(hjust,3) 98 TOOLS_ARG_ENUM(left), 96 TOOLS_ARG_ENUM(left), 99 TOOLS_ARG_ENUM(center), 97 TOOLS_ARG_ENUM(center), 100 TOOLS_ARG_ENUM(right) 98 TOOLS_ARG_ENUM(right) 101 TOOLS_ARG_FIELD_DESC_ENUMS_END, 99 TOOLS_ARG_FIELD_DESC_ENUMS_END, 102 100 103 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(vjust,3) 101 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(vjust,3) 104 TOOLS_ARG_ENUM(bottom), 102 TOOLS_ARG_ENUM(bottom), 105 TOOLS_ARG_ENUM(middle), 103 TOOLS_ARG_ENUM(middle), 106 TOOLS_ARG_ENUM(top) 104 TOOLS_ARG_ENUM(top) 107 TOOLS_ARG_FIELD_DESC_ENUMS_END 105 TOOLS_ARG_FIELD_DESC_ENUMS_END 108 ); 106 ); 109 return s_v; 107 return s_v; 110 } 108 } 111 private: 109 private: 112 void add_fields(){ 110 void add_fields(){ 113 add_field(&strings); 111 add_field(&strings); 114 add_field(&confine); 112 add_field(&confine); 115 113 116 add_field(&color); 114 add_field(&color); 117 add_field(&font); 115 add_field(&font); 118 add_field(&font_modeling); 116 add_field(&font_modeling); 119 add_field(&encoding); 117 add_field(&encoding); 120 add_field(&line_width); 118 add_field(&line_width); 121 add_field(&front_face); 119 add_field(&front_face); 122 120 123 add_field(&back_visible); 121 add_field(&back_visible); 124 122 125 add_field(&enforce_front_height); 123 add_field(&enforce_front_height); 126 add_field(&front_height); 124 add_field(&front_height); 127 add_field(&enforce_front_width); 125 add_field(&enforce_front_width); 128 add_field(&front_width); 126 add_field(&front_width); 129 127 130 add_field(&wmargin_factor); 128 add_field(&wmargin_factor); 131 add_field(&hmargin_factor); 129 add_field(&hmargin_factor); 132 add_field(&hjust); 130 add_field(&hjust); 133 add_field(&vjust); 131 add_field(&vjust); 134 } 132 } 135 public: 133 public: 136 virtual void render(render_action& a_action) 134 virtual void render(render_action& a_action) { 137 if(touched()) { 135 if(touched()) { 138 update_sg(); 136 update_sg(); 139 reset_touched(); 137 reset_touched(); 140 } 138 } 141 if(back_visible.value()) m_back_sep.render 139 if(back_visible.value()) m_back_sep.render(a_action); 142 m_sep.render(a_action); 140 m_sep.render(a_action); 143 } 141 } 144 virtual void pick(pick_action& a_action) { 142 virtual void pick(pick_action& a_action) { 145 if(touched()) { 143 if(touched()) { 146 update_sg(); 144 update_sg(); 147 reset_touched(); 145 reset_touched(); 148 } 146 } 149 if(back_visible.value()) { 147 if(back_visible.value()) { 150 nodekit_pick(a_action,m_back_sep,this); 148 nodekit_pick(a_action,m_back_sep,this); 151 } 149 } 152 //m_sep.pick(a_action); 150 //m_sep.pick(a_action); 153 } 151 } 154 virtual void search(search_action& a_action) 152 virtual void search(search_action& a_action) { 155 if(touched()) { 153 if(touched()) { 156 update_sg(); 154 update_sg(); 157 reset_touched(); 155 reset_touched(); 158 } 156 } 159 parent::search(a_action); 157 parent::search(a_action); 160 if(a_action.done()) return; 158 if(a_action.done()) return; 161 if(a_action.do_path()) a_action.path_push( 159 if(a_action.do_path()) a_action.path_push(this); 162 if(back_visible.value()) { 160 if(back_visible.value()) { 163 m_back_sep.search(a_action); 161 m_back_sep.search(a_action); 164 if(a_action.done()) return; 162 if(a_action.done()) return; 165 } 163 } 166 m_sep.search(a_action); 164 m_sep.search(a_action); 167 if(a_action.done()) return; 165 if(a_action.done()) return; 168 if(a_action.do_path()) a_action.path_pop() 166 if(a_action.do_path()) a_action.path_pop(); 169 } 167 } 170 virtual void bbox(bbox_action& a_action) { 168 virtual void bbox(bbox_action& a_action) { 171 if(touched()) { 169 if(touched()) { 172 update_sg(); 170 update_sg(); 173 reset_touched(); 171 reset_touched(); 174 } 172 } 175 if(back_visible.value()) m_back_sep.bbox(a 173 if(back_visible.value()) m_back_sep.bbox(a_action); 176 m_sep.bbox(a_action); 174 m_sep.bbox(a_action); 177 } 175 } 178 public: 176 public: 179 text(const base_freetype& a_ttf) 177 text(const base_freetype& a_ttf) 180 :parent() 178 :parent() 181 ,strings() 179 ,strings() 182 ,confine(false) 180 ,confine(false) 183 181 184 ,color(colorf_black()) 182 ,color(colorf_black()) 185 ,font(font_hershey()) 183 ,font(font_hershey()) 186 ,font_modeling(font_filled) 184 ,font_modeling(font_filled) 187 ,encoding(encoding_PAW()) 185 ,encoding(encoding_PAW()) 188 ,line_width(1) 186 ,line_width(1) 189 ,front_face(winding_ccw) 187 ,front_face(winding_ccw) 190 188 191 ,back_visible(true) 189 ,back_visible(true) 192 190 193 ,enforce_front_height(false) 191 ,enforce_front_height(false) 194 ,front_height(1) 192 ,front_height(1) 195 ,enforce_front_width(false) 193 ,enforce_front_width(false) 196 ,front_width(1) 194 ,front_width(1) 197 195 198 ,wmargin_factor(0.9f) 196 ,wmargin_factor(0.9f) 199 ,hmargin_factor(0.9f) 197 ,hmargin_factor(0.9f) 200 ,hjust(left) // same default as base_text 198 ,hjust(left) // same default as base_text. 201 ,vjust(middle) // not same default as base_ 199 ,vjust(middle) // not same default as base_text (which is bottom). We take middle for backcomp of confined text. 202 // Note that text_hershey, t 200 // Note that text_hershey, text_freetype is (left,bottom) justified. 203 201 204 ,m_base_text(0) 202 ,m_base_text(0) 205 ,m_TT_text(base_freetype::create(a_ttf)) 203 ,m_TT_text(base_freetype::create(a_ttf)) 206 { 204 { 207 add_fields(); 205 add_fields(); 208 } 206 } 209 virtual ~text(){ 207 virtual ~text(){ 210 delete m_TT_text; 208 delete m_TT_text; 211 } 209 } 212 public: 210 public: 213 text(const text& a_from) 211 text(const text& a_from) 214 :parent(a_from) 212 :parent(a_from) 215 ,strings(a_from.strings) 213 ,strings(a_from.strings) 216 ,confine(a_from.confine) 214 ,confine(a_from.confine) 217 215 218 ,color(a_from.color) 216 ,color(a_from.color) 219 ,font(a_from.font) 217 ,font(a_from.font) 220 ,font_modeling(a_from.font_modeling) 218 ,font_modeling(a_from.font_modeling) 221 ,encoding(a_from.encoding) 219 ,encoding(a_from.encoding) 222 ,line_width(a_from.line_width) 220 ,line_width(a_from.line_width) 223 ,front_face(a_from.front_face) 221 ,front_face(a_from.front_face) 224 222 225 ,back_visible(a_from.back_visible) 223 ,back_visible(a_from.back_visible) 226 224 227 ,enforce_front_height(a_from.enforce_front_h 225 ,enforce_front_height(a_from.enforce_front_height) 228 ,front_height(a_from.front_height) 226 ,front_height(a_from.front_height) 229 ,enforce_front_width(a_from.enforce_front_wi 227 ,enforce_front_width(a_from.enforce_front_width) 230 ,front_width(a_from.front_width) 228 ,front_width(a_from.front_width) 231 229 232 ,wmargin_factor(a_from.wmargin_factor) 230 ,wmargin_factor(a_from.wmargin_factor) 233 ,hmargin_factor(a_from.hmargin_factor) 231 ,hmargin_factor(a_from.hmargin_factor) 234 ,hjust(a_from.hjust) 232 ,hjust(a_from.hjust) 235 ,vjust(a_from.vjust) 233 ,vjust(a_from.vjust) 236 234 237 ,m_base_text(0) 235 ,m_base_text(0) 238 ,m_TT_text(base_freetype::create(*a_from.m_T 236 ,m_TT_text(base_freetype::create(*a_from.m_TT_text)) 239 { 237 { 240 add_fields(); 238 add_fields(); 241 } 239 } 242 text& operator=(const text& a_from){ 240 text& operator=(const text& a_from){ 243 parent::operator=(a_from); 241 parent::operator=(a_from); 244 if(&a_from==this) return *this; 242 if(&a_from==this) return *this; 245 243 246 strings = a_from.strings; 244 strings = a_from.strings; 247 confine = a_from.confine; 245 confine = a_from.confine; 248 246 249 color = a_from.color; 247 color = a_from.color; 250 font = a_from.font; 248 font = a_from.font; 251 font_modeling = a_from.font_modeling; 249 font_modeling = a_from.font_modeling; 252 encoding = a_from.encoding; 250 encoding = a_from.encoding; 253 line_width = a_from.line_width; 251 line_width = a_from.line_width; 254 front_face = a_from.front_face; 252 front_face = a_from.front_face; 255 253 256 back_visible = a_from.back_visible; 254 back_visible = a_from.back_visible; 257 255 258 enforce_front_height = a_from.enforce_fron 256 enforce_front_height = a_from.enforce_front_height; 259 front_height = a_from.front_height; 257 front_height = a_from.front_height; 260 enforce_front_width = a_from.enforce_front 258 enforce_front_width = a_from.enforce_front_width; 261 front_width = a_from.front_width; 259 front_width = a_from.front_width; 262 260 263 wmargin_factor = a_from.wmargin_factor; 261 wmargin_factor = a_from.wmargin_factor; 264 hmargin_factor = a_from.hmargin_factor; 262 hmargin_factor = a_from.hmargin_factor; 265 hjust = a_from.hjust; 263 hjust = a_from.hjust; 266 vjust = a_from.vjust; 264 vjust = a_from.vjust; 267 265 268 m_base_text = 0; 266 m_base_text = 0; 269 267 270 //delete m_TT_text; 268 //delete m_TT_text; 271 //m_TT_text = base_freetype::create(*a_fro 269 //m_TT_text = base_freetype::create(*a_from.m_TT_text); 272 270 273 return *this; 271 return *this; 274 } 272 } 275 public: 273 public: 276 float text_height() const { 274 float text_height() const { 277 if(!m_base_text) return 0; 275 if(!m_base_text) return 0; 278 return m_base_text->height; 276 return m_base_text->height; 279 } 277 } 280 /*bool get_bounds(float a_height, 278 /*bool get_bounds(float a_height, 281 float& a_mn_x,float& a_mn_y, 279 float& a_mn_x,float& a_mn_y,float& a_mn_z, 282 float& a_mx_x,float& a_mx_y, 280 float& a_mx_x,float& a_mx_y,float& a_mx_z) const { 283 if(!m_base_text) { 281 if(!m_base_text) { 284 a_mn_x = 0; 282 a_mn_x = 0; 285 a_mn_y = 0; 283 a_mn_y = 0; 286 a_mn_z = 0; 284 a_mn_z = 0; 287 a_mx_x = 0; 285 a_mx_x = 0; 288 a_mx_y = 0; 286 a_mx_y = 0; 289 a_mx_z = 0; 287 a_mx_z = 0; 290 return false; 288 return false; 291 } 289 } 292 m_base_text->get_bounds(m_base_text->heigh 290 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); 293 return true; 291 return true; 294 }*/ 292 }*/ 295 bool is_empty() const { 293 bool is_empty() const { 296 tools_vforcit(std::string,strings.values() 294 tools_vforcit(std::string,strings.values(),it) { 297 const std::string& line = *it; 295 const std::string& line = *it; 298 if(line.size()) return false; 296 if(line.size()) return false; 299 } 297 } 300 return true; 298 return true; 301 } 299 } 302 300 303 const separator& container() const {return m 301 const separator& container() const {return m_back_sep;} //must be consistent with pick(). 304 public: 302 public: 305 void update_sg() { 303 void update_sg() { 306 parent::update_sg(); 304 parent::update_sg(); 307 305 308 m_sep.clear(); 306 m_sep.clear(); 309 m_base_text = 0; 307 m_base_text = 0; 310 308 311 if(width.value()<=0) return; 309 if(width.value()<=0) return; 312 if(height.value()<=0) return; 310 if(height.value()<=0) return; 313 if(is_empty()) return; 311 if(is_empty()) return; 314 312 315 rgba* mat = new rgba(); 313 rgba* mat = new rgba(); 316 mat->color = color; 314 mat->color = color; 317 m_sep.add(mat); 315 m_sep.add(mat); 318 316 319 matrix* tsf = new matrix; 317 matrix* tsf = new matrix; 320 m_sep.add(tsf); 318 m_sep.add(tsf); 321 319 322 //sf<float> zfront ? 320 //sf<float> zfront ? 323 float zz = back_visible.value()?0.01f:0; 321 float zz = back_visible.value()?0.01f:0; 324 322 325 if(font==font_hershey()) { 323 if(font==font_hershey()) { 326 324 327 draw_style* ds = new draw_style; 325 draw_style* ds = new draw_style; 328 ds->style = draw_lines; 326 ds->style = draw_lines; 329 ds->line_width = line_width; 327 ds->line_width = line_width; 330 m_sep.add(ds); 328 m_sep.add(ds); 331 329 332 text_hershey* _text = new text_hershey; 330 text_hershey* _text = new text_hershey; 333 m_base_text = _text; 331 m_base_text = _text; 334 _text->encoding = encoding; 332 _text->encoding = encoding; 335 _text->strings = strings; 333 _text->strings = strings; 336 m_sep.add(_text); 334 m_sep.add(_text); 337 335 338 } else { 336 } else { 339 337 340 m_base_text = m_TT_text; 338 m_base_text = m_TT_text; 341 //ttf/arialbd 11 339 //ttf/arialbd 11 342 //01234567890 340 //01234567890 343 m_TT_text->font = font; 341 m_TT_text->font = font; 344 m_TT_text->strings = strings; 342 m_TT_text->strings = strings; 345 m_TT_text->modeling = font_modeling; 343 m_TT_text->modeling = font_modeling; 346 344 347 //_text->modeling.value(font_outline); 345 //_text->modeling.value(font_outline); 348 346 349 m_sep.add(new noderef(*m_TT_text)); 347 m_sep.add(new noderef(*m_TT_text)); 350 348 351 } 349 } 352 350 353 if(enforce_front_height) { 351 if(enforce_front_height) { 354 352 355 m_base_text->height = front_height; 353 m_base_text->height = front_height; 356 354 357 float mn_x,mn_y,mn_z; 355 float mn_x,mn_y,mn_z; 358 float mx_x,mx_y,mx_z; 356 float mx_x,mx_y,mx_z; 359 m_base_text->get_bounds(front_height,mn_ 357 m_base_text->get_bounds(front_height,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 360 358 361 float bxw = mx_x-mn_x; 359 float bxw = mx_x-mn_x; 362 float xtrans = 0; 360 float xtrans = 0; 363 if(hjust==center) { 361 if(hjust==center) { 364 xtrans = 0; 362 xtrans = 0; 365 } else if(hjust==left) { 363 } else if(hjust==left) { 366 xtrans = bxw*0.5f; 364 xtrans = bxw*0.5f; 367 } else if(hjust==right) { 365 } else if(hjust==right) { 368 xtrans = -bxw*0.5f; 366 xtrans = -bxw*0.5f; 369 } 367 } 370 368 371 float bxh = mx_y-mn_y; 369 float bxh = mx_y-mn_y; 372 float ytrans = 0; 370 float ytrans = 0; 373 if(vjust==middle) { 371 if(vjust==middle) { 374 ytrans = 0; 372 ytrans = 0; 375 } else if(vjust==bottom) { 373 } else if(vjust==bottom) { 376 ytrans = bxh*0.5f; 374 ytrans = bxh*0.5f; 377 } else if(vjust==top) { 375 } else if(vjust==top) { 378 ytrans = -bxh*0.5f; 376 ytrans = -bxh*0.5f; 379 } 377 } 380 378 381 float xx = -(mn_x+mx_x)*0.5F+xtrans; 379 float xx = -(mn_x+mx_x)*0.5F+xtrans; 382 float yy = -(mn_y+mx_y)*0.5F+ytrans; 380 float yy = -(mn_y+mx_y)*0.5F+ytrans; 383 tsf->set_translate(xx,yy,zz); 381 tsf->set_translate(xx,yy,zz); 384 return; 382 return; 385 } 383 } 386 384 387 if(enforce_front_width) { 385 if(enforce_front_width) { 388 386 389 float fh = height * hmargin_factor; 387 float fh = height * hmargin_factor; 390 388 391 float th = fh; 389 float th = fh; 392 float mn_x,mn_y,mn_z; 390 float mn_x,mn_y,mn_z; 393 float mx_x,mx_y,mx_z; 391 float mx_x,mx_y,mx_z; 394 m_base_text->get_bounds(th,mn_x,mn_y,mn_ 392 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 395 float bxw = mx_x-mn_x; 393 float bxw = mx_x-mn_x; 396 394 397 // adjust box width : 395 // adjust box width : 398 // th -> bxw then to have front_width: 396 // th -> bxw then to have front_width: 399 if(bxw>0) { 397 if(bxw>0) { 400 th = th*front_width/bxw; 398 th = th*front_width/bxw; 401 m_base_text->get_bounds(th,mn_x,mn_y,m 399 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 402 } 400 } 403 401 404 bxw = mx_x-mn_x; 402 bxw = mx_x-mn_x; 405 float xtrans = 0; 403 float xtrans = 0; 406 if(hjust==center) { 404 if(hjust==center) { 407 xtrans = 0; 405 xtrans = 0; 408 } else if(hjust==left) { 406 } else if(hjust==left) { 409 xtrans = bxw*0.5f; 407 xtrans = bxw*0.5f; 410 } else if(hjust==right) { 408 } else if(hjust==right) { 411 xtrans = -bxw*0.5f; 409 xtrans = -bxw*0.5f; 412 } 410 } 413 411 414 float bxh = mx_y-mn_y; 412 float bxh = mx_y-mn_y; 415 float ytrans = 0; 413 float ytrans = 0; 416 if(vjust==middle) { 414 if(vjust==middle) { 417 ytrans = 0; 415 ytrans = 0; 418 } else if(vjust==bottom) { 416 } else if(vjust==bottom) { 419 ytrans = bxh*0.5f; 417 ytrans = bxh*0.5f; 420 } else if(vjust==top) { 418 } else if(vjust==top) { 421 ytrans = -bxh*0.5f; 419 ytrans = -bxh*0.5f; 422 } 420 } 423 421 424 float xx = -(mn_x+mx_x)*0.5F+xtrans; 422 float xx = -(mn_x+mx_x)*0.5F+xtrans; 425 float yy = -(mn_y+mx_y)*0.5F+ytrans; 423 float yy = -(mn_y+mx_y)*0.5F+ytrans; 426 tsf->set_translate(xx,yy,zz); 424 tsf->set_translate(xx,yy,zz); 427 425 428 m_base_text->height = bxh; //=th? 426 m_base_text->height = bxh; //=th? 429 return; 427 return; 430 } 428 } 431 429 432 //various automatic text height strategies 430 //various automatic text height strategies : 433 float fw = width * wmargin_factor; 431 float fw = width * wmargin_factor; 434 float fh = height * hmargin_factor; 432 float fh = height * hmargin_factor; 435 433 436 if(confine) { 434 if(confine) { 437 // code common to freetype and hershey : 435 // code common to freetype and hershey : 438 436 439 // try to adjust text within fw x fh (by 437 // try to adjust text within fw x fh (by attempting to be smart !). 440 // the below assumes that text bounds ar 438 // the below assumes that text bounds are linear according 441 // "text height". 439 // "text height". 442 {float mn_x,mn_y,mn_z; 440 {float mn_x,mn_y,mn_z; 443 float mx_x,mx_y,mx_z; 441 float mx_x,mx_y,mx_z; 444 442 445 float th = fh; 443 float th = fh; 446 m_base_text->get_bounds(th,mn_x,mn_y,mn_ 444 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 447 float bxh = mx_y-mn_y; 445 float bxh = mx_y-mn_y; 448 // adjust box height : 446 // adjust box height : 449 // fh -> bxh then to have fh : 447 // fh -> bxh then to have fh : 450 if(bxh>0) { 448 if(bxh>0) { 451 th = fh*fh/bxh; 449 th = fh*fh/bxh; 452 m_base_text->get_bounds(th,mn_x,mn_y,m 450 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 453 } 451 } 454 452 455 //float bxw = box.mx()[0]-box.mn()[0]; 453 //float bxw = box.mx()[0]-box.mn()[0]; 456 float bxw = mx_x-mn_x; 454 float bxw = mx_x-mn_x; 457 bxh = mx_y-mn_y; 455 bxh = mx_y-mn_y; 458 if((fh>0)&&(bxh>0)){ 456 if((fh>0)&&(bxh>0)){ 459 float fasp = fw/fh; 457 float fasp = fw/fh; 460 float basp = bxw/bxh; 458 float basp = bxw/bxh; 461 if(fasp>=basp) { 459 if(fasp>=basp) { 462 } else { 460 } else { 463 // adjust box width : 461 // adjust box width : 464 // th -> bxw then to have fw : 462 // th -> bxw then to have fw : 465 if(bxw>0) { 463 if(bxw>0) { 466 th = th*fw/bxw; 464 th = th*fw/bxw; 467 m_base_text->get_bounds(th,mn_x,mn 465 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 468 } 466 } 469 } 467 } 470 } 468 } 471 469 472 m_base_text->height = th; 470 m_base_text->height = th; 473 471 474 //bxw = box.mx()[0]-box.mn()[0]; 472 //bxw = box.mx()[0]-box.mn()[0]; 475 bxw = mx_x-mn_x; 473 bxw = mx_x-mn_x; 476 float xtrans = 0; 474 float xtrans = 0; 477 if(hjust==center) { 475 if(hjust==center) { 478 xtrans = 0; 476 xtrans = 0; 479 } else if(hjust==left) { 477 } else if(hjust==left) { 480 xtrans = -fw*0.5f+bxw*0.5f; 478 xtrans = -fw*0.5f+bxw*0.5f; 481 } else if(hjust==right) { 479 } else if(hjust==right) { 482 xtrans = fw*0.5f-bxw*0.5f; 480 xtrans = fw*0.5f-bxw*0.5f; 483 } 481 } 484 482 485 bxh = mx_y-mn_y; 483 bxh = mx_y-mn_y; 486 float ytrans = 0; 484 float ytrans = 0; 487 if(vjust==middle) { 485 if(vjust==middle) { 488 ytrans = 0; 486 ytrans = 0; 489 } else if(vjust==bottom) { 487 } else if(vjust==bottom) { 490 ytrans = -fh*0.5f+bxh*0.5f; 488 ytrans = -fh*0.5f+bxh*0.5f; 491 } else if(vjust==top) { 489 } else if(vjust==top) { 492 ytrans = fh*0.5f-bxh*0.5f; 490 ytrans = fh*0.5f-bxh*0.5f; 493 } 491 } 494 492 495 float xx = -(mn_x+mx_x)*0.5F+xtrans; 493 float xx = -(mn_x+mx_x)*0.5F+xtrans; 496 float yy = -(mn_y+mx_y)*0.5F+ytrans; 494 float yy = -(mn_y+mx_y)*0.5F+ytrans; 497 495 498 tsf->set_translate(xx,yy,zz); 496 tsf->set_translate(xx,yy,zz); 499 497 500 } 498 } 501 499 502 } else { 500 } else { 503 501 504 // we arrange yy so that two aside texts 502 // we arrange yy so that two aside texts 505 // with same height will have their text 503 // with same height will have their text base lines aligned. 506 // The max height is given by ascent+des 504 // The max height is given by ascent+descent (with descent>0). 507 float th = fh; 505 float th = fh; 508 506 509 float mxh = m_base_text->ascent(th)+ 507 float mxh = m_base_text->ascent(th)+ 510 m_base_text->y_advance(th)*( 508 m_base_text->y_advance(th)*(strings.size()-1)+ 511 m_base_text->descent(th); 509 m_base_text->descent(th); 512 510 513 //{box3f box; 511 //{box3f box; 514 // m_base_text->get_bounds(th,box); 512 // m_base_text->get_bounds(th,box); 515 // float bxh = box.mx()[1]-box.mn()[1]; //s 513 // float bxh = box.mx()[1]-box.mn()[1]; //should be idem mxh. 516 // mxh = bxh;} 514 // mxh = bxh;} 517 515 518 if(mxh) th = fh*fh/mxh; //end/final heig 516 if(mxh) th = fh*fh/mxh; //end/final height. 519 517 520 m_base_text->height = th; //then all cha 518 m_base_text->height = th; //then all chars will fit into th. 521 519 522 mxh = m_base_text->ascent(th)+ 520 mxh = m_base_text->ascent(th)+ 523 m_base_text->y_advance(th)*(string 521 m_base_text->y_advance(th)*(strings.size()-1)+ 524 m_base_text->descent(th); 522 m_base_text->descent(th); 525 523 526 float yy = -fh*0.5f+m_base_text->descent 524 float yy = -fh*0.5f+m_base_text->descent(th)+ 527 m_base_text->y_advance(th)*(s 525 m_base_text->y_advance(th)*(strings.size()-1); 528 526 529 //float xx = -fw*0.5F; //left justified. 527 //float xx = -fw*0.5F; //left justified. 530 //tsf->set_translate(xx,yy,zz); 528 //tsf->set_translate(xx,yy,zz); 531 {float mn_x,mn_y,mn_z; 529 {float mn_x,mn_y,mn_z; 532 float mx_x,mx_y,mx_z; 530 float mx_x,mx_y,mx_z; 533 m_base_text->get_bounds(th,mn_x,mn_y,mn_ 531 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 534 532 535 float bxw = mx_x-mn_x; 533 float bxw = mx_x-mn_x; 536 float xtrans = 0; 534 float xtrans = 0; 537 if(hjust==center) { 535 if(hjust==center) { 538 xtrans = 0; 536 xtrans = 0; 539 } else if(hjust==left) { 537 } else if(hjust==left) { 540 xtrans = -fw*0.5f+bxw*0.5f; 538 xtrans = -fw*0.5f+bxw*0.5f; 541 } else if(hjust==right) { 539 } else if(hjust==right) { 542 xtrans = fw*0.5f-bxw*0.5f; 540 xtrans = fw*0.5f-bxw*0.5f; 543 } 541 } 544 /* 542 /* 545 float bxh = mx_y-mn_y; 543 float bxh = mx_y-mn_y; 546 float ytrans = 0; 544 float ytrans = 0; 547 if(vjust==middle) { 545 if(vjust==middle) { 548 ytrans = 0; 546 ytrans = 0; 549 } else if(vjust==bottom) { 547 } else if(vjust==bottom) { 550 ytrans = -fh*0.5f+bxh*0.5f; 548 ytrans = -fh*0.5f+bxh*0.5f; 551 } else if(vjust==top) { 549 } else if(vjust==top) { 552 ytrans = fh*0.5f-bxh*0.5f; 550 ytrans = fh*0.5f-bxh*0.5f; 553 } 551 } 554 */ 552 */ 555 float xx = -(mn_x+mx_x)*0.5F+xtrans; 553 float xx = -(mn_x+mx_x)*0.5F+xtrans; 556 tsf->set_translate(xx,yy,zz);} 554 tsf->set_translate(xx,yy,zz);} 557 555 558 // truncate text at right if out of bord 556 // truncate text at right if out of border : 559 {std::vector<std::string> labcut; 557 {std::vector<std::string> labcut; 560 tools_vforcit(std::string,strings.values 558 tools_vforcit(std::string,strings.values(),it) { 561 std::string scut; 559 std::string scut; 562 m_base_text->truncate(*it,th,fw,scut); 560 m_base_text->truncate(*it,th,fw,scut); 563 labcut.push_back(std::move(scut)); << 561 labcut.push_back(scut); 564 } 562 } 565 m_base_text->strings = labcut;} 563 m_base_text->strings = labcut;} 566 } 564 } 567 } 565 } 568 566 569 void map_back_area_to_text() { 567 void map_back_area_to_text() { 570 if(!m_base_text) return; 568 if(!m_base_text) return; 571 569 572 float mn_x,mn_y,mn_z; 570 float mn_x,mn_y,mn_z; 573 float mx_x,mx_y,mx_z; 571 float mx_x,mx_y,mx_z; 574 m_base_text->get_bounds(front_height,mn_x, 572 m_base_text->get_bounds(front_height,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 575 573 576 float bxw = mx_x-mn_x; 574 float bxw = mx_x-mn_x; 577 float bxh = mx_y-mn_y; 575 float bxh = mx_y-mn_y; 578 parent::width = bxw/wmargin_factor; 576 parent::width = bxw/wmargin_factor; 579 parent::height = bxh/hmargin_factor; 577 parent::height = bxh/hmargin_factor; 580 } 578 } 581 579 582 protected: 580 protected: 583 separator m_sep; 581 separator m_sep; 584 base_text* m_base_text; 582 base_text* m_base_text; 585 base_freetype* m_TT_text; //optimize : avoid 583 base_freetype* m_TT_text; //optimize : avoid too much freetype load font. 586 }; 584 }; 587 585 588 }} 586 }} 589 587 590 #endif 588 #endif