/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// This file contains the iOS-specific versions of the functions which were touched in the commit to // fix tdf#138122. The functions are here (for now) as they were before that commit. The // macOS-specific versions of these functions are in vcl/osx/salmacos.cxx.
bool QuartzSalBitmap::Create(CGLayerHolder const & rLayerHolder, int nBitmapBits, int nX, int nY, int nWidth, int nHeight, bool bFlipped)
{
SAL_WARN_IF(!rLayerHolder.isSet(), "vcl", "QuartzSalBitmap::Create() from non-layered context");
if( bSameGraphics &&
(rPosAry.mnSrcWidth == rPosAry.mnDestWidth) &&
(rPosAry.mnSrcHeight == rPosAry.mnDestHeight))
{ // short circuit if there is nothing to do if( (rPosAry.mnSrcX == rPosAry.mnDestX) &&
(rPosAry.mnSrcY == rPosAry.mnDestY))
{ return;
} // use copyArea() if source and destination context are identical
copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY,
rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, false/*bWindowInvalidate*/ ); return;
}
mrShared.applyXorContext(); if (!bSameGraphics)
pSrcShared->applyXorContext();
SAL_WARN_IF (!pSrcShared->maLayer.isSet(), "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 &&
rPosAry.mnSrcHeight == rPosAry.mnDestHeight) &&
(!mrShared.mnBitmapDepth || (aDstPoint.x + pSrcShared->mnWidth) <= mrShared.mnWidth)
&& pSrcShared->maLayer.isSet()) // workaround for a Quartz crash
{ // 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
CGContextHolder aCopyContext = mrShared.maContextHolder; if (mrShared.mpXorEmulation && mrShared.mpXorEmulation->IsEnabled())
{ if (bSameGraphics)
{
aCopyContext.set(mrShared.mpXorEmulation->GetTargetContext());
}
}
aCopyContext.saveState();
// draw at new destination // NOTE: flipped drawing gets disabled for this, else the subimage would be drawn upside down if (pSrcShared->isFlipped())
{
CGContextTranslateCTM(aCopyContext.get(), 0, +mrShared.mnHeight);
CGContextScaleCTM(aCopyContext.get(), +1, -1);
}
// in XOR mode the drawing context is redirected to the XOR mask // copyArea() always works on the target context though
CGContextRef xCopyContext = mrShared.maContextHolder.get();
if (mrShared.mpXorEmulation && mrShared.mpXorEmulation->IsEnabled())
{
xCopyContext = mrShared.mpXorEmulation->GetTargetContext();
}
// If we have a scaled layer, we need to revert the scaling or else // it will interfere with the coordinate calculation
CGContextScaleCTM(xCopyContext, 1.0 / fScale, 1.0 / fScale);
// drawing a layer onto its own context causes trouble on OSX => copy it first // TODO: is it possible to get rid of this unneeded copy more often? // e.g. on OSX>=10.5 only this situation causes problems: // mnBitmapDepth && (aDstPoint.x + pSrc->mnWidth) > mnWidth
// re-enable XorEmulation for the new context if (maShared.mpXorEmulation)
{
maShared.mpXorEmulation->SetTarget(maShared.mnWidth, maShared.mnHeight, maShared.mnBitmapDepth, maShared.maContextHolder.get(), maShared.maLayer.get()); if (maShared.mpXorEmulation->IsEnabled())
{
maShared.maContextHolder.set(maShared.mpXorEmulation->GetMaskContext());
}
}
// initialize stack of CGContext states
maShared.maContextHolder.saveState();
maShared.setState();
}
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 )
{ // cleanup the mask context
CGContextRelease( m_xMaskContext ); delete[] m_pMaskBuffer;
m_xMaskContext = nullptr;
m_pMaskBuffer = nullptr;
// return early if there is nothing more to do if( !xTargetContext )
{ return;
} // retarget drawing operations to the XOR mask
m_xTargetLayer = xTargetLayer;
m_xTargetContext = xTargetContext;
if( mbForeignContext )
{ // Do not delete/resize mxContext that we have received from outside VCL returntrue;
}
if (maLayer.isSet())
{ const CGSize aSize = CGLayerGetSize(maLayer.get()); if( (nDX == aSize.width) && (nDY == aSize.height) )
{ // Yay, we do not have to do anything :) returntrue;
}
}
Destroy();
mnWidth = nDX;
mnHeight = nDY;
// create a CGLayer matching to the intended virdev usage
CGContextHolder xCGContextHolder; if( mnBitmapDepth && (mnBitmapDepth < 16) )
{
mnBitmapDepth = 8; // TODO: are 1bit vdevs worth it? constint nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;
if (maLayer.isSet() && mpGraphics)
{ // get the matching Quartz context
CGContextRef xDrawContext = CGLayerGetContext( maLayer.get() );
// Here we pass the CGLayerRef that the CGLayerHolder maLayer holds as the first parameter // to SetVirDevGraphics(). That parameter is of type CGLayerHolder, so what we actually pass // is an implicitly constructed *separate* CGLayerHolder. Is that what we want? No idea. // Possibly we could pass just maLayer as such? But doing that does not fix tdf#138122.
mpGraphics->SetVirDevGraphics(this, maLayer.get(), xDrawContext, mnBitmapDepth);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.