TASImage, DrawRectangle and refreshing

First I need to mention I use AstroImage which is inherited from TASImage, but it seems that it is TASImage problem in general. Root 5.18

In procedure handling kButton1Motion for my main GUI window, I have:

disp[0]->SetEditable(kFALSE); disp[0]->DrawRectangle(x_cur, y_cur, x_cur+1, y_cur+1, "#FFFFFF", 10); disp[0]->UnZoom(); gPad->Modified(kTRUE); gPad->Update(); disp[0]->SetEditable(kTRUE);

disp[0] is TASImage. The important part is “UnZoom()”. Whithout it, rectangles do not appear until I resize the window.

Either I’m doing something wrong, or there is some kind of bug here. Using UnZoom() for refresh is not a nice thing, I guess for obvious reasons :slight_smile:

I discovered it when I saw that DrawBox appears immediately when it is filled, and after resize when it’s not filled - the difference is “DrawFilled()”, which calls procedure which calls UnZoom.

It would be nice if you could provide some self contained running example showing the problem.

OK, following must be executed in root command line:

TASImage *a = new TASImage("subtracted.png"); a->Draw(); a->DrawRectangle(300, 300, 300+10, 300+10, "#FFFFFF", 10); gPad->Modified(); gPad->Update();

where “subtracted.png” must be replaced by any image larger than 300x300 you have. In above, nothing is drawn on top of image, until you resize window.

If you add a->UnZoom() before gPad->Modified(), rectangle is draw.

You are right. Note that it also works if you do:

TASImage *a = new TASImage("xyscan.gif");   
a->DrawRectangle(300, 300, 300+10, 300+10, "#FFFF00", 10); 
a->Draw(); 

I will have a look.

also if you use a interpreted macro it works:

{
        TASImage *a = new TASImage("xyscan.gif");
        a->Draw();
        a->DrawRectangle(300, 300, 300+10, 300+10, "#FFFF00", 10);
}

Yes, interpreted macro works, but it does not work in my compiled version…

and what about if you do the Draw of the Image after the rectangle drawing ?

Depends. I’ve checked, that if I do

TASImage *a = new.... a->Draw(); a->DrawRectangle(...; a->Draw();

it does not work in intepreted and compiled version. If I do not draw image before drawing rectangle, it works in intepreted - not sure about compiled, for I would have to do a little bit more to check it, but I guess it works…

Yes i guess that building the picture completely and Draw it when it is ready should work (only one Draw at the end after the rectangle Drawing).

I see. However in my case I need to have picture drawn before adding primitives to it, so I think even some kind of deleting picture and redrawing would be a very unefficient workaround.

I will try to understand the problem. Right now I have no answer. Does the UnZoom trick works also in the compiled code ?

Yes, I first checked it in my compiled application.

UnZoom seems to be a solution. But I’m afraid it won’t do any good if I will draw something on zoomed picture :slight_smile:

Found something else. It works if you do:

TASImage *a = new TASImage("xyscan.gif");
a->Draw("X");
a->DrawRectangle(300, 300, 300+10, 300+10, "#FFFF00", 10);
gPad->Modified();

No, it does not work, neither in compiled nor in intepreted version… Maybe it’s my version of root (5.18). And also, this draw options somehow removes image palette.

I am experimenting a solution right now. But needs some testing because it might have side effects.
And be ready to change version otherwise it is not worth it !!

I’m ready, ofcourse :slight_smile:

I thought a bit more about the solution I tried to implement. Basically the idea was to rebuild the image (in TASImage::Paint(Option_t *option) ) each time the a new primitive has been created. But doing that implies to run the following part of TASImage::Paint much much more !

            delete fScaledImage;
            fScaledImage = 0;

That might have some performance impact and I guess that the reason why the author of this code did not do it. I think the right approach is to first create the picture then draw all the primitives in it and then Draw the picture at the end when finished.

True, it affects performance a lot, but there are 2 issues:

  1. If you are drawing filled rectangle, like box, it automatically calls UnZoom() and refreshes each time you draw. So here is some kind of inconsequence…

  2. It could be done in some efficient way, for… it is done that way, when for example, a rectangle showing how much of the TASImage will be zoomed is drawn. When you drag the mouse, the rectangle is smoothly drawn changing size, without using lots of CPU. Although I am not sure how it is done.

Yes right Fill rectangle does it… ok so i can add it in DrawRectangle and that will be it ?

If you don’t think that what’s FillRectangle is doing is a bug, I think not-filled prmitive should behave the same way… But I am just a ROOT user :slight_smile: