diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/desktop.cpp | 42 | ||||
| -rw-r--r-- | src/desktop.h | 28 | ||||
| -rw-r--r-- | src/display/canvas-grid.cpp | 15 | ||||
| -rw-r--r-- | src/display/sodipodi-ctrlrect.cpp | 3 | ||||
| -rw-r--r-- | src/verbs.cpp | 38 | ||||
| -rw-r--r-- | src/verbs.h | 5 |
6 files changed, 124 insertions, 7 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp index c2fdee959..730a542e2 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1129,6 +1129,48 @@ SPDesktop::rotate_relative_center_point (Geom::Point const &c, double rotate) /** + * Flip keeping the point 'c' fixed in the desktop window. + */ +void +SPDesktop::flip_absolute_keep_point (Geom::Point const &c, CanvasFlip flip) +{ + Geom::Point w = d2w( c ); // Must be before flip. + _current_affine.setFlip( flip ); + set_display_area( c, w ); +} + + +void +SPDesktop::flip_relative_keep_point (Geom::Point const &c, CanvasFlip flip) +{ + Geom::Point w = d2w( c ); // Must be before flip. + _current_affine.addFlip( flip ); + set_display_area( c, w ); +} + + +/** + * Flip aligning the point 'c' to the center of desktop window. + */ +void +SPDesktop::flip_absolute_center_point (Geom::Point const &c, CanvasFlip flip) +{ + _current_affine.setFlip( flip ); + Geom::Rect viewbox = canvas->getViewbox(); + set_display_area( c, viewbox.midpoint() ); +} + + +void +SPDesktop::flip_relative_center_point (Geom::Point const &c, CanvasFlip flip) +{ + _current_affine.addFlip( flip ); + Geom::Rect viewbox = canvas->getViewbox(); + set_display_area( c, viewbox.midpoint() ); +} + + +/** * Scroll canvas by to a particular point (window coordinates). */ void diff --git a/src/desktop.h b/src/desktop.h index 633e66046..757ca8cb0 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -351,6 +351,16 @@ public: void rotate_absolute_center_point (Geom::Point const &c, double const rotate); void rotate_relative_center_point (Geom::Point const &c, double const rotate); + enum CanvasFlip { + FLIP_NONE = 0, + FLIP_HORIZONTAL = 1, + FLIP_VERTICAL = 2 + }; + void flip_absolute_keep_point (Geom::Point const &c, CanvasFlip flip); + void flip_relative_keep_point (Geom::Point const &c, CanvasFlip flip); + void flip_absolute_center_point (Geom::Point const &c, CanvasFlip flip); + void flip_relative_center_point (Geom::Point const &c, CanvasFlip flip); + double current_rotation() const { return _current_affine.getRotation(); } void scroll_absolute (Geom::Point const &point, bool is_scrolling = false); @@ -476,6 +486,21 @@ private: _update(); } + void setFlip( CanvasFlip flip ) { + _flip = Geom::Scale(); + addFlip( flip ); + } + + void addFlip( CanvasFlip flip ) { + if (flip & FLIP_HORIZONTAL) { + _flip *= Geom::Scale(-1.0, 1.0); + } + if (flip & FLIP_VERTICAL) { + _flip *= Geom::Scale(1.0, -1.0); + } + _update(); + } + double getZoom() const { return _d2w.descrim(); } @@ -496,13 +521,14 @@ private: private: void _update() { - _d2w = _rotate * _scale; + _d2w = _rotate * _scale * _flip; _w2d = _d2w.inverse(); } Geom::Affine _w2d; // Window to desktop Geom::Affine _d2w; // Desktop to window Geom::Rotate _rotate; // Rotate part of _w2d Geom::Scale _scale; // Scale part of _w2d + Geom::Scale _flip; // Flip part of _w2d Geom::Point _offset; // Point on canvas to align to (0,0) of window }; diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index c8951525f..4243d3365 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -853,7 +853,7 @@ CanvasXYGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/) scaling_factor = 5; scaled[dim] = false; - while (sw[dim].length() < 8.0) { + while (fabs(sw[dim].length()) < 8.0) { scaled[dim] = true; sw[dim] *= scaling_factor; /* First pass, go up to the major line spacing, then @@ -927,8 +927,8 @@ CanvasXYGrid::Render (SPCanvasBuf *buf) Geom::Line axis = Geom::Line::from_origin_and_vector( ow, sw[dim] ); Geom::Line orth = Geom::Line::from_origin_and_vector( ow, sw[(dim+1)%2] ); - double spacing = fabs( sw[(dim+1)%2].length()); // Spacing between grid lines. - double dash = fabs( sw[dim].length()); // Total length of dash pattern. + double spacing = sw[(dim+1)%2].length(); // Spacing between grid lines. + double dash = sw[dim].length(); // Total length of dash pattern. // std::cout << " axis: " << axis.origin() << ", " << axis.vector() << std::endl; // std::cout << " spacing: " << spacing << std::endl; @@ -941,9 +941,12 @@ CanvasXYGrid::Render (SPCanvasBuf *buf) // We need signed distance... lib2geom offers only positive distance. double distance = signed_distance( buf->rect.corner(c), axis ); - if (dim == 1 ) { // YFLIP? + + // Correct it for coordinate flips (inverts handedness). + if (Geom::cross( axis.vector(), orth.vector() ) > 0 ) { distance = -distance; } + if (distance < min) min = distance; if (distance > max) @@ -996,7 +999,9 @@ CanvasXYGrid::Render (SPCanvasBuf *buf) // Dash pattern must use spacing from orthogonal direction. // Offset is to center dash on orthogonal lines. double offset = fmod( signed_distance( x[0], orth ), sw[dim].length()); - if (dim == 1) offset = -offset; + if (Geom::cross( axis.vector(), orth.vector() ) > 0 ) { + offset = -offset; + } double dashes[2]; if (!scaled[dim] && (j % empspacing) != 0) { diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp index b27a81ab3..075e04e6d 100644 --- a/src/display/sodipodi-ctrlrect.cpp +++ b/src/display/sodipodi-ctrlrect.cpp @@ -124,7 +124,8 @@ void CtrlRect::render(SPCanvasBuf *buf) if (_shadow_width > 0 && !_dashed) { // Offset by half stroke width (_shadow_width is in window coordinates). - Geom::Point shadow( _shadow_width/2.0, _shadow_width/2.0 ); + // Need to handle change in handedness with flips. + Geom::Point shadow( _shadow_width/2.0, (_affine.det()>0?-1:1)*_shadow_width/2.0 ); shadow *= Geom::Rotate( rotation ); if (axis_aligned) { diff --git a/src/verbs.cpp b/src/verbs.cpp index 78967e89b..b7b6da340 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1996,6 +1996,40 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_ROTATE_ZERO: dt->rotate_absolute_center_point( midpoint, 0.0 ); break; + case SP_VERB_FLIP_HORIZONTAL: + { + // While drawing with the pen/pencil tool, flip towards the end of the unfinished path + if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) { + SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve; + if (!rc->is_empty()) { + Geom::Point const flip_to (*rc->last_point()); + dt->flip_relative_keep_point(flip_to, SPDesktop::FLIP_HORIZONTAL); + break; + } + } + + dt->flip_relative_center_point( midpoint, SPDesktop::FLIP_HORIZONTAL); + break; + } + case SP_VERB_FLIP_VERTICAL: + { + gint mul = 1 + Inkscape::UI::Tools::gobble_key_events( GDK_KEY_parenright, 0); + // While drawing with the pen/pencil tool, flip towards the end of the unfinished path + if (tools_isactive(dt, TOOLS_FREEHAND_PENCIL) || tools_isactive(dt, TOOLS_FREEHAND_PEN)) { + SPCurve *rc = SP_DRAW_CONTEXT(ec)->red_curve; + if (!rc->is_empty()) { + Geom::Point const flip_to (*rc->last_point()); + dt->flip_relative_keep_point(flip_to, SPDesktop::FLIP_VERTICAL); + break; + } + } + + dt->flip_relative_center_point( midpoint, SPDesktop::FLIP_VERTICAL); + break; + } + case SP_VERB_FLIP_NONE: + dt->flip_absolute_center_point( midpoint, SPDesktop::FLIP_NONE); + break; case SP_VERB_TOGGLE_RULERS: dt->toggleRulers(); break; @@ -2961,6 +2995,10 @@ Verb *Verb::_base_verbs[] = { new ZoomVerb(SP_VERB_ROTATE_CCW, "RotateCounterClockwise", N_("Rotate Counter-Clockwise"), N_("Rotate canvas counter-clockwise"), NULL), new ZoomVerb(SP_VERB_ROTATE_ZERO, "RotateZero", N_("Rotate Zero"), N_("Reset canvas rotation to zero"), NULL), + new ZoomVerb(SP_VERB_FLIP_HORIZONTAL, "FlipHorizontal", N_("Flip Horizontal"), N_("Flip canvas horizontally"), INKSCAPE_ICON("object-flip-horizontal")), + new ZoomVerb(SP_VERB_FLIP_VERTICAL, "FlipVertical", N_("Flip Vertical"), N_("Flip canvas vertically"), INKSCAPE_ICON("object-flip-vertical")), + new ZoomVerb(SP_VERB_FLIP_NONE, "FlipNone", N_("Flip None"), N_("Undo any flip"), NULL), + // WHY ARE THE FOLLOWING ZoomVerbs??? diff --git a/src/verbs.h b/src/verbs.h index d57988583..6846f1f40 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -271,6 +271,11 @@ enum { SP_VERB_ROTATE_CCW, SP_VERB_ROTATE_ZERO, + /* Canvas Flip */ + SP_VERB_FLIP_HORIZONTAL, + SP_VERB_FLIP_VERTICAL, + SP_VERB_FLIP_NONE, + /* Desktop settings */ SP_VERB_TOGGLE_RULERS, SP_VERB_TOGGLE_SCROLLBARS, |
