[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

[XaraXtreme-dev] OSRenderRegion::DrawTransformedBitmap

I'm trying to fix up the above so the bitmap gallery (inter-alia) works.

What it does is plots a KernelBitmap to the screen, having scaled it. You
would have thought this would be simple, but no it's not.

Firstly, internally we appear to store our bitmaps (inside an OilBitmap) in
a format which is neither a wxImage or a wxBitmap (fair enough as neither
of those classes are sufficiently flexible). So if I am taking the "use the
OS" route, I need to convert it to a wxImage in order to do any processing
on it at all. Cue a conversion to 32bpp and a large amount of memory use.
Also, cue stepping through the image pixel by pixel, which doesn't seem fun.
Next I need to resize it to the correct size as wx seems to have no concept
of StretchBlit (or more accurately its blit code just calls the resize code
anyway). Well, at least that frees up most of the memory as these are just
thumbnails. Next, I need to convert it to a wxBitmap, which will downsample
the colour if necessary as I understand it. And lastly, I need to plot it
in the right place.

All this sounds a horribly memory-consumptive activity. Let's say I have
a 1bpp bitmap which is an A4 scan at 300dpi. That's a quite reasonable
1Mb if my calculations are correct. Just plotting the bitmap is going to
cause 32Mb to be allocated, filled, and removed, every time the bitmap
is redrawn in the gallery (or better yet, every time a rectangle
intersecting the bitmap is redrawn!). At 600dpi, that would be a 128Mb
memory allocation. And I hear the rescale call is pretty useless too
(lack of antialiasing).

I can't convert the whole thing over to use GRenderRegion as the system
text plotting stuff doesn't work there.

So I am left with the following cunning plan, which is sufficiently
disgusting I'd like a second opinion on it!

* Inside OSRenderRegion::DrawTransformedBitmap, create a new
 GRenderRegion, which lasts only for the life of the call.

* The new GRenderRegion will either render directly to the OSRenderRegion's
 DC (or rather a copy of it), which I think will work, or if that
 fails I'm left with GRenderBitmap (or whatever the equivalent call
 is called) and converting the (scaled) bitmap to a wxImage/wxBitmap or
 possibly some new subclass of GRenderRegion which produces a
 wxImage/wxBitmap directly.

* All the GRenderRegion's short life consists of is one call to
 GRenderRegion::DrawTransformedBitmap, which will do the job properly
 using GDraw (I hope).

Is this feasible? Is it disgusting? Should I be avoiding using GRenderRegion
(or gdraw as a whole) from OSRenderRegion? Would we do better writing a
fast call to generate an arbitrary size wxImage (say) from a KernelBitmap?
Do we indeed already have a similar call to this?