summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--solenv/clang-format/excludelist4
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/Library_vclplug_osx.mk3
-rw-r--r--vcl/inc/quartz/salgdi.h14
-rw-r--r--vcl/ios/salios.cxx443
-rw-r--r--vcl/osx/salgdiutils.cxx (renamed from vcl/quartz/salgdiutils.cxx)0
-rw-r--r--vcl/osx/salmacos.cxx387
-rw-r--r--vcl/quartz/salbmp.cxx58
-rw-r--r--vcl/quartz/salgdicommon.cxx181
-rw-r--r--vcl/quartz/salvd.cxx104
10 files changed, 843 insertions, 352 deletions
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index 99a3d5089d75..bef00255118e 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -14779,6 +14779,7 @@ vcl/inc/window.h
vcl/inc/wizdlg.hxx
vcl/ios/dummies.cxx
vcl/ios/iosinst.cxx
+vcl/ios/salios.cxx
vcl/null/printerinfomanager.cxx
vcl/osx/DataFlavorMapping.cxx
vcl/osx/DataFlavorMapping.hxx
@@ -14804,7 +14805,9 @@ vcl/osx/documentfocuslistener.cxx
vcl/osx/documentfocuslistener.hxx
vcl/osx/saldata.cxx
vcl/osx/salframe.cxx
+vcl/osx/salgdiutils.cxx
vcl/osx/salinst.cxx
+vcl/osx/salmacos.cxx
vcl/osx/salmenu.cxx
vcl/osx/salnativewidgets.cxx
vcl/osx/salobj.cxx
@@ -14830,7 +14833,6 @@ vcl/quartz/ctfonts.cxx
vcl/quartz/salbmp.cxx
vcl/quartz/salgdi.cxx
vcl/quartz/salgdicommon.cxx
-vcl/quartz/salgdiutils.cxx
vcl/quartz/salvd.cxx
vcl/quartz/utils.cxx
vcl/source/app/IconThemeInfo.cxx
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index d937fceb0a69..51b45594f97f 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -685,6 +685,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/ios/iosinst \
vcl/ios/dummies \
vcl/ios/clipboard \
+ vcl/ios/salios \
vcl/ios/iOSTransferable \
vcl/ios/DataFlavorMapping \
vcl/ios/HtmlFmtFlt \
diff --git a/vcl/Library_vclplug_osx.mk b/vcl/Library_vclplug_osx.mk
index f0d22298a0c8..9b82bd44c2a6 100644
--- a/vcl/Library_vclplug_osx.mk
+++ b/vcl/Library_vclplug_osx.mk
@@ -120,7 +120,9 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_osx,\
vcl/osx/documentfocuslistener \
vcl/osx/saldata \
vcl/osx/salframe \
+ vcl/osx/salgdiutils \
vcl/osx/salinst \
+ vcl/osx/salmacos \
vcl/osx/salmenu \
vcl/osx/salnativewidgets \
vcl/osx/salobj \
@@ -132,7 +134,6 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_osx,\
vcl/quartz/salbmp \
vcl/quartz/salgdi \
vcl/quartz/salgdicommon \
- vcl/quartz/salgdiutils \
vcl/quartz/salvd \
vcl/quartz/utils \
))
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index eb3e7563c898..69b735787bdc 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -190,16 +190,16 @@ public:
bool IsPenVisible() const { return maLineColor.IsVisible(); }
bool IsBrushVisible() const { return maFillColor.IsVisible(); }
- float GetWindowScaling();
- void SetWindowGraphics( AquaSalFrame* pFrame );
- void SetPrinterGraphics(CGContextRef, sal_Int32 nRealDPIX, sal_Int32 nRealDPIY);
void SetVirDevGraphics(CGLayerHolder const &rLayer, CGContextRef, int nBitDepth = 0);
#ifdef MACOSX
void initResolution( NSWindow* );
void copyResolution( AquaSalGraphics& );
void updateResolution();
+ float GetWindowScaling();
+ void SetWindowGraphics( AquaSalFrame* pFrame );
bool IsWindowGraphics() const { return mbWindow; }
+ void SetPrinterGraphics(CGContextRef, sal_Int32 nRealDPIX, sal_Int32 nRealDPIY);
AquaSalFrame* getGraphicsFrame() const { return mpFrame; }
void setGraphicsFrame( AquaSalFrame* pFrame ) { mpFrame = pFrame; }
#endif
@@ -300,14 +300,12 @@ public:
virtual bool drawAlphaRect( tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight, sal_uInt8 nTransparency ) override;
+#ifdef MACOSX
+
protected:
- virtual void copyScaledArea( tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY,
- tools::Long nSrcWidth, tools::Long nSrcHeight, SalGraphics* pSrcGraphics );
// native widget rendering methods that require mirroring
-#ifdef MACOSX
-
virtual bool isNativeControlSupported( ControlType nType, ControlPart nPart ) override;
virtual bool hitTestNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
@@ -319,6 +317,8 @@ protected:
const ImplControlValue& aValue, const OUString& aCaption,
tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion ) override;
+ void copyScaledArea( tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY,
+ tools::Long nSrcWidth, tools::Long nSrcHeight, SalGraphics* pSrcGraphics );
#endif
public:
diff --git a/vcl/ios/salios.cxx b/vcl/ios/salios.cxx
new file mode 100644
index 000000000000..625fcb049a09
--- /dev/null
+++ b/vcl/ios/salios.cxx
@@ -0,0 +1,443 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// This file contains the iOS-specific versions of the functions which were touched in the commit to
+// fix tdf#138122. The funtions are here (for now) as they were before that commit. The
+// macOS-specific versions of these functions are in vcl/osx/salmacos.cxx.
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <cstddef>
+#include <limits>
+
+#include <o3tl/make_shared.hxx>
+#include <basegfx/vector/b2ivector.hxx>
+#include <tools/color.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/BitmapAccessMode.hxx>
+#include <vcl/BitmapBuffer.hxx>
+#include <vcl/BitmapColor.hxx>
+#include <vcl/BitmapPalette.hxx>
+#include <vcl/ColorMask.hxx>
+#include <vcl/Scanline.hxx>
+
+#include <bitmap/bmpfast.hxx>
+
+#include <headless/svpframe.hxx>
+#include <headless/svpinst.hxx>
+#include <headless/svpvd.hxx>
+
+#include <quartz/salbmp.h>
+#include <quartz/salgdi.h>
+#include <quartz/salvd.h>
+#include <quartz/utils.h>
+
+#include "saldatabasic.hxx"
+
+// From salbmp.cxx
+
+bool QuartzSalBitmap::Create(CGLayerHolder const & rLayerHolder, int nBitmapBits, int nX, int nY, int nWidth, int nHeight, bool bFlipped)
+{
+ SAL_WARN_IF(!rLayerHolder.isSet(), "vcl", "QuartzSalBitmap::Create() from non-layered context");
+
+ // sanitize input parameters
+ if( nX < 0 ) {
+ nWidth += nX;
+ nX = 0;
+ }
+
+ if( nY < 0 ) {
+ nHeight += nY;
+ nY = 0;
+ }
+
+ const CGSize aLayerSize = CGLayerGetSize(rLayerHolder.get());
+
+ if( nWidth >= static_cast<int>(aLayerSize.width) - nX )
+ nWidth = static_cast<int>(aLayerSize.width) - nX;
+
+ if( nHeight >= static_cast<int>(aLayerSize.height) - nY )
+ nHeight = static_cast<int>(aLayerSize.height) - nY;
+
+ if( (nWidth < 0) || (nHeight < 0) )
+ nWidth = nHeight = 0;
+
+ // initialize properties
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ mnBits = nBitmapBits ? nBitmapBits : 32;
+
+ // initialize drawing context
+ CreateContext();
+
+ // copy layer content into the bitmap buffer
+ const CGPoint aSrcPoint = { static_cast<CGFloat>(-nX), static_cast<CGFloat>(-nY) };
+ if (maGraphicContext.isSet()) // remove warning
+ {
+ if( bFlipped )
+ {
+ CGContextTranslateCTM( maGraphicContext.get(), 0, +mnHeight );
+
+ CGContextScaleCTM( maGraphicContext.get(), +1, -1 );
+ }
+
+ CGContextDrawLayerAtPoint(maGraphicContext.get(), aSrcPoint, rLayerHolder.get());
+ }
+ return true;
+}
+
+// From salgdicommon.cxx
+
+void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGraphics )
+{
+
+ if( !pSrcGraphics )
+ {
+ pSrcGraphics = this;
+ }
+ //from unix salgdi2.cxx
+ //[FIXME] find a better way to prevent calc from crashing when width and height are negative
+ if( rPosAry.mnSrcWidth <= 0 ||
+ rPosAry.mnSrcHeight <= 0 ||
+ rPosAry.mnDestWidth <= 0 ||
+ rPosAry.mnDestHeight <= 0 )
+ {
+ return;
+ }
+
+ // If called from idle layout, maContextHolder.get() is NULL, no idea what to do
+ if (!maContextHolder.isSet())
+ return;
+
+ // accelerate trivial operations
+ /*const*/ AquaSalGraphics* pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics);
+ const bool bSameGraphics = (this == pSrc);
+
+ if( bSameGraphics &&
+ (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
+ (rPosAry.mnSrcHeight == rPosAry.mnDestHeight))
+ {
+ // short circuit if there is nothing to do
+ if( (rPosAry.mnSrcX == rPosAry.mnDestX) &&
+ (rPosAry.mnSrcY == rPosAry.mnDestY))
+ {
+ return;
+ }
+ // use copyArea() if source and destination context are identical
+ copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, false/*bWindowInvalidate*/ );
+ return;
+ }
+
+ ApplyXorContext();
+ pSrc->ApplyXorContext();
+
+ SAL_WARN_IF (!pSrc->maLayer.isSet(), "vcl.quartz",
+ "AquaSalGraphics::copyBits() from non-layered graphics this=" << this);
+
+ const CGPoint aDstPoint = CGPointMake(+rPosAry.mnDestX - rPosAry.mnSrcX, rPosAry.mnDestY - rPosAry.mnSrcY);
+ if ((rPosAry.mnSrcWidth == rPosAry.mnDestWidth &&
+ rPosAry.mnSrcHeight == rPosAry.mnDestHeight) &&
+ (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth)
+ && pSrc->maLayer.isSet()) // workaround for a Quartz crash
+ {
+ // in XOR mode the drawing context is redirected to the XOR mask
+ // if source and target are identical then copyBits() paints onto the target context though
+ CGContextHolder aCopyContext = maContextHolder;
+ if( mpXorEmulation && mpXorEmulation->IsEnabled() )
+ {
+ if( pSrcGraphics == this )
+ {
+ aCopyContext.set(mpXorEmulation->GetTargetContext());
+ }
+ }
+ aCopyContext.saveState();
+
+ const CGRect aDstRect = CGRectMake(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+ CGContextClipToRect(aCopyContext.get(), aDstRect);
+
+ // draw at new destination
+ // NOTE: flipped drawing gets disabled for this, else the subimage would be drawn upside down
+ if( pSrc->IsFlipped() )
+ {
+ CGContextTranslateCTM( aCopyContext.get(), 0, +mnHeight );
+ CGContextScaleCTM( aCopyContext.get(), +1, -1 );
+ }
+
+ // TODO: pSrc->size() != this->size()
+ CGContextDrawLayerAtPoint(aCopyContext.get(), aDstPoint, pSrc->maLayer.get());
+
+ aCopyContext.restoreState();
+ // mark the destination rectangle as updated
+ RefreshRect( aDstRect );
+ }
+ else
+ {
+ std::shared_ptr<SalBitmap> pBitmap = pSrc->getBitmap( rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight );
+ if( pBitmap )
+ {
+ SalTwoRect aPosAry( rPosAry );
+ aPosAry.mnSrcX = 0;
+ aPosAry.mnSrcY = 0;
+ drawBitmap( aPosAry, *pBitmap );
+ }
+ }
+}
+
+void AquaSalGraphics::copyArea(tools::Long nDstX, tools::Long nDstY,tools::Long nSrcX, tools::Long nSrcY,
+ tools::Long nSrcWidth, tools::Long nSrcHeight, bool /*bWindowInvalidate*/)
+{
+ SAL_WARN_IF (!maLayer.isSet(), "vcl.quartz",
+ "AquaSalGraphics::copyArea() for non-layered graphics this=" << this);
+
+ if (!maLayer.isSet())
+ return;
+
+ float fScale = maLayer.getScale();
+
+ tools::Long nScaledSourceX = nSrcX * fScale;
+ tools::Long nScaledSourceY = nSrcY * fScale;
+
+ tools::Long nScaledTargetX = nDstX * fScale;
+ tools::Long nScaledTargetY = nDstY * fScale;
+
+ tools::Long nScaledSourceWidth = nSrcWidth * fScale;
+ tools::Long nScaledSourceHeight = nSrcHeight * fScale;
+
+ ApplyXorContext();
+
+ maContextHolder.saveState();
+
+ // in XOR mode the drawing context is redirected to the XOR mask
+ // copyArea() always works on the target context though
+ CGContextRef xCopyContext = maContextHolder.get();
+
+ if( mpXorEmulation && mpXorEmulation->IsEnabled() )
+ {
+ xCopyContext = mpXorEmulation->GetTargetContext();
+ }
+
+ // If we have a scaled layer, we need to revert the scaling or else
+ // it will interfere with the coordinate calculation
+ CGContextScaleCTM(xCopyContext, 1.0 / fScale, 1.0 / fScale);
+
+ // drawing a layer onto its own context causes trouble on OSX => copy it first
+ // TODO: is it possible to get rid of this unneeded copy more often?
+ // e.g. on OSX>=10.5 only this situation causes problems:
+ // mnBitmapDepth && (aDstPoint.x + pSrc->mnWidth) > mnWidth
+
+ CGLayerHolder sSourceLayerHolder(maLayer);
+ {
+ const CGSize aSrcSize = CGSizeMake(nScaledSourceWidth, nScaledSourceHeight);
+ sSourceLayerHolder.set(CGLayerCreateWithContext(xCopyContext, aSrcSize, nullptr));
+
+ const CGContextRef xSrcContext = CGLayerGetContext(sSourceLayerHolder.get());
+
+ CGPoint aSrcPoint = CGPointMake(-nScaledSourceX, -nScaledSourceY);
+ if( IsFlipped() )
+ {
+ CGContextTranslateCTM( xSrcContext, 0, +nScaledSourceHeight );
+ CGContextScaleCTM( xSrcContext, +1, -1 );
+ aSrcPoint.y = (nScaledSourceY + nScaledSourceHeight) - (mnHeight * fScale);
+ }
+ CGContextSetBlendMode(xSrcContext, kCGBlendModeCopy);
+
+ CGContextDrawLayerAtPoint(xSrcContext, aSrcPoint, maLayer.get());
+ }
+
+ // draw at new destination
+ const CGRect aTargetRect = CGRectMake(nScaledTargetX, nScaledTargetY, nScaledSourceWidth, nScaledSourceHeight);
+ CGContextSetBlendMode(xCopyContext, kCGBlendModeCopy);
+ CGContextDrawLayerInRect(xCopyContext, aTargetRect, sSourceLayerHolder.get());
+
+ maContextHolder.restoreState();
+
+ // cleanup
+ if (sSourceLayerHolder.get() != maLayer.get())
+ {
+ CGLayerRelease(sSourceLayerHolder.get());
+ }
+ // mark the destination rectangle as updated
+ RefreshRect( nDstX, nDstY, nSrcWidth, nSrcHeight );
+}
+
+void AquaSalGraphics::SetVirDevGraphics(CGLayerHolder const & rLayer, CGContextRef xContext,
+ int nBitmapDepth)
+{
+ SAL_INFO( "vcl.quartz", "SetVirDevGraphics() this=" << this << " layer=" << rLayer.get() << " context=" << xContext );
+
+ mbPrinter = false;
+ mbVirDev = true;
+
+ // set graphics properties
+ maLayer = rLayer;
+ maContextHolder.set(xContext);
+
+ mnBitmapDepth = nBitmapDepth;
+
+ mbForeignContext = xContext != NULL;
+
+ // return early if the virdev is being destroyed
+ if( !xContext )
+ return;
+
+ // get new graphics properties
+ if (!maLayer.isSet())
+ {
+ mnWidth = CGBitmapContextGetWidth( maContextHolder.get() );
+ mnHeight = CGBitmapContextGetHeight( maContextHolder.get() );
+ }
+ else
+ {
+ const CGSize aSize = CGLayerGetSize(maLayer.get());
+ mnWidth = static_cast<int>(aSize.width);
+ mnHeight = static_cast<int>(aSize.height);
+ }
+
+ // prepare graphics for drawing
+ const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ CGContextSetFillColorSpace( maContextHolder.get(), aCGColorSpace );
+ CGContextSetStrokeColorSpace( maContextHolder.get(), aCGColorSpace );
+
+ // re-enable XorEmulation for the new context
+ if( mpXorEmulation )
+ {
+ mpXorEmulation->SetTarget(mnWidth, mnHeight, mnBitmapDepth, maContextHolder.get(), maLayer.get());
+ if( mpXorEmulation->IsEnabled() )
+ {
+ maContextHolder.set(mpXorEmulation->GetMaskContext());
+ }
+ }
+
+ // initialize stack of CGContext states
+ maContextHolder.saveState();
+ SetState();
+}
+
+/// From salvd.cxx
+
+void AquaSalVirtualDevice::Destroy()
+{
+ SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::Destroy() this=" << this << " mbForeignContext=" << mbForeignContext );
+
+ if( mbForeignContext )
+ {
+ // Do not delete mxContext that we have received from outside VCL
+ maLayer.set(nullptr);
+ return;
+ }
+
+ if (maLayer.isSet())
+ {
+ if( mpGraphics )
+ {
+ mpGraphics->SetVirDevGraphics(nullptr, nullptr);
+ }
+ CGLayerRelease(maLayer.get());
+ maLayer.set(nullptr);
+ }
+
+ if (maBitmapContext.isSet())
+ {
+ void* pRawData = CGBitmapContextGetData(maBitmapContext.get());
+ std::free(pRawData);
+ CGContextRelease(maBitmapContext.get());
+ maBitmapContext.set(nullptr);
+ }
+}
+
+bool AquaSalVirtualDevice::SetSize( tools::Long nDX, tools::Long nDY )
+{
+ SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
+ " (" << nDX << "x" << nDY << ") mbForeignContext=" << (mbForeignContext ? "YES" : "NO"));
+
+ if( mbForeignContext )
+ {
+ // Do not delete/resize mxContext that we have received from outside VCL
+ return true;
+ }
+
+ if (maLayer.isSet())
+ {
+ const CGSize aSize = CGLayerGetSize(maLayer.get());
+ if( (nDX == aSize.width) && (nDY == aSize.height) )
+ {
+ // Yay, we do not have to do anything :)
+ return true;
+ }
+ }
+
+ Destroy();
+
+ mnWidth = nDX;
+ mnHeight = nDY;
+
+ // create a CGLayer matching to the intended virdev usage
+ CGContextHolder xCGContextHolder;
+ if( mnBitmapDepth && (mnBitmapDepth < 16) )
+ {
+ mnBitmapDepth = 8; // TODO: are 1bit vdevs worth it?
+ const int nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;
+
+ void* pRawData = std::malloc( nBytesPerRow * nDY );
+ maBitmapContext.set(CGBitmapContextCreate( pRawData, nDX, nDY,
+ mnBitmapDepth, nBytesPerRow,
+ GetSalData()->mxGraySpace, kCGImageAlphaNone));
+ xCGContextHolder = maBitmapContext;
+ }
+ else
+ {
+ if (!xCGContextHolder.isSet())
+ {
+ // assert(Application::IsBitmapRendering());
+ mnBitmapDepth = 32;
+
+ const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
+ void* pRawData = std::malloc( nBytesPerRow * nDY );
+ const int nFlags = kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little;
+ maBitmapContext.set(CGBitmapContextCreate(pRawData, nDX, nDY, 8, nBytesPerRow,
+ GetSalData()->mxRGBSpace, nFlags));
+ xCGContextHolder = maBitmapContext;
+ }
+ }
+
+ SAL_WARN_IF(!xCGContextHolder.isSet(), "vcl.quartz", "No context");
+
+ const CGSize aNewSize = { static_cast<CGFloat>(nDX), static_cast<CGFloat>(nDY) };
+ maLayer.set(CGLayerCreateWithContext(xCGContextHolder.get(), aNewSize, nullptr));
+
+ if (maLayer.isSet() && mpGraphics)
+ {
+ // get the matching Quartz context
+ CGContextRef xDrawContext = CGLayerGetContext( maLayer.get() );
+
+ // Here we pass the CGLayerRef that the CGLayerHolder maLayer holds as the first parameter
+ // to SetVirDevGraphics(). That parameter is of type CGLayerHolder, so what we actually pass
+ // is an implicitly constructed *separate* CGLayerHolder. Is that what we want? No idea.
+ // Possibly we could pass just maLayer as such? But doing that does not fix tdf#138122.
+ mpGraphics->SetVirDevGraphics(maLayer.get(), xDrawContext, mnBitmapDepth);
+ }
+
+ return maLayer.isSet();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salgdiutils.cxx b/vcl/osx/salgdiutils.cxx
index 01626d348999..01626d348999 100644
--- a/vcl/quartz/salgdiutils.cxx
+++ b/vcl/osx/salgdiutils.cxx
diff --git a/vcl/osx/salmacos.cxx b/vcl/osx/salmacos.cxx
new file mode 100644
index 000000000000..7d4569d65bca
--- /dev/null
+++ b/vcl/osx/salmacos.cxx
@@ -0,0 +1,387 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// This file contains the macOS-specific versions of the functions which were touched in the commit
+// to fix tdf#138122. The iOS-specific versions of these functions are kept (for now, when this
+// comment is written) as they were before that commit in vcl/isx/salios.cxx.
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <cstddef>
+#include <limits>
+
+#include <o3tl/make_shared.hxx>
+#include <basegfx/vector/b2ivector.hxx>
+#include <tools/color.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/BitmapAccessMode.hxx>
+#include <vcl/BitmapBuffer.hxx>
+#include <vcl/BitmapColor.hxx>
+#include <vcl/BitmapPalette.hxx>
+#include <vcl/ColorMask.hxx>
+#include <vcl/Scanline.hxx>
+
+#include <bitmap/bmpfast.hxx>
+
+#include <quartz/salbmp.h>
+#include <quartz/salgdi.h>
+#include <quartz/salvd.h>
+#include <quartz/utils.h>
+
+#include <osx/saldata.hxx>
+#include <osx/salframe.h>
+#include <osx/salinst.h>
+
+// From salbmp.cxx
+
+bool QuartzSalBitmap::Create(CGLayerHolder const & rLayerHolder, int nBitmapBits, int nX, int nY, int nWidth, int nHeight, bool bFlipped)
+{
+
+ // TODO: Bitmaps from scaled layers are reverted to single precision. This is a workaround only unless bitmaps with precision of
+ // source layer are implemented.
+
+ SAL_WARN_IF(!rLayerHolder.isSet(), "vcl", "QuartzSalBitmap::Create() from non-layered context");
+
+ // sanitize input parameters
+ if( nX < 0 ) {
+ nWidth += nX;
+ nX = 0;
+ }
+
+ if( nY < 0 ) {
+ nHeight += nY;
+ nY = 0;
+ }
+
+ CGSize aLayerSize = CGLayerGetSize(rLayerHolder.get());
+ const float fScale = rLayerHolder.getScale();
+ aLayerSize.width /= fScale;
+ aLayerSize.height /= fScale;
+
+ if( nWidth >= static_cast<int>(aLayerSize.width) - nX )
+ nWidth = static_cast<int>(aLayerSize.width) - nX;
+
+ if( nHeight >= static_cast<int>(aLayerSize.height) - nY )
+ nHeight = static_cast<int>(aLayerSize.height) - nY;
+
+ if( (nWidth < 0) || (nHeight < 0) )
+ nWidth = nHeight = 0;
+
+ // initialize properties
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ mnBits = nBitmapBits ? nBitmapBits : 32;
+
+ // initialize drawing context
+ CreateContext();
+
+ // copy layer content into the bitmap buffer
+ const CGPoint aSrcPoint = { static_cast<CGFloat>(-nX * fScale), static_cast<CGFloat>(-nY * fScale) };
+ if (maGraphicContext.isSet())
+ {
+ if( bFlipped )
+ {
+ CGContextTranslateCTM(maGraphicContext.get(), 0, +mnHeight);
+ CGContextScaleCTM(maGraphicContext.get(), +1, -1);
+ }
+ maGraphicContext.saveState();
+ CGContextScaleCTM(maGraphicContext.get(), 1 / fScale, 1 / fScale);
+ CGContextDrawLayerAtPoint(maGraphicContext.get(), aSrcPoint, rLayerHolder.get());
+ maGraphicContext.restoreState();
+ }
+ return true;
+}
+
+// From salgdicommon.cxx
+
+void AquaSalGraphics::copyBits(const SalTwoRect &rPosAry, SalGraphics *pSrcGraphics)
+{
+ if (!pSrcGraphics)
+ pSrcGraphics = this;
+ AquaSalGraphics *pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics);
+ if (rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0 || rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0)
+ return;
+ if (!maContextHolder.isSet())
+ return;
+
+ SAL_WARN_IF (!pSrc->maLayer.isSet(), "vcl.quartz", "AquaSalGraphics::copyBits() from non-layered graphics this=" << this);
+
+ // Layered graphics are copied by AquaSalGraphics::copyScaledArea() which is able to consider the layer's scaling.
+
+ if (pSrc->maLayer.isSet())
+ copyScaledArea(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, pSrcGraphics);
+ else
+ {
+ ApplyXorContext();
+ pSrc->ApplyXorContext();
+ std::shared_ptr<SalBitmap> pBitmap = pSrc->getBitmap(rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
+ if (pBitmap)
+ {
+ SalTwoRect aPosAry(rPosAry);
+ aPosAry.mnSrcX = 0;
+ aPosAry.mnSrcY = 0;
+ drawBitmap(aPosAry, *pBitmap);
+ }
+ }
+}
+
+void AquaSalGraphics::copyArea(tools::Long nDstX, tools::Long nDstY,tools::Long nSrcX, tools::Long nSrcY,
+ tools::Long nSrcWidth, tools::Long nSrcHeight, bool)
+{
+ if (!maContextHolder.isSet())
+ return;
+
+ // Functionality is implemented in protected member function AquaSalGraphics::copyScaledArea() which requires an additional
+ // parameter of type SalGraphics to be used in AquaSalGraphics::copyBits() too.
+
+ copyScaledArea(nDstX, nDstY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, this);
+}
+
+void AquaSalGraphics::copyScaledArea(tools::Long nDstX, tools::Long nDstY,tools::Long nSrcX, tools::Long nSrcY,
+ tools::Long nSrcWidth, tools::Long nSrcHeight, SalGraphics *pSrcGraphics)
+{
+ if (!pSrcGraphics)
+ pSrcGraphics = this;
+ AquaSalGraphics *pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics);
+
+ SAL_WARN_IF(!maLayer.isSet(), "vcl.quartz",
+ "AquaSalGraphics::copyScaledArea() without graphics context or for non-layered graphics this=" << this);
+
+ if (!maContextHolder.isSet() || !maLayer.isSet())
+ return;
+
+ // Determine scaled geometry of source and target area assuming source and target area have the same scale
+
+ float fScale = maLayer.getScale();
+ CGFloat nScaledSourceX = nSrcX * fScale;
+ CGFloat nScaledSourceY = nSrcY * fScale;
+ CGFloat nScaledTargetX = nDstX * fScale;
+ CGFloat nScaledTargetY = nDstY * fScale;
+ CGFloat nScaledSourceWidth = nSrcWidth * fScale;
+ CGFloat nScaledSourceHeight = nSrcHeight * fScale;
+
+ // Apply XOR context and get copy context from current graphics context or XOR context
+
+ ApplyXorContext();
+ maContextHolder.saveState();
+ CGContextRef xCopyContext = maContextHolder.get();
+ if (mpXorEmulation && mpXorEmulation->IsEnabled())
+ xCopyContext = mpXorEmulation->GetTargetContext();
+
+ // Set scale matrix of copy context to consider layer scaling
+
+ CGContextScaleCTM(xCopyContext, 1 / fScale, 1 / fScale);
+
+ // Creating an additional layer is required for drawing with the required scale and extent at the drawing destination
+ // thereafter.
+
+ CGLayerHolder aSourceLayerHolder(pSrc->maLayer);
+ const CGSize aSourceSize = CGSizeMake(nScaledSourceWidth, nScaledSourceHeight);
+ aSourceLayerHolder.set(CGLayerCreateWithContext(xCopyContext, aSourceSize, nullptr));
+ const CGContextRef xSourceContext = CGLayerGetContext(aSourceLayerHolder.get());
+ CGPoint aSrcPoint = CGPointMake(-nScaledSourceX, -nScaledSourceY);
+ if (pSrc->IsFlipped())
+ {
+ CGContextTranslateCTM(xSourceContext, 0, nScaledSourceHeight);
+ CGContextScaleCTM(xSourceContext, 1, -1);
+ aSrcPoint.y = nScaledSourceY + nScaledSourceHeight - mnHeight * fScale;
+ }
+ CGContextSetBlendMode(xSourceContext, kCGBlendModeCopy);
+ CGContextDrawLayerAtPoint(xSourceContext, aSrcPoint, pSrc->maLayer.get());
+
+ // Copy source area from additional layer to traget area
+
+ const CGRect aTargetRect = CGRectMake(nScaledTargetX, nScaledTargetY, nScaledSourceWidth, nScaledSourceHeight);
+ CGContextSetBlendMode(xCopyContext, kCGBlendModeCopy);
+ CGContextDrawLayerInRect(xCopyContext, aTargetRect, aSourceLayerHolder.get());
+
+ // Housekeeping on exit
+
+ maContextHolder.restoreState();
+ if (aSourceLayerHolder.get() != maLayer.get())
+ CGLayerRelease(aSourceLayerHolder.get());
+ RefreshRect(nDstX, nDstY, nSrcWidth, nSrcHeight);
+}
+
+void AquaSalGraphics::SetVirDevGraphics(CGLayerHolder const &rLayer, CGContextRef xContext, int nBitmapDepth)
+{
+ SAL_INFO("vcl.quartz", "SetVirDevGraphics() this=" << this << " layer=" << rLayer.get() << " context=" << xContext);
+
+ // Set member variables
+
+ InvalidateContext();
+ mbWindow = false;
+ mbPrinter = false;
+ mbVirDev = true;
+ maLayer = rLayer;
+ mnBitmapDepth = nBitmapDepth;
+
+ // Get size and scale from layer if set else from bitmap and AquaSalGraphics::GetWindowScaling(), which is used to determine
+ // scaling for direct graphics output too
+
+ CGSize aSize;
+ float fScale;
+ if (maLayer.isSet())
+ {
+ maContextHolder.set(CGLayerGetContext(maLayer.get()));
+ aSize = CGLayerGetSize(maLayer.get());
+ fScale = maLayer.getScale();
+ }
+ else
+ {
+ maContextHolder.set(xContext);
+ if (!xContext)
+ return;
+ aSize.width = CGBitmapContextGetWidth(xContext);
+ aSize.height = CGBitmapContextGetHeight(xContext);
+ fScale = GetWindowScaling();
+ }
+ mnWidth = aSize.width / fScale;
+ mnHeight = aSize.height / fScale;
+
+ // Set color space for fill and stroke
+
+ CGColorSpaceRef aColorSpace = GetSalData()->mxRGBSpace;
+ CGContextSetFillColorSpace(maContextHolder.get(), aColorSpace);
+ CGContextSetStrokeColorSpace(maContextHolder.get(), aColorSpace);
+
+ // Apply scale matrix to virtual device graphics
+
+ CGContextScaleCTM(maContextHolder.get(), fScale, fScale);
+
+ // Apply XOR emulation if required
+
+ if (mpXorEmulation)
+ {
+ mpXorEmulation->SetTarget(mnWidth, mnHeight, mnBitmapDepth, maContextHolder.get(), maLayer.get());
+ if (mpXorEmulation->IsEnabled())
+ maContextHolder.set(mpXorEmulation->GetMaskContext());
+ }
+
+ // Housekeeping on exit
+
+ maContextHolder.saveState();
+ SetState();
+
+ SAL_INFO("vcl.quartz", "SetVirDevGraphics() this=" << this <<
+ " (" << mnWidth << "x" << mnHeight << ") fScale=" << fScale << " mnBitmapDepth=" << mnBitmapDepth);
+}
+
+// From salvd.cxx
+
+void AquaSalVirtualDevice::Destroy()
+{
+ SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::Destroy() this=" << this << " mbForeignContext=" << mbForeignContext );
+
+ if( mbForeignContext )
+ {
+ // Do not delete mxContext that we have received from outside VCL
+ maLayer.set(nullptr);
+ return;
+ }
+
+ if (maLayer.isSet())
+ {
+ if( mpGraphics )
+ {
+ mpGraphics->SetVirDevGraphics(nullptr, nullptr);
+ }
+ CGLayerRelease(maLayer.get());
+ maLayer.set(nullptr);
+ }
+
+ if (maBitmapContext.isSet())
+ {
+ CGContextRelease(maBitmapContext.get());
+ maBitmapContext.set(nullptr);
+ }
+}
+
+bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY)
+{
+ SAL_INFO("vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
+ " (" << nDX << "x" << nDY << ") mbForeignContext=" << (mbForeignContext ? "YES" : "NO"));
+
+ // Do not delete/resize graphics context if it has been received from outside VCL
+
+ if (mbForeignContext)
+ return true;
+
+ // Do not delete/resize graphics context if no change of geometry has been requested
+
+ float fScale;
+ if (maLayer.isSet())
+ {
+ fScale = maLayer.getScale();
+ const CGSize aSize = CGLayerGetSize(maLayer.get());
+ if ((nDX == aSize.width / fScale) && (nDY == aSize.height / fScale))
+ return true;
+ }
+
+ // Destroy graphics context if change of geometry has been requested
+
+ Destroy();
+
+ // Prepare new graphics context for initialization, use scaling independent of prior graphics context calculated by
+ // AquaSalGraphics::GetWindowScaling(), which is used to determine scaling for direct graphics output too
+
+ mnWidth = nDX;
+ mnHeight = nDY;
+ fScale = mpGraphics->GetWindowScaling();
+ CGColorSpaceRef aColorSpace;
+ uint32_t nFlags;
+ if (mnBitmapDepth && (mnBitmapDepth < 16))
+ {
+ mnBitmapDepth = 8;
+ aColorSpace = GetSalData()->mxGraySpace;
+ nFlags = kCGImageAlphaNone;
+ }
+ else
+ {
+ mnBitmapDepth = 32;
+ aColorSpace = GetSalData()->mxRGBSpace;
+
+ nFlags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
+ }
+
+ // Allocate buffer for virtual device graphics as bitmap context to store graphics with highest required (scaled) resolution
+
+ size_t nScaledWidth = mnWidth * fScale;
+ size_t nScaledHeight = mnHeight * fScale;
+ size_t nBytesPerRow = mnBitmapDepth * nScaledWidth / 8;
+ maBitmapContext.set(CGBitmapContextCreate(nullptr, nScaledWidth, nScaledHeight, 8, nBytesPerRow, aColorSpace, nFlags));
+
+ SAL_INFO("vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
+ " fScale=" << fScale << " mnBitmapDepth=" << mnBitmapDepth);
+
+ CGSize aLayerSize = { static_cast<CGFloat>(nScaledWidth), static_cast<CGFloat>(nScaledHeight) };
+ maLayer.set(CGLayerCreateWithContext(maBitmapContext.get(), aLayerSize, nullptr));
+ maLayer.setScale(fScale);
+ mpGraphics->SetVirDevGraphics(maLayer, CGLayerGetContext(maLayer.get()), mnBitmapDepth);
+
+ SAL_WARN_IF(!maBitmapContext.isSet(), "vcl.quartz", "No context");
+
+ return maLayer.isSet();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salbmp.cxx b/vcl/quartz/salbmp.cxx
index cf1f26648b7f..a1570dd04ffb 100644
--- a/vcl/quartz/salbmp.cxx
+++ b/vcl/quartz/salbmp.cxx
@@ -69,64 +69,6 @@ QuartzSalBitmap::~QuartzSalBitmap()
doDestroy();
}
-bool QuartzSalBitmap::Create(CGLayerHolder const & rLayerHolder, int nBitmapBits, int nX, int nY, int nWidth, int nHeight, bool bFlipped)
-{
-
- // TODO: Bitmaps from scaled layers are reverted to single precision. This is a workaround only unless bitmaps with precision of
- // source layer are implemented.
-
- SAL_WARN_IF(!rLayerHolder.isSet(), "vcl", "QuartzSalBitmap::Create() from non-layered context");
-
- // sanitize input parameters
- if( nX < 0 ) {
- nWidth += nX;
- nX = 0;
- }
-
- if( nY < 0 ) {
- nHeight += nY;
- nY = 0;
- }
-
- CGSize aLayerSize = CGLayerGetSize(rLayerHolder.get());
- const float fScale = rLayerHolder.getScale();
- aLayerSize.width /= fScale;
- aLayerSize.height /= fScale;
-
- if( nWidth >= static_cast<int>(aLayerSize.width) - nX )
- nWidth = static_cast<int>(aLayerSize.width) - nX;
-
- if( nHeight >= static_cast<int>(aLayerSize.height) - nY )
- nHeight = static_cast<int>(aLayerSize.height) - nY;
-
- if( (nWidth < 0) || (nHeight < 0) )
- nWidth = nHeight = 0;
-
- // initialize properties
- mnWidth = nWidth;
- mnHeight = nHeight;
- mnBits = nBitmapBits ? nBitmapBits : 32;
-
- // initialize drawing context
- CreateContext();
-
- // copy layer content into the bitmap buffer
- const CGPoint aSrcPoint = { static_cast<CGFloat>(-nX * fScale), static_cast<CGFloat>(-nY * fScale) };
- if (maGraphicContext.isSet())
- {
- if( bFlipped )
- {
- CGContextTranslateCTM(maGraphicContext.get(), 0, +mnHeight);
- CGContextScaleCTM(maGraphicContext.get(), +1, -1);
- }
- maGraphicContext.saveState();
- CGContextScaleCTM(maGraphicContext.get(), 1 / fScale, 1 / fScale);
- CGContextDrawLayerAtPoint(maGraphicContext.get(), aSrcPoint, rLayerHolder.get());
- maGraphicContext.restoreState();
- }
- return true;
-}
-
bool QuartzSalBitmap::Create( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rBitmapPalette )
{
if( !isValidBitCount( nBits ) )
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index 0597fe3d021d..33ffc43741a1 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -267,117 +267,6 @@ void AquaSalGraphics::ApplyXorContext()
}
}
-void AquaSalGraphics::copyBits(const SalTwoRect &rPosAry, SalGraphics *pSrcGraphics)
-{
- if (!pSrcGraphics)
- pSrcGraphics = this;
- AquaSalGraphics *pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics);
- if (rPosAry.mnSrcWidth <= 0 || rPosAry.mnSrcHeight <= 0 || rPosAry.mnDestWidth <= 0 || rPosAry.mnDestHeight <= 0)
- return;
- if (!maContextHolder.isSet())
- return;
-
- SAL_WARN_IF (!pSrc->maLayer.isSet(), "vcl.quartz", "AquaSalGraphics::copyBits() from non-layered graphics this=" << this);
-
- // Layered graphics are copied by AquaSalGraphics::copyScaledArea() which is able to consider the layer's scaling.
-
- if (pSrc->maLayer.isSet())
- copyScaledArea(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, pSrcGraphics);
- else
- {
- ApplyXorContext();
- pSrc->ApplyXorContext();
- std::shared_ptr<SalBitmap> pBitmap = pSrc->getBitmap(rPosAry.mnSrcX, rPosAry.mnSrcY,
- rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
- if (pBitmap)
- {
- SalTwoRect aPosAry(rPosAry);
- aPosAry.mnSrcX = 0;
- aPosAry.mnSrcY = 0;
- drawBitmap(aPosAry, *pBitmap);
- }
- }
-}
-
-void AquaSalGraphics::copyArea(tools::Long nDstX, tools::Long nDstY,tools::Long nSrcX, tools::Long nSrcY,
- tools::Long nSrcWidth, tools::Long nSrcHeight, bool)
-{
- if (!maContextHolder.isSet())
- return;
-
- // Functionality is implemented in protected member function AquaSalGraphics::copyScaledArea() which requires an additional
- // parameter of type SalGraphics to be used in AquaSalGraphics::copyBits() too.
-
- copyScaledArea(nDstX, nDstY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, this);
-}
-
-void AquaSalGraphics::copyScaledArea(tools::Long nDstX, tools::Long nDstY,tools::Long nSrcX, tools::Long nSrcY,
- tools::Long nSrcWidth, tools::Long nSrcHeight, SalGraphics *pSrcGraphics)
-{
- if (!pSrcGraphics)
- pSrcGraphics = this;
- AquaSalGraphics *pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics);
-
- SAL_WARN_IF(!maLayer.isSet(), "vcl.quartz",
- "AquaSalGraphics::copyScaledArea() without graphics context or for non-layered graphics this=" << this);
-
- if (!maContextHolder.isSet() || !maLayer.isSet())
- return;
-
- // Determine scaled geometry of source and target area assuming source and target area have the same scale
-
- float fScale = maLayer.getScale();
- CGFloat nScaledSourceX = nSrcX * fScale;
- CGFloat nScaledSourceY = nSrcY * fScale;
- CGFloat nScaledTargetX = nDstX * fScale;
- CGFloat nScaledTargetY = nDstY * fScale;
- CGFloat nScaledSourceWidth = nSrcWidth * fScale;
- CGFloat nScaledSourceHeight = nSrcHeight * fScale;
-
- // Apply XOR context and get copy context from current graphics context or XOR context
-
- ApplyXorContext();
- maContextHolder.saveState();
- CGContextRef xCopyContext = maContextHolder.get();
- if (mpXorEmulation && mpXorEmulation->IsEnabled())
- xCopyContext = mpXorEmulation->GetTargetContext();
-
- // Set scale matrix of copy context to consider layer scaling
-
- CGContextScaleCTM(xCopyContext, 1 / fScale, 1 / fScale);
-
- // Creating an additional layer is required for drawing with the required scale and extent at the drawing destination
- // thereafter.
-
- CGLayerHolder aSourceLayerHolder(pSrc->maLayer);
- const CGSize aSourceSize = CGSizeMake(nScaledSourceWidth, nScaledSourceHeight);
- aSourceLayerHolder.set(CGLayerCreateWithContext(xCopyContext, aSourceSize, nullptr));
- const CGContextRef xSourceContext = CGLayerGetContext(aSourceLayerHolder.get());
- CGPoint aSrcPoint = CGPointMake(-nScaledSourceX, -nScaledSourceY);
- if (pSrc->IsFlipped())
- {
- CGContextTranslateCTM(xSourceContext, 0, nScaledSourceHeight);
- CGContextScaleCTM(xSourceContext, 1, -1);
- aSrcPoint.y = nScaledSourceY + nScaledSourceHeight - mnHeight * fScale;
- }
- CGContextSetBlendMode(xSourceContext, kCGBlendModeCopy);
- CGContextDrawLayerAtPoint(xSourceContext, aSrcPoint, pSrc->maLayer.get());
-
- // Copy source area from additional layer to traget area
-
- const CGRect aTargetRect = CGRectMake(nScaledTargetX, nScaledTargetY, nScaledSourceWidth, nScaledSourceHeight);
- CGContextSetBlendMode(xCopyContext, kCGBlendModeCopy);
- CGContextDrawLayerInRect(xCopyContext, aTargetRect, aSourceLayerHolder.get());
-
- // Housekeeping on exit
-
- maContextHolder.restoreState();
- if (aSourceLayerHolder.get() != maLayer.get())
- CGLayerRelease(aSourceLayerHolder.get());
- RefreshRect(nDstX, nDstY, nSrcWidth, nSrcHeight);
-}
-
#ifndef IOS
void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics )
@@ -1826,74 +1715,4 @@ bool XorEmulation::UpdateTarget()
return true;
}
-void AquaSalGraphics::SetVirDevGraphics(CGLayerHolder const &rLayer, CGContextRef xContext, int nBitmapDepth)
-{
- SAL_INFO("vcl.quartz", "SetVirDevGraphics() this=" << this << " layer=" << rLayer.get() << " context=" << xContext);
-
- // Set member variables
-
- InvalidateContext();
- mbWindow = false;
- mbPrinter = false;
- mbVirDev = true;
- maLayer = rLayer;
- mnBitmapDepth = nBitmapDepth;
-
-#ifdef IOS
-
- mbForeignContext = xContext != NULL;
-
-#endif
-
- // Get size and scale from layer if set else from bitmap and AquaSalGraphics::GetWindowScaling(), which is used to determine
- // scaling for direct graphics output too
-
- CGSize aSize;
- float fScale;
- if (maLayer.isSet())
- {
- maContextHolder.set(CGLayerGetContext(maLayer.get()));
- aSize = CGLayerGetSize(maLayer.get());
- fScale = maLayer.getScale();
- }
- else
- {
- maContextHolder.set(xContext);
- if (!xContext)
- return;
- aSize.width = CGBitmapContextGetWidth(xContext);
- aSize.height = CGBitmapContextGetHeight(xContext);
- fScale = GetWindowScaling();
- }
- mnWidth = aSize.width / fScale;
- mnHeight = aSize.height / fScale;
-
- // Set color space for fill and stroke
-
- CGColorSpaceRef aColorSpace = GetSalData()->mxRGBSpace;
- CGContextSetFillColorSpace(maContextHolder.get(), aColorSpace);
- CGContextSetStrokeColorSpace(maContextHolder.get(), aColorSpace);
-
- // Apply scale matrix to virtual device graphics
-
- CGContextScaleCTM(maContextHolder.get(), fScale, fScale);
-
- // Apply XOR emulation if required
-
- if (mpXorEmulation)
- {
- mpXorEmulation->SetTarget(mnWidth, mnHeight, mnBitmapDepth, maContextHolder.get(), maLayer.get());
- if (mpXorEmulation->IsEnabled())
- maContextHolder.set(mpXorEmulation->GetMaskContext());
- }
-
- // Housekeeping on exit
-
- maContextHolder.saveState();
- SetState();
-
- SAL_INFO("vcl.quartz", "SetVirDevGraphics() this=" << this <<
- " (" << mnWidth << "x" << mnHeight << ") fScale=" << fScale << " mnBitmapDepth=" << mnBitmapDepth);
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/salvd.cxx b/vcl/quartz/salvd.cxx
index 5d7facd3ef38..9f6bfdd930aa 100644
--- a/vcl/quartz/salvd.cxx
+++ b/vcl/quartz/salvd.cxx
@@ -161,34 +161,6 @@ AquaSalVirtualDevice::~AquaSalVirtualDevice()
Destroy();
}
-void AquaSalVirtualDevice::Destroy()
-{
- SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::Destroy() this=" << this << " mbForeignContext=" << mbForeignContext );
-
- if( mbForeignContext )
- {
- // Do not delete mxContext that we have received from outside VCL
- maLayer.set(nullptr);
- return;
- }
-
- if (maLayer.isSet())
- {
- if( mpGraphics )
- {
- mpGraphics->SetVirDevGraphics(nullptr, nullptr);
- }
- CGLayerRelease(maLayer.get());
- maLayer.set(nullptr);
- }
-
- if (maBitmapContext.isSet())
- {
- CGContextRelease(maBitmapContext.get());
- maBitmapContext.set(nullptr);
- }
-}
-
SalGraphics* AquaSalVirtualDevice::AcquireGraphics()
{
if( mbGraphicsUsed || !mpGraphics )
@@ -204,80 +176,4 @@ void AquaSalVirtualDevice::ReleaseGraphics( SalGraphics* )
mbGraphicsUsed = false;
}
-bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY)
-{
- SAL_INFO("vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
- " (" << nDX << "x" << nDY << ") mbForeignContext=" << (mbForeignContext ? "YES" : "NO"));
-
- // Do not delete/resize graphics context if it has been received from outside VCL
-
- if (mbForeignContext)
- return true;
-
- // Do not delete/resize graphics context if no change of geometry has been requested
-
- float fScale;
- if (maLayer.isSet())
- {
- fScale = maLayer.getScale();
- const CGSize aSize = CGLayerGetSize(maLayer.get());
- if ((nDX == aSize.width / fScale) && (nDY == aSize.height / fScale))
- return true;
- }
-
- // Destroy graphics context if change of geometry has been requested
-
- Destroy();
-
- // Prepare new graphics context for initialization, use scaling independent of prior graphics context calculated by
- // AquaSalGraphics::GetWindowScaling(), which is used to determine scaling for direct graphics output too
-
- mnWidth = nDX;
- mnHeight = nDY;
- fScale = mpGraphics->GetWindowScaling();
- CGColorSpaceRef aColorSpace;
- uint32_t nFlags;
- if (mnBitmapDepth && (mnBitmapDepth < 16))
- {
- mnBitmapDepth = 8;
- aColorSpace = GetSalData()->mxGraySpace;
- nFlags = kCGImageAlphaNone;
- }
- else
- {
- mnBitmapDepth = 32;
- aColorSpace = GetSalData()->mxRGBSpace;
-
-#ifdef MACOSX
-
- nFlags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
-
-#else
-
- nFlags = kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little;
-
-#endif
-
- }
-
- // Allocate buffer for virtual device graphics as bitmap context to store graphics with highest required (scaled) resolution
-
- size_t nScaledWidth = mnWidth * fScale;
- size_t nScaledHeight = mnHeight * fScale;
- size_t nBytesPerRow = mnBitmapDepth * nScaledWidth / 8;
- maBitmapContext.set(CGBitmapContextCreate(nullptr, nScaledWidth, nScaledHeight, 8, nBytesPerRow, aColorSpace, nFlags));
-
- SAL_INFO("vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
- " fScale=" << fScale << " mnBitmapDepth=" << mnBitmapDepth);
-
- CGSize aLayerSize = { static_cast<CGFloat>(nScaledWidth), static_cast<CGFloat>(nScaledHeight) };
- maLayer.set(CGLayerCreateWithContext(maBitmapContext.get(), aLayerSize, nullptr));
- maLayer.setScale(fScale);
- mpGraphics->SetVirDevGraphics(maLayer, CGLayerGetContext(maLayer.get()), mnBitmapDepth);
-
- SAL_WARN_IF(!maBitmapContext.isSet(), "vcl.quartz", "No context");
-
- return maLayer.isSet();
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */