comparison src/graphics.cc @ 12502:13640f7f40bb

improve calculation of axes tightinset for empty axes labels/title
author Konstantinos Poulios <logari81@googlemail.com>
date Sun, 06 Mar 2011 16:54:39 +0100
parents 245b5efb07c2
children 0dda50ae4997
comparison
equal deleted inserted replaced
12501:5454b687fd14 12502:13640f7f40bb
4232 axes::properties::update_xlabel_position (void) 4232 axes::properties::update_xlabel_position (void)
4233 { 4233 {
4234 text::properties& xlabel_props = reinterpret_cast<text::properties&> 4234 text::properties& xlabel_props = reinterpret_cast<text::properties&>
4235 (gh_manager::get_object (get_xlabel ()).get_properties ()); 4235 (gh_manager::get_object (get_xlabel ()).get_properties ());
4236 4236
4237 if (! xlabel_props.get_string ().empty ()) 4237 bool is_empty = xlabel_props.get_string ().empty ();
4238 { 4238
4239 xlabel_props.set_autopos_tag ("none"); 4239 xlabel_props.set_autopos_tag ("none");
4240 4240
4241 if (! is_empty)
4242 {
4241 if (xlabel_props.horizontalalignmentmode_is ("auto")) 4243 if (xlabel_props.horizontalalignmentmode_is ("auto"))
4242 { 4244 {
4243 xlabel_props.set_horizontalalignment 4245 xlabel_props.set_horizontalalignment
4244 (xstate > AXE_DEPTH_DIR 4246 (xstate > AXE_DEPTH_DIR
4245 ? "center" : (xyzSym ? "left" : "right")); 4247 ? "center" : (xyzSym ? "left" : "right"));
4252 xlabel_props.set_verticalalignment 4254 xlabel_props.set_verticalalignment
4253 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top"); 4255 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top");
4254 4256
4255 xlabel_props.set_verticalalignmentmode ("auto"); 4257 xlabel_props.set_verticalalignmentmode ("auto");
4256 } 4258 }
4257 4259 }
4258 if (xlabel_props.positionmode_is ("auto") 4260
4259 || xlabel_props.rotationmode_is ("auto")) 4261 if (xlabel_props.positionmode_is ("auto")
4260 { 4262 || xlabel_props.rotationmode_is ("auto"))
4261 graphics_xform xform = get_transform (); 4263 {
4262 4264 graphics_xform xform = get_transform ();
4263 Matrix ext (1, 2, 0.0); 4265
4264 ext = get_ticklabel_extents (get_xtick ().matrix_value (), 4266 Matrix ext (1, 2, 0.0);
4265 get_xticklabel ().all_strings (), 4267 ext = get_ticklabel_extents (get_xtick ().matrix_value (),
4266 get_xlim ().matrix_value ()); 4268 get_xticklabel ().all_strings (),
4267 4269 get_xlim ().matrix_value ());
4268 double wmax = ext(0), hmax = ext(1), angle = 0; 4270
4269 ColumnVector p = 4271 double wmax = ext(0), hmax = ext(1), angle = 0;
4270 graphics_xform::xform_vector ((xpTickN+xpTick)/2, ypTick, zpTick); 4272 ColumnVector p =
4271 4273 graphics_xform::xform_vector ((xpTickN+xpTick)/2, ypTick, zpTick);
4272 bool tick_along_z = nearhoriz || xisinf (fy); 4274
4273 if (tick_along_z) 4275 bool tick_along_z = nearhoriz || xisinf (fy);
4274 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset); 4276 if (tick_along_z)
4275 else 4277 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset);
4276 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset); 4278 else
4277 4279 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset);
4278 p = xform.transform (p(0), p(1), p(2), false); 4280
4279 4281 p = xform.transform (p(0), p(1), p(2), false);
4280 switch (xstate) 4282
4281 { 4283 switch (xstate)
4282 case AXE_ANY_DIR: 4284 {
4283 p(0) += (xyzSym ? wmax : -wmax); 4285 case AXE_ANY_DIR:
4284 p(1) += hmax; 4286 p(0) += (xyzSym ? wmax : -wmax);
4285 break; 4287 p(1) += hmax;
4286 4288 break;
4287 case AXE_VERT_DIR: 4289
4288 p(0) -= wmax; 4290 case AXE_VERT_DIR:
4289 angle = 90; 4291 p(0) -= wmax;
4290 break; 4292 angle = 90;
4291 4293 break;
4292 case AXE_HORZ_DIR: 4294
4293 p(1) += (x2Dtop ? -hmax : hmax); 4295 case AXE_HORZ_DIR:
4294 break; 4296 p(1) += (x2Dtop ? -hmax : hmax);
4295 } 4297 break;
4296 4298 }
4297 if (xlabel_props.positionmode_is ("auto")) 4299
4298 { 4300 if (xlabel_props.positionmode_is ("auto"))
4299 p = xform.untransform (p(0), p(1), p(2), true); 4301 {
4300 xlabel_props.set_position (p.extract_n (0, 3).transpose ()); 4302 p = xform.untransform (p(0), p(1), p(2), true);
4301 xlabel_props.set_positionmode ("auto"); 4303 xlabel_props.set_position (p.extract_n (0, 3).transpose ());
4302 } 4304 xlabel_props.set_positionmode ("auto");
4303 4305 }
4304 if (xlabel_props.rotationmode_is ("auto")) 4306
4305 { 4307 if (! is_empty && xlabel_props.rotationmode_is ("auto"))
4306 xlabel_props.set_rotation (angle); 4308 {
4307 xlabel_props.set_rotationmode ("auto"); 4309 xlabel_props.set_rotation (angle);
4308 } 4310 xlabel_props.set_rotationmode ("auto");
4309 } 4311 }
4310 4312 }
4311 xlabel_props.set_autopos_tag ("xlabel"); 4313
4312 } 4314 xlabel_props.set_autopos_tag ("xlabel");
4313 } 4315 }
4314 4316
4315 void 4317 void
4316 axes::properties::update_ylabel_position (void) 4318 axes::properties::update_ylabel_position (void)
4317 { 4319 {
4318 text::properties& ylabel_props = reinterpret_cast<text::properties&> 4320 text::properties& ylabel_props = reinterpret_cast<text::properties&>
4319 (gh_manager::get_object (get_ylabel ()).get_properties ()); 4321 (gh_manager::get_object (get_ylabel ()).get_properties ());
4320 4322
4321 if (! ylabel_props.get_string ().empty ()) 4323 bool is_empty = ylabel_props.get_string ().empty ();
4322 { 4324
4323 ylabel_props.set_autopos_tag ("none"); 4325 ylabel_props.set_autopos_tag ("none");
4324 4326
4327 if (! is_empty)
4328 {
4325 if (ylabel_props.horizontalalignmentmode_is ("auto")) 4329 if (ylabel_props.horizontalalignmentmode_is ("auto"))
4326 { 4330 {
4327 ylabel_props.set_horizontalalignment 4331 ylabel_props.set_horizontalalignment
4328 (ystate > AXE_DEPTH_DIR 4332 (ystate > AXE_DEPTH_DIR
4329 ? "center" : (!xyzSym ? "left" : "right")); 4333 ? "center" : (!xyzSym ? "left" : "right"));
4336 ylabel_props.set_verticalalignment 4340 ylabel_props.set_verticalalignment
4337 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top"); 4341 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top");
4338 4342
4339 ylabel_props.set_verticalalignmentmode ("auto"); 4343 ylabel_props.set_verticalalignmentmode ("auto");
4340 } 4344 }
4341 4345 }
4342 if (ylabel_props.positionmode_is ("auto") 4346
4343 || ylabel_props.rotationmode_is ("auto")) 4347 if (ylabel_props.positionmode_is ("auto")
4344 { 4348 || ylabel_props.rotationmode_is ("auto"))
4345 graphics_xform xform = get_transform (); 4349 {
4346 4350 graphics_xform xform = get_transform ();
4347 Matrix ext (1, 2, 0.0); 4351
4348 ext = get_ticklabel_extents (get_ytick ().matrix_value (), 4352 Matrix ext (1, 2, 0.0);
4349 get_yticklabel ().all_strings (), 4353 ext = get_ticklabel_extents (get_ytick ().matrix_value (),
4350 get_ylim ().matrix_value ()); 4354 get_yticklabel ().all_strings (),
4351 4355 get_ylim ().matrix_value ());
4352 double wmax = ext(0), hmax = ext(1), angle = 0; 4356
4353 ColumnVector p = 4357 double wmax = ext(0), hmax = ext(1), angle = 0;
4354 graphics_xform::xform_vector (xpTick, (ypTickN+ypTick)/2, zpTick); 4358 ColumnVector p =
4355 4359 graphics_xform::xform_vector (xpTick, (ypTickN+ypTick)/2, zpTick);
4356 bool tick_along_z = nearhoriz || xisinf (fx); 4360
4357 if (tick_along_z) 4361 bool tick_along_z = nearhoriz || xisinf (fx);
4358 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset); 4362 if (tick_along_z)
4359 else 4363 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset);
4360 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset); 4364 else
4361 4365 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset);
4362 p = xform.transform (p(0), p(1), p(2), false); 4366
4363 4367 p = xform.transform (p(0), p(1), p(2), false);
4364 switch (ystate) 4368
4365 { 4369 switch (ystate)
4366 case AXE_ANY_DIR: 4370 {
4367 p(0) += (!xyzSym ? wmax : -wmax); 4371 case AXE_ANY_DIR:
4368 p(1) += hmax; 4372 p(0) += (!xyzSym ? wmax : -wmax);
4369 break; 4373 p(1) += hmax;
4370 4374 break;
4371 case AXE_VERT_DIR: 4375
4372 p(0) += (y2Dright ? wmax : -wmax); 4376 case AXE_VERT_DIR:
4373 angle = 90; 4377 p(0) += (y2Dright ? wmax : -wmax);
4374 break; 4378 angle = 90;
4375 4379 break;
4376 case AXE_HORZ_DIR: 4380
4377 p(1) += hmax; 4381 case AXE_HORZ_DIR:
4378 break; 4382 p(1) += hmax;
4379 } 4383 break;
4380 4384 }
4381 if (ylabel_props.positionmode_is ("auto")) 4385
4382 { 4386 if (ylabel_props.positionmode_is ("auto"))
4383 p = xform.untransform (p(0), p(1), p(2), true); 4387 {
4384 ylabel_props.set_position (p.extract_n (0, 3).transpose ()); 4388 p = xform.untransform (p(0), p(1), p(2), true);
4385 ylabel_props.set_positionmode ("auto"); 4389 ylabel_props.set_position (p.extract_n (0, 3).transpose ());
4386 } 4390 ylabel_props.set_positionmode ("auto");
4387 4391 }
4388 if (ylabel_props.rotationmode_is ("auto")) 4392
4389 { 4393 if (! is_empty && ylabel_props.rotationmode_is ("auto"))
4390 ylabel_props.set_rotation (angle); 4394 {
4391 ylabel_props.set_rotationmode ("auto"); 4395 ylabel_props.set_rotation (angle);
4392 } 4396 ylabel_props.set_rotationmode ("auto");
4393 } 4397 }
4394 4398 }
4395 ylabel_props.set_autopos_tag ("ylabel"); 4399
4396 } 4400 ylabel_props.set_autopos_tag ("ylabel");
4397 } 4401 }
4398 4402
4399 void 4403 void
4400 axes::properties::update_zlabel_position (void) 4404 axes::properties::update_zlabel_position (void)
4401 { 4405 {
4402 text::properties& zlabel_props = reinterpret_cast<text::properties&> 4406 text::properties& zlabel_props = reinterpret_cast<text::properties&>
4403 (gh_manager::get_object (get_zlabel ()).get_properties ()); 4407 (gh_manager::get_object (get_zlabel ()).get_properties ());
4404 4408
4405 if (! zlabel_props.get_string ().empty ()) 4409 bool camAuto = cameraupvectormode_is ("auto");
4406 { 4410 bool is_empty = zlabel_props.get_string ().empty ();
4407 zlabel_props.set_autopos_tag ("none"); 4411
4408 4412 zlabel_props.set_autopos_tag ("none");
4409 bool camAuto = cameraupvectormode_is ("auto"); 4413
4410 4414 if (! is_empty)
4415 {
4411 if (zlabel_props.horizontalalignmentmode_is ("auto")) 4416 if (zlabel_props.horizontalalignmentmode_is ("auto"))
4412 { 4417 {
4413 zlabel_props.set_horizontalalignment 4418 zlabel_props.set_horizontalalignment
4414 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right"); 4419 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right");
4415 4420
4422 (zstate == AXE_VERT_DIR 4427 (zstate == AXE_VERT_DIR
4423 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top")); 4428 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top"));
4424 4429
4425 zlabel_props.set_verticalalignmentmode ("auto"); 4430 zlabel_props.set_verticalalignmentmode ("auto");
4426 } 4431 }
4427 4432 }
4428 if (zlabel_props.positionmode_is ("auto") 4433
4429 || zlabel_props.rotationmode_is ("auto")) 4434 if (zlabel_props.positionmode_is ("auto")
4430 { 4435 || zlabel_props.rotationmode_is ("auto"))
4431 graphics_xform xform = get_transform (); 4436 {
4432 4437 graphics_xform xform = get_transform ();
4433 Matrix ext (1, 2, 0.0); 4438
4434 ext = get_ticklabel_extents (get_ztick ().matrix_value (), 4439 Matrix ext (1, 2, 0.0);
4435 get_zticklabel ().all_strings (), 4440 ext = get_ticklabel_extents (get_ztick ().matrix_value (),
4436 get_zlim ().matrix_value ()); 4441 get_zticklabel ().all_strings (),
4437 4442 get_zlim ().matrix_value ());
4438 double wmax = ext(0), hmax = ext(1), angle = 0; 4443
4439 ColumnVector p; 4444 double wmax = ext(0), hmax = ext(1), angle = 0;
4440 4445 ColumnVector p;
4441 if (xySym) 4446
4442 { 4447 if (xySym)
4443 p = graphics_xform::xform_vector (xPlaneN, yPlane, 4448 {
4444 (zpTickN+zpTick)/2); 4449 p = graphics_xform::xform_vector (xPlaneN, yPlane,
4445 if (xisinf (fy)) 4450 (zpTickN+zpTick)/2);
4446 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset); 4451 if (xisinf (fy))
4447 else 4452 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset);
4448 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset);
4449 }
4450 else 4453 else
4451 { 4454 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset);
4452 p = graphics_xform::xform_vector (xPlane, yPlaneN, 4455 }
4453 (zpTickN+zpTick)/2); 4456 else
4454 if (xisinf (fx)) 4457 {
4455 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset); 4458 p = graphics_xform::xform_vector (xPlane, yPlaneN,
4456 else 4459 (zpTickN+zpTick)/2);
4457 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset); 4460 if (xisinf (fx))
4458 } 4461 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset);
4459 4462 else
4460 p = xform.transform (p(0), p(1), p(2), false); 4463 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset);
4461 4464 }
4462 switch (zstate) 4465
4463 { 4466 p = xform.transform (p(0), p(1), p(2), false);
4464 case AXE_ANY_DIR: 4467
4465 if (camAuto) 4468 switch (zstate)
4466 { 4469 {
4467 p(0) -= wmax; 4470 case AXE_ANY_DIR:
4468 angle = 90; 4471 if (camAuto)
4469 } 4472 {
4470
4471 // FIXME -- what's the correct offset?
4472 //
4473 // p[0] += (!xySym ? wmax : -wmax);
4474 // p[1] += (zSign ? hmax : -hmax);
4475
4476 break;
4477
4478 case AXE_VERT_DIR:
4479 p(0) -= wmax; 4473 p(0) -= wmax;
4480 angle = 90; 4474 angle = 90;
4481 break; 4475 }
4482 4476
4483 case AXE_HORZ_DIR: 4477 // FIXME -- what's the correct offset?
4484 p(1) += hmax; 4478 //
4485 break; 4479 // p[0] += (!xySym ? wmax : -wmax);
4486 } 4480 // p[1] += (zSign ? hmax : -hmax);
4487 4481
4488 if (zlabel_props.positionmode_is ("auto")) 4482 break;
4489 { 4483
4490 p = xform.untransform (p(0), p(1), p(2), true); 4484 case AXE_VERT_DIR:
4491 zlabel_props.set_position (p.extract_n (0, 3).transpose ()); 4485 p(0) -= wmax;
4492 zlabel_props.set_positionmode ("auto"); 4486 angle = 90;
4493 } 4487 break;
4494 4488
4495 if (zlabel_props.rotationmode_is ("auto")) 4489 case AXE_HORZ_DIR:
4496 { 4490 p(1) += hmax;
4497 zlabel_props.set_rotation (angle); 4491 break;
4498 zlabel_props.set_rotationmode ("auto"); 4492 }
4499 } 4493
4500 } 4494 if (zlabel_props.positionmode_is ("auto"))
4501 4495 {
4502 zlabel_props.set_autopos_tag ("zlabel"); 4496 p = xform.untransform (p(0), p(1), p(2), true);
4503 } 4497 zlabel_props.set_position (p.extract_n (0, 3).transpose ());
4498 zlabel_props.set_positionmode ("auto");
4499 }
4500
4501 if (! is_empty && zlabel_props.rotationmode_is ("auto"))
4502 {
4503 zlabel_props.set_rotation (angle);
4504 zlabel_props.set_rotationmode ("auto");
4505 }
4506 }
4507
4508 zlabel_props.set_autopos_tag ("zlabel");
4504 } 4509 }
4505 4510
4506 void 4511 void
4507 axes::properties::update_title_position (void) 4512 axes::properties::update_title_position (void)
4508 { 4513 {
4509 text::properties& title_props = reinterpret_cast<text::properties&> 4514 text::properties& title_props = reinterpret_cast<text::properties&>
4510 (gh_manager::get_object (get_title ()).get_properties ()); 4515 (gh_manager::get_object (get_title ()).get_properties ());
4511 4516
4512 if (! title_props.get_string ().empty ()) 4517 title_props.set_autopos_tag ("none");
4513 { 4518
4514 title_props.set_autopos_tag ("none"); 4519 if (title_props.positionmode_is ("auto"))
4515 4520 {
4516 if (title_props.positionmode_is ("auto")) 4521 graphics_xform xform = get_transform ();
4517 { 4522
4518 graphics_xform xform = get_transform (); 4523 // FIXME: bbox should be stored in axes::properties
4519 4524 Matrix bbox = get_extent (false);
4520 // FIXME: bbox should be stored in axes::properties 4525 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10),
4521 Matrix bbox = get_extent (false); 4526 (x_zlim(0)+x_zlim(1))/2, true);
4522 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10), 4527
4523 (x_zlim(0)+x_zlim(1))/2, true); 4528 title_props.set_position (p.extract_n(0, 3).transpose ());
4524 4529 title_props.set_positionmode ("auto");
4525 title_props.set_position (p.extract_n(0, 3).transpose ()); 4530 }
4526 title_props.set_positionmode ("auto"); 4531
4527 } 4532 title_props.set_autopos_tag ("title");
4528
4529 title_props.set_autopos_tag ("title");
4530 }
4531 } 4533 }
4532 4534
4533 void 4535 void
4534 axes::properties::update_autopos (const std::string& elem_type) 4536 axes::properties::update_autopos (const std::string& elem_type)
4535 { 4537 {
4755 text_handle = get_zlabel (); 4757 text_handle = get_zlabel ();
4756 4758
4757 text::properties& text_props = reinterpret_cast<text::properties&> 4759 text::properties& text_props = reinterpret_cast<text::properties&>
4758 (gh_manager::get_object (text_handle).get_properties ()); 4760 (gh_manager::get_object (text_handle).get_properties ());
4759 4761
4760 if (! text_props.get_string ().empty ()) 4762 Matrix text_pos = text_props.get_position ().matrix_value ();
4763 text_pos = xform.transform (text_pos(0), text_pos(1), text_pos(2));
4764 if (text_props.get_string ().empty ())
4765 {
4766 ext(0) = std::min (ext(0), text_pos(0));
4767 ext(1) = std::min (ext(1), text_pos(1));
4768 ext(2) = std::max (ext(2), text_pos(0));
4769 ext(3) = std::max (ext(3), text_pos(1));
4770 }
4771 else
4761 { 4772 {
4762 Matrix text_ext = text_props.get_extent_matrix (); 4773 Matrix text_ext = text_props.get_extent_matrix ();
4763 Matrix text_pos = text_props.get_position ().matrix_value ();
4764 text_pos = xform.transform (text_pos(0), text_pos(1), text_pos(2));
4765 4774
4766 bool ignore_horizontal = false; 4775 bool ignore_horizontal = false;
4767 bool ignore_vertical = false; 4776 bool ignore_vertical = false;
4768 if (only_text_height) 4777 if (only_text_height)
4769 { 4778 {