xref: /haiku/src/servers/app/drawing/Painter/Painter.h (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
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 	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 
255 private:
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 
328 private:
329 	class BitmapPainter;
330 
331 	friend class BitmapPainter; // needed only for gcc2
332 
333 private:
334 	mutable	PainterAggInterface	fInternal;
335 
336 	// for internal coordinate rounding/transformation
337 			bool				fSubpixelPrecise : 1;
338 			bool				fValidClipping : 1;
339 			bool				fAttached : 1;
340 			bool				fIdentityTransform : 1;
341 
342 			Transformable		fTransform;
343 			float				fPenSize;
344 			const BRegion*		fClippingRegion;
345 			drawing_mode		fDrawingMode;
346 			source_alpha		fAlphaSrcMode;
347 			alpha_function		fAlphaFncMode;
348 			cap_mode			fLineCapMode;
349 			join_mode			fLineJoinMode;
350 			float				fMiterLimit;
351 
352 			PatternHandler		fPatternHandler;
353 
354 	// a class handling rendering and caching of glyphs
355 	// it is setup to load from a specific Freetype supported
356 	// font file which it gets from ServerFont
357 	mutable	AGGTextRenderer		fTextRenderer;
358 };
359 
360 
361 inline BRect
362 Painter::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 
376 inline BRect
377 Painter::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 
387 inline BRect
388 Painter::AlignAndClipRect(BRect rect) const
389 {
390 	return _Clipped(AlignRect(rect));
391 }
392 
393 
394 inline BRect
395 Painter::TransformAlignAndClipRect(BRect rect) const
396 {
397 	rect = AlignRect(rect);
398 	if (!fIdentityTransform)
399 		rect = fTransform.TransformBounds(rect);
400 	return _Clipped(rect);
401 }
402 
403 
404 inline BRect
405 Painter::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