move ToolboxButtonColorUpdater bitmap update to VirtualDevice
to avoid doing a read-modify-write cycle on the item images on the
toolbar, add an overlay image member to Toolbox items.
part of the process of making Bitmap an internal detail of vcl/
Change-Id: Ie4a886c48484a06694fc4c066ee0845b39d27f0b
Reviewed-on: https://gerrit.libreoffice.org/49649
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/include/vcl/toolbox.hxx b/include/vcl/toolbox.hxx
index eeab33c..700da27 100644
--- a/include/vcl/toolbox.hxx
+++ b/include/vcl/toolbox.hxx
@@ -373,6 +373,7 @@ public:
void SetItemData( sal_uInt16 nItemId, void* pNewData );
void* GetItemData( sal_uInt16 nItemId ) const;
void SetItemImage( sal_uInt16 nItemId, const Image& rImage );
void SetItemOverlayImage( sal_uInt16 nItemId, const Image& rImage );
Image GetItemImage( sal_uInt16 nItemId ) const;
void SetItemImageAngle( sal_uInt16 nItemId, long nAngle10 );
void SetItemImageMirrorMode( sal_uInt16 nItemId, bool bMirror );
diff --git a/svx/source/tbxctrls/tbxcolorupdate.cxx b/svx/source/tbxctrls/tbxcolorupdate.cxx
index 9748340..4b80480 100644
--- a/svx/source/tbxctrls/tbxcolorupdate.cxx
+++ b/svx/source/tbxctrls/tbxcolorupdate.cxx
@@ -23,7 +23,7 @@
#include <svx/xdef.hxx>
#include <vcl/toolbox.hxx>
#include <vcl/bitmapaccess.hxx>
#include <vcl/virdev.hxx>
#include <vcl/settings.hxx>
#include <tools/debug.hxx>
@@ -82,54 +82,21 @@ namespace svx
if ((maCurColor == aColor) && !bSizeChanged && !bDisplayModeChanged && !bForceUpdate)
return;
// create an empty bitmap, and copy the original bitmap inside
// (so that it grows in case the original bitmap was smaller)
sal_uInt8 nAlpha = 255;
BitmapEx aBmpEx(Bitmap(aItemSize, 24), AlphaMask(aItemSize, &nAlpha));
BitmapEx aSource(aImage.GetBitmapEx());
long nWidth = std::min(aItemSize.Width(), aSource.GetSizePixel().Width());
long nHeight = std::min(aItemSize.Height(), aSource.GetSizePixel().Height());
tools::Rectangle aRect(Point(0, 0), Size(nWidth, nHeight));
aBmpEx.CopyPixel( aRect, aRect, &aSource );
Bitmap aBmp( aBmpEx.GetBitmap() );
BitmapWriteAccess* pBmpAcc = aBmp.IsEmpty() ? nullptr : aBmp.AcquireWriteAccess();
maBmpSize = aBmp.GetSizePixel();
if (!pBmpAcc)
if (!aItemSize.Width() || !aItemSize.Height())
return;
Bitmap aMsk;
BitmapWriteAccess* pMskAcc;
if (aBmpEx.IsAlpha())
{
aMsk = aBmpEx.GetAlpha().GetBitmap();
pMskAcc = aMsk.AcquireWriteAccess();
}
else if (aBmpEx.IsTransparent())
{
aMsk = aBmpEx.GetMask();
pMskAcc = aMsk.AcquireWriteAccess();
}
else
{
pMskAcc = nullptr;
}
ScopedVclPtr<VirtualDevice> pVirDev(VclPtr<VirtualDevice>::Create());
pVirDev->SetOutputSizePixel(aItemSize);
maBmpSize = aItemSize;
mbWasHiContrastMode = mpTbx->GetSettings().GetStyleSettings().GetHighContrastMode();
if ((COL_TRANSPARENT != aColor.GetColor()) && (maBmpSize.Width() == maBmpSize.Height()))
pBmpAcc->SetLineColor(aColor);
pVirDev->SetLineColor(aColor);
else if( mpTbx->GetBackground().GetColor().IsDark() )
pBmpAcc->SetLineColor(Color(COL_WHITE));
pVirDev->SetLineColor(Color(COL_WHITE));
else
pBmpAcc->SetLineColor(Color(COL_BLACK));
pVirDev->SetLineColor(Color(COL_BLACK));
// use not only COL_TRANSPARENT for detection of transparence,
// but the method/way which is designed to do that
@@ -138,11 +105,11 @@ namespace svx
if (bIsTransparent)
{
pBmpAcc->SetFillColor();
pVirDev->SetFillColor(Color(255, 0, 0, 0));
}
else
{
pBmpAcc->SetFillColor(maCurColor);
pVirDev->SetFillColor(maCurColor);
}
if (maBmpSize.Width() == maBmpSize.Height())
@@ -151,34 +118,9 @@ namespace svx
else
maUpdRect = tools::Rectangle(Point( maBmpSize.Height() + 2, 2), Point(maBmpSize.Width() - 3, maBmpSize.Height() - 3));
pBmpAcc->DrawRect(maUpdRect);
pVirDev->DrawRect(maUpdRect);
if (pMskAcc)
{
if (bIsTransparent)
{
pMskAcc->SetLineColor(COL_BLACK);
pMskAcc->SetFillColor(COL_WHITE);
}
else
pMskAcc->SetFillColor(COL_BLACK);
pMskAcc->DrawRect(maUpdRect);
}
Bitmap::ReleaseAccess(pBmpAcc);
if (pMskAcc)
Bitmap::ReleaseAccess(pMskAcc);
if (aBmpEx.IsAlpha())
aBmpEx = BitmapEx(aBmp, AlphaMask(aMsk));
else if (aBmpEx.IsTransparent())
aBmpEx = BitmapEx(aBmp, aMsk);
else
aBmpEx = aBmp;
mpTbx->SetItemImage(mnBtnId, Image(aBmpEx));
mpTbx->SetItemOverlayImage(mnBtnId, Image(pVirDev->GetBitmapEx(Point(0,0), aItemSize)));
}
}
diff --git a/vcl/inc/toolbox.h b/vcl/inc/toolbox.h
index f908cc5b..9d928ce 100644
--- a/vcl/inc/toolbox.h
+++ b/vcl/inc/toolbox.h
@@ -37,6 +37,7 @@ struct ImplToolItem
VclPtr<vcl::Window> mpWindow; //don't dispose mpWindow - we get copied around
void* mpUserData;
Image maImage;
Image maOverlayImage;
long mnImageAngle;
bool mbMirrorMode;
OUString maText;
diff --git a/vcl/source/window/toolbox.cxx b/vcl/source/window/toolbox.cxx
index a2b1400..e803124 100644
--- a/vcl/source/window/toolbox.cxx
+++ b/vcl/source/window/toolbox.cxx
@@ -2793,6 +2793,7 @@ void ToolBox::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplToolItems::si
if ( bImage )
{
const Image* pImage = &(pItem->maImage);
const Image& rOverlayImage = pItem->maOverlayImage;
aImageSize = pImage->GetSizePixel();
// determine drawing flags
@@ -2837,6 +2838,8 @@ void ToolBox::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplToolItems::si
}
}
rRenderContext.DrawImage(Point( nImageOffX, nImageOffY ), *pImage, nImageStyle);
if (!!rOverlayImage)
rRenderContext.DrawImage(Point( nImageOffX, nImageOffY ), rOverlayImage, nImageStyle);
}
// draw the text
diff --git a/vcl/source/window/toolbox2.cxx b/vcl/source/window/toolbox2.cxx
index 23d5971..6cdd0ed 100644
--- a/vcl/source/window/toolbox2.cxx
+++ b/vcl/source/window/toolbox2.cxx
@@ -965,6 +965,28 @@ void ToolBox::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
}
}
void ToolBox::SetItemOverlayImage( sal_uInt16 nItemId, const Image& rImage )
{
ImplToolItems::size_type nPos = GetItemPos( nItemId );
if ( nPos != ITEM_NOTFOUND )
{
ImplToolItem* pItem = &mpData->m_aItems[nPos];
Size aOldSize = pItem->maOverlayImage.GetSizePixel();
pItem->maOverlayImage = rImage;
// only once all is calculated, do extra work
if (!mbCalc)
{
if (aOldSize != pItem->maOverlayImage.GetSizePixel())
ImplInvalidate( true );
else
ImplUpdateItem( nPos );
}
}
}
static Image ImplRotImage( const Image& rImage, long nAngle10 )
{
BitmapEx aRotBitmapEx( rImage.GetBitmapEx() );