summaryrefslogtreecommitdiff
path: root/vcl/quartz
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2014-03-10 17:22:02 +0200
committerTor Lillqvist <tml@collabora.com>2014-03-10 17:37:43 +0200
commitbff2ddbbfb8a4cebee2cc223c3bba6a8d9ebc038 (patch)
tree1f8868aa88c3410ee7460493367bc2a4f3b9290b /vcl/quartz
parent81932318df11a9f389ac1dcf7650917a622d1889 (diff)
Hack on the iOS vcl code
Attempt to make some more complex documents render OK. Stop using SvpSalVirtualDevice on iOS. Use AquaSalVirtualDevice in all cases. Do use a CGLayer (the AquaSalVirtualDevice::mxLayer field) after all, like on OS X. Change-Id: I7f7dc00c526453786cc871fd88dfb73517b15c39
Diffstat (limited to 'vcl/quartz')
-rw-r--r--vcl/quartz/salgdi.cxx13
-rw-r--r--vcl/quartz/salgdicommon.cxx62
-rw-r--r--vcl/quartz/salvd.cxx50
3 files changed, 54 insertions, 71 deletions
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index c44eda16a720..213948da9e1d 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -283,10 +283,14 @@ AquaSalGraphics::AquaSalGraphics()
, mbPrinter( false )
, mbVirDev( false )
#endif
-{}
+{
+ SAL_INFO( "vcl.quartz", "AquaSalGraphics::AquaSalGraphics() this=" << this );
+}
AquaSalGraphics::~AquaSalGraphics()
{
+ SAL_INFO( "vcl.quartz", "AquaSalGraphics::~AquaSalGraphics() this=" << this );
+
CGPathRelease( mxClipPath );
delete mpTextStyle;
@@ -821,9 +825,16 @@ SystemFontData AquaSalGraphics::GetSysFontData( int /* nFallbacklevel */ ) const
bool SvpSalGraphics::CheckContext()
{
if (mbForeignContext)
+ {
+ SAL_INFO("vcl.ios", "CheckContext() this=" << this << ", mbForeignContext, return true");
return true;
+ }
+
if(m_aDevice == NULL) // fix tiledrendering crash when changing content size
+ {
+ SAL_INFO( "vcl.ios", "CheckContext() this=" << this << ", m_aDevice==NULL, return false");
return false;
+ }
const basegfx::B2IVector size = m_aDevice->getSize();
const basegfx::B2IVector bufferSize = m_aDevice->getBufferSize();
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index 2c0226a8334b..7c81f73719ee 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -326,7 +326,7 @@ void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGrap
ApplyXorContext();
pSrc->ApplyXorContext();
- DBG_ASSERT( pSrc->mxLayer!=NULL, "AquaSalGraphics::copyBits() from non-layered graphics" );
+ SAL_WARN_IF( !pSrc->mxLayer, "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 &&
@@ -444,6 +444,8 @@ void AquaSalGraphics::ApplyXorContext()
void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY,
long nSrcWidth, long nSrcHeight, sal_uInt16 /*nFlags*/ )
{
+ SAL_WARN_IF( !mxLayer, "vcl.quartz", "AquaSalGraphics::copyArea() for non-layered graphics this=" << this );
+
#ifdef IOS
if( !mxLayer )
return;
@@ -451,8 +453,6 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY,
ApplyXorContext();
- DBG_ASSERT( mxLayer!=NULL, "AquaSalGraphics::copyArea() for non-layered graphics" );
-
// in XOR mode the drawing context is redirected to the XOR mask
// copyArea() always works on the target context though
CGContextRef xCopyContext = mrContext;
@@ -1119,7 +1119,6 @@ void AquaSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
RefreshRect( nX, nY, nWidth, nHeight );
}
-
void AquaSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
{
if( nPoints < 1 )
@@ -1157,46 +1156,7 @@ sal_uInt16 AquaSalGraphics::GetBitCount() const
SalBitmap* AquaSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
{
-#ifdef IOS
- if (!mbForeignContext && m_aDevice != NULL)
- {
- // on ios virtual device are Svp so use Svp bitmap to get the content
- basegfx::B2IBox aRect( nX, nY, nX+nDX, nY+nDY );
- basebmp::BitmapDeviceSharedPtr aSubSet = basebmp::subsetBitmapDevice(m_aDevice , aRect );
-
- SvpSalBitmap* pSalBitmap = new SvpSalBitmap;
- pSalBitmap->setBitmap(aSubSet);
- BitmapBuffer* pBuffer = pSalBitmap->AcquireBuffer(true);
- QuartzSalBitmap* pBitmap = new QuartzSalBitmap;
- if( !pBitmap->Create(*pBuffer))
- {
- delete pBitmap;
- pBitmap = NULL;
- }
- pSalBitmap->ReleaseBuffer(pBuffer, true);
- delete pSalBitmap;
- return pBitmap;
- }
- else if (mbForeignContext)
- {
- //if using external context like on ios, check if we can get a backing image and copy it
- CGImageRef backImage = CGBitmapContextCreateImage(mrContext);
- if (backImage)
- {
- QuartzSalBitmap* pBitmap = new QuartzSalBitmap;
- if( !pBitmap->Create(backImage, mnBitmapDepth, nX, nY, nDX, nDY))
- {
- delete pBitmap;
- pBitmap = NULL;
- }
- CGImageRelease(backImage);
- return pBitmap;
- }
- return NULL;
- }
-#endif
-
- DBG_ASSERT( mxLayer, "AquaSalGraphics::getBitmap() with no layer" );
+ SAL_WARN_IF( !mxLayer, "vcl.quartz", "AquaSalGraphics::getBitmap() with no layer this=" << this );
ApplyXorContext();
@@ -1477,6 +1437,7 @@ void AquaSalGraphics::Pattern50Fill()
CGAffineTransformIdentity, 4, 4,
kCGPatternTilingConstantSpacing,
false, &aCallback );
+ SAL_WARN_IF( !mrContext, "vcl.quartz", "mrContext is NULL" );
CGContextSetFillColorSpace( mrContext, mxP50Space );
CGContextSetFillPattern( mrContext, mxP50Pattern, aFillCol );
CGContextFillPath( mrContext );
@@ -1687,10 +1648,13 @@ XorEmulation::XorEmulation()
, m_pTempBuffer( NULL )
, m_nBufferLongs( 0 )
, m_bIsEnabled( false )
-{}
+{
+ SAL_INFO( "vcl.quartz", "XorEmulation::XorEmulation() this=" << this );
+}
XorEmulation::~XorEmulation()
{
+ SAL_INFO( "vcl.quartz", "XorEmulation::~XorEmulation() this=" << this );
Disable();
SetTarget( 0, 0, 0, NULL, NULL );
}
@@ -1698,6 +1662,8 @@ XorEmulation::~XorEmulation()
void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
CGContextRef xTargetContext, CGLayerRef xTargetLayer )
{
+ SAL_INFO( "vcl.quartz", "XorEmulation::SetTarget() this=" << this << " (" << nWidth << "x" << nHeight << ") depth=" << nTargetDepth << " context=" << xTargetContext << " layer=" << xTargetLayer );
+
// prepare to replace old mask+temp context
if( m_xMaskContext )
{
@@ -1751,6 +1717,8 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
nWidth, nHeight,
nBitsPerComponent, nBytesPerRow,
aCGColorSpace, aCGBmpInfo );
+ SAL_WARN_IF( !m_xMaskContext, "vcl.quartz", "mask context creation failed" );
+
// reset the XOR mask to black
memset( m_pMaskBuffer, 0, m_nBufferLongs * sizeof(sal_uLong) );
@@ -1766,6 +1734,7 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
nWidth, nHeight,
nBitsPerComponent, nBytesPerRow,
aCGColorSpace, aCGBmpInfo );
+ SAL_WARN_IF( !m_xTempContext, "vcl.quartz", "temp context creation failed" );
}
// initialize XOR mask context for drawing
@@ -1792,6 +1761,8 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth,
bool XorEmulation::UpdateTarget()
{
+ SAL_INFO( "vcl.quartz", "XorEmulation::UpdateTarget() this=" << this );
+
if( !IsEnabled() )
{
return false;
@@ -1799,6 +1770,7 @@ bool XorEmulation::UpdateTarget()
// update the temp bitmap buffer if needed
if( m_xTempContext )
{
+ SAL_WARN_IF( m_xTargetContext == NULL, "vcl.quartz", "Target layer is NULL");
CGContextDrawLayerAtPoint( m_xTempContext, CGPointZero, m_xTargetLayer );
}
// do a manual XOR with the XorMask
diff --git a/vcl/quartz/salvd.cxx b/vcl/quartz/salvd.cxx
index 78a5352ad9ea..2204bea79970 100644
--- a/vcl/quartz/salvd.cxx
+++ b/vcl/quartz/salvd.cxx
@@ -45,7 +45,7 @@ SalVirtualDevice* AquaSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
if( pData )
return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
else
- return new SvpSalVirtualDevice( nBitCount );
+ return new AquaSalVirtualDevice( NULL, nDX, nDY, nBitCount, NULL );
#else
return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
#endif
@@ -66,26 +66,19 @@ AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX,
, mnBitmapDepth( 0 )
, mxLayer( NULL )
{
+ SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::AquaSalVirtualDevice() this=" << this << " size=(" << nDX << "x" << nDY << ") bitcount=" << nBitCount << " pData=" << pData << " context=" << (pData ? pData->rCGContext : 0) );
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.
// WTF does the above mean, SystemGraphicsData has no size field(s).
- mbForeignContext = true; // the mxContext is from pData
+ mbForeignContext = true; // the mxContext is from pData (what "mxContext"? there is no such field anywhere in vcl;)
mpGraphics = new AquaSalGraphics( /*pGraphic*/ );
-#ifdef IOS
- // Note: we should *not* create a CGLayer and assign it to
- // mxLayer here. Don't confuse CGLayer and CALayer. A CGLayer
- // is basically a fancy off-screen bitmap not related to
- // anything being displayed at all. The CGContext passed in
- // here refers to something actively part of the compositor
- // stack and being dislayed on the device, and *there*
- // CALayers are involved, sure. The use of mxLayer in this
- // code is for "traditional" LO virtual devices, off-screen
- // bitmaps. I think. On the other hand, the use of
- // VirtualDevice with a "foreign" CGContext for OS X is
- // actually dead code...
-#endif
+ if (nDX == 0)
+ nDX = 1;
+ if (nDY == 0)
+ nDY = 1;
+ mxLayer = CGLayerCreateWithContext( pData->rCGContext, CGSizeMake( nDX, nDY), NULL );
mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
}
else
@@ -117,6 +110,7 @@ AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX,
AquaSalVirtualDevice::~AquaSalVirtualDevice()
{
+ SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::~AquaSalVirtualDevice() this=" << this );
if( mpGraphics )
{
mpGraphics->SetVirDevGraphics( NULL, NULL );
@@ -130,6 +124,8 @@ AquaSalVirtualDevice::~AquaSalVirtualDevice()
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
mxLayer = NULL;
@@ -175,11 +171,7 @@ void AquaSalVirtualDevice::ReleaseGraphics( SalGraphics* )
bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
{
-#ifdef IOS
- (void) nDX;
- (void) nDY;
- assert(mbForeignContext);
-#endif
+ SAL_INFO( "vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this << " (" << nDX << "x" << nDY << ")" << " mbForeignContext=" << mbForeignContext );
if( mbForeignContext )
{
@@ -187,9 +179,6 @@ bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
return true;
}
-#ifdef IOS
- return false;
-#else
if( mxLayer )
{
const CGSize aSize = CGLayerGetSize( mxLayer );
@@ -218,6 +207,7 @@ bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
}
else
{
+#ifdef MACOSX
// default to a NSView target context
AquaSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
if( !pSalFrame || !AquaSalFrame::isAlive( pSalFrame ))
@@ -260,9 +250,20 @@ bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
xCGContext = mxBitmapContext;
}
}
+#else
+ 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;
+#endif
}
- DBG_ASSERT( xCGContext, "no context" );
+ SAL_WARN_IF( !xCGContext, "vcl.quartz", "No context" );
const CGSize aNewSize = { static_cast<CGFloat>(nDX), static_cast<CGFloat>(nDY) };
mxLayer = CGLayerCreateWithContext( xCGContext, aNewSize, NULL );
@@ -275,7 +276,6 @@ bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
}
return (mxLayer != NULL);
-#endif
}