1/*
2 * Copyright 2006-2012, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan Aßmus <superstippi@gmx.de>
7 */
8#ifndef VECTOR_PATH_H
9#define VECTOR_PATH_H
10
11
12#include "IconBuild.h"
13#include "Transformable.h"
14
15#include <agg_path_storage.h>
16
17#include <Rect.h>
18#include <String.h>
19
20#ifdef ICON_O_MATIC
21#	include "IconObject.h"
22
23#	include <Archivable.h>
24#	include <List.h>
25#endif // ICON_O_MATIC
26
27class BBitmap;
28class BMessage;
29class BView;
30
31
32_BEGIN_ICON_NAMESPACE
33
34
35struct control_point {
36	BPoint		point;		// actual point on path
37	BPoint		point_in;	// control point for incomming curve
38	BPoint		point_out;	// control point for outgoing curve
39	bool		connected;	// if all 3 points should be on one line
40};
41
42#ifdef ICON_O_MATIC
43class PathListener {
44 public:
45								PathListener();
46	virtual						~PathListener();
47
48	virtual	void				PointAdded(int32 index) = 0;
49	virtual	void				PointRemoved(int32 index) = 0;
50	virtual	void				PointChanged(int32 index) = 0;
51	virtual	void				PathChanged() = 0;
52	virtual	void				PathClosedChanged() = 0;
53	virtual	void				PathReversed() = 0;
54};
55
56class VectorPath : public BArchivable,
57				   public IconObject {
58#else
59class VectorPath {
60#endif // ICON_O_MATIC
61 public:
62
63	class Iterator {
64	 public:
65								Iterator() {}
66		virtual					~Iterator() {}
67
68		virtual	void			MoveTo(BPoint point) = 0;
69		virtual	void			LineTo(BPoint point) = 0;
70	};
71
72								VectorPath();
73								VectorPath(const VectorPath& from);
74								VectorPath(BMessage* archive);
75
76	virtual						~VectorPath();
77
78#ifdef ICON_O_MATIC
79	// IconObject
80	virtual	status_t			Archive(BMessage* into,
81										bool deep = true) const;
82
83	virtual	PropertyObject*		MakePropertyObject() const;
84	virtual	bool				SetToPropertyObject(
85									const PropertyObject* object);
86#else
87	inline	void				Notify() {}
88#endif // ICON_O_MATIC
89
90	// VectorPath
91			VectorPath&			operator=(const VectorPath& from);
92			bool				operator==(const VectorPath& from) const;
93
94			void				MakeEmpty();
95
96			bool				AddPoint(BPoint point);
97			bool				AddPoint(const BPoint& point,
98										 const BPoint& pointIn,
99										 const BPoint& pointOut,
100										 bool connected);
101			bool				AddPoint(BPoint point, int32 index);
102
103			bool				RemovePoint(int32 index);
104
105								// modify existing points position
106			bool				SetPoint(int32 index, BPoint point);
107			bool				SetPoint(int32 index, BPoint point,
108													  BPoint pointIn,
109													  BPoint pointOut,
110													  bool connected);
111			bool				SetPointIn(int32 index, BPoint point);
112			bool				SetPointOut(int32 index, BPoint point,
113										   bool mirrorDist = false);
114
115			bool				SetInOutConnected(int32 index, bool connected);
116
117								// query existing points position
118			bool				GetPointAt(int32 index, BPoint& point) const;
119			bool				GetPointInAt(int32 index, BPoint& point) const;
120			bool				GetPointOutAt(int32 index, BPoint& point) const;
121			bool				GetPointsAt(int32 index,
122											BPoint& point,
123											BPoint& pointIn,
124											BPoint& pointOut,
125											bool* connected = NULL) const;
126
127			int32				CountPoints() const;
128
129#ifdef ICON_O_MATIC
130								// iterates over curve segments and returns
131								// the distance and index of the point that
132								// started the segment that is closest
133			bool				GetDistance(BPoint point,
134											float* distance, int32* index) const;
135
136								// at curve segment indicated by "index", this
137								// function looks for the closest point
138								// directly on the curve and returns a "scale"
139								// that indicates the distance on the curve
140								// between [0..1]
141			bool				FindBezierScale(int32 index, BPoint point,
142												double* scale) const;
143								// this function can be used to get a point
144								// directly on the segment indicated by "index"
145								// "scale" is on [0..1] indicating the distance
146								// from the start of the segment to the end
147			bool				GetPoint(int32 index, double scale,
148										 BPoint& point) const;
149#endif // ICON_O_MATIC
150
151			void				SetClosed(bool closed);
152			bool				IsClosed() const
153									{ return fClosed; }
154
155			BRect				Bounds() const;
156			BRect				ControlPointBounds() const;
157
158			void				Iterate(Iterator* iterator,
159										float smoothScale = 1.0) const;
160
161			void				CleanUp();
162			void				Reverse();
163			void				ApplyTransform(const Transformable& transform);
164
165			void				PrintToStream() const;
166
167			bool				GetAGGPathStorage(agg::path_storage& path) const;
168
169#ifdef ICON_O_MATIC
170			bool				AddListener(PathListener* listener);
171			bool				RemoveListener(PathListener* listener);
172			int32				CountListeners() const;
173			PathListener*		ListenerAtFast(int32 index) const;
174#endif // ICON_O_MATIC
175
176
177 private:
178			BRect				_Bounds() const;
179			void				_SetPoint(int32 index, BPoint point);
180			void				_SetPoint(int32 index,
181										  const BPoint& point,
182										  const BPoint& pointIn,
183										  const BPoint& pointOut,
184										  bool connected);
185			bool				_SetPointCount(int32 count);
186
187#ifndef ICON_O_MATIC
188	inline	void				_NotifyPointAdded(int32 index) const {}
189	inline	void				_NotifyPointChanged(int32 index) const {}
190	inline	void				_NotifyPointRemoved(int32 index) const {}
191	inline	void				_NotifyPathChanged() const {}
192	inline	void				_NotifyClosedChanged() const {}
193	inline	void				_NotifyPathReversed() const {}
194#else
195			void				_NotifyPointAdded(int32 index) const;
196			void				_NotifyPointChanged(int32 index) const;
197			void				_NotifyPointRemoved(int32 index) const;
198			void				_NotifyPathChanged() const;
199			void				_NotifyClosedChanged() const;
200			void				_NotifyPathReversed() const;
201
202			BList				fListeners;
203#endif // ICON_O_MATIC
204
205			control_point*		fPath;
206			bool				fClosed;
207
208			int32				fPointCount;
209			int32				fAllocCount;
210
211	mutable	BRect				fCachedBounds;
212};
213
214
215_END_ICON_NAMESPACE
216
217
218#endif	// VECTOR_PATH_H
219