iwbnwif - 2013-10-29

I have been playing with creating soft shadows under shapes and got some reasonably good results. The following code can go into an overload for wxSFRectShape::DrawShadow(wxDC& dc)

~~~~~~~~~~~~~~~~~~~~~~

// get the shadow offset
double offset = GetParentCanvas()->GetShadowOffset().x;
wxSize bmpSize = Conv2Size(m_nRectSize);
bmpSize.IncBy(offset); // the maximum size 'allowed' for a shape and its shadow

ifdef NON_GC

// draw the shadow on a bitmap in memory via a memory DC
wxBitmap drawBmp(bmpSize);
wxMemoryDC drawDc(drawBmp);
drawDc.Clear();
drawDc.SetBrush(GetParentCanvas()->GetShadowFill());
drawDc.SetPen(*wxTRANSPARENT_PEN);
drawDc.DrawRectangle(offset / 4.0, offset / 4.0, bmpSize.x - offset, bmpSize.y - offset);
// convert the bitmap to an image
wxImage blurImage = drawBmp.ConvertToImage();
// blur and write to a second bitmap
wxBitmap outBmp (blurImage.Blur(offset / 2.0));

else

wxImage image(bmpSize);
image.InitAlpha();

unsigned char alpha=image.GetAlpha();
memset(alpha, wxIMAGE_ALPHA_TRANSPARENT, image.GetWidth()
image.GetHeight());

wxGraphicsContext gc=wxGraphicsContext::Create(image);
gc->SetBrush(GetParentCanvas()->GetShadowFill());
gc->SetPen(
wxTRANSPARENT_PEN );
gc->DrawRectangle(offset / 4.0, offset / 4.0, bmpSize.x - offset, bmpSize.y - offset);
delete gc;
wxBitmap outBmp (image.Blur(offset / 2.0));

endif

dc.DrawBitmap(outBmp, Conv2Point(GetAbsolutePosition()));

~~~~~~~~~~~~~~~~~~~~~~~~~~~

The GC version includes transparency, but of course the non-gc version can't do that.

Performance is not too bad as the wxImage::Blur method uses a simple box blur algorithm.

An improvement I would like to make is to cache the shadow bitmap and only re-generate it if the shape changes size / aspect.

One area where performance does get hit is zooming a drawing using the mouse wheel with a large number of shapes. Redrawing all the shadows does slow things, and I ponder changing the way wxSF performs mouse wheel zooms to be more like Google or Office 2013. i.e. grab the image as a bitmap and zoom the bitmap (temporarily sacrificing resolution for speed). When the user releases the CTRL key, do a proper draw.

 

Last edit: iwbnwif 2013-10-29