summaryrefslogtreecommitdiffstats
path: root/vcl/quartz
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2013-12-09 21:53:23 +0200
committerTor Lillqvist <tml@collabora.com>2013-12-14 01:42:02 +0200
commit6265876ae9f1bb862440182d2d2c9b9b5b322668 (patch)
treecb64f9a87dd4a98556c2708be0ff8dbfd152ce58 /vcl/quartz
parentcppcheck: reduce scope (diff)
downloadcore-6265876ae9f1bb862440182d2d2c9b9b5b322668.tar.gz
core-6265876ae9f1bb862440182d2d2c9b9b5b322668.zip
iOS tiled rendering work
Possibly quite broken intermediate commit. But anyway, now it is possible to render the tile diretly to a CGContext. Can be seen in the MobileLibreOffice app when build in the Debug_tile_tester configuration. See touch_lo_draw_tile() in viewsh.cxx. Unfortunately the old plain LibreOffice test app is now broken, though, and displays nothing at all. This refactoring and hacking in vcl was done in a quite ugly fashion, with ifdefs etc. But trust me, I did try, several times, for many days, to get where I wanted in an elegant and clean fashion. But doing it cleanly meant not being able to actually build it for days while trying to figure ut which bits go where and which class should be split into what base and derived class(es), and it was too much for my limited brain capacity. I just couldn't juggle all the vcl class structure in my head, especially as I don't have any good understanding of the general design of it all. Change-Id: Ia59d6a9cce15a63e63f94e8d8574bef21993fb1f
Diffstat (limited to 'vcl/quartz')
-rw-r--r--vcl/quartz/salbmp.cxx6
-rw-r--r--vcl/quartz/salgdi.cxx33
-rw-r--r--vcl/quartz/salgdicommon.cxx92
-rw-r--r--vcl/quartz/salvd.cxx284
4 files changed, 369 insertions, 46 deletions
diff --git a/vcl/quartz/salbmp.cxx b/vcl/quartz/salbmp.cxx
index 1a509bd68e46..933bd2b13221 100644
--- a/vcl/quartz/salbmp.cxx
+++ b/vcl/quartz/salbmp.cxx
@@ -75,7 +75,7 @@ QuartzSalBitmap::~QuartzSalBitmap()
// ------------------------------------------------------------------
bool QuartzSalBitmap::Create( CGLayerRef xLayer, int nBitmapBits,
- int nX, int nY, int nWidth, int nHeight, bool /*bMirrorVert*/ )
+ int nX, int nY, int nWidth, int nHeight )
{
DBG_ASSERT( xLayer, "QuartzSalBitmap::Create() from non-layered context" );
@@ -102,7 +102,7 @@ bool QuartzSalBitmap::Create( CGLayerRef xLayer, int nBitmapBits,
// copy layer content into the bitmap buffer
const CGPoint aSrcPoint = { static_cast<CGFloat>(-nX), static_cast<CGFloat>(-nY) };
- ::CGContextDrawLayerAtPoint( mxGraphicContext, aSrcPoint, xLayer );
+ CGContextDrawLayerAtPoint( mxGraphicContext, aSrcPoint, xLayer );
return true;
}
@@ -239,7 +239,7 @@ bool QuartzSalBitmap::CreateContext()
if( maContextBuffer.get() )
{
- mxGraphicContext = ::CGBitmapContextCreate( maContextBuffer.get(), mnWidth, mnHeight,
+ mxGraphicContext = CGBitmapContextCreate( maContextBuffer.get(), mnWidth, mnHeight,
bitsPerComponent, nContextBytesPerRow, aCGColorSpace, aCGBmpInfo );
}
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index ee802056a2d3..25a219ff5770 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -266,39 +266,53 @@ AquaSalGraphics::AquaSalGraphics()
, mbVirDev( false )
, mbWindow( false )
#else
- : mrContext( NULL )
+ : mxLayer( NULL )
+ , mbForeignContext( false )
+ , mrContext( NULL )
+ , mpXorEmulation( NULL )
+ , mnXorMode( 0 )
+ , mnWidth( 0 )
+ , mnHeight( 0 )
+ , mnBitmapDepth( 0 )
, mfFakeDPIScale( 1.0 )
+ , mxClipPath( NULL )
+ , maLineColor( COL_WHITE )
+ , maFillColor( COL_BLACK )
, mpFontData( NULL )
, mpTextStyle( NULL )
, maTextColor( COL_BLACK )
, mbNonAntialiasedText( false )
+ , mbPrinter( false )
+ , mbVirDev( false )
#endif
{}
-// -----------------------------------------------------------------------
-
AquaSalGraphics::~AquaSalGraphics()
{
-#ifdef MACOSX
CGPathRelease( mxClipPath );
delete mpTextStyle;
if( mpXorEmulation )
delete mpXorEmulation;
+#ifdef IOS
+ if (mbForeignContext)
+ return;
+#endif
if( mxLayer )
CGLayerRelease( mxLayer );
- else if( mrContext && mbWindow )
+ else if( mrContext
+#ifdef MACOSX
+ && mbWindow
+#endif
+ )
{
// destroy backbuffer bitmap context that we created ourself
CGContextRelease( mrContext );
mrContext = NULL;
}
-#endif
}
-// =======================================================================
-
void AquaSalGraphics::SetTextColor( SalColor nSalColor )
{
maTextColor = RGBAColor( nSalColor );
@@ -792,6 +806,9 @@ SystemFontData AquaSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
bool SvpSalGraphics::CheckContext()
{
+ if (mbForeignContext)
+ return true;
+
const basegfx::B2IVector size = m_aDevice->getSize();
const basegfx::B2IVector bufferSize = m_aDevice->getBufferSize();
const sal_Int32 scanlineStride = m_aDevice->getScanlineStride();
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index 85e6a9ee3904..a204d7426cd6 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -25,7 +25,7 @@
#include <osl/endian.h>
#include <osl/file.hxx>
-#include "basegfx/polygon/b2dpolygon.hxx"
+#include <basegfx/polygon/b2dpolygon.hxx>
#include "quartz/salbmp.h"
#include "quartz/salgdi.h"
@@ -33,10 +33,12 @@
#include "fontsubset.hxx"
#include "sft.hxx"
-using namespace vcl;
+#ifdef IOS
+#include "saldatabasic.hxx"
+#endif
+using namespace vcl;
-//typedef unsigned char Boolean; // copied from MacTypes.h, should be properly included
typedef std::vector<unsigned char> ByteVector;
static const basegfx::B2DPoint aHalfPointOfs ( 0.5, 0.5 );
@@ -307,8 +309,11 @@ void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGrap
// accelerate trivial operations
/*const*/ AquaSalGraphics* pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics);
- const bool bSameGraphics = (this == pSrc) ||
- (mbWindow && mpFrame && pSrc->mbWindow && (mpFrame == pSrc->mpFrame));
+ const bool bSameGraphics = (this == pSrc)
+#ifdef MACOSX
+ || (mbWindow && mpFrame && pSrc->mbWindow && (mpFrame == pSrc->mpFrame))
+#endif
+ ;
if( bSameGraphics
&& (rPosAry.mnSrcWidth == rPosAry.mnDestWidth)
&& (rPosAry.mnSrcHeight == rPosAry.mnDestHeight))
@@ -333,6 +338,10 @@ void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGrap
rPosAry.mnSrcHeight == rPosAry.mnDestHeight) &&
(!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher
{
+#ifdef IOS
+ if( !CheckContext() )
+ return;
+#endif
// 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
CGContextRef xCopyContext = mrContext;
@@ -354,7 +363,7 @@ void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGrap
CGContextTranslateCTM( xCopyContext, 0, +mnHeight ); CGContextScaleCTM( xCopyContext, +1, -1 );
}
// TODO: pSrc->size() != this->size()
- ::CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, pSrc->mxLayer );
+ CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, pSrc->mxLayer );
CGContextRestoreGState( xCopyContext );
// mark the destination rectangle as updated
RefreshRect( aDstRect );
@@ -462,21 +471,21 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY,
// TODO: if( mnBitmapDepth > 0 )
{
const CGSize aSrcSize = CGSizeMake(nSrcWidth, nSrcHeight);
- xSrcLayer = ::CGLayerCreateWithContext( xCopyContext, aSrcSize, NULL );
+ xSrcLayer = CGLayerCreateWithContext( xCopyContext, aSrcSize, NULL );
const CGContextRef xSrcContext = CGLayerGetContext( xSrcLayer );
CGPoint aSrcPoint = CGPointMake(-nSrcX, -nSrcY);
if( IsFlipped() )
{
- ::CGContextTranslateCTM( xSrcContext, 0, +nSrcHeight );
- ::CGContextScaleCTM( xSrcContext, +1, -1 );
+ CGContextTranslateCTM( xSrcContext, 0, +nSrcHeight );
+ CGContextScaleCTM( xSrcContext, +1, -1 );
aSrcPoint.y = (nSrcY + nSrcHeight) - mnHeight;
}
- ::CGContextDrawLayerAtPoint( xSrcContext, aSrcPoint, mxLayer );
+ CGContextDrawLayerAtPoint( xSrcContext, aSrcPoint, mxLayer );
}
// draw at new destination
const CGPoint aDstPoint = CGPointMake(+nDstX, +nDstY);
- ::CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, xSrcLayer );
+ CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, xSrcLayer );
// cleanup
if( xSrcLayer != mxLayer )
@@ -488,6 +497,8 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY,
}
+#ifndef IOS
+
void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics )
{
if( !rGraphics.mnRealDPIY && rGraphics.mbWindow && rGraphics.mpFrame )
@@ -499,6 +510,8 @@ void AquaSalGraphics::copyResolution( AquaSalGraphics& rGraphics )
mfFakeDPIScale = rGraphics.mfFakeDPIScale;
}
+#endif
+
bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
const SalBitmap& rSrcBitmap,
const SalBitmap& rAlphaBmp )
@@ -655,6 +668,8 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rS
RefreshRect( aDstRect );
}
+#ifndef IOS
+
sal_Bool AquaSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight,
void* pEpsData, sal_uLong nByteCount )
{
@@ -700,6 +715,8 @@ sal_Bool AquaSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight,
return bOK;
}
+#endif
+
void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
if( nX1 == nX2 && nY1 == nY2 )
@@ -1129,7 +1146,7 @@ SalBitmap* AquaSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY
ApplyXorContext();
QuartzSalBitmap* pBitmap = new QuartzSalBitmap;
- if( !pBitmap->Create( mxLayer, mnBitmapDepth, nX, nY, nDX, nDY, !mbWindow ) )
+ if( !pBitmap->Create( mxLayer, mnBitmapDepth, nX, nY, nDX, nDY) )
{
delete pBitmap;
pBitmap = NULL;
@@ -1138,6 +1155,8 @@ SalBitmap* AquaSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY
return pBitmap;
}
+#ifndef IOS
+
SystemGraphicsData AquaSalGraphics::GetGraphicsData() const
{
SystemGraphicsData aRes;
@@ -1184,8 +1203,8 @@ SalColor AquaSalGraphics::getPixel( long nX, long nY )
// create a one-pixel bitmap context
// TODO: is it worth to cache it?
CGContextRef xOnePixelContext =
- ::CGBitmapContextCreate( &aPixel, 1, 1, 8, sizeof(aPixel),
- aCGColorSpace, aCGBmpInfo );
+ CGBitmapContextCreate( &aPixel, 1, 1, 8, sizeof(aPixel),
+ aCGColorSpace, aCGBmpInfo );
// update this graphics layer
ApplyXorContext();
@@ -1214,6 +1233,8 @@ void AquaSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
rDPIY = static_cast<sal_Int32>(mfFakeDPIScale * mnRealDPIY);
}
+#endif
+
void AquaSalGraphics::ImplDrawPixel( long nX, long nY, const RGBAColor& rColor )
{
if( !CheckContext() )
@@ -1230,6 +1251,8 @@ void AquaSalGraphics::ImplDrawPixel( long nX, long nY, const RGBAColor& rColor )
CGContextSetFillColor( mrContext, maFillColor.AsArray() );
}
+#ifndef IOS
+
void AquaSalGraphics::initResolution( NSWindow* )
{
// #i100617# read DPI only once; there is some kind of weird caching going on
@@ -1322,6 +1345,8 @@ void AquaSalGraphics::initResolution( NSWindow* )
mfFakeDPIScale = 1.0;
}
+#endif
+
void AquaSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags )
{
if ( CheckContext() )
@@ -1395,19 +1420,13 @@ void AquaSalGraphics::Pattern50Fill()
{
static const CGFloat aFillCol[4] = { 1,1,1,1 };
static const CGPatternCallbacks aCallback = { 0, &DrawPattern50, NULL };
- if( ! GetSalData()->mxP50Space )
- {
- GetSalData()->mxP50Space = CGColorSpaceCreatePattern( GetSalData()->mxRGBSpace );
- }
- if( ! GetSalData()->mxP50Pattern )
- {
- GetSalData()->mxP50Pattern = CGPatternCreate( NULL, CGRectMake( 0, 0, 4, 4 ),
- CGAffineTransformIdentity, 4, 4,
- kCGPatternTilingConstantSpacing,
- false, &aCallback );
- }
- CGContextSetFillColorSpace( mrContext, GetSalData()->mxP50Space );
- CGContextSetFillPattern( mrContext, GetSalData()->mxP50Pattern, aFillCol );
+ static const CGColorSpaceRef mxP50Space = CGColorSpaceCreatePattern( GetSalData()->mxRGBSpace );
+ static const CGPatternRef mxP50Pattern = CGPatternCreate( NULL, CGRectMake( 0, 0, 4, 4 ),
+ CGAffineTransformIdentity, 4, 4,
+ kCGPatternTilingConstantSpacing,
+ false, &aCallback );
+ CGContextSetFillColorSpace( mrContext, mxP50Space );
+ CGContextSetFillPattern( mrContext, mxP50Pattern, aFillCol );
CGContextFillPath( mrContext );
}
@@ -1590,6 +1609,8 @@ void AquaSalGraphics::SetXORMode( bool bSet, bool bInvertOnly )
}
}
+#ifndef IOS
+
void AquaSalGraphics::updateResolution()
{
DBG_ASSERT( mbWindow, "updateResolution on inappropriate graphics" );
@@ -1597,6 +1618,7 @@ void AquaSalGraphics::updateResolution()
initResolution( (mbWindow && mpFrame) ? mpFrame->getNSWindow() : nil );
}
+#endif
// -----------------------------------------------------------
@@ -1669,10 +1691,10 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
// create a XorMask context
m_pMaskBuffer = new sal_uLong[ m_nBufferLongs ];
- m_xMaskContext = ::CGBitmapContextCreate( m_pMaskBuffer,
- nWidth, nHeight,
- nBitsPerComponent, nBytesPerRow,
- aCGColorSpace, aCGBmpInfo );
+ m_xMaskContext = CGBitmapContextCreate( m_pMaskBuffer,
+ nWidth, nHeight,
+ nBitsPerComponent, nBytesPerRow,
+ aCGColorSpace, aCGBmpInfo );
// reset the XOR mask to black
memset( m_pMaskBuffer, 0, m_nBufferLongs * sizeof(sal_uLong) );
@@ -1684,10 +1706,10 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
{
// create a bitmap context matching to the target context
m_pTempBuffer = new sal_uLong[ m_nBufferLongs ];
- m_xTempContext = ::CGBitmapContextCreate( m_pTempBuffer,
- nWidth, nHeight,
- nBitsPerComponent, nBytesPerRow,
- aCGColorSpace, aCGBmpInfo );
+ m_xTempContext = CGBitmapContextCreate( m_pTempBuffer,
+ nWidth, nHeight,
+ nBitsPerComponent, nBytesPerRow,
+ aCGColorSpace, aCGBmpInfo );
}
// initialize XOR mask context for drawing
diff --git a/vcl/quartz/salvd.cxx b/vcl/quartz/salvd.cxx
new file mode 100644
index 000000000000..7b041b9dbf56
--- /dev/null
+++ b/vcl/quartz/salvd.cxx
@@ -0,0 +1,284 @@
+/* -*- 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 "vcl/svapp.hxx"
+#include "vcl/sysdata.hxx"
+
+#include "quartz/salvd.h"
+#ifdef MACOSX
+#include "osx/salinst.h"
+#include "osx/saldata.hxx"
+#include "osx/salframe.h"
+#else
+#include "headless/svpframe.hxx"
+#include "headless/svpgdi.hxx"
+#include "headless/svpinst.hxx"
+#include "headless/svpvd.hxx"
+#endif
+#include "quartz/salgdi.h"
+
+// -----------------------------------------------------------------------
+
+SalVirtualDevice* AquaSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
+ long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
+{
+ // #i92075# can be called first in a thread
+ SalData::ensureThreadAutoreleasePool();
+
+#ifdef IOS
+ if( pData )
+ return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
+ else
+ return new SvpSalVirtualDevice( nBitCount );
+#else
+ return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void AquaSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
+{
+ delete pDevice;
+}
+
+// =======================================================================
+
+AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
+: mbGraphicsUsed( false )
+, mxBitmapContext( NULL )
+, mnBitmapDepth( 0 )
+, mxLayer( NULL )
+{
+ if( pGraphic && pData && pData->rCGContext )
+ {
+ // Create virtual device based on existing SystemGraphicsData
+ // We ignore nDx and nDY, as the desired size comes from the SystemGraphicsData
+ mbForeignContext = true; // the mxContext is from pData
+ mpGraphics = new AquaSalGraphics( /*pGraphic*/ );
+ mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
+ }
+ else
+ {
+ // create empty new virtual device
+ mbForeignContext = false; // the mxContext is created within VCL
+ mpGraphics = new AquaSalGraphics(); // never fails
+ mnBitmapDepth = nBitCount;
+#ifdef MACOSX
+ // inherit resolution from reference device
+ if( pGraphic )
+ {
+ AquaSalFrame* pFrame = pGraphic->getGraphicsFrame();
+ if( pFrame && AquaSalFrame::isAlive( pFrame ) )
+ {
+ mpGraphics->setGraphicsFrame( pFrame );
+ mpGraphics->copyResolution( *pGraphic );
+ }
+ }
+#endif
+ if( nDX && nDY )
+ SetSize( nDX, nDY );
+
+ // NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
+ }
+}
+
+// -----------------------------------------------------------------------
+
+AquaSalVirtualDevice::~AquaSalVirtualDevice()
+{
+ if( mpGraphics )
+ {
+ mpGraphics->SetVirDevGraphics( NULL, NULL );
+ delete mpGraphics;
+ mpGraphics = 0;
+ }
+ Destroy();
+}
+
+// -----------------------------------------------------------------------
+
+void AquaSalVirtualDevice::Destroy()
+{
+ if( mbForeignContext ) {
+ // Do not delete mxContext that we have received from outside VCL
+ mxLayer = NULL;
+ return;
+ }
+
+ if( mxLayer )
+ {
+ if( mpGraphics )
+ mpGraphics->SetVirDevGraphics( NULL, NULL );
+ CGLayerRelease( mxLayer );
+ mxLayer = NULL;
+ }
+
+ if( mxBitmapContext )
+ {
+ void* pRawData = CGBitmapContextGetData( mxBitmapContext );
+ rtl_freeMemory( pRawData );
+ CGContextRelease( mxBitmapContext );
+ mxBitmapContext = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+SalGraphics* AquaSalVirtualDevice::GetGraphics()
+{
+ if( mbGraphicsUsed || !mpGraphics )
+ return 0;
+
+ mbGraphicsUsed = true;
+ return mpGraphics;
+}
+
+// -----------------------------------------------------------------------
+
+void AquaSalVirtualDevice::ReleaseGraphics( SalGraphics* )
+{
+ mbGraphicsUsed = false;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
+{
+#ifdef IOS
+ (void) nDX;
+ (void) nDY;
+ assert(mbForeignContext);
+#endif
+
+ if( mbForeignContext )
+ {
+ // Do not delete/resize mxContext that we have received from outside VCL
+ return true;
+ }
+
+#ifdef IOS
+ return false;
+#else
+ if( mxLayer )
+ {
+ const CGSize aSize = CGLayerGetSize( mxLayer );
+ if( (nDX == aSize.width) && (nDY == aSize.height) )
+ {
+ // Yay, we do not have to do anything :)
+ return true;
+ }
+ }
+
+ Destroy();
+
+ // create a Quartz layer matching to the intended virdev usage
+ CGContextRef xCGContext = NULL;
+ if( mnBitmapDepth && (mnBitmapDepth < 16) )
+ {
+ mnBitmapDepth = 8; // TODO: are 1bit vdevs worth it?
+ const CGColorSpaceRef aCGColorSpace = GetSalData()->mxGraySpace;
+ const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNone;
+ const int nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;
+
+ void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
+ mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
+ mnBitmapDepth, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
+ xCGContext = mxBitmapContext;
+ }
+ else
+ {
+ // default to a NSView target context
+ AquaSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
+ if( !pSalFrame || !AquaSalFrame::isAlive( pSalFrame ))
+ {
+ if( !GetSalData()->maFrames.empty() )
+ {
+ // get the first matching frame
+ pSalFrame = *GetSalData()->maFrames.begin();
+ }
+ else
+ {
+ // ensure we don't reuse a dead AquaSalFrame on the very
+ // unlikely case of no other frame to use
+ pSalFrame = NULL;
+ }
+ // update the frame reference
+ mpGraphics->setGraphicsFrame( pSalFrame );
+ }
+ if( pSalFrame )
+ {
+ // #i91990#
+ NSWindow* pNSWindow = pSalFrame->getNSWindow();
+ if ( pNSWindow )
+ {
+ NSGraphicsContext* pNSContext = [NSGraphicsContext graphicsContextWithWindow: pNSWindow];
+ if( pNSContext )
+ xCGContext = reinterpret_cast<CGContextRef>([pNSContext graphicsPort]);
+ }
+ else
+ {
+ // fall back to a bitmap context
+ mnBitmapDepth = 32;
+ const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
+ const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
+ const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
+
+ void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
+ mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
+ 8, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
+ xCGContext = mxBitmapContext;
+ }
+ }
+ }
+
+ DBG_ASSERT( xCGContext, "no context" );
+
+ const CGSize aNewSize = { static_cast<CGFloat>(nDX), static_cast<CGFloat>(nDY) };
+ mxLayer = CGLayerCreateWithContext( xCGContext, aNewSize, NULL );
+
+ if( mxLayer && mpGraphics )
+ {
+ // get the matching Quartz context
+ CGContextRef xDrawContext = CGLayerGetContext( mxLayer );
+ mpGraphics->SetVirDevGraphics( mxLayer, xDrawContext, mnBitmapDepth );
+ }
+
+ return (mxLayer != NULL);
+#endif
+}
+
+// -----------------------------------------------------------------------
+
+void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
+{
+ if( mxLayer )
+ {
+ const CGSize aSize = CGLayerGetSize( mxLayer );
+ rWidth = static_cast<long>(aSize.width);
+ rHeight = static_cast<long>(aSize.height);
+ }
+ else
+ {
+ rWidth = 0;
+ rHeight = 0;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */