Paint Event - Areas()

Is this fully documented anywhere?
Who controls it? the developer? the event manager?

I have a paint event the is basically g.drawpicture pic,0,0 … not seeing how this could be leveraged?

The example is the LR is not real clear on what is going on.

From the Language Reference…

When you call Invalidate (specifying the rect to invalidate), the areas parameter gets the coordindates for the rectangles that need redrawing. You can then choose to redraw just those parts of the Graphics or you can continue to redraw everything as you have done in the past. You may also get areas that do not come directly from Invalidate calls as the operating system is ultimately in control of drawing.

NOTE: The areas parameter is not used for Carbon applications.

Areas is a list of the regions that were invalidated if you happened to use “invalidaterect”.
If you have you can use it to optimize your drawing by only redrawing those areas instead of the whole rectangle.

If you paint event is just drawing a buffer image, then it probably doesn’t apply.

If you’re like me and haven’t needed them (yet), then keep the compiler from complaining with:

#pragma unused areas

Ok… but I thought the contents of a canvas were non-persistent… and the Paint Event was used to keep it visually intact (or updated as the case may be)…

What I am trying to do is speed up the updating of a drawing program… All images are buffered in an array to allow Undo/Redo operations… and the Paint Event simply uses DrawPicture and uses the top of the buffer stack (with the size altered to fit the current “zoom” level).
But when the user actually “draws” they only cover a small portion (like when using a pencil) between when the image needs to be updated.

So if I had say a 1000x600 image… .and in MouseMove I detected they moved from 100,100 to 150,150 (for example), and called canvas1.invalidate(100,100,50,50) instead of just canvas1.invalidate then I could check AREA() for a UBOUND>=0 and reduce my DRAWPICTURE to only that piece?

If that is how it works, how would AREAS ever have more than one entry?

Basically for large images I want to reduce the DRAWPICTURE time if possible

My guess without testing is if the OS calls Invalidate for you. For example, your window is in the background with two windows covering opposing corners. When the window activates, you’d have two Areas to redraw.

I guess.

The code editor makes use of this.
It is a canvas but we invalidate only the “rows of text” that actually need updating and so avoid drawing any text in areas that do not need to be updated.
It’s not trivial but it makes a big difference.
And, if you just use “Invalidate” in the canvas (or refresh) you won’t get more than 1 rectangle - which is the whole area.
If however you can use InvalidateRect, which we do in the code editor, then you get a list of the areas that need redrawing.

The OS can, as Kem alludes to, also cause rects to be added to the areas list.

Is it fair to say that Refresh/RefreshRect causes something to happen immediately whereas Invalidate/InvalidateRect adds an event to the queue that will be handled during the normal event cycle? Because that was my understanding, but I don’t recall what I based that on.

Yes, which is why Refresh/RefreshRect shouldn’t be used.

So if I have a tight loop that calls InvalidateRect with overlapping rectangles, will the system minimize that?

For example, let’s say my Canvas has a “row” that has 2 cells. The first InvalidateRect is with the dimensions that cover the first cell, and the second covers both cells. Will Areas have both rects, or just one rect for both cells?

To add to Kems question… if there are two rect and they are inside one another (ie a 10x10 inside a 20x20) does it toss out the small one since the bigger covers both?

[quote=75832:@Dave S]If that is how it works, how would AREAS ever have more than one entry?

[/quote]

If, for example the MouseMoved events firing in rapid succession were happening faster than the OS could repaint the areas, it would buffer the invalid areas and send them all to be repainted at once at the next opportunity rather than one at a time.

I just tested and it turns out to be even smarter than that. If there is overlap, it will figure out the rectangles that need updating and send those.

For example, if you call Invalidate with 0, 0, 5, 5 and then with 1, 1, 7, 7, it will send the Paint event three rectangles.

1, 5, 7, 3
0, 1, 8, 4
0, 0, 5, 1

[quote=75842:@Kem Tekinay]So if I have a tight loop that calls InvalidateRect with overlapping rectangles, will the system minimize that?

For example, let’s say my Canvas has a “row” that has 2 cells. The first InvalidateRect is with the dimensions that cover the first cell, and the second covers both cells. Will Areas have both rects, or just one rect for both cells?[/quote]

The system will coalesce rects in whatever way it feels is best. If you’re invalidating most of the canvas, it might just have the canvas update itself entirely. That said, I don’t think there will ever be overlapping rectangles in the array.

I was just looking at Cocoa’s getRectsBeingDrawn:count: method… it does give a smart list of rectangles.
I wonder if that’s true for other platforms or just cocoa? Carbon doesn’t use the areas() at all though…

[quote=75855:@jim mckay]I was just looking at Cocoa’s getRectsBeingDrawn:count: method… it does give a smart list of rectangles.
I wonder if that’s true for other platforms or just cocoa? Carbon doesn’t use the areas() at all though…[/quote]

All platforms except for Carbon use something similar to Cocoa’s getRectsBeingDrawn:count: method (and by Carbon I mean our Carbon framework, not anything relating to HIToolbox itself).

Good to know! Perhaps the docs should be clearer about this…

What would you like to be clearer? To me it’s fairly clear from the documentation that the areas you get back correspond to, but may not be exactly, what you send for invalidation.

I was referring to the fact that the rectangles passed would be individual non-overlapping areas that comprise the invalid area, rather than a list of areas that have been invalidated or unions of areas that overlap.