summaryrefslogtreecommitdiff
path: root/vcl/quartz/salgdiutils.cxx
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2013-12-05 22:01:05 +0200
committerTor Lillqvist <tml@collabora.com>2013-12-06 15:05:00 +0200
commitc49721950cb3d897b35f08bf871239308680b18e (patch)
tree6a76e91557328b9195960d065065b1a6914bf9be /vcl/quartz/salgdiutils.cxx
parent693eced961a3d3014d15e0a406f4e001ee817522 (diff)
Re-organize OS X and iOS code in vcl a bit
Now with the ATSUI code gone is a good time for some re-organisation. Get rid of "aqua" in file names and the separate "coretext" folders. CoreText is all we use now for OS X (and has always been so for iOS), so no need for a "coretext" folder, we can keep the CoreText-using code under "quartz". Keep OS X -specific code in "osx". Ditto for headers. Keep "Aqua" as part of class names for now, though. This is also preparation for planned further unification between OS X and iOS code. Change-Id: Ic60bd73fea4ab98183e7c8a09c7d3f66b9a34223
Diffstat (limited to 'vcl/quartz/salgdiutils.cxx')
-rw-r--r--vcl/quartz/salgdiutils.cxx299
1 files changed, 299 insertions, 0 deletions
diff --git a/vcl/quartz/salgdiutils.cxx b/vcl/quartz/salgdiutils.cxx
new file mode 100644
index 000000000000..f31b09a40d12
--- /dev/null
+++ b/vcl/quartz/salgdiutils.cxx
@@ -0,0 +1,299 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 .
+ */
+
+
+#include "basebmp/scanlineformats.hxx"
+#include "basebmp/color.hxx"
+
+#include "basegfx/range/b2drectangle.hxx"
+#include "basegfx/range/b2irange.hxx"
+#include "basegfx/vector/b2ivector.hxx"
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/polygon/b2dpolygontools.hxx"
+
+#include "vcl/svapp.hxx"
+
+#include "quartz/salgdi.h"
+#include "osx/salframe.h"
+#include "osx/saldata.hxx"
+
+// ----------------------------------------------------------------------
+
+void AquaSalGraphics::SetWindowGraphics( AquaSalFrame* pFrame )
+{
+ mpFrame = pFrame;
+
+ mbWindow = true;
+ mbPrinter = false;
+ mbVirDev = false;
+}
+
+void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, long nDPIY, double fScale )
+{
+ mbWindow = false;
+ mbPrinter = true;
+ mbVirDev = false;
+
+ mrContext = xContext;
+ mfFakeDPIScale = fScale;
+ mnRealDPIX = nDPIX;
+ mnRealDPIY = nDPIY;
+
+ // a previously set clip path is now invalid
+ if( mxClipPath )
+ {
+ CGPathRelease( mxClipPath );
+ mxClipPath = NULL;
+ }
+
+ if( mrContext )
+ {
+ CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
+ CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
+ CGContextSaveGState( mrContext );
+ SetState();
+ }
+}
+
+void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContext,
+ int nBitmapDepth )
+{
+ mbWindow = false;
+ mbPrinter = false;
+ mbVirDev = true;
+
+ // set graphics properties
+ mxLayer = xLayer;
+ mrContext = xContext;
+ mnBitmapDepth = nBitmapDepth;
+
+ // return early if the virdev is being destroyed
+ if( !xContext )
+ return;
+
+ // get new graphics properties
+ if( !mxLayer )
+ {
+ mnWidth = CGBitmapContextGetWidth( mrContext );
+ mnHeight = CGBitmapContextGetHeight( mrContext );
+ }
+ else
+ {
+ const CGSize aSize = CGLayerGetSize( mxLayer );
+ mnWidth = static_cast<int>(aSize.width);
+ mnHeight = static_cast<int>(aSize.height);
+ }
+
+ // prepare graphics for drawing
+ const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ CGContextSetFillColorSpace( mrContext, aCGColorSpace );
+ CGContextSetStrokeColorSpace( mrContext, aCGColorSpace );
+
+ // re-enable XorEmulation for the new context
+ if( mpXorEmulation )
+ {
+ mpXorEmulation->SetTarget( mnWidth, mnHeight, mnBitmapDepth, mrContext, mxLayer );
+ if( mpXorEmulation->IsEnabled() )
+ mrContext = mpXorEmulation->GetMaskContext();
+ }
+
+ // initialize stack of CGContext states
+ CGContextSaveGState( mrContext );
+ SetState();
+}
+
+// ----------------------------------------------------------------------
+
+void AquaSalGraphics::InvalidateContext()
+{
+ UnsetState();
+ mrContext = 0;
+}
+
+// ----------------------------------------------------------------------
+
+void AquaSalGraphics::UnsetState()
+{
+ if( mrContext )
+ {
+ CGContextRestoreGState( mrContext );
+ mrContext = 0;
+ }
+ if( mxClipPath )
+ {
+ CGPathRelease( mxClipPath );
+ mxClipPath = NULL;
+ }
+}
+
+void AquaSalGraphics::SetState()
+{
+ CGContextRestoreGState( mrContext );
+ CGContextSaveGState( mrContext );
+
+ // setup clipping
+ if( mxClipPath )
+ {
+ CGContextBeginPath( mrContext ); // discard any existing path
+ CGContextAddPath( mrContext, mxClipPath ); // set the current path to the clipping path
+ CGContextClip( mrContext ); // use it for clipping
+ }
+
+ // set RGB colorspace and line and fill colors
+ CGContextSetFillColor( mrContext, maFillColor.AsArray() );
+ CGContextSetStrokeColor( mrContext, maLineColor.AsArray() );
+ CGContextSetShouldAntialias( mrContext, false );
+ if( mnXorMode == 2 )
+ CGContextSetBlendMode( mrContext, kCGBlendModeDifference );
+}
+
+// ----------------------------------------------------------------------
+
+bool AquaSalGraphics::CheckContext()
+{
+ if( mbWindow && mpFrame != NULL )
+ {
+ const unsigned int nWidth = mpFrame->maGeometry.nWidth;
+ const unsigned int nHeight = mpFrame->maGeometry.nHeight;
+
+ CGContextRef rReleaseContext = 0;
+ CGLayerRef rReleaseLayer = NULL;
+
+ // check if a new drawing context is needed (e.g. after a resize)
+ if( (unsigned(mnWidth) != nWidth) || (unsigned(mnHeight) != nHeight) )
+ {
+ mnWidth = nWidth;
+ mnHeight = nHeight;
+ // prepare to release the corresponding resources
+ rReleaseContext = mrContext;
+ rReleaseLayer = mxLayer;
+ mrContext = NULL;
+ mxLayer = NULL;
+ }
+
+ if( !mrContext )
+ {
+ const CGSize aLayerSize = { static_cast<CGFloat>(nWidth), static_cast<CGFloat>(nHeight) };
+ NSGraphicsContext* pNSGContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getNSWindow()];
+ CGContextRef xCGContext = reinterpret_cast<CGContextRef>([pNSGContext graphicsPort]);
+ mxLayer = CGLayerCreateWithContext( xCGContext, aLayerSize, NULL );
+ if( mxLayer )
+ mrContext = CGLayerGetContext( mxLayer );
+
+ if( mrContext )
+ {
+ // copy original layer to resized layer
+ if( rReleaseLayer )
+ CGContextDrawLayerAtPoint( mrContext, CGPointZero, rReleaseLayer );
+
+ CGContextTranslateCTM( mrContext, 0, nHeight );
+ CGContextScaleCTM( mrContext, 1.0, -1.0 );
+ CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
+ CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
+ CGContextSaveGState( mrContext );
+ SetState();
+
+ // re-enable XOR emulation for the new context
+ if( mpXorEmulation )
+ mpXorEmulation->SetTarget( mnWidth, mnHeight, mnBitmapDepth, mrContext, mxLayer );
+ }
+ }
+
+ if( rReleaseLayer )
+ CGLayerRelease( rReleaseLayer );
+ else if( rReleaseContext )
+ CGContextRelease( rReleaseContext );
+ }
+
+ DBG_ASSERT( mrContext || mbPrinter, "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!\n" );
+ return (mrContext != NULL);
+}
+
+CGContextRef AquaSalGraphics::GetContext()
+{
+ if(!mrContext)
+ {
+ CheckContext();
+ }
+ return mrContext;
+}
+
+void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeight)
+{
+ if( ! mbWindow ) // view only on Window graphics
+ return;
+
+ if( mpFrame )
+ {
+ // update a little more around the designated rectangle
+ // this helps with antialiased rendering
+ const Rectangle aVclRect(Point(static_cast<long int>(lX-1),
+ static_cast<long int>(lY-1) ),
+ Size( static_cast<long int>(lWidth+2),
+ static_cast<long int>(lHeight+2) ) );
+ mpFrame->maInvalidRect.Union( aVclRect );
+ }
+}
+
+CGPoint* AquaSalGraphics::makeCGptArray(sal_uLong nPoints, const SalPoint* pPtAry)
+{
+ CGPoint *CGpoints = new CGPoint[nPoints];
+ if ( CGpoints )
+ {
+ for(sal_uLong i=0;i<nPoints;i++)
+ {
+ CGpoints[i].x = (float)(pPtAry[i].mnX);
+ CGpoints[i].y = (float)(pPtAry[i].mnY);
+ }
+ }
+ return CGpoints;
+}
+
+// -----------------------------------------------------------------------
+
+void AquaSalGraphics::UpdateWindow( NSRect& )
+{
+ if( !mpFrame )
+ return;
+ NSGraphicsContext* pContext = [NSGraphicsContext currentContext];
+ if( (mxLayer != NULL) && (pContext != NULL) )
+ {
+ CGContextRef rCGContext = reinterpret_cast<CGContextRef>([pContext graphicsPort]);
+
+ CGMutablePathRef rClip = mpFrame->getClipPath();
+ if( rClip )
+ {
+ CGContextSaveGState( rCGContext );
+ CGContextBeginPath( rCGContext );
+ CGContextAddPath( rCGContext, rClip );
+ CGContextClip( rCGContext );
+ }
+
+ ApplyXorContext();
+ CGContextDrawLayerAtPoint( rCGContext, CGPointZero, mxLayer );
+ if( rClip ) // cleanup clipping
+ CGContextRestoreGState( rCGContext );
+ }
+ else
+ DBG_ASSERT( mpFrame->mbInitShow, "UpdateWindow called on uneligible graphics" );
+}
+
+// -----------------------------------------------------------------------
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */