diff options
author | Tor Lillqvist <tml@collabora.com> | 2014-03-10 17:22:02 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2014-03-10 17:37:43 +0200 |
commit | bff2ddbbfb8a4cebee2cc223c3bba6a8d9ebc038 (patch) | |
tree | 1f8868aa88c3410ee7460493367bc2a4f3b9290b /vcl/quartz | |
parent | 81932318df11a9f389ac1dcf7650917a622d1889 (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.cxx | 13 | ||||
-rw-r--r-- | vcl/quartz/salgdicommon.cxx | 62 | ||||
-rw-r--r-- | vcl/quartz/salvd.cxx | 50 |
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 } |