sw/source/core/doc/notxtfrm.cxx | 198 +------------------------------- sw/source/core/inc/frmtool.hxx | 6 sw/source/core/inc/notxtfrm.hxx | 6 vcl/headless/svpbmp.cxx | 7 - vcl/headless/svpgdi.cxx | 219 +++-------------------------------- vcl/inc/headless/svpbmp.hxx | 26 ---- vcl/source/outdev/bitmap.cxx | 247 +++++++++++----------------------------- 7 files changed, 107 insertions(+), 602 deletions(-)
New commits: commit 4e19d09360220a181d7bdad92e6112390ff49f39 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Wed Feb 26 03:59:48 2020 +0000 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Wed Feb 26 09:53:26 2020 +0100 Revert "tdf#130768 speedup huge pixel graphics Cairo" This reverts commit ef6f94e93bbe55a26b67b55b2aecda67d406ab85. Change-Id: I34d4d4782d9d9711a78c0d5a8eaf019bfcdd701c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89496 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Michael Meeks <michael.me...@collabora.com> diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx index f2b148361994..04e556277738 100644 --- a/sw/source/core/doc/notxtfrm.cxx +++ b/sw/source/core/doc/notxtfrm.cxx @@ -82,14 +82,6 @@ #include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> -// MM02 needed for VOC mechanism and getting the OC - may be moved to an own file -#include <svx/sdrpagewindow.hxx> -#include <svx/svdpagv.hxx> -#include <svx/sdr/contact/viewcontact.hxx> -#include <svx/sdr/contact/viewobjectcontact.hxx> -#include <svx/sdr/contact/objectcontact.hxx> -#include <svx/sdr/contact/displayinfo.hxx> - using namespace com::sun::star; static bool GetRealURL( const SwGrfNode& rNd, OUString& rText ) @@ -156,9 +148,7 @@ static void lcl_PaintReplacement( const SwRect &rRect, const OUString &rText, SwNoTextFrame::SwNoTextFrame(SwNoTextNode * const pNode, SwFrame* pSib ) : SwContentFrame( pNode, pSib ), // RotateFlyFrame3 - mpTransformableSwFrame(), - // MM02 - mpViewContact() + mpTransformableSwFrame() { mnFrameType = SwFrameType::NoTxt; } @@ -935,7 +925,6 @@ static bool paintUsingPrimitivesHelper( return false; } -// MM02 original using falölback to VOC and primitive-based version void paintGraphicUsingPrimitivesHelper( vcl::RenderContext & rOutputDevice, GraphicObject const& rGrfObj, @@ -947,24 +936,12 @@ void paintGraphicUsingPrimitivesHelper( // -> the primitive renderer will create the needed pdf export data // -> if bitmap content, it will be cached system-dependent drawinglayer::primitive2d::Primitive2DContainer aContent(1); + aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D( rGraphicTransform, rGrfObj, rGraphicAttr); - // MM02 use primitive-based version for visualization - paintGraphicUsingPrimitivesHelper( - rOutputDevice, - aContent, - rGraphicTransform); -} - -// MM02 new VOC and primitive-based version -void paintGraphicUsingPrimitivesHelper( - vcl::RenderContext & rOutputDevice, - drawinglayer::primitive2d::Primitive2DContainer& rContent, - const basegfx::B2DHomMatrix& rGraphicTransform) -{ // RotateFlyFrame3: If ClipRegion is set at OutputDevice, we // need to use that. Usually the renderer would be a VCL-based // PrimitiveRenderer, but there are system-specific shortcuts that @@ -1031,12 +1008,9 @@ void paintGraphicUsingPrimitivesHelper( aTarget.append(aClip); } - drawinglayer::primitive2d::MaskPrimitive2D* pNew( - new drawinglayer::primitive2d::MaskPrimitive2D( - aTarget, - rContent)); - rContent.resize(1); - rContent[0] = pNew; + aContent[0] = new drawinglayer::primitive2d::MaskPrimitive2D( + aTarget, + aContent); } } @@ -1045,111 +1019,11 @@ void paintGraphicUsingPrimitivesHelper( paintUsingPrimitivesHelper( rOutputDevice, - rContent, + aContent, aTargetRange, aTargetRange); } -// DrawContact section -namespace { // anonymous namespace -class ViewObjectContactOfSwNoTextFrame : public sdr::contact::ViewObjectContact -{ -protected: - virtual drawinglayer::primitive2d::Primitive2DContainer createPrimitive2DSequence( - const sdr::contact::DisplayInfo& rDisplayInfo) const override; - -public: - ViewObjectContactOfSwNoTextFrame( - sdr::contact::ObjectContact& rObjectContact, - sdr::contact::ViewContact& rViewContact); -}; - -class ViewContactOfSwNoTextFrame : public sdr::contact::ViewContact -{ -private: - // owner - const SwNoTextFrame& mrSwNoTextFrame; - -protected: - // Create an Object-Specific ViewObjectContact, set ViewContact and - // ObjectContact. Always needs to return something. - virtual sdr::contact::ViewObjectContact& CreateObjectSpecificViewObjectContact( - sdr::contact::ObjectContact& rObjectContact) override; - -public: - // read-access to owner - const SwNoTextFrame& getSwNoTextFrame() const { return mrSwNoTextFrame; } - - // basic constructor, used from SwNoTextFrame. - explicit ViewContactOfSwNoTextFrame(const SwNoTextFrame& rSwNoTextFrame); -}; - -drawinglayer::primitive2d::Primitive2DContainer ViewObjectContactOfSwNoTextFrame::createPrimitive2DSequence( - const sdr::contact::DisplayInfo& /*rDisplayInfo*/) const -{ - // MM02 get all the parameters formally used in paintGraphicUsingPrimitivesHelper - ViewContactOfSwNoTextFrame& rVCOfNTF(static_cast<ViewContactOfSwNoTextFrame&>(GetViewContact())); - const SwNoTextFrame& rSwNoTextFrame(rVCOfNTF.getSwNoTextFrame()); - SwNoTextNode& rNoTNd(const_cast<SwNoTextNode&>(*static_cast<const SwNoTextNode*>(rSwNoTextFrame.GetNode()))); - SwGrfNode* pGrfNd(rNoTNd.GetGrfNode()); - - if(nullptr != pGrfNd) - { - const bool bPrn(GetObjectContact().isOutputToPrinter() || GetObjectContact().isOutputToRecordingMetaFile()); - const GraphicObject& rGrfObj(pGrfNd->GetGrfObj(bPrn)); - GraphicAttr aGraphicAttr; - pGrfNd->GetGraphicAttr(aGraphicAttr, &rSwNoTextFrame); - const basegfx::B2DHomMatrix aGraphicTransform(rSwNoTextFrame.getFrameAreaTransformation()); - - // MM02 this is the right place in the VOC-Mechanism to create - // the primitives for visualization - these will be automatically - // buffered and reused - drawinglayer::primitive2d::Primitive2DContainer aContent(1); - aContent[0] = new drawinglayer::primitive2d::GraphicPrimitive2D( - aGraphicTransform, - rGrfObj, - aGraphicAttr); - - return aContent; - } - - return drawinglayer::primitive2d::Primitive2DContainer(); -} - -ViewObjectContactOfSwNoTextFrame::ViewObjectContactOfSwNoTextFrame( - sdr::contact::ObjectContact& rObjectContact, - sdr::contact::ViewContact& rViewContact) -: sdr::contact::ViewObjectContact(rObjectContact, rViewContact) -{ -} - -sdr::contact::ViewObjectContact& ViewContactOfSwNoTextFrame::CreateObjectSpecificViewObjectContact( - sdr::contact::ObjectContact& rObjectContact) -{ - sdr::contact::ViewObjectContact* pRetval = new ViewObjectContactOfSwNoTextFrame(rObjectContact, *this); - return *pRetval; -} - -ViewContactOfSwNoTextFrame::ViewContactOfSwNoTextFrame( - const SwNoTextFrame& rSwNoTextFrame -) -: sdr::contact::ViewContact(), - mrSwNoTextFrame(rSwNoTextFrame) -{ -} -} // end of anonymous namespace - -sdr::contact::ViewContact& SwNoTextFrame::GetViewContact() const -{ - if(!mpViewContact) - { - const_cast< SwNoTextFrame* >(this)->mpViewContact = - std::make_unique<ViewContactOfSwNoTextFrame>(*this); - } - - return *mpViewContact; -} - /** Paint the graphic. We require either a QuickDraw-Bitmap or a graphic here. If we do not have @@ -1275,61 +1149,13 @@ void SwNoTextFrame::PaintPicture( vcl::RenderContext* pOut, const SwRect &rGrfAr } else { - // MM02 To allow system-dependent buffering of the involved - // bitmaps it is necessary to re-use the involved primitives - // and their already executed decomposition (also for - // performance reasons). This is usually done in DrawingLayer - // by using the VOC-Mechanism (see descriptions elsewhere). - // To get that here, make the involved SwNoTextFrame (this) - // a sdr::contact::ViewContact supplier by supporing - // a GetViewContact() - call. For ObjectContact we can use - // the already exising ObjectContact from the involved - // DrawingLayer. For tis, the helper classes - // ViewObjectContactOfSwNoTextFrame - // ViewContactOfSwNoTextFrame - // are created which support the VOC-mechanism in it's minimal - // form. This allows automatic and view-dependent (multiple edit - // windows, print, etc.) re-use of the created primitives. - // Also: Will be very useful when completely changing the Writer - // repaint to VOC and Primitives, too. - static const char* pDisableMM02Goodies(getenv("SAL_DISABLE_MM02_GOODIES")); - static bool bUseViewObjectContactMechanism(nullptr == pDisableMM02Goodies); - - if(bUseViewObjectContactMechanism) - { - // MM02 use VOC-mechanism and buffer primitives - SwViewShellImp* pImp(pShell->Imp()); - SdrPageView* pPageView(nullptr != pImp ? pImp->GetPageView() : nullptr); - SdrPageWindow* pPageWindow(nullptr != pPageView ? pPageView->FindPageWindow(*pShell->GetOut()) : nullptr); + const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); - if(nullptr != pPageWindow) - { - sdr::contact::ObjectContact& rOC(pPageWindow->GetObjectContact()); - sdr::contact::ViewContact& rVC(GetViewContact()); - sdr::contact::ViewObjectContact& rVOC(rVC.GetViewObjectContact(rOC)); - sdr::contact::DisplayInfo aDisplayInfo; - - drawinglayer::primitive2d::Primitive2DContainer aPrimitives(rVOC.getPrimitive2DSequence(aDisplayInfo)); - const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); - - paintGraphicUsingPrimitivesHelper( - *pOut, - aPrimitives, - aGraphicTransform); - } - } - else - { - // MM02 fallback to direct paint with primitive-recreation - // which will block reusage of system-dependent bitmap data - const basegfx::B2DHomMatrix aGraphicTransform(getFrameAreaTransformation()); - - paintGraphicUsingPrimitivesHelper( - *pOut, - rGrfObj, - aGrfAttr, - aGraphicTransform); - } + paintGraphicUsingPrimitivesHelper( + *pOut, + rGrfObj, + aGrfAttr, + aGraphicTransform); } } else diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx index 54c1c9231e28..5ffcd20083f7 100644 --- a/sw/source/core/inc/frmtool.hxx +++ b/sw/source/core/inc/frmtool.hxx @@ -97,12 +97,6 @@ void paintGraphicUsingPrimitivesHelper( GraphicAttr const& rGraphicAttr, const basegfx::B2DHomMatrix& rGraphicTransform); -// MM02 new VOC and primitive-based version -void paintGraphicUsingPrimitivesHelper( - vcl::RenderContext & rOutputDevice, - drawinglayer::primitive2d::Primitive2DContainer& rContent, - const basegfx::B2DHomMatrix& rGraphicTransform); - // method to align rectangle. // Created declaration here to avoid <extern> declarations void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContext* pRenderContext ); diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx index 6c168041d244..fad416c27d8f 100644 --- a/sw/source/core/inc/notxtfrm.hxx +++ b/sw/source/core/inc/notxtfrm.hxx @@ -20,8 +20,6 @@ #define INCLUDED_SW_SOURCE_CORE_INC_NOTXTFRM_HXX #include "cntfrm.hxx" -// MM02 -#include <svx/sdr/contact/viewcontact.hxx> class SwNoTextNode; class OutputDevice; @@ -51,10 +49,6 @@ private: void ClearCache(); - // MM02 - std::unique_ptr<sdr::contact::ViewContact> mpViewContact; - sdr::contact::ViewContact& GetViewContact() const; - protected: virtual void MakeAll(vcl::RenderContext* pRenderContext) override; virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override; diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx index a7e5bdb55ddb..824fb847a732 100644 --- a/vcl/headless/svpbmp.cxx +++ b/vcl/headless/svpbmp.cxx @@ -34,13 +34,6 @@ using namespace basegfx; -SvpSalBitmap::SvpSalBitmap() -: SalBitmap(), - basegfx::SystemDependentDataHolder(), // MM02 - mpDIB() -{ -} - SvpSalBitmap::~SvpSalBitmap() { Destroy(); diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index ad99b21ba6ef..bcfde817b604 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -334,44 +334,6 @@ namespace SourceHelper& operator=(const SourceHelper&) = delete; }; - class SystemDependentData_SourceHelper : public basegfx::SystemDependentData - { - private: - std::shared_ptr<SourceHelper> maSourceHelper; - - public: - SystemDependentData_SourceHelper( - basegfx::SystemDependentDataManager& rSystemDependentDataManager, - const std::shared_ptr<SourceHelper>& rSourceHelper) - : basegfx::SystemDependentData(rSystemDependentDataManager), - maSourceHelper(rSourceHelper) - { - } - - const std::shared_ptr<SourceHelper>& getSourceHelper() const { return maSourceHelper; }; - virtual sal_Int64 estimateUsageInBytes() const override; - }; - - // MM02 class to allow buffering of SourceHelper - sal_Int64 SystemDependentData_SourceHelper::estimateUsageInBytes() const - { - sal_Int64 nRetval(0); - cairo_surface_t* source(maSourceHelper ? maSourceHelper->getSurface() : nullptr); - - if(source) - { - const long nStride(cairo_image_surface_get_stride(source)); - const long nHeight(cairo_image_surface_get_height(source)); - - if(0 != nStride && 0 != nHeight) - { - nRetval = nStride * nHeight; - } - } - - return nRetval; - } - class MaskHelper { public: @@ -437,123 +399,6 @@ namespace MaskHelper(const MaskHelper&) = delete; MaskHelper& operator=(const MaskHelper&) = delete; }; - - class SystemDependentData_MaskHelper : public basegfx::SystemDependentData - { - private: - std::shared_ptr<MaskHelper> maMaskHelper; - - public: - SystemDependentData_MaskHelper( - basegfx::SystemDependentDataManager& rSystemDependentDataManager, - const std::shared_ptr<MaskHelper>& rMaskHelper) - : basegfx::SystemDependentData(rSystemDependentDataManager), - maMaskHelper(rMaskHelper) - { - } - - const std::shared_ptr<MaskHelper>& getMaskHelper() const { return maMaskHelper; }; - virtual sal_Int64 estimateUsageInBytes() const override; - }; - - // MM02 class to allow buffering of MaskHelper - sal_Int64 SystemDependentData_MaskHelper::estimateUsageInBytes() const - { - sal_Int64 nRetval(0); - cairo_surface_t* mask(maMaskHelper ? maMaskHelper->getMask() : nullptr); - - if(mask) - { - const long nStride(cairo_image_surface_get_stride(mask)); - const long nHeight(cairo_image_surface_get_height(mask)); - - if(0 != nStride && 0 != nHeight) - { - nRetval = nStride * nHeight; - } - } - - return nRetval; - } - - // MM02 decide to use buffers or not - static const char* pDisableMM02Goodies(getenv("SAL_DISABLE_MM02_GOODIES")); - static bool bUseBuffer(nullptr == pDisableMM02Goodies); - static long nMinimalSquareSizeToBuffer(64*64); - - void tryToUseSourceBuffer( - const SalBitmap& rSourceBitmap, - std::shared_ptr<SourceHelper>& rSurface) - { - // MM02 try to access buffered SourceHelper - std::shared_ptr<SystemDependentData_SourceHelper> pSystemDependentData_SourceHelper; - const bool bBufferSource(bUseBuffer - && rSourceBitmap.GetSize().Width() * rSourceBitmap.GetSize().Height() > nMinimalSquareSizeToBuffer); - - if(bBufferSource) - { - const SvpSalBitmap& rSrcBmp(static_cast<const SvpSalBitmap&>(rSourceBitmap)); - pSystemDependentData_SourceHelper = rSrcBmp.getSystemDependentData<SystemDependentData_SourceHelper>(); - - if(pSystemDependentData_SourceHelper) - { - // reuse buffered data - rSurface = pSystemDependentData_SourceHelper->getSourceHelper(); - } - } - - if(!rSurface) - { - // create data on-demand - rSurface = std::make_shared<SourceHelper>(rSourceBitmap); - - if(bBufferSource) - { - // add to buffering mechanism to potentially reuse next time - const SvpSalBitmap& rSrcBmp(static_cast<const SvpSalBitmap&>(rSourceBitmap)); - rSrcBmp.addOrReplaceSystemDependentData<SystemDependentData_SourceHelper>( - ImplGetSystemDependentDataManager(), - rSurface); - } - } - } - - void tryToUseMaskBuffer( - const SalBitmap& rMaskBitmap, - std::shared_ptr<MaskHelper>& rMask) - { - // MM02 try to access buffered MaskHelper - std::shared_ptr<SystemDependentData_MaskHelper> pSystemDependentData_MaskHelper; - const bool bBufferMask(bUseBuffer - && rMaskBitmap.GetSize().Width() * rMaskBitmap.GetSize().Height() > nMinimalSquareSizeToBuffer); - - if(bBufferMask) - { - const SvpSalBitmap& rSrcBmp(static_cast<const SvpSalBitmap&>(rMaskBitmap)); - pSystemDependentData_MaskHelper = rSrcBmp.getSystemDependentData<SystemDependentData_MaskHelper>(); - - if(pSystemDependentData_MaskHelper) - { - // reuse buffered data - rMask = pSystemDependentData_MaskHelper->getMaskHelper(); - } - } - - if(!rMask) - { - // create data on-demand - rMask = std::make_shared<MaskHelper>(rMaskBitmap); - - if(bBufferMask) - { - // add to buffering mechanism to potentially reuse next time - const SvpSalBitmap& rSrcBmp(static_cast<const SvpSalBitmap&>(rMaskBitmap)); - rSrcBmp.addOrReplaceSystemDependentData<SystemDependentData_MaskHelper>( - ImplGetSystemDependentDataManager(), - rMask); - } - } - } } bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) @@ -564,22 +409,16 @@ bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, const SalBitmap& rS return false; } - // MM02 try to access buffered SourceHelper - std::shared_ptr<SourceHelper> aSurface; - tryToUseSourceBuffer(rSourceBitmap, aSurface); - cairo_surface_t* source = aSurface->getSurface(); - + SourceHelper aSurface(rSourceBitmap); + cairo_surface_t* source = aSurface.getSurface(); if (!source) { SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawAlphaBitmap case"); return false; } - // MM02 try to access buffered MaskHelper - std::shared_ptr<MaskHelper> aMask; - tryToUseMaskBuffer(rAlphaBitmap, aMask); - cairo_surface_t *mask = aMask->getMask(); - + MaskHelper aMask(rAlphaBitmap); + cairo_surface_t *mask = aMask.getMask(); if (!mask) { SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawAlphaBitmap case"); @@ -640,34 +479,29 @@ bool SvpSalGraphics::drawTransformedBitmap( return false; } - // MM02 try to access buffered SourceHelper - std::shared_ptr<SourceHelper> aSurface; - tryToUseSourceBuffer(rSourceBitmap, aSurface); - cairo_surface_t* source(aSurface->getSurface()); - - if(!source) + SourceHelper aSurface(rSourceBitmap); + cairo_surface_t* source = aSurface.getSurface(); + if (!source) { SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawTransformedBitmap case"); return false; } - // MM02 try to access buffered MaskHelper - std::shared_ptr<MaskHelper> aMask; - - if(nullptr != pAlphaBitmap) + std::unique_ptr<MaskHelper> xMask; + cairo_surface_t *mask = nullptr; + if (pAlphaBitmap) { - tryToUseMaskBuffer(*pAlphaBitmap, aMask); - } - - // access cairo_surface_t from MaskHelper - cairo_surface_t* mask(aMask ? aMask->getMask() : nullptr); - if(nullptr != pAlphaBitmap && nullptr == mask) - { - SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawTransformedBitmap case"); - return false; + xMask.reset(new MaskHelper(*pAlphaBitmap)); + mask = xMask->getMask(); + if (!mask) + { + SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawTransformedBitmap case"); + return false; + } } const Size aSize = rSourceBitmap.GetSize(); + cairo_t* cr = getCairoContext(false); clipRegion(cr); @@ -1903,17 +1737,8 @@ void SvpSalGraphics::copyBits( const SalTwoRect& rTR, void SvpSalGraphics::drawBitmap(const SalTwoRect& rTR, const SalBitmap& rSourceBitmap) { - // MM02 try to access buffered SourceHelper - std::shared_ptr<SourceHelper> aSurface; - tryToUseSourceBuffer(rSourceBitmap, aSurface); - cairo_surface_t* source = aSurface->getSurface(); - - if (!source) - { - SAL_WARN("vcl.gdi", "unsupported SvpSalGraphics::drawAlphaBitmap case"); - return; - } - + SourceHelper aSurface(rSourceBitmap); + cairo_surface_t* source = aSurface.getSurface(); copySource(rTR, source); } @@ -1981,10 +1806,6 @@ void SvpSalGraphics::drawMask( const SalTwoRect& rTR, { /** creates an image from the given rectangle, replacing all black pixels * with nMaskColor and make all other full transparent */ - // MM02 here decided *against* using buffered SourceHelper - // because the data gets somehow 'unmuliplied'. This may also be - // done just once, but I am not sure if this is safe to do. - // So for now dispense re-using data here. SourceHelper aSurface(rSalBitmap, true); // The mask is argb32 if (!aSurface.getSurface()) { diff --git a/vcl/inc/headless/svpbmp.hxx b/vcl/inc/headless/svpbmp.hxx index a1e30d8b3903..d97c0fee128e 100644 --- a/vcl/inc/headless/svpbmp.hxx +++ b/vcl/inc/headless/svpbmp.hxx @@ -24,13 +24,11 @@ #include <tools/solar.h> #include <salbmp.hxx> -#include <basegfx/utils/systemdependentdata.hxx> -class VCL_DLLPUBLIC SvpSalBitmap : public SalBitmap, public basegfx::SystemDependentDataHolder // MM02 +class VCL_DLLPUBLIC SvpSalBitmap : public SalBitmap { std::unique_ptr<BitmapBuffer> mpDIB; public: - SvpSalBitmap(); virtual ~SvpSalBitmap() override; // SalBitmap @@ -61,28 +59,6 @@ public: virtual bool ScalingSupported() const override; virtual bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag ) override; virtual bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol ) override; - - // MM02 exclusive management op's for SystemDependentData at WinSalBitmap - template<class T> - std::shared_ptr<T> getSystemDependentData() const - { - return std::static_pointer_cast<T>(basegfx::SystemDependentDataHolder::getSystemDependentData(typeid(T).hash_code())); - } - - template<class T, class... Args> - std::shared_ptr<T> addOrReplaceSystemDependentData(basegfx::SystemDependentDataManager& manager, Args&&... args) const - { - std::shared_ptr<T> r = std::make_shared<T>(manager, std::forward<Args>(args)...); - - // tdf#129845 only add to buffer if a relevant buffer time is estimated - if(r->calculateCombinedHoldCyclesInSeconds() > 0) - { - basegfx::SystemDependentData_SharedPtr r2(r); - const_cast< SvpSalBitmap* >(this)->basegfx::SystemDependentDataHolder::addOrReplaceSystemDependentData(r2); - } - - return r; - } }; #endif // INCLUDED_VCL_INC_HEADLESS_SVPBMP_HXX diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx index 7fe75ec21a14..42aa0d78c486 100644 --- a/vcl/source/outdev/bitmap.cxx +++ b/vcl/source/outdev/bitmap.cxx @@ -1163,32 +1163,6 @@ bool OutputDevice::TransformAndReduceBitmapExToTargetRange( return true; } -// MM02 add som etest class to get a simple timer-based output to be able -// to check if it gets faster - and how much. Uncomment next line or set -// DO_TIME_TEST for compile tiome if you want to use it -// #define DO_TIME_TEST -#ifdef DO_TIME_TEST -#include <tools/time.hxx> -struct LocalTimeTest -{ - const sal_uInt64 nStartTime; - LocalTimeTest() : nStartTime(tools::Time::GetSystemTicks()) {} - ~LocalTimeTest() - { - const sal_uInt64 nEndTime(tools::Time::GetSystemTicks()); - const sal_uInt64 nDiffTime(nEndTime - nStartTime); - - if(nDiffTime > 0) - { - OStringBuffer aOutput("Time: "); - OString aNumber(OString::number(nDiffTime)); - aOutput.append(aNumber); - OSL_FAIL(aOutput.getStr()); - } - } -}; -#endif - void OutputDevice::DrawTransformedBitmapEx( const basegfx::B2DHomMatrix& rTransformation, const BitmapEx& rBitmapEx) @@ -1204,41 +1178,6 @@ void OutputDevice::DrawTransformedBitmapEx( if ( mnDrawMode & DrawModeFlags::NoBitmap ) return; - // this test was missing and led to zero-ptr-accesses - if ( !mpGraphics && !AcquireGraphics() ) - return; - -#ifdef DO_TIME_TEST - // MM02 start time test when some data (not for trivial stuff). Will - // trigger and show data when leaving this method by destructing helper - static const char* pEnableBitmapDrawTimerTimer(getenv("SAL_ENABLE_TIMER_BITMAPDRAW")); - static bool bUseTimer(nullptr != pEnableBitmapDrawTimerTimer); - std::unique_ptr<LocalTimeTest> aTimeTest( - bUseTimer && rBitmapEx.GetSizeBytes() > 10000 - ? new LocalTimeTest() - : nullptr); -#endif - - // MM02 reorganize order: Prefer DrawTransformBitmapExDirect due - // to this having evolved and is improved on quite some systems. - // Check for exclusion parameters that may prevent using it - static bool bAllowPreferDirectPaint(true); - const bool bInvert(RasterOp::Invert == meRasterOp); - const bool bBitmapChangedColor(mnDrawMode & (DrawModeFlags::BlackBitmap | DrawModeFlags::WhiteBitmap | DrawModeFlags::GrayBitmap )); - const bool bMetafile(nullptr != mpMetaFile); - const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile); - - if(bAllowPreferDirectPaint && bTryDirectPaint) - { - const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); - - if(DrawTransformBitmapExDirect(aFullTransform, rBitmapEx)) - { - // we are done - return; - } - } - // decompose matrix to check rotation and shear basegfx::B2DVector aScale, aTranslate; double fRotate, fShearX; @@ -1248,7 +1187,10 @@ void OutputDevice::DrawTransformedBitmapEx( const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0)); const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0)); - if(!bRotated && !bSheared && !bMirroredX && !bMirroredY) + static bool bForceToOwnTransformer(false); + const bool bMetafile = mpMetaFile != nullptr; + + if(!bForceToOwnTransformer && !bRotated && !bSheared && !bMirroredX && !bMirroredY) { // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx // do *not* execute the mirroring here, it's done in the fallback @@ -1273,140 +1215,99 @@ void OutputDevice::DrawTransformedBitmapEx( return; } - // MM02 bAllowPreferDirectPaint may have been false to allow - // to specify order of executions, so give bTryDirectPaint a call - if(bTryDirectPaint) + // we have rotation,shear or mirror, check if some crazy mode needs the + // created transformed bitmap + const bool bInvert(RasterOp::Invert == meRasterOp); + const bool bBitmapChangedColor(mnDrawMode & (DrawModeFlags::BlackBitmap | DrawModeFlags::WhiteBitmap | DrawModeFlags::GrayBitmap | DrawModeFlags::GhostedBitmap)); + bool bDone(false); + const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); + const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile ); + + if(!bForceToOwnTransformer && bTryDirectPaint) { - const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); + bDone = DrawTransformBitmapExDirect(aFullTransform, rBitmapEx); + } - if(DrawTransformBitmapExDirect(aFullTransform, rBitmapEx)) + if(!bDone) + { + // take the fallback when no rotate and shear, but mirror (else we would have done this above) + if(!bForceToOwnTransformer && !bRotated && !bSheared) { - // we are done + // with no rotation or shear it can be mapped to DrawBitmapEx + // do *not* execute the mirroring here, it's done in the fallback + // #i124580# the correct DestSize needs to be calculated based on MaxXY values + const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + const Size aDestSize( + basegfx::fround(aScale.getX() + aTranslate.getX()) - aDestPt.X(), + basegfx::fround(aScale.getY() + aTranslate.getY()) - aDestPt.Y()); + + DrawBitmapEx(aDestPt, aDestSize, rBitmapEx); return; } - } - // take the fallback when no rotate and shear, but mirror (else we would have done this above) - if(!bRotated && !bSheared) - { - // with no rotation or shear it can be mapped to DrawBitmapEx - // do *not* execute the mirroring here, it's done in the fallback - // #i124580# the correct DestSize needs to be calculated based on MaxXY values - const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); - const Size aDestSize( - basegfx::fround(aScale.getX() + aTranslate.getX()) - aDestPt.X(), - basegfx::fround(aScale.getY() + aTranslate.getY()) - aDestPt.Y()); - - DrawBitmapEx(aDestPt, aDestSize, rBitmapEx); - return; - } + // fallback; create transformed bitmap the hard way (back-transform + // the pixels) and paint + basegfx::B2DRange aVisibleRange(0.0, 0.0, 1.0, 1.0); - // at this point we are either sheared or rotated or both - assert(bSheared || bRotated); + // limit maximum area to something looking good for non-pixel-based targets (metafile, printer) + // by using a fixed minimum (allow at least, but no need to utilize) for good smoothing and an area + // dependent of original size for good quality when e.g. rotated/sheared. Still, limit to a maximum + // to avoid crashes/resource problems (ca. 1500x3000 here) + const Size& rOriginalSizePixel(rBitmapEx.GetSizePixel()); + const double fOrigArea(rOriginalSizePixel.Width() * rOriginalSizePixel.Height() * 0.5); + const double fOrigAreaScaled(bSheared || bRotated ? fOrigArea * 1.44 : fOrigArea); + double fMaximumArea(std::min(4500000.0, std::max(1000000.0, fOrigAreaScaled))); - // fallback; create transformed bitmap the hard way (back-transform - // the pixels) and paint - basegfx::B2DRange aVisibleRange(0.0, 0.0, 1.0, 1.0); - - // limit maximum area to something looking good for non-pixel-based targets (metafile, printer) - // by using a fixed minimum (allow at least, but no need to utilize) for good smoothing and an area - // dependent of original size for good quality when e.g. rotated/sheared. Still, limit to a maximum - // to avoid crashes/resource problems (ca. 1500x3000 here) - const Size& rOriginalSizePixel(rBitmapEx.GetSizePixel()); - const double fOrigArea(rOriginalSizePixel.Width() * rOriginalSizePixel.Height() * 0.5); - const double fOrigAreaScaled(fOrigArea * 1.44); - double fMaximumArea(std::min(4500000.0, std::max(1000000.0, fOrigAreaScaled))); - basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); - - if(!bMetafile) - { - if ( !TransformAndReduceBitmapExToTargetRange( aFullTransform, aVisibleRange, fMaximumArea ) ) - return; - } - - if(!aVisibleRange.isEmpty()) - { - static bool bDoSmoothAtAll(true); - BitmapEx aTransformed(rBitmapEx); + if(!bMetafile) + { + if ( !TransformAndReduceBitmapExToTargetRange( aFullTransform, aVisibleRange, fMaximumArea ) ) + return; + } - // #122923# when the result needs an alpha channel due to being rotated or sheared - // and thus uncovering areas, add these channels so that the own transformer (used - // in getTransformed) also creates a transformed alpha channel - if(!aTransformed.IsTransparent() && (bSheared || bRotated)) + if(!aVisibleRange.isEmpty()) { - // parts will be uncovered, extend aTransformed with a mask bitmap - const Bitmap aContent(aTransformed.GetBitmap()); + static bool bDoSmoothAtAll(true); + BitmapEx aTransformed(rBitmapEx); - AlphaMask aMaskBmp(aContent.GetSizePixel()); - aMaskBmp.Erase(0); + // #122923# when the result needs an alpha channel due to being rotated or sheared + // and thus uncovering areas, add these channels so that the own transformer (used + // in getTransformed) also creates a transformed alpha channel + if(!aTransformed.IsTransparent() && (bSheared || bRotated)) + { + // parts will be uncovered, extend aTransformed with a mask bitmap + const Bitmap aContent(aTransformed.GetBitmap()); - aTransformed = BitmapEx(aContent, aMaskBmp); - } + AlphaMask aMaskBmp(aContent.GetSizePixel()); + aMaskBmp.Erase(0); - // Remove scaling from aFulltransform: we transform due to shearing or rotation, scaling - // will happen according to aDestSize. - basegfx::B2DVector aFullScale, aFullTranslate; - double fFullRotate, fFullShearX; - aFullTransform.decompose(aFullScale, aFullTranslate, fFullRotate, fFullShearX); - // Require positive scaling, negative scaling would loose horizontal or vertical flip. - if (aFullScale.getX() > 0 && aFullScale.getY() > 0) - { - basegfx::B2DHomMatrix aTransform = basegfx::utils::createScaleB2DHomMatrix( - rOriginalSizePixel.getWidth() / aFullScale.getX(), - rOriginalSizePixel.getHeight() / aFullScale.getY()); - aFullTransform *= aTransform; - } + aTransformed = BitmapEx(aContent, aMaskBmp); + } - double fSourceRatio = 1.0; - if (rOriginalSizePixel.getHeight() != 0) - { - fSourceRatio = rOriginalSizePixel.getWidth() / rOriginalSizePixel.getHeight(); - } - double fTargetRatio = 1.0; - if (aFullScale.getY() != 0) - { - fTargetRatio = aFullScale.getX() / aFullScale.getY(); - } - bool bAspectRatioKept = rtl::math::approxEqual(fSourceRatio, fTargetRatio); - if (bSheared || !bAspectRatioKept) - { - // Not only rotation, or scaling does not keep aspect ratio. aTransformed = aTransformed.getTransformed( aFullTransform, aVisibleRange, fMaximumArea, bDoSmoothAtAll); - } - else - { - // Just rotation, can do that directly. - fFullRotate = fmod(fFullRotate * -1, F_2PI); - if (fFullRotate < 0) - { - fFullRotate += F_2PI; - } - long nAngle10 = basegfx::fround(basegfx::rad2deg(fFullRotate) * 10); - aTransformed.Rotate(nAngle10, COL_TRANSPARENT); - } - basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); + basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); - // get logic object target range - aTargetRange.transform(rTransformation); + // get logic object target range + aTargetRange.transform(rTransformation); - // get from unified/relative VisibleRange to logoc one - aVisibleRange.transform( - basegfx::utils::createScaleTranslateB2DHomMatrix( - aTargetRange.getRange(), - aTargetRange.getMinimum())); + // get from unified/relative VisibleRange to logoc one + aVisibleRange.transform( + basegfx::utils::createScaleTranslateB2DHomMatrix( + aTargetRange.getRange(), + aTargetRange.getMinimum())); - // extract point and size; do not remove size, the bitmap may have been prepared reduced by purpose - // #i124580# the correct DestSize needs to be calculated based on MaxXY values - const Point aDestPt(basegfx::fround(aVisibleRange.getMinX()), basegfx::fround(aVisibleRange.getMinY())); - const Size aDestSize( - basegfx::fround(aVisibleRange.getMaxX()) - aDestPt.X(), - basegfx::fround(aVisibleRange.getMaxY()) - aDestPt.Y()); + // extract point and size; do not remove size, the bitmap may have been prepared reduced by purpose + // #i124580# the correct DestSize needs to be calculated based on MaxXY values + const Point aDestPt(basegfx::fround(aVisibleRange.getMinX()), basegfx::fround(aVisibleRange.getMinY())); + const Size aDestSize( + basegfx::fround(aVisibleRange.getMaxX()) - aDestPt.X(), + basegfx::fround(aVisibleRange.getMaxY()) - aDestPt.Y()); - DrawBitmapEx(aDestPt, aDestSize, aTransformed); + DrawBitmapEx(aDestPt, aDestSize, aTransformed); + } } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits