261 lines
8.2 KiB
C++
261 lines
8.2 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
#include "precompiled_vcl.hxx"
|
|
|
|
#include "vcl/svapp.hxx"
|
|
#include "vcl/sysdata.hxx"
|
|
|
|
#include "ios/salvd.h"
|
|
#include "ios/salinst.h"
|
|
#include "ios/salgdi.h"
|
|
#include "ios/saldata.hxx"
|
|
#include "ios/salframe.h"
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
SalVirtualDevice* IosSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
|
|
long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
|
|
{
|
|
// #i92075# can be called first in a thread
|
|
SalData::ensureThreadAutoreleasePool();
|
|
|
|
return new IosSalVirtualDevice( static_cast< IosSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void IosSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
|
|
{
|
|
delete pDevice;
|
|
}
|
|
|
|
// =======================================================================
|
|
|
|
IosSalVirtualDevice::IosSalVirtualDevice( IosSalGraphics* 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 IosSalGraphics( /*pGraphic*/ );
|
|
mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
|
|
}
|
|
else
|
|
{
|
|
// create empty new virtual device
|
|
mbForeignContext = false; // the mxContext is created within VCL
|
|
mpGraphics = new IosSalGraphics(); // never fails
|
|
mnBitmapDepth = nBitCount;
|
|
|
|
// inherit resolution from reference device
|
|
if( pGraphic )
|
|
{
|
|
IosSalFrame* pFrame = pGraphic->getGraphicsFrame();
|
|
if( pFrame && IosSalFrame::isAlive( pFrame ) )
|
|
{
|
|
mpGraphics->setGraphicsFrame( pFrame );
|
|
mpGraphics->copyResolution( *pGraphic );
|
|
}
|
|
}
|
|
|
|
if( nDX && nDY )
|
|
SetSize( nDX, nDY );
|
|
|
|
// NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
IosSalVirtualDevice::~IosSalVirtualDevice()
|
|
{
|
|
if( mpGraphics )
|
|
{
|
|
mpGraphics->SetVirDevGraphics( NULL, NULL );
|
|
delete mpGraphics;
|
|
mpGraphics = 0;
|
|
}
|
|
Destroy();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void IosSalVirtualDevice::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* IosSalVirtualDevice::GetGraphics()
|
|
{
|
|
if( mbGraphicsUsed || !mpGraphics )
|
|
return 0;
|
|
|
|
mbGraphicsUsed = true;
|
|
return mpGraphics;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void IosSalVirtualDevice::ReleaseGraphics( SalGraphics* )
|
|
{
|
|
mbGraphicsUsed = false;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
sal_Bool IosSalVirtualDevice::SetSize( long nDX, long nDY )
|
|
{
|
|
if( mbForeignContext )
|
|
{
|
|
// Do not delete/resize mxContext that we have received from outside VCL
|
|
return true;
|
|
}
|
|
|
|
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 UIView target context
|
|
IosSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
|
|
if( !pSalFrame && !GetSalData()->maFrames.empty() )
|
|
pSalFrame = *GetSalData()->maFrames.begin();
|
|
if( pSalFrame )
|
|
{
|
|
#if 0 // No idea...
|
|
// #i91990#
|
|
UIWindow* pWindow = pSalFrame->getWindow();
|
|
if ( pWindow )
|
|
{
|
|
UIGraphicsContext* pUIContext = [UIGraphicsContext graphicsContextWithWindow: pWindow];
|
|
if( pUIContext )
|
|
xCGContext = reinterpret_cast<CGContextRef>([pUIContext graphicsPort]);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
// 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 = { nDX, 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);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void IosSalVirtualDevice::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: */
|