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 >> 320 float fw = width * wmargin_factor; >> 321 float fh = height * hmargin_factor; >> 322 322 //sf<float> zfront ? 323 //sf<float> zfront ? 323 float zz = back_visible.value()?0.01f:0; 324 float zz = back_visible.value()?0.01f:0; 324 325 325 if(font==font_hershey()) { 326 if(font==font_hershey()) { 326 327 327 draw_style* ds = new draw_style; 328 draw_style* ds = new draw_style; 328 ds->style = draw_lines; 329 ds->style = draw_lines; 329 ds->line_width = line_width; 330 ds->line_width = line_width; 330 m_sep.add(ds); 331 m_sep.add(ds); 331 332 332 text_hershey* _text = new text_hershey; 333 text_hershey* _text = new text_hershey; 333 m_base_text = _text; 334 m_base_text = _text; 334 _text->encoding = encoding; 335 _text->encoding = encoding; 335 _text->strings = strings; 336 _text->strings = strings; 336 m_sep.add(_text); 337 m_sep.add(_text); 337 338 338 } else { 339 } else { 339 340 340 m_base_text = m_TT_text; 341 m_base_text = m_TT_text; 341 //ttf/arialbd 11 342 //ttf/arialbd 11 342 //01234567890 343 //01234567890 343 m_TT_text->font = font; 344 m_TT_text->font = font; 344 m_TT_text->strings = strings; 345 m_TT_text->strings = strings; 345 m_TT_text->modeling = font_modeling; 346 m_TT_text->modeling = font_modeling; 346 347 347 //_text->modeling.value(font_outline); 348 //_text->modeling.value(font_outline); 348 349 349 m_sep.add(new noderef(*m_TT_text)); 350 m_sep.add(new noderef(*m_TT_text)); 350 351 351 } 352 } 352 353 353 if(enforce_front_height) { 354 if(enforce_front_height) { 354 355 355 m_base_text->height = front_height; 356 m_base_text->height = front_height; 356 357 357 float mn_x,mn_y,mn_z; 358 float mn_x,mn_y,mn_z; 358 float mx_x,mx_y,mx_z; 359 float mx_x,mx_y,mx_z; 359 m_base_text->get_bounds(front_height,mn_ 360 m_base_text->get_bounds(front_height,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 360 361 361 float bxw = mx_x-mn_x; 362 float bxw = mx_x-mn_x; 362 float xtrans = 0; 363 float xtrans = 0; 363 if(hjust==center) { 364 if(hjust==center) { 364 xtrans = 0; 365 xtrans = 0; 365 } else if(hjust==left) { 366 } else if(hjust==left) { 366 xtrans = bxw*0.5f; << 367 xtrans = -fw*0.5f+bxw*0.5f; 367 } else if(hjust==right) { 368 } else if(hjust==right) { 368 xtrans = -bxw*0.5f; << 369 xtrans = fw*0.5f-bxw*0.5f; 369 } 370 } 370 371 371 float bxh = mx_y-mn_y; 372 float bxh = mx_y-mn_y; 372 float ytrans = 0; 373 float ytrans = 0; 373 if(vjust==middle) { 374 if(vjust==middle) { 374 ytrans = 0; 375 ytrans = 0; 375 } else if(vjust==bottom) { 376 } else if(vjust==bottom) { 376 ytrans = bxh*0.5f; << 377 ytrans = -fh*0.5f+bxh*0.5f; 377 } else if(vjust==top) { 378 } else if(vjust==top) { 378 ytrans = -bxh*0.5f; << 379 ytrans = fh*0.5f-bxh*0.5f; 379 } 380 } 380 381 381 float xx = -(mn_x+mx_x)*0.5F+xtrans; 382 float xx = -(mn_x+mx_x)*0.5F+xtrans; 382 float yy = -(mn_y+mx_y)*0.5F+ytrans; 383 float yy = -(mn_y+mx_y)*0.5F+ytrans; 383 tsf->set_translate(xx,yy,zz); 384 tsf->set_translate(xx,yy,zz); >> 385 384 return; 386 return; 385 } 387 } 386 388 387 if(enforce_front_width) { 389 if(enforce_front_width) { 388 390 389 float fh = height * hmargin_factor; << 390 << 391 float th = fh; 391 float th = fh; 392 float mn_x,mn_y,mn_z; 392 float mn_x,mn_y,mn_z; 393 float mx_x,mx_y,mx_z; 393 float mx_x,mx_y,mx_z; 394 m_base_text->get_bounds(th,mn_x,mn_y,mn_ 394 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; 395 float bxw = mx_x-mn_x; 396 396 397 // adjust box width : 397 // adjust box width : 398 // th -> bxw then to have front_width: 398 // th -> bxw then to have front_width: 399 if(bxw>0) { 399 if(bxw>0) { 400 th = th*front_width/bxw; 400 th = th*front_width/bxw; 401 m_base_text->get_bounds(th,mn_x,mn_y,m 401 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 402 } 402 } 403 403 404 bxw = mx_x-mn_x; 404 bxw = mx_x-mn_x; 405 float xtrans = 0; 405 float xtrans = 0; 406 if(hjust==center) { 406 if(hjust==center) { 407 xtrans = 0; 407 xtrans = 0; 408 } else if(hjust==left) { 408 } else if(hjust==left) { 409 xtrans = bxw*0.5f; << 409 xtrans = -fw*0.5f+bxw*0.5f; 410 } else if(hjust==right) { 410 } else if(hjust==right) { 411 xtrans = -bxw*0.5f; << 411 xtrans = fw*0.5f-bxw*0.5f; 412 } 412 } 413 413 414 float bxh = mx_y-mn_y; 414 float bxh = mx_y-mn_y; 415 float ytrans = 0; 415 float ytrans = 0; 416 if(vjust==middle) { 416 if(vjust==middle) { 417 ytrans = 0; 417 ytrans = 0; 418 } else if(vjust==bottom) { 418 } else if(vjust==bottom) { 419 ytrans = bxh*0.5f; << 419 ytrans = -fh*0.5f+bxh*0.5f; 420 } else if(vjust==top) { 420 } else if(vjust==top) { 421 ytrans = -bxh*0.5f; << 421 ytrans = fh*0.5f-bxw*0.5f; 422 } 422 } 423 423 424 float xx = -(mn_x+mx_x)*0.5F+xtrans; 424 float xx = -(mn_x+mx_x)*0.5F+xtrans; 425 float yy = -(mn_y+mx_y)*0.5F+ytrans; 425 float yy = -(mn_y+mx_y)*0.5F+ytrans; 426 tsf->set_translate(xx,yy,zz); 426 tsf->set_translate(xx,yy,zz); 427 427 428 m_base_text->height = bxh; //=th? 428 m_base_text->height = bxh; //=th? >> 429 429 return; 430 return; 430 } 431 } 431 432 432 //various automatic text height strategies 433 //various automatic text height strategies : 433 float fw = width * wmargin_factor; << 434 float fh = height * hmargin_factor; << 435 434 436 if(confine) { 435 if(confine) { 437 // code common to freetype and hershey : 436 // code common to freetype and hershey : 438 << 437 439 // try to adjust text within fw x fh (by 438 // try to adjust text within fw x fh (by attempting to be smart !). 440 // the below assumes that text bounds ar 439 // the below assumes that text bounds are linear according 441 // "text height". 440 // "text height". 442 {float mn_x,mn_y,mn_z; 441 {float mn_x,mn_y,mn_z; 443 float mx_x,mx_y,mx_z; 442 float mx_x,mx_y,mx_z; 444 443 445 float th = fh; 444 float th = fh; 446 m_base_text->get_bounds(th,mn_x,mn_y,mn_ 445 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; 446 float bxh = mx_y-mn_y; 448 // adjust box height : 447 // adjust box height : 449 // fh -> bxh then to have fh : 448 // fh -> bxh then to have fh : 450 if(bxh>0) { 449 if(bxh>0) { 451 th = fh*fh/bxh; 450 th = fh*fh/bxh; 452 m_base_text->get_bounds(th,mn_x,mn_y,m 451 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 453 } 452 } 454 453 455 //float bxw = box.mx()[0]-box.mn()[0]; 454 //float bxw = box.mx()[0]-box.mn()[0]; 456 float bxw = mx_x-mn_x; 455 float bxw = mx_x-mn_x; 457 bxh = mx_y-mn_y; 456 bxh = mx_y-mn_y; 458 if((fh>0)&&(bxh>0)){ 457 if((fh>0)&&(bxh>0)){ 459 float fasp = fw/fh; 458 float fasp = fw/fh; 460 float basp = bxw/bxh; 459 float basp = bxw/bxh; 461 if(fasp>=basp) { 460 if(fasp>=basp) { 462 } else { 461 } else { 463 // adjust box width : 462 // adjust box width : 464 // th -> bxw then to have fw : 463 // th -> bxw then to have fw : 465 if(bxw>0) { 464 if(bxw>0) { 466 th = th*fw/bxw; 465 th = th*fw/bxw; 467 m_base_text->get_bounds(th,mn_x,mn 466 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 468 } 467 } 469 } 468 } 470 } 469 } 471 470 472 m_base_text->height = th; 471 m_base_text->height = th; 473 472 474 //bxw = box.mx()[0]-box.mn()[0]; 473 //bxw = box.mx()[0]-box.mn()[0]; 475 bxw = mx_x-mn_x; 474 bxw = mx_x-mn_x; 476 float xtrans = 0; 475 float xtrans = 0; 477 if(hjust==center) { 476 if(hjust==center) { 478 xtrans = 0; 477 xtrans = 0; 479 } else if(hjust==left) { 478 } else if(hjust==left) { 480 xtrans = -fw*0.5f+bxw*0.5f; 479 xtrans = -fw*0.5f+bxw*0.5f; 481 } else if(hjust==right) { 480 } else if(hjust==right) { 482 xtrans = fw*0.5f-bxw*0.5f; 481 xtrans = fw*0.5f-bxw*0.5f; 483 } 482 } 484 483 485 bxh = mx_y-mn_y; 484 bxh = mx_y-mn_y; 486 float ytrans = 0; 485 float ytrans = 0; 487 if(vjust==middle) { 486 if(vjust==middle) { 488 ytrans = 0; 487 ytrans = 0; 489 } else if(vjust==bottom) { 488 } else if(vjust==bottom) { 490 ytrans = -fh*0.5f+bxh*0.5f; 489 ytrans = -fh*0.5f+bxh*0.5f; 491 } else if(vjust==top) { 490 } else if(vjust==top) { 492 ytrans = fh*0.5f-bxh*0.5f; << 491 ytrans = fh*0.5f-bxw*0.5f; 493 } 492 } 494 493 495 float xx = -(mn_x+mx_x)*0.5F+xtrans; 494 float xx = -(mn_x+mx_x)*0.5F+xtrans; 496 float yy = -(mn_y+mx_y)*0.5F+ytrans; 495 float yy = -(mn_y+mx_y)*0.5F+ytrans; 497 496 498 tsf->set_translate(xx,yy,zz); 497 tsf->set_translate(xx,yy,zz); 499 498 500 } 499 } 501 500 502 } else { << 501 } else { 503 502 504 // we arrange yy so that two aside texts 503 // we arrange yy so that two aside texts 505 // with same height will have their text 504 // with same height will have their text base lines aligned. 506 // The max height is given by ascent+des 505 // The max height is given by ascent+descent (with descent>0). 507 float th = fh; 506 float th = fh; 508 507 509 float mxh = m_base_text->ascent(th)+ 508 float mxh = m_base_text->ascent(th)+ 510 m_base_text->y_advance(th)*( 509 m_base_text->y_advance(th)*(strings.size()-1)+ 511 m_base_text->descent(th); 510 m_base_text->descent(th); 512 511 513 //{box3f box; 512 //{box3f box; 514 // m_base_text->get_bounds(th,box); 513 // m_base_text->get_bounds(th,box); 515 // float bxh = box.mx()[1]-box.mn()[1]; //s 514 // float bxh = box.mx()[1]-box.mn()[1]; //should be idem mxh. 516 // mxh = bxh;} 515 // mxh = bxh;} 517 516 518 if(mxh) th = fh*fh/mxh; //end/final heig 517 if(mxh) th = fh*fh/mxh; //end/final height. 519 518 520 m_base_text->height = th; //then all cha 519 m_base_text->height = th; //then all chars will fit into th. 521 520 522 mxh = m_base_text->ascent(th)+ 521 mxh = m_base_text->ascent(th)+ 523 m_base_text->y_advance(th)*(string 522 m_base_text->y_advance(th)*(strings.size()-1)+ 524 m_base_text->descent(th); 523 m_base_text->descent(th); 525 524 526 float yy = -fh*0.5f+m_base_text->descent 525 float yy = -fh*0.5f+m_base_text->descent(th)+ 527 m_base_text->y_advance(th)*(s 526 m_base_text->y_advance(th)*(strings.size()-1); 528 527 529 //float xx = -fw*0.5F; //left justified. 528 //float xx = -fw*0.5F; //left justified. 530 //tsf->set_translate(xx,yy,zz); 529 //tsf->set_translate(xx,yy,zz); 531 {float mn_x,mn_y,mn_z; 530 {float mn_x,mn_y,mn_z; 532 float mx_x,mx_y,mx_z; 531 float mx_x,mx_y,mx_z; 533 m_base_text->get_bounds(th,mn_x,mn_y,mn_ 532 m_base_text->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z); 534 533 535 float bxw = mx_x-mn_x; 534 float bxw = mx_x-mn_x; 536 float xtrans = 0; 535 float xtrans = 0; 537 if(hjust==center) { 536 if(hjust==center) { 538 xtrans = 0; 537 xtrans = 0; 539 } else if(hjust==left) { 538 } else if(hjust==left) { 540 xtrans = -fw*0.5f+bxw*0.5f; 539 xtrans = -fw*0.5f+bxw*0.5f; 541 } else if(hjust==right) { 540 } else if(hjust==right) { 542 xtrans = fw*0.5f-bxw*0.5f; 541 xtrans = fw*0.5f-bxw*0.5f; 543 } 542 } 544 /* 543 /* 545 float bxh = mx_y-mn_y; 544 float bxh = mx_y-mn_y; 546 float ytrans = 0; 545 float ytrans = 0; 547 if(vjust==middle) { 546 if(vjust==middle) { 548 ytrans = 0; 547 ytrans = 0; 549 } else if(vjust==bottom) { 548 } else if(vjust==bottom) { 550 ytrans = -fh*0.5f+bxh*0.5f; 549 ytrans = -fh*0.5f+bxh*0.5f; 551 } else if(vjust==top) { 550 } else if(vjust==top) { 552 ytrans = fh*0.5f-bxh*0.5f; << 551 ytrans = fh*0.5f-bxw*0.5f; 553 } 552 } 554 */ 553 */ 555 float xx = -(mn_x+mx_x)*0.5F+xtrans; 554 float xx = -(mn_x+mx_x)*0.5F+xtrans; 556 tsf->set_translate(xx,yy,zz);} 555 tsf->set_translate(xx,yy,zz);} 557 556 558 // truncate text at right if out of bord 557 // truncate text at right if out of border : 559 {std::vector<std::string> labcut; 558 {std::vector<std::string> labcut; 560 tools_vforcit(std::string,strings.values 559 tools_vforcit(std::string,strings.values(),it) { 561 std::string scut; 560 std::string scut; 562 m_base_text->truncate(*it,th,fw,scut); 561 m_base_text->truncate(*it,th,fw,scut); 563 labcut.push_back(std::move(scut)); << 562 labcut.push_back(scut); 564 } 563 } 565 m_base_text->strings = labcut;} 564 m_base_text->strings = labcut;} 566 } 565 } 567 } << 568 << 569 void map_back_area_to_text() { << 570 if(!m_base_text) return; << 571 << 572 float mn_x,mn_y,mn_z; << 573 float mx_x,mx_y,mx_z; << 574 m_base_text->get_bounds(front_height,mn_x, << 575 << 576 float bxw = mx_x-mn_x; << 577 float bxh = mx_y-mn_y; << 578 parent::width = bxw/wmargin_factor; << 579 parent::height = bxh/hmargin_factor; << 580 } 566 } 581 567 582 protected: 568 protected: 583 separator m_sep; 569 separator m_sep; 584 base_text* m_base_text; 570 base_text* m_base_text; 585 base_freetype* m_TT_text; //optimize : avoid 571 base_freetype* m_TT_text; //optimize : avoid too much freetype load font. 586 }; 572 }; 587 573 588 }} 574 }} 589 575 590 #endif 576 #endif