Drawing a VSIS image bitmap on a non-visible area - image

I am trying to create a flipview based windowsRT application where each item of the flipview(a page in my app's terminology) is a VSIS backed image. As per the design of VSIS, whenever any image comes into the visible area, the updatesneeded function of VSIS gets called and draws the bitmap for me.
As an enhancement, I want to cache the image/bitmap of the next page which will be displayed if the user clicks on the next button. To achieve that, I call the invalidate function of the corresponding VSIS in a different thread hoping that this would render the bitmap in background(by a call to UpdatesNeeded) and by the time user clicks the next button, the image would already be ready to be displayed.
But it seems that the invalidate function does not call the updatesneeded callback when the VSIS is not in the visible area and hence my caching design is failing. Is there a way/workaround for the same? I know the dimensions of the page/image beforehand so getting the update rects for vsis is not a problem. Moreover, my updatesneeded function will just return if the bitmap is already rendered taking care that when the image comes in the visible area and updatesneeded is called, VSIS would not need to redraw the whole image again.

I have found the solution. Actually it was wrong on my side to assume that the UpdatesNeeded function would get called even when my image is not in the visible region. So instead, I have implemented my own function PreCacheImage. When called, this function creates an ID2D1Bitmap of the image and stores it. And when the UpdatesNeeded function gets called(when image becomes visible), I check whether my Bitmap is valid, and if it is, I just blit it onto the screen.

Related

Add image over cell such that it should not be edited by other user except owner & assign script to run when user click

In Google sheets, I would like to add an image and make it static such that other users cannot edit or delete the image similar to lock image in Google slides. Is there a way to lock image from editing? Or any workaround?
Note: I am not asking for image in cell.
Edit: I tried to insert image in the cell using =IMAGE("url") and locked the cell. Yes this partly solves my problem. However I need this image to be assigned a script/macro so that when a user clicks on it, it should run a script.
For assigning the script, I tried to solve it by adding a transparent drawing object that overlayed on to the image and assigned the macro script but when i reload the sheet, the transparent object keeps moving. Can I set the drawing object to a standard/default position or lock the drawing object too (idea is that, the user should be able to move any of the object i.e image or the drawing object)
Please let me know your thoughts.

Callback function first time render out to call in three.js?

I want to know when is the first time all the object are rendered? Is there any callback function option?
It seems that there is only a callback function available for image loading.
I want to hide something after all the objects are rendered. Could anyone tell me when my function to do this hiding should be called?
The render works all the time, but I don't know when is the first time all the objects in my scene are rendered.
As the image is ajax loaded,i should have a flag on the loadTexture callback funtion.That may be the key.
THREE.ImageUtils.loadTexture(this.scenedata.urls[i],THREE.UVMapping,function(){
self.isLoaded=true;
})
in the update()
if(this.isLoaded) this.hideLoadingbar()
It works better,just after image loaded and before everything is rendered.
Images sometimes take some time to load, but everything else will be in place when the first animation frame is executed. So in your animation code, just check if this is the first time it is called, and hide your object at that point.

"CoreAnimation: surface is too large"

I'm creating a custom (layer-hosting) document view, which is contained within a scroll view. The root layer has two sub layers of the same size--one for the view's content, and one for anything that needs to hover over the main content. I set the frame to 2500x2500 and added a number of cells to the content layer, which was fine. On adding a translucent clone of one of the cell's layers to the overlay layer, the whole view clears briefly, and I get a log message 'core animation: surface 2502x2502 is too large'. This happens between adding the new layer and the next cycle of the event loop, so I guess when core animation renders the new layer.
I knew that a layer's content size is related to opengl texture size, but didn't think its frame mattered. I'm not drawing anything to these layers, not setting any style properties, and remove offscreen sub layers. All I'm really using them for is to handle the geometry of the document view. Is this an appropriate use of CA layers? If not, are there better ways of handling a large core animation-based document view?
Edit:
I've had this problem again, caused by an implicit animation on adding sublayers to the large parent. So in addition to what is suggested below, that's one to check if you run into this.
I would check to make sure that you're not setting any properties on your 2500x2500 layers which could require offscreen rendering. (This causes the layer to try and create a full-size buffer off-screen and render its contents into that buffer, rather than just rendering the contents to the screen directly.)
For example, setting an opacity, masksToBounds, mask, shouldRasterize, etc, could cause offscreen-rendering. You can see if offscreen-rendering is happening with the Core Animation instrument. (There's a checkbox to highlight offscreen-rendered areas.)

Does Direct2D use back-buffer?

Reading https://learn.microsoft.com/en-us/windows/win32/direct2d/comparing-direct2d-and-gdi :
Presentation Model
When Windows was
first designed, there was insufficient
memory to allow every window to be
stored in its own bitmap. As a result,
GDI always rendered logically directly
to the screen, with various clipping
regions applied to ensure that it did
not render outside of its window. In
contract, Direct2D follows a model
where the application renders to a
back-buffer and the result is
atomically “flipped” when the
application is done drawing. This
allows Direct2D to handle animation
scenarios much more fluidly that GDI
can.
The author says Direct2D uses back-buffer and by 'flipped' he meant swap-chain I guess. I created a simple demo that draw a rectangle at random location on mouse click. But previous rectangles are not cleared so it seems that it is drawn directly to the screen and does not use any back-buffer.
When you initialize the RenderTarget for your Direct2D operations you can specify in the second parameter the D2D1_PRESENT_OPTIONS option.
I think what confuses you is the D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS and the fact that the buffer isn't swapped but copied.
That doesn't disprove the existence of back-buffers, it only means the back-buffer isn't cleared between redraws. Right observation, wrong conclusion!
If you increase the number of back-buffers in the chain, you'll start noticing flickering rectangles as you keep clicking, so you should always clear your back-buffer between redraws.
Direct2D indeed uses back-buffer.
Perhaps you forgot to clear your render target, which is the back-buffer, right after calling begindraw and so previous draws stayed there?

How do I perform my own redraw in the Paint event of a VB6 PictureBox?

A coworker is encountering an error when he tries to run a VB6 app we're working on. The error is, "480: Can't create AutoRedraw image". Microsoft's documentation says this is because "There isn't enough available memory for the AutoRedraw property to be set to True. Set the AutoRedraw property to False and perform your own redraw in the Paint event procedure or make the PictureBox control or Form object smaller..."
Making the PictureBox smaller isn't an option. I'd be glad to "...perform my own redraw in the Paint event procedure...", but I'm not sure how to go about it. Can someone show me the way?
Without details this will be a simplistic answer. In general most beginning VB6 programmers use AutoRedraw=True draw in responds to some input. Fill out some data, click draw, and it appears in the picture box.
The click event in the Draw Button is linked do your drawing code. The first step is move the call to the drawing code to the paint event of the picture. The second step is to replace all calls to the drawing code with MyPictureBox.Refresh. Refresh forces the paint event of that picture box to fire.
The main problem you will have to be concerned with is that the paint event is going to be fired everytime the form needs refreshed. Like if a window covering it is moved. This means that any speed issue in your drawing code will be exposed. AutoRedraw=True takes what you drew and puts in a hidden bitmap that the PictureBox uses to display what you drew.
The Paint event will execute each step of your drawing process so you have to make sure you are as fast as possible. Depending on how dynamic your application is the worse slowdown issues will become. If you are displaying a static image then the problem isn't as bad.
Making the PictureBox smaller isn't an option. I'd be glad to "...perform my own redraw in the Paint event procedure...", but I'm not sure how to go about it. Can someone show me the way?
That is easy. You just implement the _Paint()-Event of your Form or PictureBox and draw.
Because you are asking, i think i should clarify what the AutoRedraw-Propeprty does. If it is set to true, you can "just draw your image" any way you want. In multiple steps. Whatever. If it needs to be redrawn, for example, because another windows was on top it, it will be magically done. The down site is, that is slow, for the drawing part.
If AutoRedraw is false, no magic will happen. The Paint()-Event will be fired and you are responsible to draw your image again. This will be much faster, if your window is not "invalidated" (e.g. "covered") often. Or you are doing a lot of drawing.
Or you are running out of memory for the "magic space" ;-)
If you don't mind rewriting your graphics code to use the GDI API - this could be a fairly big task - I found this thread from 2006 in the VB6 discussion group, where Mike Sutton said in answer to a similar problem:
VB's back-buffer implementation uses a
Device Dependant Bitmap (DDB) to store
the image data, which is quite limited
in how large it can be made. On older
OS' this used to be ~16mb uncompressed
data size, on later OS this has been
expanded but is still quite
restrictive.
A workaround for this is to use a
Device Independent Bitmap (DIB) and
manage the GDI resources yourself,
have a look at the DIB article on my
site for an example of how to work
with them.
I haven't tried it myself.
There's usually a drop-down box of events for your control in the forms code window. You need to pick the paint event:
Private Sub object_Paint()
and fill in your your code for drawing on the PictureBox.

Resources