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