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
31class Shape;
32
33
34typedef 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*/
40class 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 {
48public:
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
116private:
117			void				_CheckValidity();
118#endif // ICON_O_MATIC
119
120private:
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