summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m26
-rw-r--r--vcl/quartz/salgdicommon.cxx141
2 files changed, 165 insertions, 2 deletions
diff --git a/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m b/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m
index 80680dd52269..aafbd430682e 100644
--- a/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m
+++ b/ios/experimental/TiledLibreOffice/TiledLibreOffice/TiledView.m
@@ -82,6 +82,20 @@ static void updateTilesPerSecond(UILabel *label)
}
}
+static int DBG_DRAW_DELAY = 10;
+int DBG_DRAW_ROUNDS = -1;
+int DBG_DRAW_COUNTER = 0;
+int DBG_DRAW_ROUNDS_MAX = INT_MAX;
+
+- (void)redraw
+{
+ DBG_DRAW_ROUNDS++;
+ DBG_DRAW_COUNTER = 0;
+ [self setNeedsDisplay];
+ if (DBG_DRAW_ROUNDS < DBG_DRAW_ROUNDS_MAX)
+ [NSTimer scheduledTimerWithTimeInterval:DBG_DRAW_DELAY target:self selector:@selector(redraw) userInfo:nil repeats:NO];
+}
+
- (id)initWithFrame:(CGRect)frame scale:(CGFloat)scale maxZoom:(int)maxZoom
{
self = [super initWithFrame:frame];
@@ -93,6 +107,13 @@ static void updateTilesPerSecond(UILabel *label)
catl.levelsOfDetailBias = catl.levelsOfDetail - 1;
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTilesPerSecond) userInfo:nil repeats:YES];
+ if (getenv("DRAW_INCREMENTALLY_FROM")) {
+ DBG_DRAW_ROUNDS = atoi(getenv("DRAW_INCREMENTALLY_FROM"));
+ if (getenv("DRAW_INCREMENTALLY_DELAY") &&
+ atoi(getenv("DRAW_INCREMENTALLY_DELAY")) > 1)
+ DBG_DRAW_DELAY = atoi(getenv("DRAW_INCREMENTALLY_DELAY"));
+ [NSTimer scheduledTimerWithTimeInterval:DBG_DRAW_DELAY target:self selector:@selector(redraw) userInfo:nil repeats:NO];
+ }
}
return self;
}
@@ -138,12 +159,13 @@ static bool tileMatches(const char *spec, CGRect bb)
// as needed at the current zoom levels. I keep thinking about
// "pixels" incorrectly.
- if (!getenv("DRAW_ONLY_TILE") || tileMatches(getenv("DRAW_ONLY_TILE"), bb))
+ if (!getenv("DRAW_ONLY_TILE") || tileMatches(getenv("DRAW_ONLY_TILE"), bb)) {
+ fprintf(stderr, "+++ rendering to context %p\n", ctx);
touch_lo_draw_tile(ctx,
tileSize.width, tileSize.height,
CGPointMake(bb.origin.x/self.scale, bb.origin.y/self.scale),
CGSizeMake(bb.size.width/self.scale, bb.size.height/self.scale));
- else {
+ } else {
CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
CGContextFillRect(ctx, CGRectMake(0, 0, bb.size.width, bb.size.height));
}
diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx
index 873f18851b8a..8591b633d5c4 100644
--- a/vcl/quartz/salgdicommon.cxx
+++ b/vcl/quartz/salgdicommon.cxx
@@ -40,6 +40,33 @@
#include <basegfx/range/b2ibox.hxx>
#endif
+#if defined(IOS) && defined(DBG_UTIL)
+
+// Variables in TiledView.m
+extern int DBG_DRAW_ROUNDS, DBG_DRAW_COUNTER, DBG_DRAW_DEPTH;
+
+#define DBG_DRAW_OPERATION(s,v) \
+ do { \
+ if (DBG_DRAW_ROUNDS >= 0) { \
+ if (DBG_DRAW_COUNTER++ > DBG_DRAW_ROUNDS) \
+ return v; \
+ SAL_DEBUG("===> " << s << " " << DBG_DRAW_COUNTER); \
+ } \
+ } while (false)
+
+#define DBG_DRAW_OPERATION_EXIT(s) \
+ do { \
+ if (DBG_DRAW_ROUNDS >= 0) \
+ SAL_DEBUG("<=== " << s << " " << DBG_DRAW_COUNTER); \
+ } while (false)
+
+#else
+
+#define DBG_DRAW_OPERATION(s) /* empty */
+#define DBG_DRAW_OPERATION_EXIT(s) /* empty */
+
+#endif
+
using namespace vcl;
typedef std::vector<unsigned char> ByteVector;
@@ -539,15 +566,20 @@ bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
const SalBitmap& rSrcBitmap,
const SalBitmap& rAlphaBmp )
{
+ DBG_DRAW_OPERATION("drawAlphaBitmap", true);
+
// An image mask can't have a depth > 8 bits (should be 1 to 8 bits)
if( rAlphaBmp.GetBitCount() > 8 )
{
+ DBG_DRAW_OPERATION_EXIT("drawAlphaBitmap");
return false;
}
+
// are these two tests really necessary? (see vcl/unx/source/gdi/salgdi2.cxx)
// horizontal/vertical mirroring not implemented yet
if( rTR.mnDestWidth < 0 || rTR.mnDestHeight < 0 )
{
+ DBG_DRAW_OPERATION_EXIT("drawAlphaBitmap");
return false;
}
@@ -558,8 +590,10 @@ bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
rTR.mnSrcHeight );
if( !xMaskedImage )
{
+ DBG_DRAW_OPERATION_EXIT("drawAlphaBitmap");
return false;
}
+
if ( CheckContext() )
{
const CGRect aDstRect = CGRectMake( rTR.mnDestX, rTR.mnDestY, rTR.mnDestWidth, rTR.mnDestHeight);
@@ -570,6 +604,8 @@ bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR,
CG_TRACE("CGImageRelease(" << xMaskedImage << ")");
CGImageRelease(xMaskedImage);
+
+ DBG_DRAW_OPERATION_EXIT("drawAlphaBitmap");
return true;
}
@@ -577,8 +613,13 @@ bool AquaSalGraphics::drawTransformedBitmap(
const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY,
const SalBitmap& rSrcBitmap, const SalBitmap* pAlphaBmp )
{
+ DBG_DRAW_OPERATION("drawTransformedBitmap", true);
+
if( !CheckContext() )
+ {
+ DBG_DRAW_OPERATION_EXIT("drawTransformedBitmap");
return true;
+ }
// get the Quartz image
CGImageRef xImage = NULL;
@@ -590,7 +631,10 @@ bool AquaSalGraphics::drawTransformedBitmap(
else
xImage = rSrcSalBmp.CreateWithMask( *pMaskSalBmp, 0, 0, (int)aSize.Width(), (int)aSize.Height() );
if( !xImage )
+ {
+ DBG_DRAW_OPERATION_EXIT("drawTransformedBitmap");
return false;
+ }
// setup the image transformation
// using the rNull,rX,rY points as destinations for the (0,0),(0,Width),(Height,0) source points
@@ -618,16 +662,22 @@ bool AquaSalGraphics::drawTransformedBitmap(
// mark the destination as painted
const CGRect aDstRect = CGRectApplyAffineTransform( aSrcRect, aCGMat );
RefreshRect( aDstRect );
+
+ DBG_DRAW_OPERATION_EXIT("drawTransformedBitmap");
return true;
}
bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
long nHeight, sal_uInt8 nTransparency )
{
+ DBG_DRAW_OPERATION("drawAlphaRect", true);
+
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawAlphaRect");
return true;
}
+
// save the current state
CG_TRACE( "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth );
CGContextSaveGState( mrContext );
@@ -652,20 +702,27 @@ bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth,
CG_TRACE("CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth--);
CGContextRestoreGState(mrContext);
RefreshRect( aRect );
+
+ DBG_DRAW_OPERATION_EXIT("drawAlphaRect");
return true;
}
void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap )
{
+ DBG_DRAW_OPERATION("drawBitmap",);
+
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawBitmap");
return;
}
+
const QuartzSalBitmap& rBitmap = static_cast<const QuartzSalBitmap&>(rSalBitmap);
CGImageRef xImage = rBitmap.CreateCroppedImage( (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY,
(int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight );
if( !xImage )
{
+ DBG_DRAW_OPERATION_EXIT("drawBitmap");
return;
}
@@ -675,6 +732,8 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rS
CG_TRACE( "CGImageRelease(" << xImage << ")" );
CGImageRelease( xImage );
RefreshRect( aDstRect );
+
+ DBG_DRAW_OPERATION_EXIT("drawBitmap");
}
void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap,SalColor )
@@ -686,16 +745,21 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rS
void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap,
const SalBitmap& rTransparentBitmap )
{
+ DBG_DRAW_OPERATION("drawBitmap",);
+
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawBitmap");
return;
}
+
const QuartzSalBitmap& rBitmap = static_cast<const QuartzSalBitmap&>(rSalBitmap);
const QuartzSalBitmap& rMask = static_cast<const QuartzSalBitmap&>(rTransparentBitmap);
CGImageRef xMaskedImage( rBitmap.CreateWithMask( rMask, rPosAry.mnSrcX, rPosAry.mnSrcY,
rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ) );
if( !xMaskedImage )
{
+ DBG_DRAW_OPERATION_EXIT("drawBitmap");
return;
}
@@ -705,6 +769,8 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rS
CG_TRACE( "CGImageRelease(" << xMaskedImage << ")" );
CGImageRelease( xMaskedImage );
RefreshRect( aDstRect );
+
+ DBG_DRAW_OPERATION_EXIT("drawBitmap");
}
#ifndef IOS
@@ -761,17 +827,23 @@ bool AquaSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight,
void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
{
+ DBG_DRAW_OPERATION("drawLine",);
+
if( nX1 == nX2 && nY1 == nY2 )
{
// #i109453# platform independent code expects at least one pixel to be drawn
drawPixel( nX1, nY1 );
+
+ DBG_DRAW_OPERATION_EXIT("drawLine");
return;
}
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawLine");
return;
}
+
CG_TRACE( "CGContextBeginPath(" << mrContext << ")" );
CGContextBeginPath( mrContext );
CG_TRACE( "CGContextMoveToPoint(" << mrContext << "," << static_cast<float>(nX1)+0.5 << "," << static_cast<float>(nY1)+0.5 << ")" );
@@ -784,20 +856,27 @@ void AquaSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
Rectangle aRefreshRect( nX1, nY1, nX2, nY2 );
(void) aRefreshRect;
// Is a call to RefreshRect( aRefreshRect ) missing here?
+
+ DBG_DRAW_OPERATION_EXIT("drawLine");
}
void AquaSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor )
{
+ DBG_DRAW_OPERATION("drawMask",);
+
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawMask");
return;
}
+
const QuartzSalBitmap& rBitmap = static_cast<const QuartzSalBitmap&>(rSalBitmap);
CGImageRef xImage = rBitmap.CreateColorMask( rPosAry.mnSrcX, rPosAry.mnSrcY,
rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
nMaskColor );
if( !xImage )
{
+ DBG_DRAW_OPERATION_EXIT("drawMask");
return;
}
@@ -807,6 +886,8 @@ void AquaSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSal
CG_TRACE( "CGImageRelease(" << xImage << ")" );
CGImageRelease( xImage );
RefreshRect( aDstRect );
+
+ DBG_DRAW_OPERATION_EXIT("drawMask");
}
void AquaSalGraphics::drawPixel( long nX, long nY )
@@ -828,31 +909,41 @@ bool AquaSalGraphics::drawPolyLine(
basegfx::B2DLineJoin eLineJoin,
com::sun::star::drawing::LineCap eLineCap)
{
+ DBG_DRAW_OPERATION("drawPolyLine", true);
+
// short circuit if there is nothing to do
const int nPointCount = rPolyLine.count();
if( nPointCount <= 0 )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return true;
}
+
// reject requests that cannot be handled yet
if( rLineWidths.getX() != rLineWidths.getY() )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return false;
}
+
#ifdef IOS
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return false;
}
#endif
+
// #i101491# Aqua does not support B2DLINEJOIN_NONE; return false to use
// the fallback (own geometry preparation)
// #i104886# linejoin-mode and thus the above only applies to "fat" lines
if( (basegfx::B2DLINEJOIN_NONE == eLineJoin) &&
(rLineWidths.getX() > 1.3) )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return false;
}
+
// setup line attributes
CGLineJoin aCGLineJoin = kCGLineJoinMiter;
switch( eLineJoin )
@@ -922,6 +1013,7 @@ bool AquaSalGraphics::drawPolyLine(
CG_TRACE( "CGPathRelease(" << xPath << ")" );
CGPathRelease( xPath );
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return true;
}
@@ -933,17 +1025,23 @@ bool AquaSalGraphics::drawPolyLineBezier( sal_uInt32, const SalPoint*, const sal
bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly,
double fTransparency )
{
+ DBG_DRAW_OPERATION("drawPolyPolygon", true);
+
// short circuit if there is nothing to do
const int nPolyCount = rPolyPoly.count();
if( nPolyCount <= 0 )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return true;
}
+
// ignore invisible polygons
if( (fTransparency >= 1.0) || (fTransparency < 0) )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return true;
}
+
// setup poly-polygon path
CGMutablePathRef xPath = CGPathCreateMutable();
CG_TRACE( "CGPathCreateMutable() = " << xPath );
@@ -954,6 +1052,7 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol
}
const CGRect aRefreshRect = CGPathGetBoundingBox( xPath );
+ CG_TRACE( "CGPathGetBoundingBox(" << xPath << ") = " << aRefreshRect );
// #i97317# workaround for Quartz having problems with drawing small polygons
if( ! ((aRefreshRect.size.width <= 0.125) && (aRefreshRect.size.height <= 0.125)) )
{
@@ -976,6 +1075,7 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol
SAL_WARN( "vcl.quartz", "Neither pen nor brush visible" );
CG_TRACE( "CGPathRelease(" << xPath << ")" );
CGPathRelease( xPath );
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return true;
}
@@ -1003,15 +1103,25 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol
CG_TRACE( "CGPathRelease(" << xPath << ")" );
CGPathRelease( xPath );
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return true;
}
void AquaSalGraphics::drawPolyPolygon( sal_uInt32 nPolyCount, const sal_uInt32 *pPoints, PCONSTSALPOINT *ppPtAry )
{
+ DBG_DRAW_OPERATION("drawPolyPolygon",);
+
if( nPolyCount <= 0 )
+ {
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return;
+ }
+
if( !CheckContext() )
+ {
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return;
+ }
// find bound rect
long leftX = 0, topY = 0, maxWidth = 0, maxHeight = 0;
@@ -1056,8 +1166,11 @@ void AquaSalGraphics::drawPolyPolygon( sal_uInt32 nPolyCount, const sal_uInt32 *
}
else
{
+ SAL_WARN( "vcl.quartz", "Neither pen nor brush visible" );
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
return;
}
+
// convert to CGPath
CG_TRACE( "CGContextBeginPath(" << mrContext << ")" );
CGContextBeginPath( mrContext );
@@ -1117,14 +1230,25 @@ void AquaSalGraphics::drawPolyPolygon( sal_uInt32 nPolyCount, const sal_uInt32 *
CGContextDrawPath( mrContext, eMode );
RefreshRect( leftX, topY, maxWidth, maxHeight );
+
+ DBG_DRAW_OPERATION_EXIT("drawPolyPolygon");
}
void AquaSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint *pPtAry )
{
+ DBG_DRAW_OPERATION("drawPolygon",);
+
if( nPoints <= 1 )
+ {
+ DBG_DRAW_OPERATION_EXIT("drawPolygon");
return;
+ }
+
if( !CheckContext() )
+ {
+ DBG_DRAW_OPERATION_EXIT("drawPolygon");
return;
+ }
long nX = 0, nY = 0, nWidth = 0, nHeight = 0;
getBoundRect( nPoints, pPtAry, nX, nY, nWidth, nHeight );
@@ -1144,8 +1268,10 @@ void AquaSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint *pPtAry )
}
else
{
+ SAL_WARN( "vcl.quartz", "Neither pen nor brush visible" );
return;
}
+
CG_TRACE( "CGContextBeginPath(" << mrContext << ")" );
CGContextBeginPath( mrContext );
@@ -1180,6 +1306,8 @@ void AquaSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint *pPtAry )
CG_TRACE( "CGContextDrawPath(" << mrContext << "," << eMode << ")" );
CGContextDrawPath( mrContext, eMode );
RefreshRect( nX, nY, nWidth, nHeight );
+
+ DBG_DRAW_OPERATION_EXIT("drawPolygon");
}
bool AquaSalGraphics::drawPolygonBezier( sal_uInt32, const SalPoint*, const sal_uInt8* )
@@ -1195,10 +1323,14 @@ bool AquaSalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
void AquaSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
{
+ DBG_DRAW_OPERATION("drawRect",);
+
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawRect");
return;
}
+
CGRect aRect( CGRectMake(nX, nY, nWidth, nHeight) );
if( IsPenVisible() )
{
@@ -1219,16 +1351,23 @@ void AquaSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
CGContextStrokeRect( mrContext, aRect );
}
RefreshRect( nX, nY, nWidth, nHeight );
+
+ DBG_DRAW_OPERATION_EXIT("drawRect");
}
void AquaSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
{
+ DBG_DRAW_OPERATION("drawPolyLine",);
+
if( nPoints < 1 )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return;
}
+
if( !CheckContext() )
{
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
return;
}
@@ -1252,6 +1391,8 @@ void AquaSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry )
CGContextDrawPath( mrContext, kCGPathStroke );
RefreshRect( nX, nY, nWidth, nHeight );
+
+ DBG_DRAW_OPERATION_EXIT("drawPolyLine");
}
sal_uInt16 AquaSalGraphics::GetBitCount() const