fix rendering issues in iOS with aqua
This commit is contained in:
@@ -47,7 +47,7 @@ namespace
|
|||||||
VDevBuffer();
|
VDevBuffer();
|
||||||
virtual ~VDevBuffer();
|
virtual ~VDevBuffer();
|
||||||
|
|
||||||
VirtualDevice* alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMono);
|
VirtualDevice* alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, sal_Int32 nBits);
|
||||||
void free(VirtualDevice& rDevice);
|
void free(VirtualDevice& rDevice);
|
||||||
|
|
||||||
// Timer virtuals
|
// Timer virtuals
|
||||||
@@ -80,7 +80,7 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDevice* VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMono)
|
VirtualDevice* VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, sal_Int32 nBits)
|
||||||
{
|
{
|
||||||
::osl::MutexGuard aGuard(m_aMutex);
|
::osl::MutexGuard aGuard(m_aMutex);
|
||||||
VirtualDevice* pRetval = 0;
|
VirtualDevice* pRetval = 0;
|
||||||
@@ -94,7 +94,7 @@ namespace
|
|||||||
{
|
{
|
||||||
OSL_ENSURE(*a, "Empty pointer in VDevBuffer (!)");
|
OSL_ENSURE(*a, "Empty pointer in VDevBuffer (!)");
|
||||||
|
|
||||||
if((bMono && 1 == (*a)->GetBitCount()) || (!bMono && (*a)->GetBitCount() > 1))
|
if(nBits == (*a)->GetBitCount())
|
||||||
{
|
{
|
||||||
// candidate is valid due to bit depth
|
// candidate is valid due to bit depth
|
||||||
if(aFound != maFreeBuffers.end())
|
if(aFound != maFreeBuffers.end())
|
||||||
@@ -160,7 +160,7 @@ namespace
|
|||||||
// no success yet, create new buffer
|
// no success yet, create new buffer
|
||||||
if(!pRetval)
|
if(!pRetval)
|
||||||
{
|
{
|
||||||
pRetval = (bMono) ? new VirtualDevice(rOutDev, 1) : new VirtualDevice(rOutDev);
|
pRetval = new VirtualDevice(rOutDev, nBits);
|
||||||
pRetval->SetOutputSizePixel(rSizePixel, bClear);
|
pRetval->SetOutputSizePixel(rSizePixel, bClear);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -233,7 +233,7 @@ namespace drawinglayer
|
|||||||
|
|
||||||
if(isVisible())
|
if(isVisible())
|
||||||
{
|
{
|
||||||
mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, false);
|
mpContent = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), false, 0);
|
||||||
|
|
||||||
// #i93485# assert when copying from window to VDev is used
|
// #i93485# assert when copying from window to VDev is used
|
||||||
OSL_ENSURE(mrOutDev.GetOutDevType() != OUTDEV_WINDOW,
|
OSL_ENSURE(mrOutDev.GetOutDevType() != OUTDEV_WINDOW,
|
||||||
@@ -348,7 +348,7 @@ namespace drawinglayer
|
|||||||
OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
|
OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
|
||||||
if(!mpMask)
|
if(!mpMask)
|
||||||
{
|
{
|
||||||
mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, true);
|
mpMask = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, 1);
|
||||||
mpMask->SetMapMode(mpContent->GetMapMode());
|
mpMask->SetMapMode(mpContent->GetMapMode());
|
||||||
|
|
||||||
// do NOT copy AA flag for mask!
|
// do NOT copy AA flag for mask!
|
||||||
@@ -362,7 +362,7 @@ namespace drawinglayer
|
|||||||
OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
|
OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)");
|
||||||
if(!mpAlpha)
|
if(!mpAlpha)
|
||||||
{
|
{
|
||||||
mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, false);
|
mpAlpha = getVDevBuffer().alloc(mrOutDev, maDestPixel.GetSize(), true, 8);
|
||||||
mpAlpha->SetMapMode(mpContent->GetMapMode());
|
mpAlpha->SetMapMode(mpContent->GetMapMode());
|
||||||
|
|
||||||
// copy AA flag for new target; masking needs to be smooth
|
// copy AA flag for new target; masking needs to be smooth
|
||||||
|
@@ -55,6 +55,7 @@ public:
|
|||||||
int mnWidth;
|
int mnWidth;
|
||||||
int mnHeight;
|
int mnHeight;
|
||||||
sal_uInt32 mnBytesPerRow;
|
sal_uInt32 mnBytesPerRow;
|
||||||
|
void* maExternalData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QuartzSalBitmap();
|
QuartzSalBitmap();
|
||||||
@@ -70,6 +71,8 @@ public:
|
|||||||
virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
|
virtual bool Create( const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > xBitmapCanvas,
|
||||||
Size& rSize,
|
Size& rSize,
|
||||||
bool bMask = false );
|
bool bMask = false );
|
||||||
|
// creating quartz wrapper from existing buffer
|
||||||
|
bool Create( BitmapBuffer& buffer);
|
||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
@@ -93,6 +96,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool Create( CGLayerRef xLayer, int nBitCount, int nX, int nY, int nWidth, int nHeight );
|
bool Create( CGLayerRef xLayer, int nBitCount, int nX, int nY, int nWidth, int nHeight );
|
||||||
|
bool Create( CGImageRef xImage, int nBitCount, int nX, int nY, int nWidth, int nHeight );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGImageRef CreateWithMask( const QuartzSalBitmap& rMask, int nX, int nY, int nWidth, int nHeight ) const;
|
CGImageRef CreateWithMask( const QuartzSalBitmap& rMask, int nX, int nY, int nWidth, int nHeight ) const;
|
||||||
|
@@ -62,6 +62,7 @@ QuartzSalBitmap::QuartzSalBitmap()
|
|||||||
, mnWidth(0)
|
, mnWidth(0)
|
||||||
, mnHeight(0)
|
, mnHeight(0)
|
||||||
, mnBytesPerRow(0)
|
, mnBytesPerRow(0)
|
||||||
|
, maExternalData(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +103,63 @@ bool QuartzSalBitmap::Create( CGLayerRef xLayer, int nBitmapBits,
|
|||||||
|
|
||||||
// copy layer content into the bitmap buffer
|
// copy layer content into the bitmap buffer
|
||||||
const CGPoint aSrcPoint = { static_cast<CGFloat>(-nX), static_cast<CGFloat>(-nY) };
|
const CGPoint aSrcPoint = { static_cast<CGFloat>(-nX), static_cast<CGFloat>(-nY) };
|
||||||
CGContextDrawLayerAtPoint( mxGraphicContext, aSrcPoint, xLayer );
|
if(mxGraphicContext) // remove warning
|
||||||
|
CGContextDrawLayerAtPoint( mxGraphicContext, aSrcPoint, xLayer );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool QuartzSalBitmap::Create( CGImageRef xImage, int nBitmapBits,
|
||||||
|
int nX, int nY, int nWidth, int nHeight )
|
||||||
|
{
|
||||||
|
DBG_ASSERT( xImage, "QuartzSalBitmap::Create() from null image" );
|
||||||
|
|
||||||
|
// sanitize input parameters
|
||||||
|
if( nX < 0 )
|
||||||
|
nWidth += nX, nX = 0;
|
||||||
|
if( nY < 0 )
|
||||||
|
nHeight += nY, nY = 0;
|
||||||
|
const CGSize aLayerSize = CGSizeMake(CGImageGetWidth(xImage), CGImageGetHeight(xImage));
|
||||||
|
if( nWidth >= (int)aLayerSize.width - nX )
|
||||||
|
nWidth = (int)aLayerSize.width - nX;
|
||||||
|
if( nHeight >= (int)aLayerSize.height - nY )
|
||||||
|
nHeight = (int)aLayerSize.height - nY;
|
||||||
|
if( (nWidth < 0) || (nHeight < 0) )
|
||||||
|
nWidth = nHeight = 0;
|
||||||
|
|
||||||
|
// initialize properties
|
||||||
|
mnWidth = nWidth;
|
||||||
|
mnHeight = nHeight;
|
||||||
|
mnBits = nBitmapBits ? nBitmapBits : 32;
|
||||||
|
|
||||||
|
// initialize drawing context
|
||||||
|
CreateContext();
|
||||||
|
|
||||||
|
// copy layer content into the bitmap buffer
|
||||||
|
if(mxGraphicContext) // remove warning
|
||||||
|
CGContextDrawImage( mxGraphicContext,
|
||||||
|
CGRectMake(static_cast<CGFloat>(-nX),
|
||||||
|
static_cast<CGFloat>(-nY),
|
||||||
|
aLayerSize.width,
|
||||||
|
aLayerSize.height),
|
||||||
|
xImage );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuartzSalBitmap::Create( BitmapBuffer& buffer)
|
||||||
|
{
|
||||||
|
// initialize properties
|
||||||
|
mnWidth = buffer.mnWidth;
|
||||||
|
mnHeight = buffer.mnHeight;
|
||||||
|
mnBits = buffer.mnBitCount;
|
||||||
|
mnBytesPerRow = buffer.mnScanlineSize;
|
||||||
|
maExternalData = buffer.mpBits;
|
||||||
|
maPalette = buffer.maPalette;
|
||||||
|
|
||||||
|
// initialize drawing context
|
||||||
|
CreateContext();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +225,7 @@ void QuartzSalBitmap::Destroy()
|
|||||||
{
|
{
|
||||||
DestroyContext();
|
DestroyContext();
|
||||||
maUserBuffer.reset();
|
maUserBuffer.reset();
|
||||||
|
maExternalData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
@@ -193,12 +251,16 @@ bool QuartzSalBitmap::CreateContext()
|
|||||||
|
|
||||||
// prepare graphics context
|
// prepare graphics context
|
||||||
// convert image from user input if available
|
// convert image from user input if available
|
||||||
const bool bSkipConversion = !maUserBuffer;
|
const bool bSkipConversion = !maUserBuffer && !maExternalData;
|
||||||
if( bSkipConversion )
|
if( bSkipConversion )
|
||||||
AllocateUserData();
|
AllocateUserData();
|
||||||
|
|
||||||
// default to RGBA color space
|
// default to RGBA color space
|
||||||
|
#ifdef IOS
|
||||||
|
CGColorSpaceRef aCGColorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
|
#else
|
||||||
CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
|
CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
|
||||||
|
#endif
|
||||||
CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
|
CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
|
||||||
|
|
||||||
// convert data into something accepted by CGBitmapContextCreate()
|
// convert data into something accepted by CGBitmapContextCreate()
|
||||||
@@ -206,14 +268,28 @@ bool QuartzSalBitmap::CreateContext()
|
|||||||
sal_uInt32 nContextBytesPerRow = mnBytesPerRow;
|
sal_uInt32 nContextBytesPerRow = mnBytesPerRow;
|
||||||
if( (mnBits == 16) || (mnBits == 32) )
|
if( (mnBits == 16) || (mnBits == 32) )
|
||||||
{
|
{
|
||||||
// no conversion needed for truecolor
|
if (!maExternalData)
|
||||||
maContextBuffer = maUserBuffer;
|
{
|
||||||
|
// no conversion needed for truecolor
|
||||||
|
maContextBuffer = maUserBuffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( (mnBits == 8) && maPalette.IsGreyPalette() )
|
else if( mnBits == 8
|
||||||
|
#ifndef IOS
|
||||||
|
&& maPalette.IsGreyPalette()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// no conversion needed for grayscale
|
// no conversion needed for grayscale
|
||||||
maContextBuffer = maUserBuffer;
|
if (!maExternalData)
|
||||||
|
{
|
||||||
|
maContextBuffer = maUserBuffer;
|
||||||
|
}
|
||||||
|
#ifdef IOS
|
||||||
|
aCGColorSpace = CGColorSpaceCreateDeviceGray();
|
||||||
|
#else
|
||||||
aCGColorSpace = GetSalData()->mxGraySpace;
|
aCGColorSpace = GetSalData()->mxGraySpace;
|
||||||
|
#endif
|
||||||
aCGBmpInfo = kCGImageAlphaNone;
|
aCGBmpInfo = kCGImageAlphaNone;
|
||||||
bitsPerComponent = mnBits;
|
bitsPerComponent = mnBits;
|
||||||
}
|
}
|
||||||
@@ -237,9 +313,14 @@ bool QuartzSalBitmap::CreateContext()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( maContextBuffer.get() )
|
if(maExternalData)
|
||||||
{
|
{
|
||||||
mxGraphicContext = CGBitmapContextCreate( maContextBuffer.get(), mnWidth, mnHeight,
|
mxGraphicContext = ::CGBitmapContextCreate( maExternalData, mnWidth, mnHeight,
|
||||||
|
bitsPerComponent, nContextBytesPerRow, aCGColorSpace, aCGBmpInfo );
|
||||||
|
}
|
||||||
|
else if( maContextBuffer.get() )
|
||||||
|
{
|
||||||
|
mxGraphicContext = ::CGBitmapContextCreate( maContextBuffer.get(), mnWidth, mnHeight,
|
||||||
bitsPerComponent, nContextBytesPerRow, aCGColorSpace, aCGBmpInfo );
|
bitsPerComponent, nContextBytesPerRow, aCGColorSpace, aCGBmpInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,7 +361,7 @@ bool QuartzSalBitmap::AllocateUserData()
|
|||||||
catch( const std::bad_alloc& )
|
catch( const std::bad_alloc& )
|
||||||
{
|
{
|
||||||
OSL_FAIL( "vcl::QuartzSalBitmap::AllocateUserData: bad alloc" );
|
OSL_FAIL( "vcl::QuartzSalBitmap::AllocateUserData: bad alloc" );
|
||||||
maUserBuffer.reset();
|
maUserBuffer.reset( static_cast<sal_uInt8*>(NULL) );
|
||||||
mnBytesPerRow = 0;
|
mnBytesPerRow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,7 +852,7 @@ CGImageRef QuartzSalBitmap::CreateWithMask( const QuartzSalBitmap& rMask,
|
|||||||
|
|
||||||
// CGImageCreateWithMask() only likes masks or greyscale images => convert if needed
|
// CGImageCreateWithMask() only likes masks or greyscale images => convert if needed
|
||||||
// TODO: isolate in an extra method?
|
// TODO: isolate in an extra method?
|
||||||
if( !CGImageIsMask(xMask) || (CGImageGetColorSpace(xMask) != GetSalData()->mxGraySpace) )
|
if( !CGImageIsMask(xMask) || rMask.GetBitCount() != 8)//(CGImageGetColorSpace(xMask) != GetSalData()->mxGraySpace) )
|
||||||
{
|
{
|
||||||
const CGRect xImageRect=CGRectMake( 0, 0, nWidth, nHeight );//the rect has no offset
|
const CGRect xImageRect=CGRectMake( 0, 0, nWidth, nHeight );//the rect has no offset
|
||||||
|
|
||||||
|
@@ -806,6 +806,8 @@ bool SvpSalGraphics::CheckContext()
|
|||||||
{
|
{
|
||||||
if (mbForeignContext)
|
if (mbForeignContext)
|
||||||
return true;
|
return true;
|
||||||
|
if(m_aDevice == NULL) // fix tiledrendering crash when changing content size
|
||||||
|
return false;
|
||||||
|
|
||||||
const basegfx::B2IVector size = m_aDevice->getSize();
|
const basegfx::B2IVector size = m_aDevice->getSize();
|
||||||
const basegfx::B2IVector bufferSize = m_aDevice->getBufferSize();
|
const basegfx::B2IVector bufferSize = m_aDevice->getBufferSize();
|
||||||
@@ -829,32 +831,14 @@ bool SvpSalGraphics::CheckContext()
|
|||||||
kCGImageAlphaNone);
|
kCGImageAlphaNone);
|
||||||
break;
|
break;
|
||||||
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
|
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA:
|
||||||
mrContext = CGBitmapContextCreate(pixelBuffer.get(),
|
|
||||||
bufferSize.getX(), bufferSize.getY(),
|
|
||||||
8, scanlineStride,
|
|
||||||
CGColorSpaceCreateDeviceRGB(),
|
|
||||||
kCGImageAlphaNoneSkipLast);
|
|
||||||
break;
|
|
||||||
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
|
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB:
|
||||||
mrContext = CGBitmapContextCreate(pixelBuffer.get(),
|
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
|
||||||
bufferSize.getX(), bufferSize.getY(),
|
|
||||||
8, scanlineStride,
|
|
||||||
CGColorSpaceCreateDeviceRGB(),
|
|
||||||
kCGImageAlphaNoneSkipFirst);
|
|
||||||
break;
|
|
||||||
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
|
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA:
|
||||||
mrContext = CGBitmapContextCreate(pixelBuffer.get(),
|
mrContext = CGBitmapContextCreate(pixelBuffer.get(),
|
||||||
bufferSize.getX(), bufferSize.getY(),
|
bufferSize.getX(), bufferSize.getY(),
|
||||||
8, scanlineStride,
|
8, scanlineStride,
|
||||||
CGColorSpaceCreateDeviceRGB(),
|
CGColorSpaceCreateDeviceRGB(),
|
||||||
kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little);
|
kCGImageAlphaNoneSkipFirst);//kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little);
|
||||||
break;
|
|
||||||
case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR:
|
|
||||||
mrContext = CGBitmapContextCreate(pixelBuffer.get(),
|
|
||||||
bufferSize.getX(), bufferSize.getY(),
|
|
||||||
8, scanlineStride,
|
|
||||||
CGColorSpaceCreateDeviceRGB(),
|
|
||||||
kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Little);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SAL_WARN( "vcl.ios", "CheckContext: unsupported color format " << basebmp::formatName( m_aDevice->getScanlineFormat() ) );
|
SAL_WARN( "vcl.ios", "CheckContext: unsupported color format " << basebmp::formatName( m_aDevice->getScanlineFormat() ) );
|
||||||
|
@@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
#ifdef IOS
|
#ifdef IOS
|
||||||
#include "saldatabasic.hxx"
|
#include "saldatabasic.hxx"
|
||||||
|
#include "headless/svpbmp.hxx"
|
||||||
|
#include <basegfx/range/b2ibox.hxx>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace vcl;
|
using namespace vcl;
|
||||||
@@ -285,12 +287,6 @@ static inline void alignLinePoint( const SalPoint* i_pIn, float& o_fX, float& o_
|
|||||||
|
|
||||||
void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGraphics )
|
void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGraphics )
|
||||||
{
|
{
|
||||||
#ifdef IOS
|
|
||||||
// Horrible horrible this is all crack, mxLayer is always NULL on iOS,
|
|
||||||
// all this stuff should be rewritten anyway for iOS
|
|
||||||
if( !mxLayer )
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( !pSrcGraphics )
|
if( !pSrcGraphics )
|
||||||
{
|
{
|
||||||
@@ -335,12 +331,9 @@ void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGrap
|
|||||||
const CGPoint aDstPoint = CGPointMake(+rPosAry.mnDestX - rPosAry.mnSrcX, rPosAry.mnDestY - rPosAry.mnSrcY);
|
const CGPoint aDstPoint = CGPointMake(+rPosAry.mnDestX - rPosAry.mnSrcX, rPosAry.mnDestY - rPosAry.mnSrcY);
|
||||||
if( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth &&
|
if( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth &&
|
||||||
rPosAry.mnSrcHeight == rPosAry.mnDestHeight) &&
|
rPosAry.mnSrcHeight == rPosAry.mnDestHeight) &&
|
||||||
(!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher
|
(!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth)
|
||||||
|
&& pSrc->mxLayer ) // workaround a Quartz crasher
|
||||||
{
|
{
|
||||||
#ifdef IOS
|
|
||||||
if( !CheckContext() )
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
// in XOR mode the drawing context is redirected to the XOR mask
|
// in XOR mode the drawing context is redirected to the XOR mask
|
||||||
// if source and target are identical then copyBits() paints onto the target context though
|
// if source and target are identical then copyBits() paints onto the target context though
|
||||||
CGContextRef xCopyContext = mrContext;
|
CGContextRef xCopyContext = mrContext;
|
||||||
@@ -895,6 +888,25 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol
|
|||||||
// #i97317# workaround for Quartz having problems with drawing small polygons
|
// #i97317# workaround for Quartz having problems with drawing small polygons
|
||||||
if( ! ((aRefreshRect.size.width <= 0.125) && (aRefreshRect.size.height <= 0.125)) )
|
if( ! ((aRefreshRect.size.width <= 0.125) && (aRefreshRect.size.height <= 0.125)) )
|
||||||
{
|
{
|
||||||
|
// prepare drawing mode
|
||||||
|
CGPathDrawingMode eMode;
|
||||||
|
if( IsBrushVisible() && IsPenVisible() )
|
||||||
|
{
|
||||||
|
eMode = kCGPathEOFillStroke;
|
||||||
|
}
|
||||||
|
else if( IsPenVisible() )
|
||||||
|
{
|
||||||
|
eMode = kCGPathStroke;
|
||||||
|
}
|
||||||
|
else if( IsBrushVisible() )
|
||||||
|
{
|
||||||
|
eMode = kCGPathEOFill;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// use the path to prepare the graphics context
|
// use the path to prepare the graphics context
|
||||||
CGContextSaveGState( mrContext );
|
CGContextSaveGState( mrContext );
|
||||||
CGContextBeginPath( mrContext );
|
CGContextBeginPath( mrContext );
|
||||||
@@ -903,7 +915,7 @@ bool AquaSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPol
|
|||||||
// draw path with antialiased polygon
|
// draw path with antialiased polygon
|
||||||
CGContextSetShouldAntialias( mrContext, true );
|
CGContextSetShouldAntialias( mrContext, true );
|
||||||
CGContextSetAlpha( mrContext, 1.0 - fTransparency );
|
CGContextSetAlpha( mrContext, 1.0 - fTransparency );
|
||||||
CGContextDrawPath( mrContext, kCGPathEOFillStroke );
|
CGContextDrawPath( mrContext, eMode );
|
||||||
CGContextRestoreGState( mrContext );
|
CGContextRestoreGState( mrContext );
|
||||||
|
|
||||||
// mark modified rectangle as updated
|
// mark modified rectangle as updated
|
||||||
@@ -1145,18 +1157,56 @@ sal_uInt16 AquaSalGraphics::GetBitCount() const
|
|||||||
|
|
||||||
SalBitmap* AquaSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
|
SalBitmap* AquaSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY )
|
||||||
{
|
{
|
||||||
DBG_ASSERT( mxLayer, "AquaSalGraphics::getBitmap() with no layer" );
|
if (!mbForeignContext && m_aDevice != NULL)
|
||||||
|
|
||||||
ApplyXorContext();
|
|
||||||
|
|
||||||
QuartzSalBitmap* pBitmap = new QuartzSalBitmap;
|
|
||||||
if( !pBitmap->Create( mxLayer, mnBitmapDepth, nX, nY, nDX, nDY) )
|
|
||||||
{
|
{
|
||||||
delete pBitmap;
|
// on ios virtual device are Svp so use Svp bitmap to get the content
|
||||||
pBitmap = NULL;
|
basegfx::B2IBox aRect( nX, nY, nX+nDX, nY+nDY );
|
||||||
}
|
basebmp::BitmapDeviceSharedPtr aSubSet = basebmp::subsetBitmapDevice(m_aDevice , aRect );
|
||||||
|
|
||||||
return pBitmap;
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG_ASSERT( mxLayer, "AquaSalGraphics::getBitmap() with no layer" );
|
||||||
|
|
||||||
|
ApplyXorContext();
|
||||||
|
|
||||||
|
QuartzSalBitmap* pBitmap = new QuartzSalBitmap;
|
||||||
|
if( !pBitmap->Create( mxLayer, mnBitmapDepth, nX, nY, nDX, nDY) )
|
||||||
|
{
|
||||||
|
delete pBitmap;
|
||||||
|
pBitmap = NULL;
|
||||||
|
}
|
||||||
|
return pBitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IOS
|
#ifndef IOS
|
||||||
|
Reference in New Issue
Block a user