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