getUnclippedArea


#1

Hi Jules, any particular reason the Component::getUnclippedArea is private? I’d like to get hold of it to minimize time in paint…


#2

You should use getVisibleArea() for that. The private one is just used internally for stuff.


#3

…BTW that’s definitely not a good way to optimise your painting - use Graphics::getClipBounds() to find the area that’s being drawn.


#4

Thanks Jules, that is really what I wanted.


#5

While on topic, how’d you suggest handling a component that is being scrolled so that every now & then a bit more of it is shown. A fully optimised drawing would draw only that part. But getClipBounds returns the whole area that is visible, not just that little piece ?


#6

It’s actually quite a fiddly problem, because you’d need to keep a buffered image of the content, so you can quickly draw the bits that haven’t changed, and then render and add the new bits. (Unless the content is really slow to draw, this often wouldn’t really be much faster, though)


#7

Mmm… that’s about what I had in mind. I noticed though that in release build, the repaint time is quite tolerable, so I’ll skip it for now.


#8

Strange, I did a get-uncovered-area-thingy that correctly returns the invalidated area so I can render only there, and it works nicely in debug mode, but in release mode once in a while the whole invalidated area is not drawn, just part of it. But only in release mode… :?


#9

Got any code to reproduce it?


#10

Yup, something like this:

[code]//==============================================================================
void MyComponent::paint (Graphics& g)
{
Rectangle clipBounds = g.getClipBounds();
if (!clipBounds.isEmpty())
{
Rectangle toDrawInto = getUncoveredArea(clipBounds);
if (!toDrawInto.isEmpty() || (m_cachedImage.get() == 0))
{
if (m_cachedImage.get() == 0)
{
m_cachedImage.reset(new Image(Image::ARGB, getWidth(), getHeight(), true));
// New image, draw everything within clipping area.
toDrawInto = clipBounds;
}
else
{
m_cachedImage->clear(toDrawInto.getX(), toDrawInto.getY(), toDrawInto.getWidth(), toDrawInto.getHeight());
}
Graphics memG(*m_cachedImage.get());
// Here comes the drawing stuff which will draw from
// toDrawInto.getX() to toDrawInto.getRight()
[…snip…]
}

    if (m_waveImage.get() != 0)
    {
        g.drawImage(m_waveImage.get(), clipBounds.getX(), clipBounds.getY(), clipBounds.getWidth(), clipBounds.getHeight(), 

clipBounds.getX(), clipBounds.getY(), clipBounds.getWidth(), clipBounds.getHeight());
}

}

}

void MyComponent::resized()
{
// Clear cached image so entire clipping area will be redrawn…
m_cachedImage.reset( 0 );
}

[/code]
And it does work nicely in debug mode… (the .get() and .reset(…) on m_cachedImage has to do with it being a std::auto_ptr )


#11

Ehrm… it was a bug in my impl of getUncoveredArea. Now I only return the uncovered area if the last clip bounds are of the same size as the new clip bounds, otherwise I return the clip bounds. Now it works in release to. Yay! :slight_smile:

Ps. It occasionally didn’t work in debug either…


#12