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