xref: /haiku/src/servers/app/drawing/Painter/Painter.h (revision a5061ecec55353a5f394759473f1fd6df04890da)
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 
31 class BBitmap;
32 class BRegion;
33 class BGradient;
34 class BGradientLinear;
35 class BGradientRadial;
36 class BGradientRadialFocus;
37 class BGradientDiamond;
38 class BGradientConic;
39 class DrawState;
40 class FontCacheReference;
41 class RenderingBuffer;
42 class ServerBitmap;
43 class ServerFont;
44 
45 
46 // Defines for SIMD support.
47 #define APPSERVER_SIMD_MMX	(1 << 0)
48 #define APPSERVER_SIMD_SSE	(1 << 1)
49 
50 
51 class Painter {
52 public:
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 									bool drawingText = false);
94 	inline	pattern				Pattern() const
95 									{ return *fPatternHandler.GetR5Pattern(); }
96 			void				SetDrawingMode(drawing_mode mode);
97 	inline	drawing_mode		DrawingMode() const
98 									{ return fDrawingMode; }
99 			void				SetBlendingMode(source_alpha srcAlpha,
100 									alpha_function alphaFunc);
101 
102 			void				SetFont(const ServerFont& font);
103 			void				SetFont(const DrawState* state);
104 	inline	const ServerFont&	Font() const
105 									{ return fTextRenderer.Font(); }
106 
107 								// painting functions
108 
109 								// lines
110 			void				StrokeLine(BPoint a, BPoint b);
111 
112 			// returns true if the line was either vertical or horizontal
113 			// draws a solid one pixel wide line of color c, no blending
114 			bool				StraightLine(BPoint a, BPoint b,
115 									const rgb_color& c) const;
116 
117 								// triangles
118 			BRect				StrokeTriangle(BPoint pt1, BPoint pt2,
119 									BPoint pt3) const;
120 
121 			BRect				FillTriangle(BPoint pt1, BPoint pt2,
122 									BPoint pt3) const;
123 			BRect				FillTriangle(BPoint pt1, BPoint pt2,
124 									BPoint pt3,
125 									const BGradient& gradient) const;
126 
127 								// polygons
128 			BRect				DrawPolygon(BPoint* ptArray, int32 numPts,
129 									bool filled, bool closed) const;
130 			BRect				FillPolygon(BPoint* ptArray, int32 numPts,
131 									const BGradient& gradient,
132 									bool closed) const;
133 
134 								// bezier curves
135 			BRect				DrawBezier(BPoint* controlPoints,
136 									bool filled) const;
137 			BRect				FillBezier(BPoint* controlPoints,
138 									const BGradient& gradient) const;
139 
140 								// shapes
141 			BRect				DrawShape(const int32& opCount,
142 									const uint32* opList, const int32& ptCount,
143 									const BPoint* ptList, bool filled,
144 									const BPoint& viewToScreenOffset,
145 									float viewScale) const;
146 			BRect				FillShape(const int32& opCount,
147 									const uint32* opList, const int32& ptCount,
148 									const BPoint* ptList,
149 									const BGradient& gradient,
150 									const BPoint& viewToScreenOffset,
151 									float viewScale) const;
152 
153 								// rects
154 			BRect				StrokeRect(const BRect& r) const;
155 
156 			// strokes a one pixel wide solid rect, no blending
157 			void				StrokeRect(const BRect& r,
158 									const rgb_color& c) const;
159 
160 			BRect				FillRect(const BRect& r) const;
161 			BRect				FillRect(const BRect& r,
162 									const BGradient& gradient) const;
163 
164 			// fills a solid rect with color c, no blending
165 			void				FillRect(const BRect& r,
166 									const rgb_color& c) const;
167 
168 			// fills a rect with a linear gradient, the caller should be
169 			// sure that the gradient is indeed vertical. The start point of
170 			// the gradient should be above the end point, or this function
171 			// will not draw anything.
172 			void				FillRectVerticalGradient(BRect r,
173 									const BGradientLinear& gradient) const;
174 
175 			// fills a solid rect with color c, no blending, no clipping
176 			void				FillRectNoClipping(const clipping_rect& r,
177 									const rgb_color& c) const;
178 
179 								// round rects
180 			BRect				StrokeRoundRect(const BRect& r, float xRadius,
181 									float yRadius) const;
182 
183 			BRect				FillRoundRect(const BRect& r, float xRadius,
184 									float yRadius) const;
185 			BRect				FillRoundRect(const BRect& r, float xRadius,
186 									float yRadius,
187 									const BGradient& gradient) const;
188 
189 								// ellipses
190 			void				AlignEllipseRect(BRect* rect,
191 									bool filled) const;
192 
193 			BRect				DrawEllipse(BRect r, bool filled) const;
194 			BRect				FillEllipse(BRect r,
195 									const BGradient& gradient) const;
196 
197 								// arcs
198 			BRect				StrokeArc(BPoint center, float xRadius,
199 									float yRadius, float angle,
200 									float span) const;
201 
202 			BRect				FillArc(BPoint center, float xRadius,
203 									float yRadius, float angle,
204 									float span) const;
205 			BRect				FillArc(BPoint center, float xRadius,
206 									float yRadius, float angle, float span,
207 									const BGradient& gradient) const;
208 
209 								// strings
210 			BRect				DrawString(const char* utf8String,
211 									uint32 length, BPoint baseLine,
212 									const escapement_delta* delta,
213 									FontCacheReference* cacheReference = NULL);
214 			BRect				DrawString(const char* utf8String,
215 									uint32 length, const BPoint* offsets,
216 									FontCacheReference* cacheReference = NULL);
217 
218 			BRect				BoundingBox(const char* utf8String,
219 									uint32 length, BPoint baseLine,
220 									BPoint* penLocation,
221 									const escapement_delta* delta,
222 									FontCacheReference* cacheReference
223 										= NULL) const;
224 			BRect				BoundingBox(const char* utf8String,
225 									uint32 length, const BPoint* offsets,
226 									BPoint* penLocation,
227 									FontCacheReference* cacheReference
228 										= NULL) const;
229 
230 			float				StringWidth(const char* utf8String,
231 									uint32 length,
232 									const escapement_delta* delta = NULL);
233 
234 
235 								// bitmaps
236 			BRect				DrawBitmap(const ServerBitmap* bitmap,
237 									BRect bitmapRect, BRect viewRect,
238 									uint32 options) const;
239 
240 								// some convenience stuff
241 			BRect				FillRegion(const BRegion* region) const;
242 			BRect				FillRegion(const BRegion* region,
243 									const BGradient& gradient) const;
244 
245 			BRect				InvertRect(const BRect& r) const;
246 
247 	inline	BRect				TransformAndClipRect(BRect rect) const;
248 	inline	BRect				ClipRect(BRect rect) const;
249 	inline	BRect				TransformAlignAndClipRect(BRect rect) const;
250 	inline	BRect				AlignAndClipRect(BRect rect) const;
251 	inline	BRect				AlignRect(BRect rect) const;
252 
253 			void				SetRendererOffset(int32 offsetX,
254 									int32 offsetY);
255 
256 private:
257 			float				_Align(float coord, bool round,
258 									bool centerOffset) const;
259 			void				_Align(BPoint* point, bool round,
260 									bool centerOffset) const;
261 			void				_Align(BPoint* point,
262 									bool centerOffset = true) const;
263 			BPoint				_Align(const BPoint& point,
264 									bool centerOffset = true) const;
265 			BRect				_Clipped(const BRect& rect) const;
266 
267 			void				_UpdateFont() const;
268 			void				_UpdateLineWidth();
269 			void				_UpdateDrawingMode(bool drawingText = false);
270 			void				_SetRendererColor(const rgb_color& color) const;
271 
272 								// drawing functions stroke/fill
273 			BRect				_DrawTriangle(BPoint pt1, BPoint pt2,
274 									BPoint pt3, bool fill) const;
275 
276 			void				_IterateShapeData(const int32& opCount,
277 									const uint32* opList, const int32& ptCount,
278 									const BPoint* points,
279 									const BPoint& viewToScreenOffset,
280 									float viewScale) const;
281 
282 			void				_InvertRect32(BRect r) const;
283 			void				_BlendRect32(const BRect& r,
284 									const rgb_color& c) const;
285 
286 
287 			template<class VertexSource>
288 			BRect				_BoundingBox(VertexSource& path) const;
289 
290 			template<class VertexSource>
291 			BRect				_StrokePath(VertexSource& path) const;
292 			template<class VertexSource>
293 			BRect				_StrokePath(VertexSource& path,
294 									cap_mode capMode) const;
295 			template<class VertexSource>
296 			BRect				_FillPath(VertexSource& path) const;
297 			template<class VertexSource>
298 			BRect				_RasterizePath(VertexSource& path) const;
299 
300 			template<class VertexSource>
301 			BRect				_FillPath(VertexSource& path,
302 									const BGradient& gradient) const;
303 			template<class VertexSource>
304 			BRect				_RasterizePath(VertexSource& path,
305 									const BGradient& gradient) const;
306 
307 			void				_CalcLinearGradientTransform(BPoint startPoint,
308 									BPoint endPoint, agg::trans_affine& mtx,
309 									float gradient_d2 = 100.0f) const;
310 			void				_CalcRadialGradientTransform(BPoint center,
311 									agg::trans_affine& mtx,
312 									float gradient_d2 = 100.0f) const;
313 
314 			void				_MakeGradient(const BGradient& gradient,
315 									int32 colorCount, uint32* colors,
316 									int32 arrayOffset, int32 arraySize) const;
317 
318 			template<class Array>
319 			void				_MakeGradient(Array& array,
320 									const BGradient& gradient) const;
321 
322 			template<class VertexSource, typename GradientFunction>
323 			void				_RasterizePath(VertexSource& path,
324 									const BGradient& gradient,
325 									GradientFunction function,
326 									agg::trans_affine& gradientTransform,
327 									int gradientStop = 100) const;
328 
329 private:
330 	class BitmapPainter;
331 
332 	friend class BitmapPainter; // needed only for gcc2
333 
334 private:
335 	mutable	PainterAggInterface	fInternal;
336 
337 	// for internal coordinate rounding/transformation
338 			bool				fSubpixelPrecise : 1;
339 			bool				fValidClipping : 1;
340 			bool				fDrawingText : 1;
341 			bool				fAttached : 1;
342 			bool				fIdentityTransform : 1;
343 
344 			Transformable		fTransform;
345 			float				fPenSize;
346 			const BRegion*		fClippingRegion;
347 			drawing_mode		fDrawingMode;
348 			source_alpha		fAlphaSrcMode;
349 			alpha_function		fAlphaFncMode;
350 			cap_mode			fLineCapMode;
351 			join_mode			fLineJoinMode;
352 			float				fMiterLimit;
353 
354 			PatternHandler		fPatternHandler;
355 
356 	// a class handling rendering and caching of glyphs
357 	// it is setup to load from a specific Freetype supported
358 	// font file which it gets from ServerFont
359 	mutable	AGGTextRenderer		fTextRenderer;
360 };
361 
362 
363 inline BRect
364 Painter::TransformAndClipRect(BRect rect) const
365 {
366 	rect.left = floorf(rect.left);
367 	rect.top = floorf(rect.top);
368 	rect.right = ceilf(rect.right);
369 	rect.bottom = ceilf(rect.bottom);
370 
371 	if (!fIdentityTransform)
372 		rect = fTransform.TransformBounds(rect);
373 
374 	return _Clipped(rect);
375 }
376 
377 
378 inline BRect
379 Painter::ClipRect(BRect rect) const
380 {
381 	rect.left = floorf(rect.left);
382 	rect.top = floorf(rect.top);
383 	rect.right = ceilf(rect.right);
384 	rect.bottom = ceilf(rect.bottom);
385 	return _Clipped(rect);
386 }
387 
388 
389 inline BRect
390 Painter::AlignAndClipRect(BRect rect) const
391 {
392 	return _Clipped(AlignRect(rect));
393 }
394 
395 
396 inline BRect
397 Painter::TransformAlignAndClipRect(BRect rect) const
398 {
399 	rect = AlignRect(rect);
400 	if (!fIdentityTransform)
401 		rect = fTransform.TransformBounds(rect);
402 	return _Clipped(rect);
403 }
404 
405 
406 inline BRect
407 Painter::AlignRect(BRect rect) const
408 {
409 	rect.left = floorf(rect.left);
410 	rect.top = floorf(rect.top);
411 	if (fSubpixelPrecise) {
412 		rect.right = ceilf(rect.right);
413 		rect.bottom = ceilf(rect.bottom);
414 	} else {
415 		rect.right = floorf(rect.right);
416 		rect.bottom = floorf(rect.bottom);
417 	}
418 
419 	return rect;
420 }
421 
422 
423 #endif // PAINTER_H
424