summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2018-11-26 14:08:13 +0000
committerAndras Timar <andras.timar@collabora.com>2018-12-06 10:51:04 +0100
commit244df39479a161ce6865cc3dde7629af15d5fa8f (patch)
tree77e3e3efcb86bd9138458237fec97a31d360b77d /vcl
parent1a3e67dc574c8e7053a693d47921233c08f9ecb2 (diff)
Preserve stock images until render time.
This allows us to choose to render HiDPI images at the right time, when we have the DPI of the device to render to. The first step in a better, and more industry standard way of improving our UI for HiDPI via rendering level scaling that should retain a consistent look across the app with many fewer changes. Change-Id: I36681f3242cb650de4f0b2d0fcdffbe5618e30fc (cherry picked from commit e42c6d6903ab804235671d51ae3a05d1627e2574)
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/image.h19
-rw-r--r--vcl/source/control/fixed.cxx3
-rw-r--r--vcl/source/image/Image.cxx113
-rw-r--r--vcl/source/image/ImplImage.cxx64
-rw-r--r--vcl/source/window/builder.cxx4
-rw-r--r--vcl/source/window/msgbox.cxx11
6 files changed, 141 insertions, 73 deletions
diff --git a/vcl/inc/image.h b/vcl/inc/image.h
index 873fc98432dd..c9fb5393191a 100644
--- a/vcl/inc/image.h
+++ b/vcl/inc/image.h
@@ -28,10 +28,29 @@
struct ImplImage
{
BitmapChecksum maBitmapChecksum;
+ /// if non-empty: cached original size of maStockName else Size of maBitmap
+ Size maSizePixel;
+ /// If set - defines the bitmap via images.zip*
+ OUString maStockName;
+
+ /// Original bitmap - or cache of a potentially scaled bitmap
BitmapEx maBitmapEx;
BitmapEx maDisabledBitmapEx;
ImplImage(const BitmapEx& rBitmapEx);
+ ImplImage(const OUString &aStockName);
+
+ bool isStock() const { return maStockName.getLength() > 0; }
+
+ /// get size in co-ordinates not scaled for HiDPI
+ Size getSizePixel();
+ /// Legacy - the original bitmap
+ BitmapEx getBitmapEx(bool bDisabled = false);
+ /// Taking account of HiDPI scaling
+ BitmapEx getBitmapExForHiDPI(bool bDisabled = false);
+ bool isEqual(const ImplImage &ref) const;
+ bool isSizeEmpty() const { return maSizePixel == Size(0, 0); }
+ bool loadStockAtScale(double fScale, BitmapEx &rBitmapEx);
};
#endif // INCLUDED_VCL_INC_IMAGE_H
diff --git a/vcl/source/control/fixed.cxx b/vcl/source/control/fixed.cxx
index b927cb2054a1..e990752ebc22 100644
--- a/vcl/source/control/fixed.cxx
+++ b/vcl/source/control/fixed.cxx
@@ -967,8 +967,7 @@ bool FixedImage::SetModeImage( const Image& rImage )
Image FixedImage::loadThemeImage(const OUString &rFileName)
{
- BitmapEx aBitmap(rFileName);
- return Image(aBitmap);
+ return Image("private:graphicrepository/" + rFileName);
}
bool FixedImage::set_property(const OString &rKey, const OUString &rValue)
diff --git a/vcl/source/image/Image.cxx b/vcl/source/image/Image.cxx
index e99cccd0f256..fdda197f2654 100644
--- a/vcl/source/image/Image.cxx
+++ b/vcl/source/image/Image.cxx
@@ -55,45 +55,44 @@ Image::Image(const css::uno::Reference< css::graphic::XGraphic >& rxGraphic)
Image::Image(const OUString & rFileUrl)
{
OUString aPath;
- osl::FileBase::getSystemPathFromFileURL(rFileUrl, aPath);
- Graphic aGraphic;
- const OUString aFilterName(IMP_PNG);
- if (ERRCODE_NONE == GraphicFilter::LoadGraphic(aPath, aFilterName, aGraphic))
+ sal_Int32 nIndex = 0;
+ if (rFileUrl.getToken( 0, '/', nIndex ) == "private:graphicrepository")
{
- ImplInit(aGraphic.GetBitmapEx());
+ OUString sPathName(rFileUrl.copy(nIndex));
+ BitmapEx aBitmapEx;
+ if (vcl::ImageRepository::loadImage(sPathName, aBitmapEx))
+ mpImplData.reset(new ImplImage(rFileUrl.copy(nIndex)));
+ }
+ else
+ {
+ osl::FileBase::getSystemPathFromFileURL(rFileUrl, aPath);
+ Graphic aGraphic;
+ const OUString aFilterName(IMP_PNG);
+ if (ERRCODE_NONE == GraphicFilter::LoadGraphic(aPath, aFilterName, aGraphic))
+ ImplInit(aGraphic.GetBitmapEx());
}
}
void Image::ImplInit(const BitmapEx& rBitmapEx)
{
if (!rBitmapEx.IsEmpty())
- {
mpImplData.reset(new ImplImage(rBitmapEx));
- }
}
Size Image::GetSizePixel() const
{
- Size aRet;
-
if (mpImplData)
- {
- aRet = mpImplData->maBitmapEx.GetSizePixel();
- }
-
- return aRet;
+ return mpImplData->getSizePixel();
+ else
+ return Size();
}
BitmapEx Image::GetBitmapEx() const
{
- BitmapEx aRet;
-
if (mpImplData)
- {
- aRet = mpImplData->maBitmapEx;
- }
-
- return aRet;
+ return mpImplData->getBitmapEx();
+ else
+ return BitmapEx();
}
bool Image::operator==(const Image& rImage) const
@@ -105,7 +104,7 @@ bool Image::operator==(const Image& rImage) const
else if (!rImage.mpImplData || !mpImplData)
bRet = false;
else
- bRet = rImage.mpImplData->maBitmapEx == mpImplData->maBitmapEx;
+ bRet = rImage.mpImplData->isEqual(*mpImplData);
return bRet;
}
@@ -116,60 +115,48 @@ void Image::Draw(OutputDevice* pOutDev, const Point& rPos, DrawImageFlags nStyle
return;
const Point aSrcPos(0, 0);
- Size aBitmapSizePixel = mpImplData->maBitmapEx.GetSizePixel();
+ Size aBitmapSizePixel = mpImplData->getSizePixel();
Size aOutSize = pSize ? *pSize : pOutDev->PixelToLogic(aBitmapSizePixel);
- if (nStyle & DrawImageFlags::Disable)
+ BitmapEx aRenderBmp = mpImplData->getBitmapEx(!!(nStyle & DrawImageFlags::Disable));
+
+ if (!(nStyle & DrawImageFlags::Disable) &&
+ (nStyle & (DrawImageFlags::ColorTransform | DrawImageFlags::Highlight |
+ DrawImageFlags::Deactive | DrawImageFlags::SemiTransparent)))
{
- BitmapChecksum aChecksum = mpImplData->maBitmapEx.GetChecksum();
- if (mpImplData->maBitmapChecksum != aChecksum)
+ BitmapEx aTempBitmapEx(aRenderBmp);
+
+ if (nStyle & (DrawImageFlags::Highlight | DrawImageFlags::Deactive))
{
- mpImplData->maBitmapChecksum = aChecksum;
- mpImplData->maDisabledBitmapEx = BitmapProcessor::createDisabledImage(mpImplData->maBitmapEx);
+ const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
+ Color aColor;
+ if (nStyle & DrawImageFlags::Highlight)
+ aColor = rSettings.GetHighlightColor();
+ else
+ aColor = rSettings.GetDeactiveColor();
+
+ BitmapProcessor::colorizeImage(aTempBitmapEx, aColor);
}
- pOutDev->DrawBitmapEx(rPos, aOutSize, aSrcPos, aBitmapSizePixel, mpImplData->maDisabledBitmapEx);
- }
- else
- {
- if (nStyle & (DrawImageFlags::ColorTransform | DrawImageFlags::Highlight |
- DrawImageFlags::Deactive | DrawImageFlags::SemiTransparent))
- {
- BitmapEx aTempBitmapEx(mpImplData->maBitmapEx);
- if (nStyle & (DrawImageFlags::Highlight | DrawImageFlags::Deactive))
+ if (nStyle & DrawImageFlags::SemiTransparent)
+ {
+ if (aTempBitmapEx.IsTransparent())
{
- const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
- Color aColor;
- if (nStyle & DrawImageFlags::Highlight)
- aColor = rSettings.GetHighlightColor();
- else
- aColor = rSettings.GetDeactiveColor();
-
- BitmapProcessor::colorizeImage(aTempBitmapEx, aColor);
+ Bitmap aAlphaBmp(aTempBitmapEx.GetAlpha().GetBitmap());
+ aAlphaBmp.Adjust(50);
+ aTempBitmapEx = BitmapEx(aTempBitmapEx.GetBitmap(), AlphaMask(aAlphaBmp));
}
-
- if (nStyle & DrawImageFlags::SemiTransparent)
+ else
{
- if (aTempBitmapEx.IsTransparent())
- {
- Bitmap aAlphaBmp(aTempBitmapEx.GetAlpha().GetBitmap());
- aAlphaBmp.Adjust(50);
- aTempBitmapEx = BitmapEx(aTempBitmapEx.GetBitmap(), AlphaMask(aAlphaBmp));
- }
- else
- {
- sal_uInt8 cErase = 128;
- aTempBitmapEx = BitmapEx(aTempBitmapEx.GetBitmap(), AlphaMask(aTempBitmapEx.GetSizePixel(), &cErase));
- }
+ sal_uInt8 cErase = 128;
+ aTempBitmapEx = BitmapEx(aTempBitmapEx.GetBitmap(), AlphaMask(aTempBitmapEx.GetSizePixel(), &cErase));
}
- pOutDev->DrawBitmapEx(rPos, aOutSize, aSrcPos, aTempBitmapEx.GetSizePixel(), aTempBitmapEx);
- }
- else
- {
- pOutDev->DrawBitmapEx(rPos, aOutSize, aSrcPos, mpImplData->maBitmapEx.GetSizePixel(), mpImplData->maBitmapEx);
}
+ aRenderBmp = aTempBitmapEx;
}
+
+ pOutDev->DrawBitmapEx(rPos, aOutSize, aSrcPos, aBitmapSizePixel, aRenderBmp);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/image/ImplImage.cxx b/vcl/source/image/ImplImage.cxx
index 82a2099e8813..e9024229f482 100644
--- a/vcl/source/image/ImplImage.cxx
+++ b/vcl/source/image/ImplImage.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/log.hxx>
#include <vcl/outdev.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/alpha.hxx>
@@ -25,15 +26,76 @@
#include <vcl/virdev.hxx>
#include <vcl/image.hxx>
#include <vcl/settings.hxx>
+#include <vcl/imagerepository.hxx>
+#include <BitmapProcessor.hxx>
#include <image.h>
#include <memory>
ImplImage::ImplImage(const BitmapEx &rBitmapEx)
: maBitmapChecksum(0)
+ , maSizePixel(rBitmapEx.GetSizePixel())
, maBitmapEx(rBitmapEx)
- , maDisabledBitmapEx()
{
}
+ImplImage::ImplImage(const OUString &aStockName)
+ : maBitmapChecksum(0)
+ , maSizePixel(0,0) // defer size lookup
+ , maStockName( aStockName )
+{
+}
+
+Size ImplImage::getSizePixel()
+{
+ Size aRet;
+ if (!isSizeEmpty())
+ aRet = maSizePixel;
+ else if (isStock())
+ {
+ BitmapEx aBitmapEx;
+ if (vcl::ImageRepository::loadImage(maStockName, aBitmapEx))
+ {
+ assert(!maDisabledBitmapEx);
+ assert(maBitmapChecksum == 0);
+ maBitmapEx = aBitmapEx;
+ maSizePixel = aBitmapEx.GetSizePixel();
+ aRet = maSizePixel;
+ }
+ else
+ SAL_WARN("vcl", "Failed to load stock icon " << maStockName);
+ }
+ return aRet;
+}
+
+/// non-HiDPI compatibility method.
+BitmapEx ImplImage::getBitmapEx(bool bDisabled)
+{
+ getSizePixel(); // force load, and at unity scale.
+ if (bDisabled)
+ {
+ // Changed since we last generated this.
+ BitmapChecksum aChecksum = maBitmapEx.GetChecksum();
+ if (maBitmapChecksum != aChecksum ||
+ maDisabledBitmapEx.GetSizePixel() != maBitmapEx.GetSizePixel())
+ {
+ maDisabledBitmapEx = BitmapProcessor::createDisabledImage(maBitmapEx);
+ maBitmapChecksum = aChecksum;
+ }
+ return maDisabledBitmapEx;
+ }
+
+ return maBitmapEx;
+}
+
+bool ImplImage::isEqual(const ImplImage &ref) const
+{
+ if (isStock() != ref.isStock())
+ return false;
+ if (isStock())
+ return maStockName == ref.maStockName;
+ else
+ return maBitmapEx == ref.maBitmapEx;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 8af60681afb1..60e968771d78 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -365,8 +365,8 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr
SAL_WARN_IF(eType != SymbolType::IMAGE, "vcl.layout", "inimplemented symbol type for radiobuttons");
if (eType == SymbolType::IMAGE)
{
- BitmapEx aBitmap(mapStockToImageResource(rImageInfo.m_sStock));
- Image const aImage(aBitmap);
+ Image const aImage("private:graphicrepository/" +
+ mapStockToImageResource(rImageInfo.m_sStock));
if (!aI->m_bRadio)
pTargetButton->SetModeImage(aImage);
else
diff --git a/vcl/source/window/msgbox.cxx b/vcl/source/window/msgbox.cxx
index 2a99d25ac2ee..40a120e0508a 100644
--- a/vcl/source/window/msgbox.cxx
+++ b/vcl/source/window/msgbox.cxx
@@ -37,12 +37,13 @@
static void ImplInitMsgBoxImageList()
{
ImplSVData* pSVData = ImplGetSVData();
- if (pSVData->maWinData.maMsgBoxImgList.empty())
+ std::vector<Image> &rImages = pSVData->maWinData.maMsgBoxImgList;
+ if (rImages.empty())
{
- pSVData->maWinData.maMsgBoxImgList.emplace_back(BitmapEx(SV_RESID_BITMAP_ERRORBOX));
- pSVData->maWinData.maMsgBoxImgList.emplace_back(BitmapEx(SV_RESID_BITMAP_QUERYBOX));
- pSVData->maWinData.maMsgBoxImgList.emplace_back(BitmapEx(SV_RESID_BITMAP_WARNINGBOX));
- pSVData->maWinData.maMsgBoxImgList.emplace_back(BitmapEx(SV_RESID_BITMAP_INFOBOX));
+ rImages.emplace_back(Image("private:graphicrepository/" SV_RESID_BITMAP_ERRORBOX));
+ rImages.emplace_back(Image("private:graphicrepository/" SV_RESID_BITMAP_QUERYBOX));
+ rImages.emplace_back(Image("private:graphicrepository/" SV_RESID_BITMAP_WARNINGBOX));
+ rImages.emplace_back(Image("private:graphicrepository/" SV_RESID_BITMAP_INFOBOX));
}
}