1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24 */ 25 26 namespace juce 27 { 28 29 //============================================================================== 30 /** 31 A graphics context, used for drawing a component or image. 32 33 When a Component needs painting, a Graphics context is passed to its 34 Component::paint() method, and this you then call methods within this 35 object to actually draw the component's content. 36 37 A Graphics can also be created from an image, to allow drawing directly onto 38 that image. 39 40 @see Component::paint 41 42 @tags{Graphics} 43 */ 44 class JUCE_API Graphics final 45 { 46 public: 47 //============================================================================== 48 /** Creates a Graphics object to draw directly onto the given image. 49 50 The graphics object that is created will be set up to draw onto the image, 51 with the context's clipping area being the entire size of the image, and its 52 origin being the image's origin. To draw into a subsection of an image, use the 53 reduceClipRegion() and setOrigin() methods. 54 55 Obviously you shouldn't delete the image before this context is deleted. 56 */ 57 explicit Graphics (const Image& imageToDrawOnto); 58 59 /** Destructor. */ 60 ~Graphics(); 61 62 //============================================================================== 63 /** Changes the current drawing colour. 64 65 This sets the colour that will now be used for drawing operations - it also 66 sets the opacity to that of the colour passed-in. 67 68 If a brush is being used when this method is called, the brush will be deselected, 69 and any subsequent drawing will be done with a solid colour brush instead. 70 71 @see setOpacity 72 */ 73 void setColour (Colour newColour); 74 75 /** Changes the opacity to use with the current colour. 76 77 If a solid colour is being used for drawing, this changes its opacity 78 to this new value (i.e. it doesn't multiply the colour's opacity by this amount). 79 80 If a gradient is being used, this will have no effect on it. 81 82 A value of 0.0 is completely transparent, 1.0 is completely opaque. 83 */ 84 void setOpacity (float newOpacity); 85 86 /** Sets the context to use a gradient for its fill pattern. */ 87 void setGradientFill (const ColourGradient& gradient); 88 89 /** Sets the context to use a gradient for its fill pattern. */ 90 void setGradientFill (ColourGradient&& gradient); 91 92 /** Sets the context to use a tiled image pattern for filling. 93 Make sure that you don't delete this image while it's still being used by 94 this context! 95 */ 96 void setTiledImageFill (const Image& imageToUse, 97 int anchorX, int anchorY, 98 float opacity); 99 100 /** Changes the current fill settings. 101 @see setColour, setGradientFill, setTiledImageFill 102 */ 103 void setFillType (const FillType& newFill); 104 105 //============================================================================== 106 /** Changes the font to use for subsequent text-drawing functions. 107 @see drawSingleLineText, drawMultiLineText, drawText, drawFittedText 108 */ 109 void setFont (const Font& newFont); 110 111 /** Changes the size of the currently-selected font. 112 This is a convenient shortcut that changes the context's current font to a 113 different size. The typeface won't be changed. 114 @see Font 115 */ 116 void setFont (float newFontHeight); 117 118 /** Returns the currently selected font. */ 119 Font getCurrentFont() const; 120 121 /** Draws a one-line text string. 122 123 This will use the current colour (or brush) to fill the text. The font is the last 124 one specified by setFont(). 125 126 @param text the string to draw 127 @param startX the position to draw the left-hand edge of the text 128 @param baselineY the position of the text's baseline 129 @param justification the horizontal flags indicate which end of the text string is 130 anchored at the specified point. 131 @see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText 132 */ 133 void drawSingleLineText (const String& text, 134 int startX, int baselineY, 135 Justification justification = Justification::left) const; 136 137 /** Draws text across multiple lines. 138 139 This will break the text onto a new line where there's a new-line or 140 carriage-return character, or at a word-boundary when the text becomes wider 141 than the size specified by the maximumLineWidth parameter. New-lines 142 will be vertically separated by the specified leading. 143 144 @see setFont, drawSingleLineText, drawFittedText, GlyphArrangement::addJustifiedText 145 */ 146 void drawMultiLineText (const String& text, 147 int startX, int baselineY, 148 int maximumLineWidth, 149 Justification justification = Justification::left, 150 float leading = 0.0f) const; 151 152 /** Draws a line of text within a specified rectangle. 153 154 The text will be positioned within the rectangle based on the justification 155 flags passed-in. If the string is too long to fit inside the rectangle, it will 156 either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig 157 flag is true). 158 159 @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText 160 */ 161 void drawText (const String& text, 162 int x, int y, int width, int height, 163 Justification justificationType, 164 bool useEllipsesIfTooBig = true) const; 165 166 /** Draws a line of text within a specified rectangle. 167 168 The text will be positioned within the rectangle based on the justification 169 flags passed-in. If the string is too long to fit inside the rectangle, it will 170 either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig 171 flag is true). 172 173 @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText 174 */ 175 void drawText (const String& text, 176 Rectangle<int> area, 177 Justification justificationType, 178 bool useEllipsesIfTooBig = true) const; 179 180 /** Draws a line of text within a specified rectangle. 181 182 The text will be positioned within the rectangle based on the justification 183 flags passed-in. If the string is too long to fit inside the rectangle, it will 184 either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig 185 flag is true). 186 187 @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText 188 */ 189 void drawText (const String& text, 190 Rectangle<float> area, 191 Justification justificationType, 192 bool useEllipsesIfTooBig = true) const; 193 194 /** Tries to draw a text string inside a given space. 195 196 This does its best to make the given text readable within the specified rectangle, 197 so it's useful for labelling things. 198 199 If the text is too big, it'll be squashed horizontally or broken over multiple lines 200 if the maximumLinesToUse value allows this. If the text just won't fit into the space, 201 it'll cram as much as possible in there, and put some ellipsis at the end to show that 202 it's been truncated. 203 204 A Justification parameter lets you specify how the text is laid out within the rectangle, 205 both horizontally and vertically. 206 207 The minimumHorizontalScale parameter specifies how much the text can be squashed horizontally 208 to try to squeeze it into the space. If you don't want any horizontal scaling to occur, you 209 can set this value to 1.0f. Pass 0 if you want it to use a default value. 210 211 @see GlyphArrangement::addFittedText 212 */ 213 void drawFittedText (const String& text, 214 int x, int y, int width, int height, 215 Justification justificationFlags, 216 int maximumNumberOfLines, 217 float minimumHorizontalScale = 0.0f) const; 218 219 /** Tries to draw a text string inside a given space. 220 221 This does its best to make the given text readable within the specified rectangle, 222 so it's useful for labelling things. 223 224 If the text is too big, it'll be squashed horizontally or broken over multiple lines 225 if the maximumLinesToUse value allows this. If the text just won't fit into the space, 226 it'll cram as much as possible in there, and put some ellipsis at the end to show that 227 it's been truncated. 228 229 A Justification parameter lets you specify how the text is laid out within the rectangle, 230 both horizontally and vertically. 231 232 The minimumHorizontalScale parameter specifies how much the text can be squashed horizontally 233 to try to squeeze it into the space. If you don't want any horizontal scaling to occur, you 234 can set this value to 1.0f. Pass 0 if you want it to use a default value. 235 236 @see GlyphArrangement::addFittedText 237 */ 238 void drawFittedText (const String& text, 239 Rectangle<int> area, 240 Justification justificationFlags, 241 int maximumNumberOfLines, 242 float minimumHorizontalScale = 0.0f) const; 243 244 //============================================================================== 245 /** Fills the context's entire clip region with the current colour or brush. 246 247 (See also the fillAll (Colour) method which is a quick way of filling 248 it with a given colour). 249 */ 250 void fillAll() const; 251 252 /** Fills the context's entire clip region with a given colour. 253 254 This leaves the context's current colour and brush unchanged, it just 255 uses the specified colour temporarily. 256 */ 257 void fillAll (Colour colourToUse) const; 258 259 //============================================================================== 260 /** Fills a rectangle with the current colour or brush. 261 @see drawRect, fillRoundedRectangle 262 */ 263 void fillRect (Rectangle<int> rectangle) const; 264 265 /** Fills a rectangle with the current colour or brush. 266 @see drawRect, fillRoundedRectangle 267 */ 268 void fillRect (Rectangle<float> rectangle) const; 269 270 /** Fills a rectangle with the current colour or brush. 271 @see drawRect, fillRoundedRectangle 272 */ 273 void fillRect (int x, int y, int width, int height) const; 274 275 /** Fills a rectangle with the current colour or brush. 276 @see drawRect, fillRoundedRectangle 277 */ 278 void fillRect (float x, float y, float width, float height) const; 279 280 /** Fills a set of rectangles using the current colour or brush. 281 If you have a lot of rectangles to draw, it may be more efficient 282 to create a RectangleList and use this method than to call fillRect() 283 multiple times. 284 */ 285 void fillRectList (const RectangleList<float>& rectangles) const; 286 287 /** Fills a set of rectangles using the current colour or brush. 288 If you have a lot of rectangles to draw, it may be more efficient 289 to create a RectangleList and use this method than to call fillRect() 290 multiple times. 291 */ 292 void fillRectList (const RectangleList<int>& rectangles) const; 293 294 /** Uses the current colour or brush to fill a rectangle with rounded corners. 295 @see drawRoundedRectangle, Path::addRoundedRectangle 296 */ 297 void fillRoundedRectangle (float x, float y, float width, float height, 298 float cornerSize) const; 299 300 /** Uses the current colour or brush to fill a rectangle with rounded corners. 301 @see drawRoundedRectangle, Path::addRoundedRectangle 302 */ 303 void fillRoundedRectangle (Rectangle<float> rectangle, 304 float cornerSize) const; 305 306 /** Fills a rectangle with a checkerboard pattern, alternating between two colours. */ 307 void fillCheckerBoard (Rectangle<float> area, 308 float checkWidth, float checkHeight, 309 Colour colour1, Colour colour2) const; 310 311 /** Draws a rectangular outline, using the current colour or brush. 312 The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. 313 @see fillRect 314 */ 315 void drawRect (int x, int y, int width, int height, int lineThickness = 1) const; 316 317 /** Draws a rectangular outline, using the current colour or brush. 318 The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. 319 @see fillRect 320 */ 321 void drawRect (float x, float y, float width, float height, float lineThickness = 1.0f) const; 322 323 /** Draws a rectangular outline, using the current colour or brush. 324 The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. 325 @see fillRect 326 */ 327 void drawRect (Rectangle<int> rectangle, int lineThickness = 1) const; 328 329 /** Draws a rectangular outline, using the current colour or brush. 330 The lines are drawn inside the given rectangle, and greater line thicknesses extend inwards. 331 @see fillRect 332 */ 333 void drawRect (Rectangle<float> rectangle, float lineThickness = 1.0f) const; 334 335 /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners. 336 @see fillRoundedRectangle, Path::addRoundedRectangle 337 */ 338 void drawRoundedRectangle (float x, float y, float width, float height, 339 float cornerSize, float lineThickness) const; 340 341 /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners. 342 @see fillRoundedRectangle, Path::addRoundedRectangle 343 */ 344 void drawRoundedRectangle (Rectangle<float> rectangle, 345 float cornerSize, float lineThickness) const; 346 347 //============================================================================== 348 /** Fills an ellipse with the current colour or brush. 349 The ellipse is drawn to fit inside the given rectangle. 350 @see drawEllipse, Path::addEllipse 351 */ 352 void fillEllipse (float x, float y, float width, float height) const; 353 354 /** Fills an ellipse with the current colour or brush. 355 The ellipse is drawn to fit inside the given rectangle. 356 @see drawEllipse, Path::addEllipse 357 */ 358 void fillEllipse (Rectangle<float> area) const; 359 360 /** Draws an elliptical stroke using the current colour or brush. 361 @see fillEllipse, Path::addEllipse 362 */ 363 void drawEllipse (float x, float y, float width, float height, 364 float lineThickness) const; 365 366 /** Draws an elliptical stroke using the current colour or brush. 367 @see fillEllipse, Path::addEllipse 368 */ 369 void drawEllipse (Rectangle<float> area, float lineThickness) const; 370 371 //============================================================================== 372 /** Draws a line between two points. 373 The line is 1 pixel wide and drawn with the current colour or brush. 374 TIP: If you're trying to draw horizontal or vertical lines, don't use this - 375 it's better to use fillRect() instead unless you really need an angled line. 376 */ 377 void drawLine (float startX, float startY, float endX, float endY) const; 378 379 /** Draws a line between two points with a given thickness. 380 TIP: If you're trying to draw horizontal or vertical lines, don't use this - 381 it's better to use fillRect() instead unless you really need an angled line. 382 @see Path::addLineSegment 383 */ 384 void drawLine (float startX, float startY, float endX, float endY, float lineThickness) const; 385 386 /** Draws a line between two points. 387 The line is 1 pixel wide and drawn with the current colour or brush. 388 TIP: If you're trying to draw horizontal or vertical lines, don't use this - 389 it's better to use fillRect() instead unless you really need an angled line. 390 */ 391 void drawLine (Line<float> line) const; 392 393 /** Draws a line between two points with a given thickness. 394 @see Path::addLineSegment 395 TIP: If you're trying to draw horizontal or vertical lines, don't use this - 396 it's better to use fillRect() instead unless you really need an angled line. 397 */ 398 void drawLine (Line<float> line, float lineThickness) const; 399 400 /** Draws a dashed line using a custom set of dash-lengths. 401 402 @param line the line to draw 403 @param dashLengths a series of lengths to specify the on/off lengths - e.g. 404 { 4, 5, 6, 7 } will draw a line of 4 pixels, skip 5 pixels, 405 draw 6 pixels, skip 7 pixels, and then repeat. 406 @param numDashLengths the number of elements in the array (this must be an even number). 407 @param lineThickness the thickness of the line to draw 408 @param dashIndexToStartFrom the index in the dash-length array to use for the first segment 409 @see PathStrokeType::createDashedStroke 410 */ 411 void drawDashedLine (Line<float> line, 412 const float* dashLengths, int numDashLengths, 413 float lineThickness = 1.0f, 414 int dashIndexToStartFrom = 0) const; 415 416 /** Draws a vertical line of pixels at a given x position. 417 418 The x position is an integer, but the top and bottom of the line can be sub-pixel 419 positions, and these will be anti-aliased if necessary. 420 421 The bottom parameter must be greater than or equal to the top parameter. 422 */ 423 void drawVerticalLine (int x, float top, float bottom) const; 424 425 /** Draws a horizontal line of pixels at a given y position. 426 427 The y position is an integer, but the left and right ends of the line can be sub-pixel 428 positions, and these will be anti-aliased if necessary. 429 430 The right parameter must be greater than or equal to the left parameter. 431 */ 432 void drawHorizontalLine (int y, float left, float right) const; 433 434 //============================================================================== 435 /** Fills a path using the currently selected colour or brush. */ 436 void fillPath (const Path& path) const; 437 438 /** Fills a path using the currently selected colour or brush, and adds a transform. */ 439 void fillPath (const Path& path, const AffineTransform& transform) const; 440 441 /** Draws a path's outline using the currently selected colour or brush. */ 442 void strokePath (const Path& path, 443 const PathStrokeType& strokeType, 444 const AffineTransform& transform = {}) const; 445 446 /** Draws a line with an arrowhead at its end. 447 448 @param line the line to draw 449 @param lineThickness the thickness of the line 450 @param arrowheadWidth the width of the arrow head (perpendicular to the line) 451 @param arrowheadLength the length of the arrow head (along the length of the line) 452 */ 453 void drawArrow (Line<float> line, 454 float lineThickness, 455 float arrowheadWidth, 456 float arrowheadLength) const; 457 458 459 //============================================================================== 460 /** Types of rendering quality that can be specified when drawing images. 461 462 @see Graphics::setImageResamplingQuality 463 */ 464 enum ResamplingQuality 465 { 466 lowResamplingQuality = 0, /**< Just uses a nearest-neighbour algorithm for resampling. */ 467 mediumResamplingQuality = 1, /**< Uses bilinear interpolation for upsampling and area-averaging for downsampling. */ 468 highResamplingQuality = 2, /**< Uses bicubic interpolation for upsampling and area-averaging for downsampling. */ 469 }; 470 471 /** Changes the quality that will be used when resampling images. 472 By default a Graphics object will be set to mediumRenderingQuality. 473 @see Graphics::drawImage, Graphics::drawImageTransformed, Graphics::drawImageWithin 474 */ 475 void setImageResamplingQuality (const ResamplingQuality newQuality); 476 477 /** Draws an image. 478 479 This will draw the whole of an image, positioning its top-left corner at the 480 given coordinates, and keeping its size the same. This is the simplest image 481 drawing method - the others give more control over the scaling and clipping 482 of the images. 483 484 Images are composited using the context's current opacity, so if you 485 don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) 486 (or setColour() with an opaque colour) before drawing images. 487 */ 488 void drawImageAt (const Image& imageToDraw, int topLeftX, int topLeftY, 489 bool fillAlphaChannelWithCurrentBrush = false) const; 490 491 /** Draws part of an image, rescaling it to fit in a given target region. 492 493 The specified area of the source image is rescaled and drawn to fill the 494 specified destination rectangle. 495 496 Images are composited using the context's current opacity, so if you 497 don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) 498 (or setColour() with an opaque colour) before drawing images. 499 500 @param imageToDraw the image to overlay 501 @param destX the left of the destination rectangle 502 @param destY the top of the destination rectangle 503 @param destWidth the width of the destination rectangle 504 @param destHeight the height of the destination rectangle 505 @param sourceX the left of the rectangle to copy from the source image 506 @param sourceY the top of the rectangle to copy from the source image 507 @param sourceWidth the width of the rectangle to copy from the source image 508 @param sourceHeight the height of the rectangle to copy from the source image 509 @param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the source image's pixels, 510 the source image's alpha channel is used as a mask with 511 which to fill the destination using the current colour 512 or brush. (If the source is has no alpha channel, then 513 it will just fill the target with a solid rectangle) 514 @see setImageResamplingQuality, drawImageAt, drawImageWithin, fillAlphaMap 515 */ 516 void drawImage (const Image& imageToDraw, 517 int destX, int destY, int destWidth, int destHeight, 518 int sourceX, int sourceY, int sourceWidth, int sourceHeight, 519 bool fillAlphaChannelWithCurrentBrush = false) const; 520 521 /** Draws an image, having applied an affine transform to it. 522 523 This lets you throw the image around in some wacky ways, rotate it, shear, 524 scale it, etc. 525 526 Images are composited using the context's current opacity, so if you 527 don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) 528 (or setColour() with an opaque colour) before drawing images. 529 530 If fillAlphaChannelWithCurrentBrush is set to true, then the image's RGB channels 531 are ignored and it is filled with the current brush, masked by its alpha channel. 532 533 If you want to render only a subsection of an image, use Image::getClippedImage() to 534 create the section that you need. 535 536 @see setImageResamplingQuality, drawImage 537 */ 538 void drawImageTransformed (const Image& imageToDraw, 539 const AffineTransform& transform, 540 bool fillAlphaChannelWithCurrentBrush = false) const; 541 542 /** Draws an image to fit within a designated rectangle. 543 544 @param imageToDraw the source image to draw 545 @param targetArea the target rectangle to fit it into 546 @param placementWithinTarget this specifies how the image should be positioned 547 within the target rectangle - see the RectanglePlacement 548 class for more details about this. 549 @param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the image, just its 550 alpha channel will be used as a mask with which to 551 draw with the current brush or colour. This is 552 similar to fillAlphaMap(), and see also drawImage() 553 @see drawImage, drawImageTransformed, drawImageAt, RectanglePlacement 554 */ 555 void drawImage (const Image& imageToDraw, Rectangle<float> targetArea, 556 RectanglePlacement placementWithinTarget = RectanglePlacement::stretchToFit, 557 bool fillAlphaChannelWithCurrentBrush = false) const; 558 559 /** Draws an image to fit within a designated rectangle. 560 561 If the image is too big or too small for the space, it will be rescaled 562 to fit as nicely as it can do without affecting its aspect ratio. It will 563 then be placed within the target rectangle according to the justification flags 564 specified. 565 566 @param imageToDraw the source image to draw 567 @param destX top-left of the target rectangle to fit it into 568 @param destY top-left of the target rectangle to fit it into 569 @param destWidth size of the target rectangle to fit the image into 570 @param destHeight size of the target rectangle to fit the image into 571 @param placementWithinTarget this specifies how the image should be positioned 572 within the target rectangle - see the RectanglePlacement 573 class for more details about this. 574 @param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the image, just its 575 alpha channel will be used as a mask with which to 576 draw with the current brush or colour. This is 577 similar to fillAlphaMap(), and see also drawImage() 578 @see setImageResamplingQuality, drawImage, drawImageTransformed, drawImageAt, RectanglePlacement 579 */ 580 void drawImageWithin (const Image& imageToDraw, 581 int destX, int destY, int destWidth, int destHeight, 582 RectanglePlacement placementWithinTarget, 583 bool fillAlphaChannelWithCurrentBrush = false) const; 584 585 //============================================================================== 586 /** Returns the position of the bounding box for the current clipping region. 587 @see getClipRegion, clipRegionIntersects 588 */ 589 Rectangle<int> getClipBounds() const; 590 591 /** Checks whether a rectangle overlaps the context's clipping region. 592 593 If this returns false, no part of the given area can be drawn onto, so this 594 method can be used to optimise a component's paint() method, by letting it 595 avoid drawing complex objects that aren't within the region being repainted. 596 */ 597 bool clipRegionIntersects (Rectangle<int> area) const; 598 599 /** Intersects the current clipping region with another region. 600 601 @returns true if the resulting clipping region is non-zero in size 602 @see setOrigin, clipRegionIntersects 603 */ 604 bool reduceClipRegion (int x, int y, int width, int height); 605 606 /** Intersects the current clipping region with another region. 607 608 @returns true if the resulting clipping region is non-zero in size 609 @see setOrigin, clipRegionIntersects 610 */ 611 bool reduceClipRegion (Rectangle<int> area); 612 613 /** Intersects the current clipping region with a rectangle list region. 614 615 @returns true if the resulting clipping region is non-zero in size 616 @see setOrigin, clipRegionIntersects 617 */ 618 bool reduceClipRegion (const RectangleList<int>& clipRegion); 619 620 /** Intersects the current clipping region with a path. 621 622 @returns true if the resulting clipping region is non-zero in size 623 @see reduceClipRegion 624 */ 625 bool reduceClipRegion (const Path& path, const AffineTransform& transform = AffineTransform()); 626 627 /** Intersects the current clipping region with an image's alpha-channel. 628 629 The current clipping path is intersected with the area covered by this image's 630 alpha-channel, after the image has been transformed by the specified matrix. 631 632 @param image the image whose alpha-channel should be used. If the image doesn't 633 have an alpha-channel, it is treated as entirely opaque. 634 @param transform a matrix to apply to the image 635 @returns true if the resulting clipping region is non-zero in size 636 @see reduceClipRegion 637 */ 638 bool reduceClipRegion (const Image& image, const AffineTransform& transform); 639 640 /** Excludes a rectangle to stop it being drawn into. */ 641 void excludeClipRegion (Rectangle<int> rectangleToExclude); 642 643 /** Returns true if no drawing can be done because the clip region is zero. */ 644 bool isClipEmpty() const; 645 646 //============================================================================== 647 /** Saves the current graphics state on an internal stack. 648 To restore the state, use restoreState(). 649 @see ScopedSaveState 650 */ 651 void saveState(); 652 653 /** Restores a graphics state that was previously saved with saveState(). 654 @see ScopedSaveState 655 */ 656 void restoreState(); 657 658 /** Uses RAII to save and restore the state of a graphics context. 659 On construction, this calls Graphics::saveState(), and on destruction it calls 660 Graphics::restoreState() on the Graphics object that you supply. 661 */ 662 class ScopedSaveState 663 { 664 public: 665 ScopedSaveState (Graphics&); 666 ~ScopedSaveState(); 667 668 private: 669 Graphics& context; 670 JUCE_DECLARE_NON_COPYABLE (ScopedSaveState) 671 }; 672 673 //============================================================================== 674 /** Begins rendering to an off-screen bitmap which will later be flattened onto the current 675 context with the given opacity. 676 677 The context uses an internal stack of temporary image layers to do this. When you've 678 finished drawing to the layer, call endTransparencyLayer() to complete the operation and 679 composite the finished layer. Every call to beginTransparencyLayer() MUST be matched 680 by a corresponding call to endTransparencyLayer()! 681 682 This call also saves the current state, and endTransparencyLayer() restores it. 683 */ 684 void beginTransparencyLayer (float layerOpacity); 685 686 /** Completes a drawing operation to a temporary semi-transparent buffer. 687 See beginTransparencyLayer() for more details. 688 */ 689 void endTransparencyLayer(); 690 691 /** Moves the position of the context's origin. 692 693 This changes the position that the context considers to be (0, 0) to 694 the specified position. 695 696 So if you call setOrigin with (100, 100), then the position that was previously 697 referred to as (100, 100) will subsequently be considered to be (0, 0). 698 699 @see reduceClipRegion, addTransform 700 */ 701 void setOrigin (Point<int> newOrigin); 702 703 /** Moves the position of the context's origin. 704 705 This changes the position that the context considers to be (0, 0) to 706 the specified position. 707 708 So if you call setOrigin (100, 100), then the position that was previously 709 referred to as (100, 100) will subsequently be considered to be (0, 0). 710 711 @see reduceClipRegion, addTransform 712 */ 713 void setOrigin (int newOriginX, int newOriginY); 714 715 /** Adds a transformation which will be performed on all the graphics operations that 716 the context subsequently performs. 717 718 After calling this, all the coordinates that are passed into the context will be 719 transformed by this matrix. 720 721 @see setOrigin 722 */ 723 void addTransform (const AffineTransform& transform); 724 725 /** Resets the current colour, brush, and font to default settings. */ 726 void resetToDefaultState(); 727 728 /** Returns true if this context is drawing to a vector-based device, such as a printer. */ 729 bool isVectorDevice() const; 730 731 //============================================================================== 732 /** Create a graphics that draws with a given low-level renderer. 733 This method is intended for use only by people who know what they're doing. 734 Note that the LowLevelGraphicsContext will NOT be deleted by this object. 735 */ 736 Graphics (LowLevelGraphicsContext&) noexcept; 737 738 /** @internal */ getInternalContext()739 LowLevelGraphicsContext& getInternalContext() const noexcept { return context; } 740 741 private: 742 //============================================================================== 743 std::unique_ptr<LowLevelGraphicsContext> contextHolder; 744 LowLevelGraphicsContext& context; 745 746 bool saveStatePending = false; 747 void saveStateIfPending(); 748 749 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Graphics) 750 }; 751 752 } // namespace juce 753