xref: /haiku/src/libs/icon/transformer/PerspectiveTransformer.h (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
1 /*
2  * Copyright 2006-2007, 2023, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  *		Zardshard
8  */
9 #ifndef PERSPECTIVE_TRANSFORMER_H
10 #define PERSPECTIVE_TRANSFORMER_H
11 
12 
13 #include <Rect.h>
14 #include <Point.h>
15 
16 #include <agg_conv_transform.h>
17 #include <agg_trans_perspective.h>
18 
19 #include "IconBuild.h"
20 #include "Transformer.h"
21 #ifdef ICON_O_MATIC
22 #include "Observer.h"
23 #endif
24 #include "PathTransformer.h"
25 #include "StyleTransformer.h"
26 #include "VertexSource.h"
27 
28 
29 _BEGIN_ICON_NAMESPACE
30 
31 class Shape;
32 
33 
34 typedef agg::conv_transform<VertexSource, agg::trans_perspective> Perspective;
35 
36 /*! Transforms from the VertexSource's bounding rect to the specified
37 	quadrilateral. This class watches out for invalid transformations if
38 	\c ICON_O_MATIC is set.
39 */
40 class PerspectiveTransformer : public Transformer,
41 							   public PathTransformer,
42 							   public StyleTransformer,
43 #ifdef ICON_O_MATIC
44 							   public Observer,
45 #endif
46 							   public Perspective,
47 							   public agg::trans_perspective {
48 public:
49 	enum {
50 		archive_code	= 'prsp',
51 	};
52 
53 	/*! Initializes starting with the identity transformation.
54 		A valid perspective transformation can be rendered invalid if the shape
55 		changes. Listens to \a shape for updates and determines if the
56 		transformation is still valid if \c ICON_O_MATIC is set.
57 	*/
58 								PerspectiveTransformer(
59 									VertexSource& source,
60 									Shape* shape);
61 								PerspectiveTransformer(
62 									VertexSource& source,
63 									Shape* shape,
64 									BMessage* archive);
65 								PerspectiveTransformer(
66 									const PerspectiveTransformer& other);
67 
68 	virtual						~PerspectiveTransformer();
69 
70 	// Transformer interface
71 	virtual	Transformer*		Clone() const;
72 
73 	// PathTransformer interface
74 	virtual	void				rewind(unsigned path_id);
75 	virtual	unsigned			vertex(double* x, double* y);
76 
77 	virtual	void				SetSource(VertexSource& source);
78 
79 	virtual	double				ApproximationScale() const;
80 
81 	// StyleTransformer interface
82 	virtual void				transform(double* x, double* y) const
83 #ifdef ICON_O_MATIC
84 									{ if (fValid) agg::trans_perspective::transform(x, y); }
85 #else
86 									{ agg::trans_perspective::transform(x, y); }
87 #endif
88 
89 	/*! Inverts the perspective transformation.
90 		\warning This class can mostly only transform points when inverted. Most
91 			other features either have not been tested or are missing.
92 	*/
93 	virtual	void				Invert();
94 
95 #ifdef ICON_O_MATIC
96 	// IconObject interface
97 	virtual	status_t			Archive(BMessage* into,
98 										bool deep = true) const;
99 
100 	// Observer interface
101 	virtual	void				ObjectChanged(const Observable* object);
102 
103 	// PerspectiveTransformer
104 			void				TransformTo(BPoint leftTop, BPoint rightTop,
105 									BPoint leftBottom, BPoint rightBottom);
106 
107 			BPoint				LeftTop()
108 									{ return fToLeftTop; }
109 			BPoint				RightTop()
110 									{ return fToRightTop; }
111 			BPoint				LeftBottom()
112 									{ return fToLeftBottom; }
113 			BPoint				RightBottom()
114 									{ return fToRightBottom; }
115 
116 private:
117 			void				_CheckValidity();
118 #endif // ICON_O_MATIC
119 
120 private:
121 			Shape*				fShape;
122 #ifdef ICON_O_MATIC
123 			bool				fInverted;
124 			BRect				fFromBox;
125 			BPoint				fToLeftTop;
126 			BPoint				fToRightTop;
127 			BPoint				fToLeftBottom;
128 			BPoint				fToRightBottom;
129 			bool				fValid;
130 #endif
131 };
132 
133 
134 _END_ICON_NAMESPACE
135 
136 
137 #endif	// PERSPECTIVE_TRANSFORMER_H
138