Mercurial > hg > octave-lyh
comparison src/graphics.cc @ 12334:63dc132a1000
Move axes labels and title positioning to axes::properties
author | Konstantinos Poulios <logari81@gmail.com> |
---|---|
date | Thu, 03 Feb 2011 19:30:13 +0100 |
parents | 2ad37783bf01 |
children | f6763ab98609 |
comparison
equal
deleted
inserted
replaced
12333:f103b9c1ca05 | 12334:63dc132a1000 |
---|---|
3299 xset (xlabel.handle_value (), "rotationmode", "auto"); | 3299 xset (xlabel.handle_value (), "rotationmode", "auto"); |
3300 xset (xlabel.handle_value (), "horizontalalignmentmode", "auto"); | 3300 xset (xlabel.handle_value (), "horizontalalignmentmode", "auto"); |
3301 xset (xlabel.handle_value (), "verticalalignmentmode", "auto"); | 3301 xset (xlabel.handle_value (), "verticalalignmentmode", "auto"); |
3302 xset (xlabel.handle_value (), "clipping", "off"); | 3302 xset (xlabel.handle_value (), "clipping", "off"); |
3303 xset (xlabel.handle_value (), "color", get_xcolor ()); | 3303 xset (xlabel.handle_value (), "color", get_xcolor ()); |
3304 update_xlabel_position (); | |
3304 } | 3305 } |
3305 | 3306 |
3306 void | 3307 void |
3307 axes::properties::set_ylabel (const octave_value& v) | 3308 axes::properties::set_ylabel (const octave_value& v) |
3308 { | 3309 { |
3311 xset (ylabel.handle_value (), "rotationmode", "auto"); | 3312 xset (ylabel.handle_value (), "rotationmode", "auto"); |
3312 xset (ylabel.handle_value (), "horizontalalignmentmode", "auto"); | 3313 xset (ylabel.handle_value (), "horizontalalignmentmode", "auto"); |
3313 xset (ylabel.handle_value (), "verticalalignmentmode", "auto"); | 3314 xset (ylabel.handle_value (), "verticalalignmentmode", "auto"); |
3314 xset (ylabel.handle_value (), "clipping", "off"); | 3315 xset (ylabel.handle_value (), "clipping", "off"); |
3315 xset (ylabel.handle_value (), "color", get_ycolor ()); | 3316 xset (ylabel.handle_value (), "color", get_ycolor ()); |
3317 update_ylabel_position (); | |
3316 } | 3318 } |
3317 | 3319 |
3318 void | 3320 void |
3319 axes::properties::set_zlabel (const octave_value& v) | 3321 axes::properties::set_zlabel (const octave_value& v) |
3320 { | 3322 { |
3323 xset (zlabel.handle_value (), "rotationmode", "auto"); | 3325 xset (zlabel.handle_value (), "rotationmode", "auto"); |
3324 xset (zlabel.handle_value (), "horizontalalignmentmode", "auto"); | 3326 xset (zlabel.handle_value (), "horizontalalignmentmode", "auto"); |
3325 xset (zlabel.handle_value (), "verticalalignmentmode", "auto"); | 3327 xset (zlabel.handle_value (), "verticalalignmentmode", "auto"); |
3326 xset (zlabel.handle_value (), "clipping", "off"); | 3328 xset (zlabel.handle_value (), "clipping", "off"); |
3327 xset (zlabel.handle_value (), "color", get_zcolor ()); | 3329 xset (zlabel.handle_value (), "color", get_zcolor ()); |
3330 update_zlabel_position (); | |
3328 } | 3331 } |
3329 | 3332 |
3330 void | 3333 void |
3331 axes::properties::set_title (const octave_value& v) | 3334 axes::properties::set_title (const octave_value& v) |
3332 { | 3335 { |
3335 xset (title.handle_value (), "horizontalalignment", "center"); | 3338 xset (title.handle_value (), "horizontalalignment", "center"); |
3336 xset (title.handle_value (), "horizontalalignmentmode", "auto"); | 3339 xset (title.handle_value (), "horizontalalignmentmode", "auto"); |
3337 xset (title.handle_value (), "verticalalignment", "bottom"); | 3340 xset (title.handle_value (), "verticalalignment", "bottom"); |
3338 xset (title.handle_value (), "verticalalignmentmode", "auto"); | 3341 xset (title.handle_value (), "verticalalignmentmode", "auto"); |
3339 xset (title.handle_value (), "clipping", "off"); | 3342 xset (title.handle_value (), "clipping", "off"); |
3343 update_title_position (); | |
3340 } | 3344 } |
3341 | 3345 |
3342 void | 3346 void |
3343 axes::properties::set_defaults (base_graphics_object& obj, | 3347 axes::properties::set_defaults (base_graphics_object& obj, |
3344 const std::string& mode) | 3348 const std::string& mode) |
4061 zticklen = ticksign*7; | 4065 zticklen = ticksign*7; |
4062 | 4066 |
4063 xtickoffset = (mode2d ? std::max (0., xticklen) : std::abs (xticklen)) + 5; | 4067 xtickoffset = (mode2d ? std::max (0., xticklen) : std::abs (xticklen)) + 5; |
4064 ytickoffset = (mode2d ? std::max (0., yticklen) : std::abs (yticklen)) + 5; | 4068 ytickoffset = (mode2d ? std::max (0., yticklen) : std::abs (yticklen)) + 5; |
4065 ztickoffset = (mode2d ? std::max (0., zticklen) : std::abs (zticklen)) + 5; | 4069 ztickoffset = (mode2d ? std::max (0., zticklen) : std::abs (zticklen)) + 5; |
4070 | |
4071 update_xlabel_position (); | |
4072 update_ylabel_position (); | |
4073 update_zlabel_position (); | |
4074 update_title_position (); | |
4075 } | |
4076 | |
4077 void | |
4078 axes::properties::update_xlabel_position (void) | |
4079 { | |
4080 graphics_xform xform = get_transform (); | |
4081 | |
4082 text::properties& xlabel_props = reinterpret_cast<text::properties&> | |
4083 (gh_manager::get_object (get_xlabel ()).get_properties ()); | |
4084 | |
4085 if (xlabel_props.horizontalalignmentmode_is ("auto")) | |
4086 { | |
4087 xlabel_props.set_horizontalalignment | |
4088 (xstate > AXE_DEPTH_DIR | |
4089 ? "center" : (xyzSym ? "left" : "right")); | |
4090 | |
4091 xlabel_props.set_horizontalalignmentmode ("auto"); | |
4092 } | |
4093 | |
4094 if (xlabel_props.verticalalignmentmode_is ("auto")) | |
4095 { | |
4096 xlabel_props.set_verticalalignment | |
4097 (xstate == AXE_VERT_DIR || x2Dtop ? "bottom" : "top"); | |
4098 | |
4099 xlabel_props.set_verticalalignmentmode ("auto"); | |
4100 } | |
4101 | |
4102 if (xlabel_props.positionmode_is ("auto") | |
4103 || xlabel_props.rotationmode_is ("auto")) | |
4104 { | |
4105 Matrix ext (1, 2, 0.0); | |
4106 ext = get_ticklabel_extents (get_xtick ().matrix_value (), | |
4107 get_xticklabel ().all_strings (), | |
4108 get_xlim ().matrix_value ()); | |
4109 | |
4110 double wmax = ext(0), hmax = ext(1), angle = 0; | |
4111 ColumnVector p = | |
4112 graphics_xform::xform_vector ((xpTickN+xpTick)/2, ypTick, zpTick); | |
4113 | |
4114 bool tick_along_z = nearhoriz || xisinf (fy); | |
4115 if (tick_along_z) | |
4116 p(2) += (signum(zpTick-zpTickN)*fz*xtickoffset); | |
4117 else | |
4118 p(1) += (signum(ypTick-ypTickN)*fy*xtickoffset); | |
4119 | |
4120 p = xform.transform (p(0), p(1), p(2), false); | |
4121 | |
4122 switch (xstate) | |
4123 { | |
4124 case AXE_ANY_DIR: | |
4125 p(0) += (xyzSym ? wmax : -wmax); | |
4126 p(1) += hmax; | |
4127 break; | |
4128 | |
4129 case AXE_VERT_DIR: | |
4130 p(0) -= wmax; | |
4131 angle = 90; | |
4132 break; | |
4133 | |
4134 case AXE_HORZ_DIR: | |
4135 p(1) += (x2Dtop ? -hmax : hmax); | |
4136 break; | |
4137 } | |
4138 | |
4139 if (xlabel_props.positionmode_is ("auto")) | |
4140 { | |
4141 p = xform.untransform (p(0), p(1), p(2), true); | |
4142 xlabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
4143 xlabel_props.set_positionmode ("auto"); | |
4144 } | |
4145 | |
4146 if (xlabel_props.rotationmode_is ("auto")) | |
4147 { | |
4148 xlabel_props.set_rotation (angle); | |
4149 xlabel_props.set_rotationmode ("auto"); | |
4150 } | |
4151 } | |
4152 } | |
4153 | |
4154 void | |
4155 axes::properties::update_ylabel_position (void) | |
4156 { | |
4157 graphics_xform xform = get_transform (); | |
4158 | |
4159 text::properties& ylabel_props = reinterpret_cast<text::properties&> | |
4160 (gh_manager::get_object (get_ylabel ()).get_properties ()); | |
4161 | |
4162 if (ylabel_props.horizontalalignmentmode_is ("auto")) | |
4163 { | |
4164 ylabel_props.set_horizontalalignment | |
4165 (ystate > AXE_DEPTH_DIR | |
4166 ? "center" : (!xyzSym ? "left" : "right")); | |
4167 | |
4168 ylabel_props.set_horizontalalignmentmode ("auto"); | |
4169 } | |
4170 | |
4171 if (ylabel_props.verticalalignmentmode_is ("auto")) | |
4172 { | |
4173 ylabel_props.set_verticalalignment | |
4174 (ystate == AXE_VERT_DIR && !y2Dright ? "bottom" : "top"); | |
4175 | |
4176 ylabel_props.set_verticalalignmentmode ("auto"); | |
4177 } | |
4178 | |
4179 if (ylabel_props.positionmode_is ("auto") | |
4180 || ylabel_props.rotationmode_is ("auto")) | |
4181 { | |
4182 Matrix ext (1, 2, 0.0); | |
4183 ext = get_ticklabel_extents (get_ytick ().matrix_value (), | |
4184 get_yticklabel ().all_strings (), | |
4185 get_ylim ().matrix_value ()); | |
4186 | |
4187 double wmax = ext(0), hmax = ext(1), angle = 0; | |
4188 ColumnVector p = | |
4189 graphics_xform::xform_vector (xpTick, (ypTickN+ypTick)/2, zpTick); | |
4190 | |
4191 bool tick_along_z = nearhoriz || xisinf (fx); | |
4192 if (tick_along_z) | |
4193 p(2) += (signum(zpTick-zpTickN)*fz*ytickoffset); | |
4194 else | |
4195 p(0) += (signum(xpTick-xpTickN)*fx*ytickoffset); | |
4196 | |
4197 p = xform.transform (p(0), p(1), p(2), false); | |
4198 | |
4199 switch (ystate) | |
4200 { | |
4201 case AXE_ANY_DIR: | |
4202 p(0) += (!xyzSym ? wmax : -wmax); | |
4203 p(1) += hmax; | |
4204 break; | |
4205 | |
4206 case AXE_VERT_DIR: | |
4207 p(0) += (y2Dright ? wmax : -wmax); | |
4208 angle = 90; | |
4209 break; | |
4210 | |
4211 case AXE_HORZ_DIR: | |
4212 p(1) += hmax; | |
4213 break; | |
4214 } | |
4215 | |
4216 if (ylabel_props.positionmode_is ("auto")) | |
4217 { | |
4218 p = xform.untransform (p(0), p(1), p(2), true); | |
4219 ylabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
4220 ylabel_props.set_positionmode ("auto"); | |
4221 } | |
4222 | |
4223 if (ylabel_props.rotationmode_is ("auto")) | |
4224 { | |
4225 ylabel_props.set_rotation (angle); | |
4226 ylabel_props.set_rotationmode ("auto"); | |
4227 } | |
4228 } | |
4229 } | |
4230 | |
4231 void | |
4232 axes::properties::update_zlabel_position (void) | |
4233 { | |
4234 graphics_xform xform = get_transform (); | |
4235 | |
4236 text::properties& zlabel_props = reinterpret_cast<text::properties&> | |
4237 (gh_manager::get_object (get_zlabel ()).get_properties ()); | |
4238 | |
4239 bool camAuto = cameraupvectormode_is ("auto"); | |
4240 | |
4241 if (zlabel_props.horizontalalignmentmode_is ("auto")) | |
4242 { | |
4243 zlabel_props.set_horizontalalignment | |
4244 ((zstate > AXE_DEPTH_DIR || camAuto) ? "center" : "right"); | |
4245 | |
4246 zlabel_props.set_horizontalalignmentmode ("auto"); | |
4247 } | |
4248 | |
4249 if (zlabel_props.verticalalignmentmode_is ("auto")) | |
4250 { | |
4251 zlabel_props.set_verticalalignment | |
4252 (zstate == AXE_VERT_DIR | |
4253 ? "bottom" : ((zSign || camAuto) ? "bottom" : "top")); | |
4254 | |
4255 zlabel_props.set_verticalalignmentmode ("auto"); | |
4256 } | |
4257 | |
4258 if (zlabel_props.positionmode_is ("auto") | |
4259 || zlabel_props.rotationmode_is ("auto")) | |
4260 { | |
4261 Matrix ext (1, 2, 0.0); | |
4262 ext = get_ticklabel_extents (get_ztick ().matrix_value (), | |
4263 get_zticklabel ().all_strings (), | |
4264 get_zlim ().matrix_value ()); | |
4265 | |
4266 double wmax = ext(0), hmax = ext(1), angle = 0; | |
4267 ColumnVector p; | |
4268 | |
4269 if (xySym) | |
4270 { | |
4271 p = graphics_xform::xform_vector (xPlaneN, yPlane, | |
4272 (zpTickN+zpTick)/2); | |
4273 if (xisinf (fy)) | |
4274 p(0) += (signum(xPlaneN-xPlane)*fx*ztickoffset); | |
4275 else | |
4276 p(1) += (signum(yPlane-yPlaneN)*fy*ztickoffset); | |
4277 } | |
4278 else | |
4279 { | |
4280 p = graphics_xform::xform_vector (xPlane, yPlaneN, | |
4281 (zpTickN+zpTick)/2); | |
4282 if (xisinf (fx)) | |
4283 p(1) += (signum(yPlaneN-yPlane)*fy*ztickoffset); | |
4284 else | |
4285 p(0) += (signum(xPlane-xPlaneN)*fx*ztickoffset); | |
4286 } | |
4287 | |
4288 p = xform.transform (p(0), p(1), p(2), false); | |
4289 | |
4290 switch (zstate) | |
4291 { | |
4292 case AXE_ANY_DIR: | |
4293 if (camAuto) | |
4294 { | |
4295 p(0) -= wmax; | |
4296 angle = 90; | |
4297 } | |
4298 | |
4299 // FIXME -- what's the correct offset? | |
4300 // | |
4301 // p[0] += (!xySym ? wmax : -wmax); | |
4302 // p[1] += (zSign ? hmax : -hmax); | |
4303 | |
4304 break; | |
4305 | |
4306 case AXE_VERT_DIR: | |
4307 p(0) -= wmax; | |
4308 angle = 90; | |
4309 break; | |
4310 | |
4311 case AXE_HORZ_DIR: | |
4312 p(1) += hmax; | |
4313 break; | |
4314 } | |
4315 | |
4316 if (zlabel_props.positionmode_is ("auto")) | |
4317 { | |
4318 p = xform.untransform (p(0), p(1), p(2), true); | |
4319 zlabel_props.set_position (p.extract_n (0, 3).transpose ()); | |
4320 zlabel_props.set_positionmode ("auto"); | |
4321 } | |
4322 | |
4323 if (zlabel_props.rotationmode_is ("auto")) | |
4324 { | |
4325 zlabel_props.set_rotation (angle); | |
4326 zlabel_props.set_rotationmode ("auto"); | |
4327 } | |
4328 } | |
4329 } | |
4330 | |
4331 void | |
4332 axes::properties::update_title_position (void) | |
4333 { | |
4334 graphics_xform xform = get_transform (); | |
4335 | |
4336 text::properties& title_props = reinterpret_cast<text::properties&> | |
4337 (gh_manager::get_object (get_title ()).get_properties ()); | |
4338 | |
4339 if (title_props.positionmode_is ("auto")) | |
4340 { | |
4341 // FIXME: bbox should be stored in axes::properties | |
4342 ColumnVector bbox(4); | |
4343 bbox(0) = octave_Inf; | |
4344 bbox(1) = octave_Inf; | |
4345 bbox(2) = -octave_Inf; | |
4346 bbox(3) = -octave_Inf; | |
4347 for (int i = 0; i <= 1; i++) | |
4348 for (int j = 0; j <= 1; j++) | |
4349 for (int k = 0; k <= 1; k++) | |
4350 { | |
4351 ColumnVector p = xform.transform (i ? xPlaneN : xPlane, | |
4352 j ? yPlaneN : yPlane, | |
4353 k ? zPlaneN : zPlane, false); | |
4354 bbox(0) = std::min (bbox(0), p(0)); | |
4355 bbox(1) = std::min (bbox(1), p(1)); | |
4356 bbox(2) = std::max (bbox(2), p(0)); | |
4357 bbox(3) = std::max (bbox(3), p(1)); | |
4358 } | |
4359 | |
4360 bbox(2) = bbox(2)-bbox(0); | |
4361 bbox(3) = bbox(3)-bbox(1); | |
4362 | |
4363 ColumnVector p = xform.untransform (bbox(0)+bbox(2)/2, (bbox(1)-10), | |
4364 (x_zlim(0)+x_zlim(1))/2, true); | |
4365 | |
4366 title_props.set_position (p.extract_n(0, 3).transpose ()); | |
4367 title_props.set_positionmode ("auto"); | |
4368 } | |
4066 } | 4369 } |
4067 | 4370 |
4068 static void | 4371 static void |
4069 normalized_aspectratios (Matrix& aspectratios, const Matrix& scalefactors, | 4372 normalized_aspectratios (Matrix& aspectratios, const Matrix& scalefactors, |
4070 double xlength, double ylength, double zlength) | 4373 double xlength, double ylength, double zlength) |
4633 os << values(i); | 4936 os << values(i); |
4634 c(i) = os.str (); | 4937 c(i) = os.str (); |
4635 } | 4938 } |
4636 | 4939 |
4637 labels = c; | 4940 labels = c; |
4941 } | |
4942 | |
4943 Matrix | |
4944 axes::properties::get_ticklabel_extents (const Matrix& ticks, | |
4945 const string_vector& ticklabels, | |
4946 const Matrix& limits) | |
4947 { | |
4948 #ifdef HAVE_FREETYPE | |
4949 //FIXME: text_renderer could be cached | |
4950 ft_render text_renderer; | |
4951 text_renderer.set_font (get ("fontname").string_value (), | |
4952 get ("fontweight").string_value (), | |
4953 get ("fontangle").string_value (), | |
4954 get ("fontsize").double_value ()); | |
4955 #else | |
4956 double fontsize = get ("fontsize").double_value (); | |
4957 #endif | |
4958 | |
4959 Matrix ext (1, 2, 0.0); | |
4960 double wmax = 0., hmax = 0.; | |
4961 int n = std::min (ticklabels.numel (), ticks.numel ()); | |
4962 for (int i = 0; i < n; i++) | |
4963 { | |
4964 double val = ticks(i); | |
4965 if (limits(0) <= val && val <= limits(1)) | |
4966 { | |
4967 #ifdef HAVE_FREETYPE | |
4968 ext = text_renderer.get_extent (ticklabels(i)); | |
4969 wmax = std::max (wmax, ext(0)); | |
4970 hmax = std::max (hmax, ext(1)); | |
4971 #else | |
4972 //FIXME: find a better approximation | |
4973 int len = ticklabels(i).length(); | |
4974 wmax = std::max (wmax, 0.5*fontsize*len); | |
4975 hmax = fontsize; | |
4976 #endif | |
4977 } | |
4978 } | |
4979 | |
4980 ext(0) = wmax; | |
4981 ext(1) = hmax; | |
4982 return ext; | |
4638 } | 4983 } |
4639 | 4984 |
4640 void | 4985 void |
4641 get_children_limits (double& min_val, double& max_val, double& min_pos, | 4986 get_children_limits (double& min_val, double& max_val, double& min_pos, |
4642 const Matrix& kids, char limit_type) | 4987 const Matrix& kids, char limit_type) |