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