Kaydet (Commit) a71ea5ce authored tarafından Michael Meeks's avatar Michael Meeks

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
Reviewed-on: https://gerrit.libreoffice.org/64040
Tested-by: Jenkins
Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst 3f2ac501
......@@ -132,13 +132,10 @@ static void fillLayoutValueSet( ValueSet* pValue, const snewfoil_value_info_layo
for( ; pInfo->mpStrResId; pInfo++ )
{
OUString aText(SdResId(pInfo->mpStrResId));
BitmapEx aBmp(OUString::createFromAscii(pInfo->msBmpResId));
pValue->InsertItem(static_cast<sal_uInt16>(pInfo->maAutoLayout)+1,
Image(aBmp), aText);
aLayoutItemSize.setWidth( std::max( aLayoutItemSize.Width(), aBmp.GetSizePixel().Width() ) );
aLayoutItemSize.setHeight( std::max( aLayoutItemSize.Height(), aBmp.GetSizePixel().Height() ) );
Image aImg("private:graphicrepository/" + OUString::createFromAscii(pInfo->msBmpResId));
pValue->InsertItem(static_cast<sal_uInt16>(pInfo->maAutoLayout)+1, aImg, aText);
aLayoutItemSize.setWidth( std::max( aLayoutItemSize.Width(), aImg.GetSizePixel().Width() ) );
aLayoutItemSize.setHeight( std::max( aLayoutItemSize.Height(), aImg.GetSizePixel().Height() ) );
}
aLayoutItemSize = pValue->CalcItemSizePixel( aLayoutItemSize );
......
......@@ -28,10 +28,25 @@
struct ImplImage
{
BitmapChecksum maBitmapChecksum;
BitmapEx const maBitmapEx;
/// 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();
BitmapEx getBitmapEx(bool bDisabled = false);
bool isEqual(const ImplImage &ref) const;
bool isSizeEmpty() const { return maSizePixel == Size(0, 0); }
};
#endif // INCLUDED_VCL_INC_IMAGE_H
......
......@@ -951,8 +951,7 @@ void 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)
......
......@@ -58,17 +58,11 @@ Image::Image(const OUString & rFileUrl)
sal_Int32 nIndex = 0;
if (rFileUrl.getToken( 0, '/', nIndex ) == "private:graphicrepository")
{
OUString sPathName(rFileUrl.copy(nIndex));
BitmapEx aBitmapEx;
if (vcl::ImageRepository::loadImage(sPathName, aBitmapEx))
{
ImplInit(aBitmapEx);
}
mpImplData.reset(new ImplImage(rFileUrl.copy(nIndex)));
}
else
{
Graphic aGraphic;
if (ERRCODE_NONE == GraphicFilter::LoadGraphic(rFileUrl, IMP_PNG, aGraphic))
{
ImplInit(aGraphic.GetBitmapEx());
......@@ -79,33 +73,23 @@ Image::Image(const OUString & rFileUrl)
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
......@@ -117,7 +101,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;
}
......@@ -128,63 +112,49 @@ 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)
{
BitmapChecksum aChecksum = mpImplData->maBitmapEx.GetChecksum();
if (mpImplData->maBitmapChecksum != aChecksum)
{
BitmapEx aDisabledBmpEx(mpImplData->maBitmapEx);
BitmapFilter::Filter(aDisabledBmpEx, BitmapDisabledImageFilter());
// FIXME: do the HiDPI scaling fun here [!] =)
BitmapEx aRenderBmp = mpImplData->getBitmapEx(!!(nStyle & DrawImageFlags::Disable));
mpImplData->maBitmapChecksum = aChecksum;
mpImplData->maDisabledBitmapEx = aDisabledBmpEx;
}
pOutDev->DrawBitmapEx(rPos, aOutSize, aSrcPos, aBitmapSizePixel, mpImplData->maDisabledBitmapEx);
}
else
if (!(nStyle & DrawImageFlags::Disable) &&
(nStyle & (DrawImageFlags::ColorTransform | DrawImageFlags::Highlight |
DrawImageFlags::Deactive | DrawImageFlags::SemiTransparent)))
{
if (nStyle & (DrawImageFlags::ColorTransform | DrawImageFlags::Highlight |
DrawImageFlags::Deactive | DrawImageFlags::SemiTransparent))
BitmapEx aTempBitmapEx(aRenderBmp);
if (nStyle & (DrawImageFlags::Highlight | DrawImageFlags::Deactive))
{
BitmapEx aTempBitmapEx(mpImplData->maBitmapEx);
const StyleSettings& rSettings = pOutDev->GetSettings().GetStyleSettings();
Color aColor;
if (nStyle & DrawImageFlags::Highlight)
aColor = rSettings.GetHighlightColor();
else
aColor = rSettings.GetDeactiveColor();
BitmapFilter::Filter(aTempBitmapEx, BitmapColorizeFilter(aColor));
}
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();
BitmapFilter::Filter(aTempBitmapEx, BitmapColorizeFilter(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: */
......@@ -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,80 @@
#include <vcl/virdev.hxx>
#include <vcl/image.hxx>
#include <vcl/settings.hxx>
#include <vcl/BitmapFilter.hxx>
#include <vcl/ImageTree.hxx>
#include <vcl/imagerepository.hxx>
#include <BitmapDisabledImageFilter.hxx>
#include <comphelper/lok.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 = maBitmapEx;
BitmapFilter::Filter(maDisabledBitmapEx, BitmapDisabledImageFilter());
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: */
......@@ -676,8 +676,8 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr
SAL_WARN_IF(eType != SymbolType::IMAGE, "vcl.layout", "unimplemented 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 (!elem.m_bRadio)
pTargetButton->SetModeImage(aImage);
else
......@@ -721,8 +721,8 @@ VclBuilder::VclBuilder(vcl::Window *pParent, const OUString& sUIDir, const OUStr
if (eType != SymbolType::IMAGE)
continue;
BitmapEx aBitmap(mapStockToImageResource(rImageInfo.m_sStock));
const Image aImage(aBitmap);
Image const aImage("private:graphicrepository/" +
mapStockToImageResource(rImageInfo.m_sStock));
pImage->SetImage(aImage);
}
......
......@@ -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));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment