Mercurial > octave
changeset 25966:d85049849e88
improve plot position updates (bug #48273)
* graphics.cc (axes::properties::update_outerposition,
axes::properties::update_position,
axes::properties::update_looseinset): Move here from graphics.in.h.
Use intermediate variables in an attempt to improve clarity. Impose
limits on position to avoid generating bounding boxes with negative
widths.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 25 Oct 2018 16:08:49 -0400 |
parents | e80a87f65997 |
children | e02f500a0980 |
files | libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h |
diffstat | 2 files changed, 202 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc Wed Oct 24 15:20:43 2018 -0700 +++ b/libinterp/corefcn/graphics.cc Thu Oct 25 16:08:49 2018 -0400 @@ -7185,6 +7185,205 @@ } } +void +axes::properties::update_outerposition (void) +{ + set_activepositionproperty ("outerposition"); + caseless_str old_units = get_units (); + set_units ("normalized"); + + Matrix outerbox = outerposition.get ().matrix_value (); + + double outer_left = outerbox(0); + double outer_bottom = outerbox(1); + double outer_width = outerbox(2); + double outer_height = outerbox(3); + + double outer_right = outer_width + outer_left; + double outer_top = outer_height + outer_bottom; + + Matrix linset = looseinset.get ().matrix_value (); + Matrix tinset = tightinset.get ().matrix_value (); + + double left_margin = std::max (linset(0), tinset(0)); + double bottom_margin = std::max (linset(1), tinset(1)); + double right_margin = std::max (linset(2), tinset(2)); + double top_margin = std::max (linset(3), tinset(3)); + + double inner_left = outer_left; + double inner_right = outer_right; + + if ((left_margin + right_margin) < outer_width) + { + inner_left += left_margin; + inner_right -= right_margin; + } + + double inner_bottom = outer_bottom; + double inner_top = outer_top; + + if ((bottom_margin + top_margin) < outer_height) + { + inner_bottom += bottom_margin; + inner_top -= top_margin; + } + + double inner_width = inner_right - inner_left; + double inner_height = inner_top - inner_bottom; + + Matrix innerbox (1, 4); + + innerbox(0) = inner_left; + innerbox(1) = inner_bottom; + innerbox(2) = inner_width; + innerbox(3) = inner_height; + + position = innerbox; + + set_units (old_units); + update_transform (); +} + +void +axes::properties::update_position (void) +{ + set_activepositionproperty ("position"); + caseless_str old_units = get_units (); + set_units ("normalized"); + + Matrix innerbox = position.get ().matrix_value (); + + double inner_left = innerbox(0); + double inner_bottom = innerbox(1); + double inner_width = innerbox(2); + double inner_height = innerbox(3); + + double inner_right = inner_width + inner_left; + double inner_top = inner_height + inner_bottom; + + Matrix linset = looseinset.get ().matrix_value (); + Matrix tinset = tightinset.get ().matrix_value (); + + double left_margin = std::max (linset(0), tinset(0)); + double bottom_margin = std::max (linset(1), tinset(1)); + double right_margin = std::max (linset(2), tinset(2)); + double top_margin = std::max (linset(3), tinset(3)); + + // FIXME: do we need to place limits on any of these? + + double outer_left = inner_left - left_margin; + double outer_bottom = inner_bottom - bottom_margin; + double outer_right = inner_right + right_margin; + double outer_top = inner_top + top_margin; + + double outer_width = outer_right - outer_left; + double outer_height = outer_top = outer_bottom; + + Matrix outerbox (1, 4); + + outerbox(0) = outer_left; + outerbox(1) = outer_bottom; + outerbox(2) = outer_width; + outerbox(3) = outer_height; + + outerposition = outerbox; + + set_units (old_units); + update_transform (); +} + +void +axes::properties::update_looseinset (void) +{ + caseless_str old_units = get_units (); + set_units ("normalized"); + + Matrix linset = looseinset.get ().matrix_value (); + Matrix tinset = tightinset.get ().matrix_value (); + + double left_margin = std::max (linset(0), tinset(0)); + double bottom_margin = std::max (linset(1), tinset(1)); + double right_margin = std::max (linset(2), tinset(2)); + double top_margin = std::max (linset(3), tinset(3)); + + if (activepositionproperty.is ("position")) + { + Matrix innerbox = position.get ().matrix_value (); + + double inner_left = innerbox(0); + double inner_bottom = innerbox(1); + double inner_width = innerbox(2); + double inner_height = innerbox(3); + + double inner_right = inner_width + inner_left; + double inner_top = inner_height + inner_bottom; + + // FIXME: do we need to place limits on any of these? + + double outer_left = inner_left - left_margin; + double outer_bottom = inner_bottom - bottom_margin; + double outer_right = inner_right + right_margin; + double outer_top = inner_top + top_margin; + + double outer_width = outer_right - outer_left; + double outer_height = outer_top = outer_bottom; + + Matrix outerbox (1, 4); + + outerbox(0) = outer_left; + outerbox(1) = outer_bottom; + outerbox(2) = outer_width; + outerbox(3) = outer_height; + + outerposition = outerbox; + } + else + { + Matrix outerbox = outerposition.get ().matrix_value (); + + double outer_left = outerbox(0); + double outer_bottom = outerbox(1); + double outer_width = outerbox(2); + double outer_height = outerbox(3); + + double outer_right = outer_width + outer_left; + double outer_top = outer_height + outer_bottom; + + double inner_left = outer_left; + double inner_right = outer_right; + + if ((left_margin + right_margin) < outer_width) + { + inner_left += left_margin; + inner_right -= right_margin; + } + + double inner_bottom = outer_bottom; + double inner_top = outer_top; + + if ((bottom_margin + top_margin) < outer_height) + { + inner_bottom += bottom_margin; + inner_top -= top_margin; + } + + double inner_width = inner_right - inner_left; + double inner_height = inner_top - inner_bottom; + + Matrix innerbox (1, 4); + + innerbox(0) = inner_left; + innerbox(1) = inner_bottom; + innerbox(2) = inner_width; + innerbox(3) = inner_height; + + position = innerbox; + } + + set_units (old_units); + update_transform (); +} + // A translation from Tom Holoryd's python code at // http://kurage.nimh.nih.gov/tomh/tics.py // FIXME: add log ticks
--- a/libinterp/corefcn/graphics.in.h Wed Oct 24 15:20:43 2018 -0700 +++ b/libinterp/corefcn/graphics.in.h Thu Oct 25 16:08:49 2018 -0400 @@ -3999,85 +3999,9 @@ sync_positions (); } - void update_outerposition (void) - { - set_activepositionproperty ("outerposition"); - caseless_str old_units = get_units (); - set_units ("normalized"); - Matrix outerbox = outerposition.get ().matrix_value (); - Matrix innerbox = position.get ().matrix_value (); - Matrix linset = looseinset.get ().matrix_value (); - Matrix tinset = tightinset.get ().matrix_value (); - outerbox(2) = outerbox(2) + outerbox(0); - outerbox(3) = outerbox(3) + outerbox(1); - innerbox(0) = outerbox(0) + std::max (linset(0), tinset(0)); - innerbox(1) = outerbox(1) + std::max (linset(1), tinset(1)); - innerbox(2) = outerbox(2) - std::max (linset(2), tinset(2)); - innerbox(3) = outerbox(3) - std::max (linset(3), tinset(3)); - innerbox(2) = innerbox(2) - innerbox(0); - innerbox(3) = innerbox(3) - innerbox(1); - position = innerbox; - set_units (old_units); - update_transform (); - } - - void update_position (void) - { - set_activepositionproperty ("position"); - caseless_str old_units = get_units (); - set_units ("normalized"); - Matrix outerbox = outerposition.get ().matrix_value (); - Matrix innerbox = position.get ().matrix_value (); - Matrix linset = looseinset.get ().matrix_value (); - Matrix tinset = tightinset.get ().matrix_value (); - innerbox(2) = innerbox(2) + innerbox(0); - innerbox(3) = innerbox(3) + innerbox(1); - outerbox(0) = innerbox(0) - std::max (linset(0), tinset(0)); - outerbox(1) = innerbox(1) - std::max (linset(1), tinset(1)); - outerbox(2) = innerbox(2) + std::max (linset(2), tinset(2)); - outerbox(3) = innerbox(3) + std::max (linset(3), tinset(3)); - outerbox(2) = outerbox(2) - outerbox(0); - outerbox(3) = outerbox(3) - outerbox(1); - outerposition = outerbox; - set_units (old_units); - update_transform (); - } - - void update_looseinset (void) - { - caseless_str old_units = get_units (); - set_units ("normalized"); - Matrix innerbox = position.get ().matrix_value (); - innerbox(2) = innerbox(2) + innerbox(0); - innerbox(3) = innerbox(3) + innerbox(1); - Matrix outerbox = outerposition.get ().matrix_value (); - outerbox(2) = outerbox(2) + outerbox(0); - outerbox(3) = outerbox(3) + outerbox(1); - Matrix linset = looseinset.get ().matrix_value (); - Matrix tinset = tightinset.get ().matrix_value (); - if (activepositionproperty.is ("position")) - { - outerbox(0) = innerbox(0) - std::max (linset(0), tinset(0)); - outerbox(1) = innerbox(1) - std::max (linset(1), tinset(1)); - outerbox(2) = innerbox(2) + std::max (linset(2), tinset(2)); - outerbox(3) = innerbox(3) + std::max (linset(3), tinset(3)); - outerbox(2) = outerbox(2) - outerbox(0); - outerbox(3) = outerbox(3) - outerbox(1); - outerposition = outerbox; - } - else - { - innerbox(0) = outerbox(0) + std::max (linset(0), tinset(0)); - innerbox(1) = outerbox(1) + std::max (linset(1), tinset(1)); - innerbox(2) = outerbox(2) - std::max (linset(2), tinset(2)); - innerbox(3) = outerbox(3) - std::max (linset(3), tinset(3)); - innerbox(2) = innerbox(2) - innerbox(0); - innerbox(3) = innerbox(3) - innerbox(1); - position = innerbox; - } - set_units (old_units); - update_transform (); - } + void update_outerposition (void); + void update_position (void); + void update_looseinset (void); double calc_tick_sep (double minval, double maxval); void calc_ticks_and_lims (array_property& lims, array_property& ticks,