1/*
2 * Copyright 2005-2007, Stephan A��mus <superstippi@gmx.de>.
3 * Copyright 2008, Andrej Spielmann <andrej.spielmann@seh.ox.ac.uk>.
4 * Copyright 2015, Julian Harnath <julian.harnath@rwth-aachen.de>
5 * All rights reserved. Distributed under the terms of the MIT License.
6 *
7 * API to the Anti-Grain Geometry based "Painter" drawing backend. Manages
8 * rendering pipe-lines for stroke, fills, bitmap and text rendering.
9 *
10 */
11#ifndef PAINTER_H
12#define PAINTER_H
13
14
15#include "AGGTextRenderer.h"
16#include "FontManager.h"
17#include "PainterAggInterface.h"
18#include "PatternHandler.h"
19#include "ServerFont.h"
20#include "Transformable.h"
21
22#include "defines.h"
23
24#include <agg_conv_curve.h>
25
26#include <AffineTransform.h>
27#include <Font.h>
28#include <Rect.h>
29
30
31class BBitmap;
32class BRegion;
33class BGradient;
34class BGradientLinear;
35class BGradientRadial;
36class BGradientRadialFocus;
37class BGradientDiamond;
38class BGradientConic;
39class DrawState;
40class FontCacheReference;
41class RenderingBuffer;
42class ServerBitmap;
43class ServerFont;
44
45
46// Defines for SIMD support.
47#define APPSERVER_SIMD_MMX	(1 << 0)
48#define APPSERVER_SIMD_SSE	(1 << 1)
49
50
51class Painter {
52public:
53								Painter();
54	virtual						~Painter();
55
56								// frame buffer stuff
57			void				AttachToBuffer(RenderingBuffer* buffer);
58			void				DetachFromBuffer();
59			BRect				Bounds() const;
60
61			void				SetDrawState(const DrawState* data,
62									int32 xOffset = 0,
63									int32 yOffset = 0);
64
65			void				ConstrainClipping(const BRegion* region);
66			const BRegion*		ClippingRegion() const
67									{ return fClippingRegion; }
68
69								// object settings
70			void				SetTransform(BAffineTransform transform,
71									int32 xOffset, int32 yOffset);
72
73	inline	bool				IsIdentityTransform() const
74									{ return fIdentityTransform; }
75			const Transformable& Transform() const
76									{ return fTransform; }
77
78			void				SetHighColor(const rgb_color& color);
79	inline	rgb_color			HighColor() const
80									{ return fPatternHandler.HighColor(); }
81
82			void				SetLowColor(const rgb_color& color);
83	inline	rgb_color			LowColor() const
84									{ return fPatternHandler.LowColor(); }
85
86			void				SetPenSize(float size);
87	inline	float				PenSize() const
88									{ return fPenSize; }
89			void				SetStrokeMode(cap_mode lineCap,
90									join_mode joinMode, float miterLimit);
91			void				SetFillRule(int32 fillRule);
92			void				SetPattern(const pattern& p);
93	inline	pattern				Pattern() const
94									{ return *fPatternHandler.GetR5Pattern(); }
95			void				SetDrawingMode(drawing_mode mode);
96	inline	drawing_mode		DrawingMode() const
97									{ return fDrawingMode; }
98			void				SetBlendingMode(source_alpha srcAlpha,
99									alpha_function alphaFunc);
100
101			void				SetFont(const ServerFont& font);
102			void				SetFont(const DrawState* state);
103	inline	const ServerFont&	Font() const
104									{ return fTextRenderer.Font(); }
105
106								// painting functions
107
108								// lines
109			void				StrokeLine(BPoint a, BPoint b);
110
111			// returns true if the line was either vertical or horizontal
112			// draws a solid one pixel wide line of color c, no blending
113			bool				StraightLine(BPoint a, BPoint b,
114									const rgb_color& c) const;
115
116								// triangles
117			BRect				StrokeTriangle(BPoint pt1, BPoint pt2,
118									BPoint pt3) const;
119
120			BRect				FillTriangle(BPoint pt1, BPoint pt2,
121									BPoint pt3) const;
122			BRect				FillTriangle(BPoint pt1, BPoint pt2,
123									BPoint pt3,
124									const BGradient& gradient);
125
126								// polygons
127			BRect				DrawPolygon(BPoint* ptArray, int32 numPts,
128									bool filled, bool closed) const;
129			BRect				FillPolygon(BPoint* ptArray, int32 numPts,
130									const BGradient& gradient,
131									bool closed);
132
133								// bezier curves
134			BRect				DrawBezier(BPoint* controlPoints,
135									bool filled) const;
136			BRect				FillBezier(BPoint* controlPoints,
137									const BGradient& gradient);
138
139								// shapes
140			BRect				DrawShape(const int32& opCount,
141									const uint32* opList, const int32& ptCount,
142									const BPoint* ptList, bool filled,
143									const BPoint& viewToScreenOffset,
144									float viewScale) const;
145			BRect				FillShape(const int32& opCount,
146									const uint32* opList, const int32& ptCount,
147									const BPoint* ptList,
148									const BGradient& gradient,
149									const BPoint& viewToScreenOffset,
150									float viewScale);
151
152								// rects
153			BRect				StrokeRect(const BRect& r) const;
154
155			// strokes a one pixel wide solid rect, no blending
156			void				StrokeRect(const BRect& r,
157									const rgb_color& c) const;
158
159			BRect				FillRect(const BRect& r) const;
160			BRect				FillRect(const BRect& r,
161									const BGradient& gradient);
162
163			// fills a solid rect with color c, no blending
164			void				FillRect(const BRect& r,
165									const rgb_color& c) const;
166
167			// fills a rect with a linear gradient, the caller should be
168			// sure that the gradient is indeed vertical. The start point of
169			// the gradient should be above the end point, or this function
170			// will not draw anything.
171			void				FillRectVerticalGradient(BRect r,
172									const BGradientLinear& gradient) const;
173
174			// fills a solid rect with color c, no blending, no clipping
175			void				FillRectNoClipping(const clipping_rect& r,
176									const rgb_color& c) const;
177
178								// round rects
179			BRect				StrokeRoundRect(const BRect& r, float xRadius,
180									float yRadius) const;
181
182			BRect				FillRoundRect(const BRect& r, float xRadius,
183									float yRadius) const;
184			BRect				FillRoundRect(const BRect& r, float xRadius,
185									float yRadius,
186									const BGradient& gradient);
187
188								// ellipses
189			void				AlignEllipseRect(BRect* rect,
190									bool filled) const;
191
192			BRect				DrawEllipse(BRect r, bool filled) const;
193			BRect				FillEllipse(BRect r,
194									const BGradient& gradient);
195
196								// arcs
197			BRect				StrokeArc(BPoint center, float xRadius,
198									float yRadius, float angle,
199									float span) const;
200
201			BRect				FillArc(BPoint center, float xRadius,
202									float yRadius, float angle,
203									float span) const;
204			BRect				FillArc(BPoint center, float xRadius,
205									float yRadius, float angle, float span,
206									const BGradient& gradient);
207
208								// strings
209			BRect				DrawString(const char* utf8String,
210									uint32 length, BPoint baseLine,
211									const escapement_delta* delta,
212									FontCacheReference* cacheReference = NULL);
213			BRect				DrawString(const char* utf8String,
214									uint32 length, const BPoint* offsets,
215									FontCacheReference* cacheReference = NULL);
216
217			BRect				BoundingBox(const char* utf8String,
218									uint32 length, BPoint baseLine,
219									BPoint* penLocation,
220									const escapement_delta* delta,
221									FontCacheReference* cacheReference
222										= NULL) const;
223			BRect				BoundingBox(const char* utf8String,
224									uint32 length, const BPoint* offsets,
225									BPoint* penLocation,
226									FontCacheReference* cacheReference
227										= NULL) const;
228
229			float				StringWidth(const char* utf8String,
230									uint32 length,
231									const escapement_delta* delta = NULL);
232
233
234								// bitmaps
235			BRect				DrawBitmap(const ServerBitmap* bitmap,
236									BRect bitmapRect, BRect viewRect,
237									uint32 options) const;
238
239								// some convenience stuff
240			BRect				FillRegion(const BRegion* region) const;
241			BRect				FillRegion(const BRegion* region,
242									const BGradient& gradient);
243
244			BRect				InvertRect(const BRect& r) const;
245
246	inline	BRect				TransformAndClipRect(BRect rect) const;
247	inline	BRect				ClipRect(BRect rect) const;
248	inline	BRect				TransformAlignAndClipRect(BRect rect) const;
249	inline	BRect				AlignAndClipRect(BRect rect) const;
250	inline	BRect				AlignRect(BRect rect) const;
251
252			void				SetRendererOffset(int32 offsetX,
253									int32 offsetY);
254
255private:
256			float				_Align(float coord, bool round,
257									bool centerOffset) const;
258			void				_Align(BPoint* point, bool round,
259									bool centerOffset) const;
260			void				_Align(BPoint* point,
261									bool centerOffset = true) const;
262			BPoint				_Align(const BPoint& point,
263									bool centerOffset = true) const;
264			BRect				_Clipped(const BRect& rect) const;
265
266			void				_UpdateFont() const;
267			void				_UpdateLineWidth();
268			void				_UpdateDrawingMode();
269			void				_SetRendererColor(const rgb_color& color) const;
270
271								// drawing functions stroke/fill
272			BRect				_DrawTriangle(BPoint pt1, BPoint pt2,
273									BPoint pt3, bool fill) const;
274
275			void				_IterateShapeData(const int32& opCount,
276									const uint32* opList, const int32& ptCount,
277									const BPoint* points,
278									const BPoint& viewToScreenOffset,
279									float viewScale) const;
280
281			void				_InvertRect32(BRect r) const;
282			void				_BlendRect32(const BRect& r,
283									const rgb_color& c) const;
284
285
286			template<class VertexSource>
287			BRect				_BoundingBox(VertexSource& path) const;
288
289			template<class VertexSource>
290			BRect				_StrokePath(VertexSource& path) const;
291			template<class VertexSource>
292			BRect				_StrokePath(VertexSource& path,
293									cap_mode capMode) const;
294			template<class VertexSource>
295			BRect				_FillPath(VertexSource& path) const;
296			template<class VertexSource>
297			BRect				_RasterizePath(VertexSource& path) const;
298
299			template<class VertexSource>
300			BRect				_FillPath(VertexSource& path,
301									const BGradient& gradient);
302			template<class VertexSource>
303			BRect				_RasterizePath(VertexSource& path,
304									const BGradient& gradient);
305
306			void				_CalcLinearGradientTransform(BPoint startPoint,
307									BPoint endPoint, agg::trans_affine& mtx,
308									float gradient_d2 = 100.0f) const;
309			void				_CalcRadialGradientTransform(BPoint center,
310									agg::trans_affine& mtx,
311									float gradient_d2 = 100.0f) const;
312
313			void				_MakeGradient(const BGradient& gradient,
314									int32 colorCount, uint32* colors,
315									int32 arrayOffset, int32 arraySize) const;
316
317			template<class Array>
318			void				_MakeGradient(Array& array,
319									const BGradient& gradient) const;
320
321			template<class VertexSource, typename GradientFunction>
322			void				_RasterizePath(VertexSource& path,
323									const BGradient& gradient,
324									GradientFunction function,
325									agg::trans_affine& gradientTransform,
326									int gradientStop = 100);
327
328private:
329	class BitmapPainter;
330
331	friend class BitmapPainter; // needed only for gcc2
332
333private:
334	// for internal coordinate rounding/transformation
335			bool				fSubpixelPrecise : 1;
336			bool				fValidClipping : 1;
337			bool				fAttached : 1;
338			bool				fIdentityTransform : 1;
339
340			Transformable		fTransform;
341			float				fPenSize;
342			const BRegion*		fClippingRegion;
343			drawing_mode		fDrawingMode;
344			source_alpha		fAlphaSrcMode;
345			alpha_function		fAlphaFncMode;
346			cap_mode			fLineCapMode;
347			join_mode			fLineJoinMode;
348			float				fMiterLimit;
349
350			PatternHandler		fPatternHandler;
351
352	// a class handling rendering and caching of glyphs
353	// it is setup to load from a specific Freetype supported
354	// font file which it gets from ServerFont
355	mutable	AGGTextRenderer		fTextRenderer;
356
357	mutable	PainterAggInterface	fInternal;
358};
359
360
361inline BRect
362Painter::TransformAndClipRect(BRect rect) const
363{
364	rect.left = floorf(rect.left);
365	rect.top = floorf(rect.top);
366	rect.right = ceilf(rect.right);
367	rect.bottom = ceilf(rect.bottom);
368
369	if (!fIdentityTransform)
370		rect = fTransform.TransformBounds(rect);
371
372	return _Clipped(rect);
373}
374
375
376inline BRect
377Painter::ClipRect(BRect rect) const
378{
379	rect.left = floorf(rect.left);
380	rect.top = floorf(rect.top);
381	rect.right = ceilf(rect.right);
382	rect.bottom = ceilf(rect.bottom);
383	return _Clipped(rect);
384}
385
386
387inline BRect
388Painter::AlignAndClipRect(BRect rect) const
389{
390	return _Clipped(AlignRect(rect));
391}
392
393
394inline BRect
395Painter::TransformAlignAndClipRect(BRect rect) const
396{
397	rect = AlignRect(rect);
398	if (!fIdentityTransform)
399		rect = fTransform.TransformBounds(rect);
400	return _Clipped(rect);
401}
402
403
404inline BRect
405Painter::AlignRect(BRect rect) const
406{
407	rect.left = floorf(rect.left);
408	rect.top = floorf(rect.top);
409	if (fSubpixelPrecise) {
410		rect.right = ceilf(rect.right);
411		rect.bottom = ceilf(rect.bottom);
412	} else {
413		rect.right = floorf(rect.right);
414		rect.bottom = floorf(rect.bottom);
415	}
416
417	return rect;
418}
419
420
421#endif // PAINTER_H
422