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));
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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