Rendering a Widget to a bitmap | developer.brewmp.com Rendering a Widget to a bitmap | developer.brewmp.com

Developer

Rendering a Widget to a bitmap

Hi,

I am new to BREW and to the widget UI specifically.

Here's the situtaion:
I have a DrawDecoratorWidget.
In its DrawHandler, I want to render the child widget to a bitmap, or a DIB.
I can't get this to work, and I am not even sure I am going the right way.

Here's what I did in init (error handling omitted):

ISHELL_CreateInstance( me->piShell, AEECLSID_DISPLAYCANVAS, &me->piCanvas);
ISHELL_CreateInstance(me->piShell, AEECLSID_DISPLAYCLONE, me->piDisplay);
IDISPLAYCANVAS_SetDisplay((IDisplayCanvas*)me->piCanvas, piDisplay );
IDISPLAY_CreateDIBitmap(piDisplay, &me->piDIB, 16, width, height);
ICANVAS_SetBitmap(me->piCanvas, IDIB_TO_IBITMAP(me->piDIB));
ICANVAS_SetClipRect( me->piCanvas, &rClipRect );

And during draw handler:

void DrawHandler(void *pCxt, ICanvas *piCanvas, int x, int y)
{
...code to init contents of me->piDIB to something obvious...

DRAWHANDLERDESC_Call(&me->dhDesc, me->piCanvas, 0, 0); // note that me->piCanvas is the offscreen canvas I made in init

...some codethat moves the contents of me->piDIB to destination piCanvas...

}

For some reason, the widget does not draw on me->piCanvas. The contents remain as they were after initialization in beginning of DrawHandler.

I know for sure that the code that moves me->piDIB to destination piCanvas works (since I draw on it using my own bitmap operations).

What am I doing wrong?

I don't think you need to create a new canvas. In your draw handler, get the bitmap from the canvas that is passed in and save it away, then set the canvas' bitmap with the new bitmap. Then do your drawing, and restore the correct bitmap at the end of the draw handler.
-Erik

I don't think you need to create a new canvas. In your draw handler, get the bitmap from the canvas that is passed in and save it away, then set the canvas' bitmap with the new bitmap. Then do your drawing, and restore the correct bitmap at the end of the draw handler.
-Erik

That's an interesting idea, but I am worried that by switching bitmaps, I would somehow unknowingly mess up some canvas (or the underlying display) property. My solution would then mysteriously fail when I get a canvas with that property.
However, I'll try it anyway, just to see if it works.
Another thing that I found that works is using a device bitmap instead of a DIB. I repaced the "IDISPLAY_CreateDIBitmap(piDisplay, &me->piDIB, 16, width, height);" line with the following code:
IDISPLAY_GetDeviceBitmap( piDisplay, &piBitmap1 );
IBITMAP_CreateCompatibleBitmap( piBitmap1, &piBitmap2, width, height );
IBITMAP_QueryInterface( piBitmap2, AEECLSID_DIB, &me->piDIB );
This works, only now I am depending on the pixel depth of the device bitmap, but I need it to be 16.
Any other ideas? Do I need to set some magical property in the bitmap/canvas/display?

That's an interesting idea, but I am worried that by switching bitmaps, I would somehow unknowingly mess up some canvas (or the underlying display) property. My solution would then mysteriously fail when I get a canvas with that property.
However, I'll try it anyway, just to see if it works.
Another thing that I found that works is using a device bitmap instead of a DIB. I repaced the "IDISPLAY_CreateDIBitmap(piDisplay, &me->piDIB, 16, width, height);" line with the following code:
IDISPLAY_GetDeviceBitmap( piDisplay, &piBitmap1 );
IBITMAP_CreateCompatibleBitmap( piBitmap1, &piBitmap2, width, height );
IBITMAP_QueryInterface( piBitmap2, AEECLSID_DIB, &me->piDIB );
This works, only now I am depending on the pixel depth of the device bitmap, but I need it to be 16.
Any other ideas? Do I need to set some magical property in the bitmap/canvas/display?