include/sal/log-areas.dox | 1 vcl/inc/headless/svpgdi.hxx | 3 vcl/inc/quartz/salgdi.h | 3 vcl/inc/quartz/salgdicommon.hxx | 12 +++ vcl/inc/quartz/utils.h | 9 +- vcl/quartz/salbmp.cxx | 6 - vcl/quartz/salgdi.cxx | 21 +++++- vcl/quartz/salgdicommon.cxx | 132 +++++++++++++++++++++++++++++++++++++++- vcl/quartz/utils.cxx | 19 ++++- 9 files changed, 188 insertions(+), 18 deletions(-)
New commits: commit 9c87596c8a0123076249c7bd59eaaa41497b48fc Author: Tor Lillqvist <t...@collabora.com> Date: Mon Mar 31 21:05:09 2014 +0300 Add SAL_INFOs for very detailed CoreGraphics tracing One would think there would exist some kind of shim library that would automatically provide such traces, hmm. Change-Id: I568d02a2ac70078dee0280d1feb3eab7bbd43030 diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index 88ca865..2d712a6 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -354,6 +354,7 @@ certain functionality. @li @c vcl @li @c vcl.a11y @li @c vcl.app +@li @c vcl.cg - CoreGraphics calls on OS X and iOS @li @c vcl.control @li @c vcl.coretext - CoreText-using code for Mac OS X and iOS @li @c vcl.emf - EMF/EMF+ processing diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index ff7f0e0..987c2e4 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -90,6 +90,9 @@ public: // mirror AquaSalVirtualDevice::mbForeignContext for SvpSalGraphics objects related to such bool mbForeignContext; CGContextRef mrContext; +#if OSL_DEBUG_LEVEL > 0 + int mnContextStackDepth; +#endif class XorEmulation* mpXorEmulation; int mnXorMode; // 0: off 1: on 2: invert only int mnWidth; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 0653484..c009c56 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -158,6 +158,9 @@ protected: AquaSalFrame* mpFrame; CGLayerRef mxLayer; // Quartz graphics layer CGContextRef mrContext; // Quartz drawing context +#if OSL_DEBUG_LEVEL > 0 + int mnContextStackDepth; +#endif class XorEmulation* mpXorEmulation; int mnXorMode; // 0: off 1: on 2: invert only int mnWidth; diff --git a/vcl/inc/quartz/salgdicommon.hxx b/vcl/inc/quartz/salgdicommon.hxx index 4250103..b0d9a2f 100644 --- a/vcl/inc/quartz/salgdicommon.hxx +++ b/vcl/inc/quartz/salgdicommon.hxx @@ -20,6 +20,8 @@ #ifndef INCLUDED_VCL_INC_QUARTZ_SALGDICOMMON_HXX #define INCLUDED_VCL_INC_QUARTZ_SALGDICOMMON_HXX +#include <iostream> + #include <premac.h> #ifdef IOS #include <CoreGraphics/CoreGraphics.h> @@ -64,6 +66,16 @@ inline RGBAColor::RGBAColor( float fRed, float fGreen, float fBlue, float fAlpha m_fRGBA[3] = fAlpha; } +inline std::ostream &operator <<(std::ostream& s, const RGBAColor &aColor) +{ +#ifndef SAL_LOG_INFO + (void) aColor; +#else + s << "{" << aColor.GetRed() << "," << aColor.GetGreen() << "," << aColor.GetBlue() << "," << aColor.GetAlpha() << "}"; +#endif + return s; +} + // XOR emulation suckage. // See http://www.openoffice.org/marketing/ooocon2008/programme/wednesday_1401.pdf // and https://bugs.freedesktop.org/show_bug.cgi?id=38844 . diff --git a/vcl/inc/quartz/utils.h b/vcl/inc/quartz/utils.h index fe81c1d..e408250 100644 --- a/vcl/inc/quartz/utils.h +++ b/vcl/inc/quartz/utils.h @@ -39,10 +39,13 @@ OUString GetOUString( NSString* ); CFStringRef CreateCFString( const OUString& ); NSString* CreateNSString( const OUString& ); -std::ostream &operator <<(std::ostream& s, CGRect &rRect); -std::ostream &operator <<(std::ostream& s, CGPoint &rPoint); -std::ostream &operator <<(std::ostream& s, CGSize &rSize); +std::ostream &operator <<(std::ostream& s, const CGRect &rRect); +std::ostream &operator <<(std::ostream& s, const CGPoint &rPoint); +std::ostream &operator <<(std::ostream& s, const CGSize &rSize); std::ostream &operator <<(std::ostream& s, CGColorRef pSize); +std::ostream &operator <<(std::ostream& s, const CGAffineTransform &aXform); + +#define CG_TRACE( e ) SAL_INFO( "vcl.cg", e ) #endif // INCLUDED_VCL_INC_QUARTZ_UTILS_H diff --git a/vcl/quartz/salbmp.cxx b/vcl/quartz/salbmp.cxx index 3732550..aaeccaa 100644 --- a/vcl/quartz/salbmp.cxx +++ b/vcl/quartz/salbmp.cxx @@ -212,11 +212,7 @@ bool QuartzSalBitmap::CreateContext() // no conversion needed for truecolor maContextBuffer = maUserBuffer; } - else if( mnBits == 8 -#ifndef IOS - && maPalette.IsGreyPalette() -#endif - ) + else if( mnBits == 8 && maPalette.IsGreyPalette() ) { // no conversion needed for grayscale maContextBuffer = maUserBuffer; diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 916926d..1ab0931 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -39,6 +39,7 @@ #include "vcl/svapp.hxx" #include "quartz/salgdi.h" +#include "quartz/utils.h" #ifdef MACOSX #include "osx/salframe.h" @@ -240,13 +241,14 @@ void CoreTextFontData::ReadMacCmapEncoding( void ) const return; } - - AquaSalGraphics::AquaSalGraphics() #ifdef MACOSX : mpFrame( NULL ) , mxLayer( NULL ) , mrContext( NULL ) +#if OSL_DEBUG_LEVEL > 0 + , mnContextStackDepth( 0 ) +#endif , mpXorEmulation( NULL ) , mnXorMode( 0 ) , mnWidth( 0 ) @@ -268,6 +270,9 @@ AquaSalGraphics::AquaSalGraphics() : mxLayer( NULL ) , mbForeignContext( false ) , mrContext( NULL ) +#if OSL_DEBUG_LEVEL > 0 + , mnContextStackDepth( 0 ) +#endif , mpXorEmulation( NULL ) , mnXorMode( 0 ) , mnWidth( 0 ) @@ -291,7 +296,12 @@ AquaSalGraphics::~AquaSalGraphics() { SAL_INFO( "vcl.quartz", "AquaSalGraphics::~AquaSalGraphics() this=" << this ); - CGPathRelease( mxClipPath ); + if( mxClipPath ) + { + CG_TRACE( "CGPathRelease(" << mxClipPath << ")" ); + CGPathRelease( mxClipPath ); + } + delete mpTextStyle; if( mpXorEmulation ) @@ -302,7 +312,10 @@ AquaSalGraphics::~AquaSalGraphics() return; #endif if( mxLayer ) + { + CG_TRACE( "CGLayerRelease(" << mxLayer << ")" ); CGLayerRelease( mxLayer ); + } else if( mrContext #ifdef MACOSX && mbWindow @@ -310,6 +323,7 @@ AquaSalGraphics::~AquaSalGraphics() ) { // destroy backbuffer bitmap context that we created ourself + CG_TRACE( "CGContextRelease(" << mrContext << ")" ); CGContextRelease( mrContext ); mrContext = NULL; } @@ -832,7 +846,6 @@ bool SvpSalGraphics::CheckContext() SAL_INFO( "vcl.ios", "CheckContext() this=" << this << ", not foreign, return false"); return false; - } CGContextRef SvpSalGraphics::GetContext() diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx index d628325..c2e9931 100644 --- a/vcl/quartz/salgdicommon.cxx +++ b/vcl/quartz/salgdicommon.cxx @@ -29,6 +29,7 @@ #include "quartz/salbmp.h" #include "quartz/salgdi.h" +#include "quartz/utils.h" #include "fontsubset.hxx" #include "sft.hxx" @@ -90,6 +91,7 @@ static void AddPolygonToPath( CGMutablePathRef xPath, if( !nPointIdx ) { // first point => just move there + CG_TRACE("CGPathMoveToPoint(" << xPath << ",NULL," << aPoint.getX() << "," << aPoint.getY() << ")"); CGPathMoveToPoint( xPath, NULL, aPoint.getX(), aPoint.getY() ); continue; } @@ -103,6 +105,7 @@ static void AddPolygonToPath( CGMutablePathRef xPath, if( !bPendingCurve ) // line segment { + CG_TRACE("CGPathAddLineToPoint(" << xPath << ",NULL," << aPoint.getX() << "," << aPoint.getY() << ")"); CGPathAddLineToPoint( xPath, NULL, aPoint.getX(), aPoint.getY() ); } else // cubic bezier segment @@ -114,13 +117,17 @@ static void AddPolygonToPath( CGMutablePathRef xPath, aCP1 += aHalfPointOfs; aCP2 += aHalfPointOfs; } + SAL_INFO( "vcl.cg", + "CGPathAddCurveToPoint(" << xPath << ",NULL," << aCP1.getX() << "," << aCP1.getY() << "," << + aCP2.getX() << "," << aCP2.getY() << "," << aPoint.getX() << "," << aPoint.getY() << ")" ); CGPathAddCurveToPoint( xPath, NULL, aCP1.getX(), aCP1.getY(), - aCP2.getX(), aCP2.getY(), aPoint.getX(), aPoint.getY() ); + aCP2.getX(), aCP2.getY(), aPoint.getX(), aPoint.getY() ); } } if( bClosePath ) { + CG_TRACE( "CGPathCloseSubpath(" << xPath << ")" ); CGPathCloseSubpath( xPath ); } } @@ -343,18 +350,25 @@ void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGrap xCopyContext = mpXorEmulation->GetTargetContext(); } } + CG_TRACE( "CGContextSaveGState(" << xCopyContext << ")" ); CGContextSaveGState( xCopyContext ); const CGRect aDstRect = CGRectMake(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight); + CG_TRACE( "CGContextClipToRect(" << xCopyContext << "," << aDstRect << ")" ); CGContextClipToRect( xCopyContext, aDstRect ); // draw at new destination // NOTE: flipped drawing gets disabled for this, else the subimage would be drawn upside down if( pSrc->IsFlipped() ) { - CGContextTranslateCTM( xCopyContext, 0, +mnHeight ); CGContextScaleCTM( xCopyContext, +1, -1 ); + CG_TRACE( "CGContextTranslateCTM(" << xCopyContext << ",0," << mnHeight << ")" ); + CGContextTranslateCTM( xCopyContext, 0, +mnHeight ); + CG_TRACE( "CGContextScaleCTM(" << xCopyContext << ",+1,-1)" ); + CGContextScaleCTM( xCopyContext, +1, -1 ); } // TODO: pSrc->size() != this->size() + CG_TRACE( "CGContextDrawLayerAtPoint(" << xCopyContext << "," << aDstPoint << "," << pSrc->mxLayer << ")" ); CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, pSrc->mxLayer ); + CG_TRACE( "CGContextRestoreGState(" << xCopyContext << ")" ); CGContextRestoreGState( xCopyContext ); // mark the destination rectangle as updated RefreshRect( aDstRect ); @@ -468,29 +482,34 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY, { const CGSize aSrcSize = CGSizeMake(nSrcWidth, nSrcHeight); xSrcLayer = CGLayerCreateWithContext( xCopyContext, aSrcSize, NULL ); + CG_TRACE( "CGLayerCreateWithContext(" << xCopyContext << "," << aSrcSize << ",NULL) = " << xSrcLayer ); const CGContextRef xSrcContext = CGLayerGetContext( xSrcLayer ); CGPoint aSrcPoint = CGPointMake(-nSrcX, -nSrcY); if( IsFlipped() ) { + CG_TRACE( "CGContextTranslateCTM(" << xSrcContext << ",0," << nSrcHeight << ")" ); CGContextTranslateCTM( xSrcContext, 0, +nSrcHeight ); + CG_TRACE( "CGContextScaleCTM(" << xSrcContext << ",+1,-1)" ); CGContextScaleCTM( xSrcContext, +1, -1 ); aSrcPoint.y = (nSrcY + nSrcHeight) - mnHeight; } + CG_TRACE( "CGContextDrawLayerAtPoint(" << xSrcContext << "," << aSrcPoint << "," << mxLayer << ")" ); CGContextDrawLayerAtPoint( xSrcContext, aSrcPoint, mxLayer ); } // draw at new destination const CGPoint aDstPoint = CGPointMake(+nDstX, +nDstY); + CG_TRACE( "CGContextDrawLayerAtPoint(" << xCopyContext << "," << aDstPoint << "," << xSrcLayer << ")" ); CGContextDrawLayerAtPoint( xCopyContext, aDstPoint, xSrcLayer ); // cleanup if( xSrcLayer != mxLayer ) { + CG_TRACE( "CGLayerRelease(" << xSrcLayer << ")" ); CGLayerRelease( xSrcLayer ); } // mark the destination rectangle as updated RefreshRect( nDstX, nDstY, nSrcWidth, nSrcHeight ); - } #ifndef IOS @@ -535,10 +554,12 @@ bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, if ( CheckContext() ) { const CGRect aDstRect = CGRectMake( rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight); + CG_TRACE( "CGContextDrawImage(" << mrContext << "," << aDstRect << "," << xMaskedImage << ")" ); CGContextDrawImage( mrContext, aDstRect, xMaskedImage ); RefreshRect( aDstRect ); } + CG_TRACE("CGImageRelease(" << xMaskedImage << ")"); CGImageRelease(xMaskedImage); return true; } @@ -564,6 +585,7 @@ bool AquaSalGraphics::drawTransformedBitmap( // setup the image transformation // using the rNull,rX,rY points as destinations for the (0,0),(0,Width),(Height,0) source points + CG_TRACE( "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth ); CGContextSaveGState( mrContext ); const basegfx::B2DVector aXRel = rX - rNull; const basegfx::B2DVector aYRel = rY - rNull; @@ -571,13 +593,17 @@ bool AquaSalGraphics::drawTransformedBitmap( aXRel.getX()/aSize.Width(), aXRel.getY()/aSize.Width(), aYRel.getX()/aSize.Height(), aYRel.getY()/aSize.Height(), rNull.getX(), rNull.getY()); + CG_TRACE( "CGContextConcatCTM(" << mrContext << "," << aCGMat << ")" ); CGContextConcatCTM( mrContext, aCGMat ); // draw the transformed image const CGRect aSrcRect = CGRectMake(0, 0, aSize.Width(), aSize.Height()); + CG_TRACE( "CGContextDrawImage(" << mrContext << "," << aSrcRect << "," << xImage << ")" ); CGContextDrawImage( mrContext, aSrcRect, xImage ); + CG_TRACE( "CGImageRelease(" << xImage << ")" ); CGImageRelease( xImage ); // restore the Quartz graphics state + CG_TRACE("CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth--); CGContextRestoreGState(mrContext); // mark the destination as painted @@ -595,7 +621,9 @@ bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, return true; } // save the current state + CG_TRACE( "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth ); CGContextSaveGState( mrContext ); + CG_TRACE( "CGContextSetAlpha(" << mrContext << "," << (100-nTransparency) * (1.0/100) << ")" ); CGContextSetAlpha( mrContext, (100-nTransparency) * (1.0/100) ); CGRect aRect = CGRectMake(nX, nY, nWidth-1, nHeight-1); @@ -605,11 +633,15 @@ bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, aRect.origin.y += 0.5; } + CG_TRACE( "CGContextBeginPath(" << mrContext << ")" ); CGContextBeginPath( mrContext ); + CG_TRACE( "CGContextAddRect(" << mrContext << "," << aRect << ")" ); CGContextAddRect( mrContext, aRect ); + CG_TRACE( "CGContextDrawPath(" << mrContext << ",kCGPathFill)" ); CGContextDrawPath( mrContext, kCGPathFill ); // restore state + CG_TRACE("CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth--); CGContextRestoreGState(mrContext); RefreshRect( aRect ); return true; @@ -630,7 +662,9 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rS } const CGRect aDstRect = CGRectMake(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight); + CG_TRACE( "CGContextDrawImage(" << mrContext << "," << aDstRect << "," << xImage << ")" ); CGContextDrawImage( mrContext, aDstRect, xImage ); + CG_TRACE( "CGImageRelease(" << xImage << ")" ); CGImageRelease( xImage ); RefreshRect( aDstRect ); } @@ -658,7 +692,9 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rS } const CGRect aDstRect = CGRectMake(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight); + CG_TRACE( "CGContextDrawImage(" << mrContext << "," << aDstRect << "," << xMaskedImage << ")" ); CGContextDrawImage( mrContext, aDstRect, xMaskedImage ); + CG_TRACE( "CGImageRelease(" << xMaskedImage << ")" ); CGImageRelease( xMaskedImage ); RefreshRect( aDstRect ); } @@ -681,8 +717,10 @@ bool AquaSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, return false; } // NOTE: flip drawing, else the nsimage would be drawn upside down + CG_TRACE( "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth ); CGContextSaveGState( mrContext ); // CGContextTranslateCTM( mrContext, 0, +mnHeight ); + CG_TRACE( "CGContextScaleCTM(" << mrContext << ",+1,-1)" ); CGContextScaleCTM( mrContext, +1, -1 ); nY = /*mnHeight*/ - (nY + nHeight); @@ -703,6 +741,7 @@ bool AquaSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, [NSGraphicsContext setCurrentContext: pOrigNSCtx]; [pOrigNSCtx release]; // restore the original retain count + CG_TRACE("CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth--); CGContextRestoreGState( mrContext ); // mark the destination rectangle as updated RefreshRect( aDstRect ); @@ -725,9 +764,13 @@ void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) { return; } + CG_TRACE( "CGContextBeginPath(" << mrContext << ")" ); CGContextBeginPath( mrContext ); + CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << static_cast<float>(nX1)+0.5 << "," << static_cast<float>(nY1)+0.5 << ")" ); CGContextMoveToPoint( mrContext, static_cast<float>(nX1)+0.5, static_cast<float>(nY1)+0.5 ); + CG_TRACE( "CGContextAddLineToPoint(" << mrContext << "," << static_cast<float>(nX2)+0.5 << "," << static_cast<float>(nY2)+0.5 << ")" ); CGContextAddLineToPoint( mrContext, static_cast<float>(nX2)+0.5, static_cast<float>(nY2)+0.5 ); + CG_TRACE( "CGContextDrawPath(" << mrContext << ",kCGPathStroke)" ); CGContextDrawPath( mrContext, kCGPathStroke ); Rectangle aRefreshRect( nX1, nY1, nX2, nY2 ); @@ -751,7 +794,9 @@ void AquaSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSal } const CGRect aDstRect = CGRectMake(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight); + CG_TRACE( "CGContextDrawImage(" << mrContext << "," << aDstRect << "," << xImage << ")" ); CGContextDrawImage( mrContext, aDstRect, xImage ); + CG_TRACE( "CGImageRelease(" << xImage << ")" ); CGImageRelease( xImage ); RefreshRect( aDstRect ); } @@ -835,6 +880,7 @@ bool AquaSalGraphics::drawPolyLine( // setup poly-polygon path CGMutablePathRef xPath = CGPathCreateMutable(); + CG_TRACE( "CGPathCreateMutable() = " << xPath ); AddPolygonToPath( xPath, rPolyLine, rPolyLine.isClosed(), !getAntiAliasB2DDraw(), true ); const CGRect aRefreshRect = CGPathGetBoundingBox( xPath ); @@ -842,21 +888,28 @@ bool AquaSalGraphics::drawPolyLine( if( ! ((aRefreshRect.size.width <= 0.125) && (aRefreshRect.size.height <= 0.125)) ) { // use the path to prepare the graphics context + CG_TRACE( "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth ); CGContextSaveGState( mrContext ); + CG_TRACE( "CGContextAddPath(" << mrContext << "," << xPath << ")" ); CGContextAddPath( mrContext, xPath ); // draw path with antialiased line CGContextSetShouldAntialias( mrContext, true ); + CG_TRACE( "CGContextSetAlpha(" << mrContext << "," << 1.0 - fTransparency << ")" ); CGContextSetAlpha( mrContext, 1.0 - fTransparency ); CGContextSetLineJoin( mrContext, aCGLineJoin ); CGContextSetLineCap( mrContext, aCGLineCap ); + CG_TRACE( "CGContextSetLineWifth(" << mrContext << "," << rLineWidths.getX() << ")" ); CGContextSetLineWidth( mrContext, rLineWidths.getX() ); + CG_TRACE( "CGContextDrawPath(" << mrContext << ",kCGPathStroke)" ); CGContextDrawPath( mrContext, kCGPathStroke ); + CG_TRACE( "CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth-- ); CGContextRestoreGState( mrContext ); // mark modified rectangle as updated RefreshRect( aRefreshRect ); } + CG_TRACE( "CGPathRelease(" << xPath << ")" ); CGPathRelease( xPath ); return true; @@ -883,6 +936,7 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol } // setup poly-polygon path CGMutablePathRef xPath = CGPathCreateMutable(); + CG_TRACE( "CGPathCreateMutable() = " << xPath ); for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) { const ::basegfx::B2DPolygon rPolygon = rPolyPoly.getB2DPolygon( nPolyIdx ); @@ -913,20 +967,27 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol } // use the path to prepare the graphics context + CG_TRACE( "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth ); CGContextSaveGState( mrContext ); + CG_TRACE( "CGContextBeginPath(" << mrContext << ")" ); CGContextBeginPath( mrContext ); + CG_TRACE( "CGContextAddPath(" << mrContext << "," << xPath << ")" ); CGContextAddPath( mrContext, xPath ); // draw path with antialiased polygon CGContextSetShouldAntialias( mrContext, true ); + CG_TRACE( "CGContextSetAlpha(" << mrContext << "," << 1.0 - fTransparency << ")" ); CGContextSetAlpha( mrContext, 1.0 - fTransparency ); + CG_TRACE( "CGContextDrawPath(" << mrContext << "," << eMode << ")" ); CGContextDrawPath( mrContext, eMode ); + CG_TRACE( "CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth-- ); CGContextRestoreGState( mrContext ); // mark modified rectangle as updated RefreshRect( aRefreshRect ); } + CG_TRACE( "CGPathRelease(" << xPath << ")" ); CGPathRelease( xPath ); return true; @@ -985,6 +1046,7 @@ void AquaSalGraphics::drawPolyPolygon( sal_uInt32 nPolyCount, const sal_uInt32 * return; } // convert to CGPath + CG_TRACE( "CGContextBeginPath(" << mrContext << ")" ); CGContextBeginPath( mrContext ); if( IsPenVisible() ) { @@ -996,13 +1058,16 @@ void AquaSalGraphics::drawPolyPolygon( sal_uInt32 nPolyCount, const sal_uInt32 * const SalPoint *pPtAry = ppPtAry[nPoly]; float fX, fY; alignLinePoint( pPtAry, fX, fY ); + CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << fX << "," << fY << ")" ); CGContextMoveToPoint( mrContext, fX, fY ); pPtAry++; for( sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ ) { alignLinePoint( pPtAry, fX, fY ); + CG_TRACE( "CGContextAddLineToPoint(" << mrContext << "," << fX << "," << fY << ")" ); CGContextAddLineToPoint( mrContext, fX, fY ); } + CG_TRACE("CGContextClosePath(" << mrContext << ")"); CGContextClosePath(mrContext); } } @@ -1015,17 +1080,27 @@ void AquaSalGraphics::drawPolyPolygon( sal_uInt32 nPolyCount, const sal_uInt32 * if( nPoints > 1 ) { const SalPoint *pPtAry = ppPtAry[nPoly]; + CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << pPtAry->mnX << "," << pPtAry->mnY << ")" ); CGContextMoveToPoint( mrContext, pPtAry->mnX, pPtAry->mnY ); pPtAry++; for( sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ ) { + CG_TRACE( "CGContextAddLineToPoint(" << mrContext << "," << pPtAry->mnX << "," << pPtAry->mnY << ")" ); CGContextAddLineToPoint( mrContext, pPtAry->mnX, pPtAry->mnY ); } + CG_TRACE("CGContextClosePath(" << mrContext << ")"); CGContextClosePath(mrContext); } } } + CG_TRACE( "CGContextDrawPath(" << mrContext << "," << + (eMode == kCGPathFill ? "kCGPathFill" : + (eMode == kCGPathEOFill ? "kCGPathEOFill" : + (eMode == kCGPathFillStroke ? "kCGPathFillStroke" : + (eMode == kCGPathEOFillStroke ? "kCGPathEOFillStroke" : + "???")))) + << ")" ); CGContextDrawPath( mrContext, eMode ); RefreshRect( leftX, topY, maxWidth, maxHeight ); @@ -1058,31 +1133,38 @@ void AquaSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint *pPtAry ) { return; } + CG_TRACE( "CGContextBeginPath(" << mrContext << ")" ); CGContextBeginPath( mrContext ); if( IsPenVisible() ) { float fX, fY; alignLinePoint( pPtAry, fX, fY ); + CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << fX << "," << fY << ")" ); CGContextMoveToPoint( mrContext, fX, fY ); pPtAry++; for( sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ ) { alignLinePoint( pPtAry, fX, fY ); + CG_TRACE( "CGContextAddLineToPoint(" << mrContext << "," << fX << "," << fY << ")" ); CGContextAddLineToPoint( mrContext, fX, fY ); } } else { + CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << pPtAry->mnX << "," << pPtAry->mnY << ")" ); CGContextMoveToPoint( mrContext, pPtAry->mnX, pPtAry->mnY ); pPtAry++; for( sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ ) { + CG_TRACE( "CGContextAddLineToPoint(" << mrContext << "," << pPtAry->mnX << "," << pPtAry->mnY << ")" ); CGContextAddLineToPoint( mrContext, pPtAry->mnX, pPtAry->mnY ); } } + CG_TRACE("CGContextClosePath(" << mrContext << ")"); CGContextClosePath( mrContext ); + CG_TRACE( "CGContextDrawPath(" << mrContext << "," << eMode << ")" ); CGContextDrawPath( mrContext, eMode ); RefreshRect( nX, nY, nWidth, nHeight ); } @@ -1115,10 +1197,12 @@ void AquaSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) if( IsBrushVisible() ) { + CG_TRACE( "CGContextFillRect(" << mrContext << "," << aRect << ")" ); CGContextFillRect( mrContext, aRect ); } if( IsPenVisible() ) { + CG_TRACE( "CGContextStrokeRect(" << mrContext << "," << aRect << ")" ); CGContextStrokeRect( mrContext, aRect ); } RefreshRect( nX, nY, nWidth, nHeight ); @@ -1139,15 +1223,19 @@ void AquaSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry ) getBoundRect( nPoints, pPtAry, nX, nY, nWidth, nHeight ); float fX, fY; + CG_TRACE( "CGContextBeginPath(" << mrContext << ")" ); CGContextBeginPath( mrContext ); alignLinePoint( pPtAry, fX, fY ); + CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << fX << "," << fY << ")" ); CGContextMoveToPoint( mrContext, fX, fY ); pPtAry++; for( sal_uInt32 nPoint = 1; nPoint < nPoints; nPoint++, pPtAry++ ) { alignLinePoint( pPtAry, fX, fY ); + CG_TRACE( "CGContextAddLineToPoint(" << mrContext << "," << fX << "," << fY << ")" ); CGContextAddLineToPoint( mrContext, fX, fY ); } + CG_TRACE( "CGContextDrawPath(" << mrContext << ",kCGPathStroke)" ); CGContextDrawPath( mrContext, kCGPathStroke ); RefreshRect( nX, nY, nWidth, nHeight ); @@ -1229,6 +1317,8 @@ SalColor AquaSalGraphics::getPixel( long nX, long nY ) CGBitmapContextCreate( &aPixel, 1, 1, 8, sizeof(aPixel), aCGColorSpace, aCGBmpInfo ); + CG_TRACE( "CGBitmapContextCreate(1x1x8) = " << xOnePixelContext ); + // update this graphics layer ApplyXorContext(); @@ -1238,7 +1328,9 @@ SalColor AquaSalGraphics::getPixel( long nX, long nY ) nY = mnHeight - nY; } const CGPoint aCGPoint = CGPointMake(-nX, -nY); + CG_TRACE( "CGContextDrawLayerAtPoint(" << xOnePixelContext << "," << aCGPoint << "," << mxLayer << ")" ); CGContextDrawLayerAtPoint( xOnePixelContext, aCGPoint, mxLayer ); + CG_TRACE( "CGContextRelease(" << xOnePixelContext << ")" ); CGContextRelease( xOnePixelContext ); SalColor nSalColor = MAKE_SALCOLOR( aPixel.r, aPixel.g, aPixel.b ); @@ -1267,12 +1359,15 @@ void AquaSalGraphics::ImplDrawPixel( long nX, long nY, const RGBAColor& rColor ) return; } // overwrite the fill color + CG_TRACE( "CGContextSetFillColor(" << mrContext << "," << rColor << ")" ); CGContextSetFillColor( mrContext, rColor.AsArray() ); // draw 1x1 rect, there is no pixel drawing in Quartz const CGRect aDstRect = CGRectMake(nX, nY, 1, 1); + CG_TRACE( "CGContextFillRect(" << mrContext << "," << aDstRect << ")" ); CGContextFillRect( mrContext, aDstRect ); RefreshRect( aDstRect ); // reset the fill color + CG_TRACE( "CGContextSetFillColor(" << mrContext << "," << maFillColor << ")" ); CGContextSetFillColor( mrContext, maFillColor.AsArray() ); } @@ -1375,15 +1470,18 @@ void AquaSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalIn if ( CheckContext() ) { CGRect aCGRect = CGRectMake( nX, nY, nWidth, nHeight); + CG_TRACE("CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth); CGContextSaveGState(mrContext); if ( nFlags & SAL_INVERT_TRACKFRAME ) { const CGFloat dashLengths[2] = { 4.0, 4.0 }; // for drawing dashed line CGContextSetBlendMode( mrContext, kCGBlendModeDifference ); + CG_TRACE( "CGContextSetRGBStrokeColor(" << mrContext << ",{1,1,1,1})" ); CGContextSetRGBStrokeColor ( mrContext, 1.0, 1.0, 1.0, 1.0 ); CGContextSetLineDash ( mrContext, 0, dashLengths, 2 ); CGContextSetLineWidth( mrContext, 2.0); + CG_TRACE("CGContextStrokeRect(" << mrContext << "," << aCGRect << ")" ); CGContextStrokeRect ( mrContext, aCGRect ); } else if ( nFlags & SAL_INVERT_50 ) @@ -1396,9 +1494,12 @@ void AquaSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalIn else // just invert { CGContextSetBlendMode(mrContext, kCGBlendModeDifference); + CG_TRACE( "CGContextSetRGBFillColor(" << mrContext << ",{1,1,1,1})" ); CGContextSetRGBFillColor ( mrContext,1.0, 1.0, 1.0 , 1.0 ); + CG_TRACE("CGContextFillRect(" << mrContext << "," << aCGRect << ")" ); CGContextFillRect ( mrContext, aCGRect ); } + CG_TRACE( "CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth-- ); CGContextRestoreGState( mrContext); RefreshRect( aCGRect ); } @@ -1423,6 +1524,7 @@ void AquaSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalIn CGPoint* CGpoints ; if ( CheckContext() ) { + CG_TRACE("CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth); CGContextSaveGState(mrContext); CGpoints = makeCGptArray(nPoints,pPtAry); CGContextAddLines ( mrContext, CGpoints, nPoints ); @@ -1430,9 +1532,11 @@ void AquaSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalIn { const CGFloat dashLengths[2] = { 4.0, 4.0 }; // for drawing dashed line CGContextSetBlendMode( mrContext, kCGBlendModeDifference ); + CG_TRACE( "CGContextSetRGBStrokeColor(" << mrContext << ",{1,1,1,1})" ); CGContextSetRGBStrokeColor ( mrContext, 1.0, 1.0, 1.0, 1.0 ); CGContextSetLineDash ( mrContext, 0, dashLengths, 2 ); CGContextSetLineWidth( mrContext, 2.0); + CG_TRACE("CGContextStrokePath(" << mrContext << ")" ); CGContextStrokePath ( mrContext ); } else if ( nSalFlags & SAL_INVERT_50 ) @@ -1443,10 +1547,13 @@ void AquaSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalIn else // just invert { CGContextSetBlendMode( mrContext, kCGBlendModeDifference ); + CG_TRACE( "CGContextSetRGBFillColor(" << mrContext << ",{1,1,1,1})" ); CGContextSetRGBFillColor( mrContext, 1.0, 1.0, 1.0, 1.0 ); + CG_TRACE("CGContextFillPath(" << mrContext << ")" ); CGContextFillPath( mrContext ); } const CGRect aRefreshRect = CGContextGetClipBoundingBox(mrContext); + CG_TRACE( "CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth-- ); CGContextRestoreGState( mrContext); delete [] CGpoints; RefreshRect( aRefreshRect ); @@ -1463,8 +1570,11 @@ void AquaSalGraphics::Pattern50Fill() kCGPatternTilingConstantSpacing, false, &aCallback ); SAL_WARN_IF( !mrContext, "vcl.quartz", "mrContext is NULL" ); + CG_TRACE( "CGContextSetFillColorSpace(" << mrContext << "," << mxP50Space << ")" ); CGContextSetFillColorSpace( mrContext, mxP50Space ); + CG_TRACE( "CGContextSetFillPattern(" << mrContext << "," << mxP50Pattern << ",{1,1,1,1})" ); CGContextSetFillPattern( mrContext, mxP50Pattern, aFillCol ); + CG_TRACE( "CGContextFillPath(" << mrContext << ")" ); CGContextFillPath( mrContext ); } @@ -1474,6 +1584,7 @@ void AquaSalGraphics::ResetClipRegion() // release old path and indicate no clipping if( mxClipPath ) { + CG_TRACE( "CGPathRelease(" << mxClipPath << ")" ); CGPathRelease( mxClipPath ); mxClipPath = NULL; } @@ -1509,6 +1620,7 @@ void AquaSalGraphics::SetLineColor() maLineColor.SetAlpha( 0.0 ); // transparent if( CheckContext() ) { + CG_TRACE( "CGContextSetRGBStrokeColor(" << mrContext << "," << maLineColor << ")" ); CGContextSetRGBStrokeColor( mrContext, maLineColor.GetRed(), maLineColor.GetGreen(), maLineColor.GetBlue(), maLineColor.GetAlpha() ); } @@ -1519,6 +1631,7 @@ void AquaSalGraphics::SetLineColor( SalColor nSalColor ) maLineColor = RGBAColor( nSalColor ); if( CheckContext() ) { + CG_TRACE( "CGContextSetRGBStrokeColor(" << mrContext << "," << maLineColor << ")" ); CGContextSetRGBStrokeColor( mrContext, maLineColor.GetRed(), maLineColor.GetGreen(), maLineColor.GetBlue(), maLineColor.GetAlpha() ); } @@ -1529,6 +1642,7 @@ void AquaSalGraphics::SetFillColor() maFillColor.SetAlpha( 0.0 ); // transparent if( CheckContext() ) { + CG_TRACE( "CGContextSetRGBFillColor(" << mrContext << "," << maFillColor << ")" ); CGContextSetRGBFillColor( mrContext, maFillColor.GetRed(), maFillColor.GetGreen(), maFillColor.GetBlue(), maFillColor.GetAlpha() ); } @@ -1539,6 +1653,7 @@ void AquaSalGraphics::SetFillColor( SalColor nSalColor ) maFillColor = RGBAColor( nSalColor ); if( CheckContext() ) { + CG_TRACE( "CGContextSetRGBFillColor(" << mrContext << "," << maFillColor << ")" ); CGContextSetRGBFillColor( mrContext, maFillColor.GetRed(), maFillColor.GetGreen(), maFillColor.GetBlue(), maFillColor.GetAlpha() ); } @@ -1569,10 +1684,12 @@ bool AquaSalGraphics::setClipRegion( const Region& i_rClip ) // release old clip path if( mxClipPath ) { + CG_TRACE( "CGPathRelease(" << mxClipPath << ")" ); CGPathRelease( mxClipPath ); mxClipPath = NULL; } mxClipPath = CGPathCreateMutable(); + CG_TRACE( "CGPathCreateMutable() = " << mxClipPath ); // set current path, either as polypolgon or sequence of rectangles if(i_rClip.HasPolyPolygonOrB2DPolyPolygon()) @@ -1597,6 +1714,7 @@ bool AquaSalGraphics::setClipRegion( const Region& i_rClip ) if(nH) { const CGRect aRect = CGRectMake( aRectIter->Left(), aRectIter->Top(), nW, nH); + CG_TRACE( "CGPathAddRect(" << mxClipPath << ",NULL," << aRect << ")" ); CGPathAddRect( mxClipPath, NULL, aRect ); } } @@ -1719,6 +1837,7 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth, if( m_xMaskContext ) { // cleanup the mask context + CG_TRACE( "CGContextRelease(" << m_xMaskContext << ")" ); CGContextRelease( m_xMaskContext ); delete[] m_pMaskBuffer; m_xMaskContext = NULL; @@ -1727,6 +1846,7 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth, // cleanup the temp context if needed if( m_xTempContext ) { + CG_TRACE( "CGContextRelease(" << m_xTempContext << ")" ); CGContextRelease( m_xTempContext ); delete[] m_pTempBuffer; m_xTempContext = NULL; @@ -1769,6 +1889,7 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth, nBitsPerComponent, nBytesPerRow, aCGColorSpace, aCGBmpInfo ); SAL_WARN_IF( !m_xMaskContext, "vcl.quartz", "mask context creation failed" ); + CG_TRACE( "CGBitmapContextCreate(" << nWidth << "x" << nHeight << ") = " << m_xMaskContext ); // reset the XOR mask to black memset( m_pMaskBuffer, 0, m_nBufferLongs * sizeof(sal_uLong) ); @@ -1786,6 +1907,7 @@ void XorEmulation::SetTarget( int nWidth, int nHeight, int nTargetDepth, nBitsPerComponent, nBytesPerRow, aCGColorSpace, aCGBmpInfo ); SAL_WARN_IF( !m_xTempContext, "vcl.quartz", "temp context creation failed" ); + CG_TRACE( "CGBitmapContextCreate(" << nWidth << "x" << nHeight << ") = " << m_xTempContext ); } // initialize XOR mask context for drawing @@ -1822,6 +1944,7 @@ bool XorEmulation::UpdateTarget() if( m_xTempContext ) { SAL_WARN_IF( m_xTargetContext == NULL, "vcl.quartz", "Target layer is NULL"); + CG_TRACE( "CGContextDrawLayerAtPoint(" << m_xTempContext << "," << CGPointZero << "," << m_xTargetLayer << ")" ); CGContextDrawLayerAtPoint( m_xTempContext, CGPointZero, m_xTargetLayer ); } // do a manual XOR with the XorMask @@ -1837,11 +1960,14 @@ bool XorEmulation::UpdateTarget() if( m_xTempContext ) { CGImageRef xXorImage = CGBitmapContextCreateImage( m_xTempContext ); + CG_TRACE( "CGBitmapContextCreateImage(" << m_xTempContext << ") = " << xXorImage ); const int nWidth = (int)CGImageGetWidth( xXorImage ); const int nHeight = (int)CGImageGetHeight( xXorImage ); // TODO: update minimal changerect const CGRect aFullRect = CGRectMake(0, 0, nWidth, nHeight); + CG_TRACE( "CGContextDrawImage(" << m_xTargetContext << "," << aFullRect << "," << xXorImage << ")" ); CGContextDrawImage( m_xTargetContext, aFullRect, xXorImage ); + CG_TRACE( "CGImageRelease(" << xXorImage << ")" ); CGImageRelease( xXorImage ); } diff --git a/vcl/quartz/utils.cxx b/vcl/quartz/utils.cxx index b2356fd..1ed6a51 100644 --- a/vcl/quartz/utils.cxx +++ b/vcl/quartz/utils.cxx @@ -67,7 +67,7 @@ NSString* CreateNSString( const OUString& rStr ) return [[NSString alloc] initWithCharacters: rStr.getStr() length: rStr.getLength()]; } -std::ostream &operator <<(std::ostream& s, CGRect &rRect) +std::ostream &operator <<(std::ostream& s, const CGRect &rRect) { #ifndef SAL_LOG_INFO (void) rRect; @@ -80,7 +80,7 @@ std::ostream &operator <<(std::ostream& s, CGRect &rRect) return s; } -std::ostream &operator <<(std::ostream& s, CGPoint &rPoint) +std::ostream &operator <<(std::ostream& s, const CGPoint &rPoint) { #ifndef SAL_LOG_INFO (void) rPoint; @@ -90,7 +90,7 @@ std::ostream &operator <<(std::ostream& s, CGPoint &rPoint) return s; } -std::ostream &operator <<(std::ostream& s, CGSize &rSize) +std::ostream &operator <<(std::ostream& s, const CGSize &rSize) { #ifndef SAL_LOG_INFO (void) rSize; @@ -116,4 +116,17 @@ std::ostream &operator <<(std::ostream& s, CGColorRef pColor) return s; } +std::ostream &operator <<(std::ostream& s, const CGAffineTransform &aXform) +{ +#ifndef SAL_LOG_INFO + (void) aXform; +#else + if (CGAffineTransformIsIdentity(aXform)) + s << "IDENT"; + else + s << "[" << aXform.a << "," << aXform.b << "," << aXform.c << "," << aXform.d << "," << aXform.tx << "," << aXform.ty << "]"; +#endif + return s; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits