diff options
Diffstat (limited to 'src/pure-transform.h')
-rw-r--r-- | src/pure-transform.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/pure-transform.h b/src/pure-transform.h new file mode 100644 index 0000000..b6393d3 --- /dev/null +++ b/src/pure-transform.h @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Class for pure transformations, such as translating, scaling, stretching, skewing, and rotating. Pure means that they + * cannot be combined. This is what makes them different from affine transformations. Pure transformations are being + * used in the selector tool and node tool + * + * Authors: + * Diederik van Lierop <mail@diedenrezi.nl> + * + * Copyright (C) 2015 Diederik van Lierop + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef SEEN_PURE_TRANSFORM_H +#define SEEN_PURE_TRANSFORM_H + +#include <glib.h> // for g_warning +#include "snapper.h" // for SnapConstraint + +class SnapManager; + +namespace Inkscape { + +class PureTransform { + +protected: + virtual SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const = 0; + virtual Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const = 0; + virtual void storeTransform(SnapCandidatePoint const &original_point, SnappedPoint &snapped_point) = 0; + +public: + //PureTransform(); + virtual ~PureTransform() = default;; +// virtual PureTransform * clone () const = 0; // https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor + + // Snap a group of points + SnappedPoint best_snapped_point; + void snap(::SnapManager *sm, std::vector<Inkscape::SnapCandidatePoint> const &points, Geom::Point const &pointer); +}; + +// ************************************************************************************************************** + +class PureTranslate: public PureTransform { + +protected: + Geom::Point _vector; + Geom::Point _vector_snapped; + + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const override; + void storeTransform(SnapCandidatePoint const &original_point, SnappedPoint &snapped_point) override; + +public: +// PureTranslate(); // Default constructor +// PureTranslate(PureTranslate const &); // Copy constructor + ~PureTranslate() override = default;; + PureTranslate(Geom::Point vector = Geom::Point()) : _vector(vector), _vector_snapped(vector) {} + + Geom::Point getTranslationSnapped() {return _vector_snapped;} +// PureTranslate * clone () const {return new PureTranslate(*this);} +}; + + +class PureTranslateConstrained: public PureTranslate { + +protected: + Geom::Dim2 _direction; + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + +public: + ~PureTranslateConstrained() override = default; + PureTranslateConstrained(Geom::Coord displacement, Geom::Dim2 direction): + PureTranslate(), + _direction(direction) + { + _vector[direction] = displacement; + _vector[1-direction] = 0.0; + } + // PureTranslateConstrained * clone () const {return new PureTranslateConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureScale: public PureTransform { + +protected: + Geom::Scale _scale; + Geom::Scale _scale_snapped; + Geom::Point _origin; + bool _uniform; + + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const override; + void storeTransform(SnapCandidatePoint const &original_point, SnappedPoint &snapped_point) override; + +public: +// PureScale(); // Default constructor +// PureScale(PureScale const &); // Copy constructor + ~PureScale() override = default; + + PureScale(Geom::Scale scale, Geom::Point origin, bool uniform) : + _scale (scale), + _scale_snapped (scale), + _origin (origin), + _uniform (uniform) + {} + + Geom::Scale getScaleSnapped() {return _scale_snapped;} +// PureScale * clone () const {return new PureScale (*this);} +}; + +class PureScaleConstrained: public PureScale { +//Magnitude of the scale components will be the same, but the sign could still be different () +protected: + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + +public: + ~PureScaleConstrained() override = default; + PureScaleConstrained(Geom::Scale scale, Geom::Point origin): + PureScale(scale, origin, true) {}; // Non-uniform constrained scaling is not supported + +// PureScaleConstrained * clone () const {return new PureScaleConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureStretchConstrained: public PureTransform { +// A stretch is always implicitly constrained + +protected: + Geom::Coord _magnitude; + Geom::Scale _stretch_snapped; + Geom::Point _origin; + Geom::Dim2 _direction; + bool _uniform; + + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const override; + void storeTransform(SnapCandidatePoint const &original_point, SnappedPoint &snapped_point) override; + +public: + ~PureStretchConstrained() override = default;; + PureStretchConstrained(Geom::Coord magnitude, Geom::Point origin, Geom::Dim2 direction, bool uniform) : + _magnitude (magnitude), + _stretch_snapped (Geom::Scale(magnitude, magnitude)), + _origin (origin), + _direction (direction), + _uniform (uniform) + { + if (not uniform) { + _stretch_snapped[1-direction] = 1.0; + } + } + + Geom::Scale getStretchSnapped() {return _stretch_snapped;} + Geom::Coord getMagnitude() {return _magnitude;} + Geom::Coord getMagnitudeSnapped() {return _stretch_snapped[_direction];} + +// PureStretchConstrained * clone () const {return new PureStretchConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureSkewConstrained: public PureTransform { +// A skew is always implicitly constrained + +protected: + Geom::Coord _skew; + Geom::Coord _skew_snapped; + Geom::Coord _scale; + Geom::Point _origin; + Geom::Dim2 _direction; + + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const override; + void storeTransform(SnapCandidatePoint const &original_point, SnappedPoint &snapped_point) override; + +public: + ~PureSkewConstrained() override = default;; + PureSkewConstrained(Geom::Coord skew, Geom::Coord scale, Geom::Point origin, Geom::Dim2 direction) : + _skew (skew), + _skew_snapped (skew), + _scale (scale), + _origin (origin), + _direction (direction) + {}; + + Geom::Coord getSkewSnapped() {return _skew_snapped;} + +// PureSkewConstrained * clone () const {return new PureSkewConstrained(*this);} +}; + +// ************************************************************************************************************** + +class PureRotateConstrained: public PureTransform { +// A rotation is always implicitly constrained, so we will hide the constructor by making it protected; devs should use PureRotateConstrained instead +// It's _constraint member variable though will be empty + +protected: + double _angle; // in radians + double _angle_snapped; + Geom::Point _origin; + bool _uniform; + + SnappedPoint snap(::SnapManager *sm, SnapCandidatePoint const &p, Geom::Point pt_orig, Geom::OptRect const &bbox_to_snap) const override; + Geom::Point getTransformedPoint(SnapCandidatePoint const &p) const override; + void storeTransform(SnapCandidatePoint const &original_point, SnappedPoint &snapped_point) override; + +public: +// PureRotate(); // Default constructor +// PureRotate(PureRotate const &); // Copy constructor + ~PureRotateConstrained() override = default;; + + PureRotateConstrained(double angle, Geom::Point origin) : + _angle (angle), // in radians! + _angle_snapped (angle), + _origin (origin), + _uniform (true) // We do not yet allow for simultaneous rotation and scaling + {} + + double getAngleSnapped() {return _angle_snapped;} + +// PureRotate * clone () const {return new PureRotate(*this);} +}; + +} + +#endif // !SEEN_PURE_TRANSFORM_H + |