merge the formfield patch from ooo-build
[ooovba.git] / vcl / aqua / source / gdi / salvd.cxx
blobc30a836597b261890cc05ec1175db0bf217fb6f6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salvd.cxx,v $
10 * $Revision: 1.27 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include "salvd.h"
35 #include "salinst.h"
36 #include "salgdi.h"
37 #include "saldata.hxx"
38 #include "salframe.h"
40 #include "vcl/sysdata.hxx"
42 // -----------------------------------------------------------------------
44 SalVirtualDevice* AquaSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
45 long nDX, long nDY, USHORT nBitCount, const SystemGraphicsData *pData )
47 // #i92075# can be called first in a thread
48 SalData::ensureThreadAutoreleasePool();
50 return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
53 // -----------------------------------------------------------------------
55 void AquaSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
57 delete pDevice;
60 // =======================================================================
62 AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX, long nDY, USHORT nBitCount, const SystemGraphicsData *pData )
63 : mbGraphicsUsed( false )
64 , mxBitmapContext( NULL )
65 , mnBitmapDepth( 0 )
66 , mxLayer( NULL )
68 if( pGraphic && pData && pData->rCGContext )
70 // Create virtual device based on existing SystemGraphicsData
71 // We ignore nDx and nDY, as the desired size comes from the SystemGraphicsData
72 mbForeignContext = true; // the mxContext is from pData
73 mpGraphics = new AquaSalGraphics( /*pGraphic*/ );
74 mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
76 else
78 // create empty new virtual device
79 mbForeignContext = false; // the mxContext is created within VCL
80 mpGraphics = new AquaSalGraphics(); // never fails
81 mnBitmapDepth = nBitCount;
83 // inherit resolution from reference device
84 if( pGraphic )
86 AquaSalFrame* pFrame = pGraphic->getGraphicsFrame();
87 if( pFrame && AquaSalFrame::isAlive( pFrame ) )
89 mpGraphics->setGraphicsFrame( pFrame );
90 mpGraphics->copyResolution( *pGraphic );
94 if( nDX && nDY )
95 SetSize( nDX, nDY );
97 // NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
101 // -----------------------------------------------------------------------
103 AquaSalVirtualDevice::~AquaSalVirtualDevice()
105 if( mpGraphics )
107 mpGraphics->SetVirDevGraphics( NULL, NULL );
108 delete mpGraphics;
109 mpGraphics = 0;
111 Destroy();
114 // -----------------------------------------------------------------------
116 void AquaSalVirtualDevice::Destroy()
118 if( mbForeignContext ) {
119 // Do not delete mxContext that we have received from outside VCL
120 mxLayer = NULL;
121 return;
124 if( mxLayer )
126 if( mpGraphics )
127 mpGraphics->SetVirDevGraphics( NULL, NULL );
128 CGLayerRelease( mxLayer );
129 mxLayer = NULL;
132 if( mxBitmapContext )
134 void* pRawData = CGBitmapContextGetData( mxBitmapContext );
135 rtl_freeMemory( pRawData );
136 CGContextRelease( mxBitmapContext );
137 mxBitmapContext = NULL;
141 // -----------------------------------------------------------------------
143 SalGraphics* AquaSalVirtualDevice::GetGraphics()
145 if( mbGraphicsUsed || !mpGraphics )
146 return 0;
148 mbGraphicsUsed = true;
149 return mpGraphics;
152 // -----------------------------------------------------------------------
154 void AquaSalVirtualDevice::ReleaseGraphics( SalGraphics *pGraphics )
156 mbGraphicsUsed = false;
159 // -----------------------------------------------------------------------
161 BOOL AquaSalVirtualDevice::SetSize( long nDX, long nDY )
163 if( mbForeignContext )
165 // Do not delete/resize mxContext that we have received from outside VCL
166 return true;
169 if( mxLayer )
171 const CGSize aSize = CGLayerGetSize( mxLayer );
172 if( (nDX == aSize.width) && (nDY == aSize.height) )
174 // Yay, we do not have to do anything :)
175 return true;
179 Destroy();
181 // create a Quartz layer matching to the intended virdev usage
182 CGContextRef xCGContext = NULL;
183 if( mnBitmapDepth && (mnBitmapDepth < 16) )
185 mnBitmapDepth = 8; // TODO: are 1bit vdevs worth it?
186 const CGColorSpaceRef aCGColorSpace = GetSalData()->mxGraySpace;
187 const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNone;
188 const int nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;
190 void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
191 mxBitmapContext = ::CGBitmapContextCreate( pRawData, nDX, nDY,
192 mnBitmapDepth, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
193 xCGContext = mxBitmapContext;
195 else
197 // default to a NSView target context
198 AquaSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
199 if( !pSalFrame && !GetSalData()->maFrames.empty() )
200 pSalFrame = *GetSalData()->maFrames.begin();
201 if( pSalFrame )
203 NSGraphicsContext* pNSContext = [NSGraphicsContext graphicsContextWithWindow: pSalFrame->getWindow()];
204 if( pNSContext )
205 xCGContext = reinterpret_cast<CGContextRef>([pNSContext graphicsPort]);
209 DBG_ASSERT( xCGContext, "no context" );
211 const CGSize aNewSize = { nDX, nDY };
212 mxLayer = CGLayerCreateWithContext( xCGContext, aNewSize, NULL );
214 if( mxLayer && mpGraphics )
216 // get the matching Quartz context
217 CGContextRef xDrawContext = CGLayerGetContext( mxLayer );
218 mpGraphics->SetVirDevGraphics( mxLayer, xDrawContext, mnBitmapDepth );
221 return (mxLayer != NULL);
224 // -----------------------------------------------------------------------
226 void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
228 if( mxLayer )
230 const CGSize aSize = CGLayerGetSize( mxLayer );
231 rWidth = static_cast<long>(aSize.width);
232 rHeight = static_cast<long>(aSize.height);
234 else
236 rWidth = 0;
237 rHeight = 0;