What happened to Graphics::getClipRegion()


#1

I want to do some drawing optimation using the following pattern:

class MyComponent : public Component
{
public:
	/*
    ...
	*/

	Rectangle clipA, clipB; // WITH EMPTY INTERSECTION

	void repaintAandB() 
	{
		repaint(clipA.getX(), clipA.getY(), clipA.getWidth(), clipA.getHeight());
		repaint(clipB.getX(), clipB.getY(), clipB.getWidth(), clipB.getHeight());
	}

	bool needsFullPaint(Graphics& g, bool doQuick = true)
	{
		const RectangleList rl(g.getClipRegion()); // !!!!!!!! ERROR !!!!!!!!

		// => 'getClipRegion' : is not a member of 'juce::Graphics'

		if (doQuick)
		{
			RectangleList::Iterator it(rl);

			while (it.next())
			{
				const Rectangle *rect = it.getRectangle();
				if (*rect != clipA && *rect != clipB)
					return true;
			}
			return false;
		}
		else
		{
			RectangleList rlc = rl;

			rlc.subtract(clipA);
			rlc.subtract(clipB);

			return !rlc.isEmpty();
		}
	}

	void paint (Graphics& g)
	{
		if (needsFullPaint(g))
		{
			// ...
		}
		// ...
	}
};

The method getClipRegion has been mentioned several times before in this forum, but it doesn’t exist anymore in the current juce version (Allthough it still is mentioned in the documentation at Graphics::getClipBounds). getClipBounds is not usable for this purpose as it gives the enclosing Rectangle. To use clipRegionIntersects would be quite cumbersome and reduceClipRegion would change the clipping region. I think this is a very common task, am I missing something?

Thanx for any help.
Jan


#2

I found a solution, but it’s not very efficient. Internally, the state is saved twice (excludeClipRegion calls saveStateIfPending for some reason :?:). The enlargement of the Rectangles are necessary, allthough there are only integers involved :?:.

Greetings
Jan

bool MyComponent::needsFullPaint(Graphics& g)
{

    g.saveState();
    g.excludeClipRegion(clipA.getX()      - 1,
                        clipA.getY()      - 1,
                        clipA.getWidth()  + 2,
                        clipA.getHeight() + 2);

    g.excludeClipRegion(clipB.getX()      - 1,
                        clipB.getY()      - 1,
                        clipB.getWidth()  + 2,
                        clipB.getHeight() + 2);

    bool empty = g.isClipEmpty();
    g.restoreState();

    return !empty;
}

#3

I took it away because not all platforms can provide that information - e.g. it might actually be clipped to a path rather than a set of rectangles.

Not sure quite why you’re trying to do what you’re doing there, but it looks very odd, and I’d be surprised if there’s not a better way of approaching it. E.g. if some these two rectangles of your interface are slow to draw, you should turn them into components - that’d handle all this logic for you.


#4

Thanx for the answer, jules

Those rectangles are very quick to draw, just two red lines for indicating level and position, but they are updated all 30 ms. The rest of the component is slow to draw, but only needs to be redrawn occasionally. I didn’t want to make a component just for a red line.

Jan


#5

It might seem like a pain to create a component for stuff like that, but often it’s actually a far easier (and faster) solution.