remove alpha device from OutputDevice

and render to a combined color+alpha bitmap

The strategy is to remove the mpAlphaVDev from OutputDevice,
and have the OutputDevice create 32-bit SalBitmap's
and then have the various backends correctly render to
those 32-bit bitmaps.

However, whenever we extract a BitmapEx from OutputDevice
(e.g. via VirtualDevice) and hand it to the rest of the
system, we split the color and alpha information.
So the rest of the codebase doesn't have to deal with
this yet.

We have some major problems to overcome here:
(*) Cairo uses 32-bit data, even if we ask for 24-bit color with no alpha.
    This is because the current version of cairo does not support RGB 24-bit data.
(*) Sometimes we want the bitmap to be initialised with an opaque white background,
    sometimes we want it to be transparent.
(*) Sometimes when we extract a bitmap from a device, we want the alpha channel,
    sometimes not.
(*) There are lots of left-over bits of previous attempts of this change lying around,
    e.g. in skia.

Notes
(*) we allow Bitmap (ie. SalBitmap) to hold color+alpha
(*) The BitmapEx(Bitmap) constructor checks if the incoming
Bitmap is color+alpha, and if so, splits into a color bitmap and an alpha bitmap
(*) Because the underlying image data is stored pre-multipled, if
we write a transparent pixel with color, and then read the pixel value back,
we might lose the color information.

Change-Id: I0fc0042d6e5be5edd99b320892fb00a8eb2842fe
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173937
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2025-07-21 10:49:25 +02:00
parent 3b22e7c3aa
commit 088a7c7c45
104 changed files with 635 additions and 1276 deletions
-22
View File
@@ -8,28 +8,6 @@ are the same.
#ifndef CONFIG_SKIA_H
#define CONFIG_SKIA_H
// This is a setting that should be set manually and it affects LO
// code rather than Skia itself. It basically controls setting
// BackendCapabilities::mbSupportsBitmap32, i.e. whether one LO bitmap
// contains all the 32bits of an image including the alpha (premultiplied).
//
// Since Skia does not natively support 24bpp, the preferred setup is
// that the setting should be enabled, it makes the code faster and cleaner.
//
// Unfortunately VCL historically splits alpha into a whole separate
// bitmap and works with 24bpp+8bpp, which is generally more complicated,
// more error-prone and just worse, but that's how LO code has been
// written and so there are many places in LO that expect this and
// do not work correctly with true 32bpp bitmaps.
//
// So ultimately the 24+8 split should be dumped (preferably in all of LO,
// not just the Skia-related code), but until all of LO works correctly
// with 32bpp keep this disabled in order to avoid such breakages.
//#define SKIA_USE_BITMAP32 1
#define SKIA_USE_BITMAP32 0
// GPU support (set by configure).
#undef SK_GANESH
// Vulkan support enabled (set by configure).
@@ -2522,6 +2522,7 @@ void DesktopLOKTest::testPaintPartTileDifferentSchemes()
constexpr int nPixelX = 128;
constexpr int nPixelY = 128 * nCanvasWidth;
// this is BGRA format data
std::array<sal_uInt8, nCanvasWidth * nCanvasHeight * 4> aPixels;
// Both parts should be painted with dark scheme
-2
View File
@@ -25,8 +25,6 @@
#include <vcl/BitmapColor.hxx>
#include <vcl/BitmapAccessMode.hxx>
bool Bitmap32IsPreMultipled();
typedef BitmapColor (*FncGetPixel)(ConstScanline pScanline, tools::Long nX);
typedef void (*FncSetPixel)(Scanline pScanline, tools::Long nX, const BitmapColor& rBitmapColor);
+3 -3
View File
@@ -35,21 +35,21 @@
*/
#if ENABLE_CAIRO_RGBA
#define SVP_24BIT_FORMAT (ScanlineFormat::N24BitTcRgb)
#define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcRgbx)
#define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcRgba)
#define SVP_CAIRO_BLUE 2
#define SVP_CAIRO_GREEN 1
#define SVP_CAIRO_RED 0
#define SVP_CAIRO_ALPHA 3
#elif defined OSL_BIGENDIAN
#define SVP_24BIT_FORMAT (ScanlineFormat::N24BitTcRgb)
#define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcXrgb)
#define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcArgb)
#define SVP_CAIRO_BLUE 3
#define SVP_CAIRO_GREEN 2
#define SVP_CAIRO_RED 1
#define SVP_CAIRO_ALPHA 0
#else
#define SVP_24BIT_FORMAT (ScanlineFormat::N24BitTcBgr)
#define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcBgrx)
#define SVP_CAIRO_FORMAT (ScanlineFormat::N32BitTcBgra)
#define SVP_CAIRO_BLUE 0
#define SVP_CAIRO_GREEN 1
#define SVP_CAIRO_RED 2
+6
View File
@@ -566,6 +566,12 @@ public:
// access to SystemDependentDataHolder, to support overload in derived class(es)
const basegfx::SystemDependentDataHolder* accessSystemDependentDataHolder() const;
/**
Can only be called on 32-bit bitmaps. Returns data split into color bitmap and alpha bitmap.
*/
std::pair<Bitmap, AlphaMask> SplitIntoColorAndAlpha() const;
public:
/** ReassignWithSize and recalculate bitmap.
+5 -8
View File
@@ -184,9 +184,6 @@ private:
// The canvas interface for this output device. Is persistent after the first GetCanvas() call
mutable css::uno::WeakReference< css::rendering::XCanvas > mxCanvas;
// TEMP TEMP TEMP
VclPtr<VirtualDevice> mpAlphaVDev;
/// Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset)
tools::Long mnOutOffOrigX;
/// Additional output offset in _logical_ coordinates, applied in PixelToLogic (used by SetPixelOffset/GetPixelOffset)
@@ -1357,7 +1354,10 @@ public:
virtual Bitmap GetBitmap( const Point& rSrcPt, const Size& rSize ) const;
bool HasAlpha() const { return bool(mpAlphaVDev); }
/**
* Does this device support alpha?
*/
virtual bool HasAlpha() const = 0;
/** Query extended bitmap (with alpha channel, if available).
*/
@@ -1460,14 +1460,11 @@ private:
const sal_Int32* pMapX,
const sal_Int32* pMapY );
SAL_DLLPRIVATE Bitmap BlendBitmapWithAlpha(
static SAL_DLLPRIVATE Bitmap BlendBitmapWithAlpha(
Bitmap& aBmp,
BitmapReadAccess const * pP,
BitmapReadAccess const * pA,
const tools::Rectangle& aDstRect,
const sal_Int32 nOffY,
const sal_Int32 nDstHeight,
const sal_Int32 nOffX,
const sal_Int32 nDstWidth,
const sal_Int32* pMapX,
const sal_Int32* pMapY );
+2
View File
@@ -156,6 +156,8 @@ public:
css::awt::DeviceInfo GetDeviceInfo() const override;
virtual bool HasAlpha() const override { return false; }
protected:
virtual void DrawDeviceMask( const Bitmap& rMask, const Color& rMaskColor,
const Point& rDestPt, const Size& rDestSize,
+5 -1
View File
@@ -55,7 +55,7 @@ private:
bool mbForceZeroExtleadBug;
SAL_DLLPRIVATE void ImplInitVirDev( const OutputDevice* pOutDev, tools::Long nDX, tools::Long nDY, const SystemGraphicsData *pData = nullptr );
SAL_DLLPRIVATE bool InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase );
SAL_DLLPRIVATE bool InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase, bool bAlphaMaskTransparent );
VirtualDevice (const VirtualDevice &) = delete;
VirtualDevice & operator= (const VirtualDevice &) = delete;
@@ -144,6 +144,10 @@ public:
bool IsScreenComp() const override { return mbScreenComp; }
bool IsWithoutAlpha() const { return meFormatAndAlpha == DeviceFormat::WITHOUT_ALPHA; }
virtual bool HasAlpha() const override { return meFormatAndAlpha != DeviceFormat::WITHOUT_ALPHA; }
private:
SAL_DLLPRIVATE void ImplSetReferenceDevice( RefDevMode, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY );
@@ -1404,6 +1404,7 @@ static Bitmap getTile(ScModelObj* pModelObj, int nTilePosX, int nTilePosY, tools
{
size_t nCanvasSize = 1024;
size_t nTileSize = 256;
// BGRA format data
std::vector<unsigned char> aPixmap(nCanvasSize * nCanvasSize * 4, 0);
ScopedVclPtrInstance<VirtualDevice> xDevice(DeviceFormat::WITHOUT_ALPHA);
xDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+5 -6
View File
@@ -72,7 +72,6 @@ void exportBitmapExToImage(OUString const& rImageName, const BitmapEx& rBitmapEx
SvFileStream aStream(rImageName, StreamMode::WRITE | StreamMode::TRUNC);
GraphicFilter::GetGraphicFilter().compressAsPNG(aBitmapEx, aStream);
}
bool is32bppSupported() { return ImplGetSVData()->mpDefInst->supportsBitmap32(); }
// Some tests need special handling in drawing code (for example, not smoothscaling
// when handling HiDPI bitmaps). Temporarily set up the test name to get such special
@@ -1787,7 +1786,7 @@ void GraphicsRenderTests::testDrawBitmap32bpp()
GraphicsTestZone zone(aTestName);
vcl::test::OutputDeviceTestBitmap aOutDevTest;
Bitmap aBitmap = aOutDevTest.setupDrawBitmap(vcl::PixelFormat::N32_BPP);
if (!SHOULD_ASSERT || !is32bppSupported())
if (!SHOULD_ASSERT)
{
appendTestResult(aTestName, u"SKIPPED"_ustr);
return;
@@ -1809,7 +1808,7 @@ void GraphicsRenderTests::testDrawTransformedBitmap32bpp()
GraphicsTestZone zone(aTestName);
vcl::test::OutputDeviceTestBitmap aOutDevTest;
Bitmap aBitmap = aOutDevTest.setupDrawTransformedBitmap(vcl::PixelFormat::N32_BPP);
if (!SHOULD_ASSERT || !is32bppSupported())
if (!SHOULD_ASSERT)
{
appendTestResult(aTestName, u"SKIPPED"_ustr);
return;
@@ -1831,7 +1830,7 @@ void GraphicsRenderTests::testDrawBitmapExWithAlpha32bpp()
GraphicsTestZone zone(aTestName);
vcl::test::OutputDeviceTestBitmap aOutDevTest;
Bitmap aBitmap = aOutDevTest.setupDrawBitmapExWithAlpha(vcl::PixelFormat::N32_BPP);
if (!SHOULD_ASSERT || !is32bppSupported())
if (!SHOULD_ASSERT)
{
appendTestResult(aTestName, u"SKIPPED"_ustr);
return;
@@ -1853,7 +1852,7 @@ void GraphicsRenderTests::testDrawMask32bpp()
GraphicsTestZone zone(aTestName);
vcl::test::OutputDeviceTestBitmap aOutDevTest;
Bitmap aBitmap = aOutDevTest.setupDrawMask(vcl::PixelFormat::N32_BPP);
if (!SHOULD_ASSERT || !is32bppSupported())
if (!SHOULD_ASSERT)
{
appendTestResult(aTestName, u"SKIPPED"_ustr);
return;
@@ -1874,7 +1873,7 @@ void GraphicsRenderTests::testDrawBlend32bpp()
GraphicsTestZone zone(aTestName);
vcl::test::OutputDeviceTestBitmap aOutDevTest;
BitmapEx aBitmapEx = aOutDevTest.setupDrawBlend(vcl::PixelFormat::N32_BPP);
if (!SHOULD_ASSERT || !is32bppSupported())
if (!SHOULD_ASSERT)
{
appendTestResult(aTestName, u"SKIPPED"_ustr);
return;
+1 -1
View File
@@ -1655,7 +1655,7 @@ TestResult OutputDeviceTestBitmap::checkBlend(const BitmapEx& rBitmapEx)
std::vector<Color> aExpected
{
COL_WHITE, COL_WHITE, COL_YELLOW, constBackgroundColor,
COL_BLACK, COL_BLACK, COL_YELLOW, constBackgroundColor,
constBackgroundColor, aBlendedColor, constBackgroundColor
};
Bitmap aBitmap(rBitmapEx.GetBitmap());
+50 -11
View File
@@ -642,6 +642,27 @@ void CairoCommon::applyColor(cairo_t* cr, Color aColor, double fTransparency)
}
}
void CairoCommon::applyColor2(cairo_t* cr, Color aColor)
{
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_content_t eContentType = cairo_surface_get_content(cairo_get_target(cr));
if (eContentType == CAIRO_CONTENT_COLOR_ALPHA)
{
cairo_set_source_rgba(cr, aColor.GetRed() / 255.0, aColor.GetGreen() / 255.0,
aColor.GetBlue() / 255.0, aColor.GetAlpha() / 255.0);
}
else if (eContentType == CAIRO_CONTENT_COLOR)
{
cairo_set_source_rgba(cr, aColor.GetRed() / 255.0, aColor.GetGreen() / 255.0,
aColor.GetBlue() / 255.0, 1.0);
}
else // CAIRO_CONTENT_ALPHA
{
double fSet = aColor == COL_BLACK ? 1.0 : 0.0;
cairo_set_source_rgba(cr, 1, 1, 1, fSet);
}
}
void CairoCommon::clipRegion(cairo_t* cr, const vcl::Region& rClipRegion)
{
RectangleVector aRectangles;
@@ -713,7 +734,25 @@ void CairoCommon::drawPixel(const std::optional<Color>& rLineColor, tools::Long
clipRegion(cr);
cairo_rectangle(cr, nX, nY, 1, 1);
CairoCommon::applyColor(cr, *rLineColor, 0.0);
cairo_content_t eContentType = cairo_surface_get_content(cairo_get_target(cr));
if (eContentType == CAIRO_CONTENT_COLOR_ALPHA)
{
cairo_set_source_rgba(cr, rLineColor->GetRed() / 255.0, rLineColor->GetGreen() / 255.0,
rLineColor->GetBlue() / 255.0, rLineColor->GetAlpha() / 255.0);
}
else if (eContentType == CAIRO_CONTENT_COLOR)
{
cairo_set_source_rgba(cr, rLineColor->GetRed() / 255.0, rLineColor->GetGreen() / 255.0,
rLineColor->GetBlue() / 255.0, 1.0);
}
else // eContentType == CAIRO_CONTENT_ALPHA
{
double fSet = *rLineColor == COL_BLACK ? 1.0 : 0.0;
cairo_set_source_rgba(cr, 1, 1, 1, fSet);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
}
cairo_fill(cr);
basegfx::B2DRange extents = getClippedFillDamage(cr);
@@ -801,7 +840,6 @@ void CairoCommon::drawRect(double nX, double nY, double nWidth, double nHeight,
// fast path for the common case of simply creating a solid block of color
if (onlyFillRect(m_oFillColor, m_oLineColor))
{
double fTransparency = 0;
// don't bother trying to draw stuff which is effectively invisible
if (nWidth < 0.1 || nHeight < 0.1)
return;
@@ -820,7 +858,7 @@ void CairoCommon::drawRect(double nX, double nY, double nWidth, double nHeight,
}
cairo_rectangle(cr, nX, nY, nWidth, nHeight);
CairoCommon::applyColor(cr, *m_oFillColor, fTransparency);
CairoCommon::applyColor2(cr, *m_oFillColor);
// Get FillDamage
basegfx::B2DRange extents = getClippedFillDamage(cr);
@@ -1876,14 +1914,15 @@ void CairoCommon::drawMask(const SalTwoRect& rTR, const SalBitmap& rSalBitmap, C
}
std::shared_ptr<SalBitmap> CairoCommon::getBitmap(tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight)
tools::Long nWidth, tools::Long nHeight,
bool bWithoutAlpha)
{
std::shared_ptr<SvpSalBitmap> pBitmap = std::make_shared<SvpSalBitmap>();
BitmapPalette aPal;
assert(GetBitCount() != 1 && "not supported anymore");
vcl::PixelFormat ePixelFormat = vcl::PixelFormat::N32_BPP;
if (!pBitmap->ImplCreate(Size(nWidth, nHeight), ePixelFormat, aPal, false))
if (!pBitmap->ImplCreate(Size(nWidth, nHeight), ePixelFormat, aPal, false, bWithoutAlpha))
{
SAL_WARN("vcl.gdi", "SvpSalGraphics::getBitmap, cannot create bitmap");
return nullptr;
@@ -2023,8 +2062,8 @@ std::optional<BitmapBuffer> FastConvert24BitRgbTo32BitCairo(const BitmapBuffer*
for (tools::Long x = 0; x < nWidth; ++x)
{
#if ENABLE_CAIRO_RGBA
static_assert(SVP_CAIRO_FORMAT == ScanlineFormat::N32BitTcRgbx,
"Expected SVP_CAIRO_FORMAT set to N32BitTcRgbx");
static_assert(SVP_CAIRO_FORMAT == ScanlineFormat::N32BitTcRgba,
"Expected SVP_CAIRO_FORMAT set to N32BitTcRgba");
static_assert(SVP_24BIT_FORMAT == ScanlineFormat::N24BitTcRgb,
"Expected SVP_24BIT_FORMAT set to N24BitTcRgb");
pD[0] = pS[0];
@@ -2032,8 +2071,8 @@ std::optional<BitmapBuffer> FastConvert24BitRgbTo32BitCairo(const BitmapBuffer*
pD[2] = pS[2];
pD[3] = 0xff; // Alpha
#elif defined OSL_BIGENDIAN
static_assert(SVP_CAIRO_FORMAT == ScanlineFormat::N32BitTcXrgb,
"Expected SVP_CAIRO_FORMAT set to N32BitTcXrgb");
static_assert(SVP_CAIRO_FORMAT == ScanlineFormat::N32BitTcArgb,
"Expected SVP_CAIRO_FORMAT set to N32BitTcArgb");
static_assert(SVP_24BIT_FORMAT == ScanlineFormat::N24BitTcRgb,
"Expected SVP_24BIT_FORMAT set to N24BitTcRgb");
pD[0] = 0xff; // Alpha
@@ -2041,8 +2080,8 @@ std::optional<BitmapBuffer> FastConvert24BitRgbTo32BitCairo(const BitmapBuffer*
pD[2] = pS[1];
pD[3] = pS[2];
#else
static_assert(SVP_CAIRO_FORMAT == ScanlineFormat::N32BitTcBgrx,
"Expected SVP_CAIRO_FORMAT set to N32BitTcBgrx");
static_assert(SVP_CAIRO_FORMAT == ScanlineFormat::N32BitTcBgra,
"Expected SVP_CAIRO_FORMAT set to N32BitTcAgrx");
static_assert(SVP_24BIT_FORMAT == ScanlineFormat::N24BitTcBgr,
"Expected SVP_24BIT_FORMAT set to N24BitTcBgr");
pD[0] = pS[0];
+3 -2
View File
@@ -182,9 +182,10 @@ void SvpGraphicsBackend::drawMask(const SalTwoRect& rTR, const SalBitmap& rSalBi
}
std::shared_ptr<SalBitmap> SvpGraphicsBackend::getBitmap(tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight)
tools::Long nWidth, tools::Long nHeight,
bool bWithoutAlpha)
{
return m_rCairoCommon.getBitmap(nX, nY, nWidth, nHeight);
return m_rCairoCommon.getBitmap(nX, nY, nWidth, nHeight, bWithoutAlpha);
}
void SvpGraphicsBackend::drawBitmapBuffer(const SalTwoRect& rTR, const BitmapBuffer* pBuffer,
+11 -4
View File
@@ -42,7 +42,8 @@ static std::optional<BitmapBuffer> ImplCreateDIB(
const Size& rSize,
vcl::PixelFormat ePixelFormat,
const BitmapPalette& rPal,
bool bClear)
bool bClear,
bool bWithoutAlpha)
{
if (!rSize.Width() || !rSize.Height())
return std::nullopt;
@@ -58,7 +59,13 @@ static std::optional<BitmapBuffer> ImplCreateDIB(
pDIB->meFormat = SVP_24BIT_FORMAT;
break;
case vcl::PixelFormat::N32_BPP:
pDIB->meFormat = SVP_CAIRO_FORMAT;
#if ENABLE_CAIRO_RGBA
pDIB->meFormat = bWithoutAlpha ? ScanlineFormat::N32BitTcRgbx : SVP_CAIRO_FORMAT;
#elif defined OSL_BIGENDIAN
pDIB->meFormat = bWithoutAlpha ? ScanlineFormat::N32BitTcXrgb : SVP_CAIRO_FORMAT;
#else
pDIB->meFormat = bWithoutAlpha ? ScanlineFormat::N32BitTcBgrx : SVP_CAIRO_FORMAT;
#endif
break;
case vcl::PixelFormat::INVALID:
assert(false);
@@ -132,10 +139,10 @@ void SvpSalBitmap::Create(const std::optional<BitmapBuffer>& pBuf)
}
bool SvpSalBitmap::ImplCreate(const Size& rSize, vcl::PixelFormat ePixelFormat,
const BitmapPalette& rPal, bool bClear)
const BitmapPalette& rPal, bool bClear, bool bWithoutAlpha)
{
Destroy();
moDIB = ImplCreateDIB(rSize, ePixelFormat, rPal, bClear);
moDIB = ImplCreateDIB(rSize, ePixelFormat, rPal, bClear, bWithoutAlpha);
return moDIB.has_value();
}
+4 -3
View File
@@ -199,12 +199,13 @@ void SvpSalInstance::DestroyObject( SalObject* pObject )
std::unique_ptr<SalVirtualDevice> SvpSalInstance::CreateVirtualDevice(SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat /*eFormat*/)
DeviceFormat /*eFormat*/,
bool bAlphaMaskTransparent)
{
SvpSalGraphics *pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(&rGraphics);
assert(pSvpSalGraphics);
std::unique_ptr<SalVirtualDevice> xNew(new SvpSalVirtualDevice(pSvpSalGraphics->getSurface(), /*pPreExistingTarget*/nullptr));
if (!xNew->SetSize(nDX, nDY))
if (!xNew->SetSize(nDX, nDY, bAlphaMaskTransparent))
xNew.reset();
return xNew;
}
@@ -227,7 +228,7 @@ std::unique_ptr<SalVirtualDevice> SvpSalInstance::CreateVirtualDevice(SalGraphic
cairo_surface_t* pPreExistingTarget = nullptr;
#endif
std::unique_ptr<SalVirtualDevice> xNew(new SvpSalVirtualDevice(pSvpSalGraphics->getSurface(), pPreExistingTarget));
if (!xNew->SetSize(nDX, nDY))
if (!xNew->SetSize(nDX, nDY, /*bAlphaMaskTransparent*/false))
xNew.reset();
return xNew;
}
+17 -3
View File
@@ -63,7 +63,7 @@ void SvpSalVirtualDevice::ReleaseGraphics( SalGraphics* pGraphics )
delete pGraphics;
}
bool SvpSalVirtualDevice::SetSize( tools::Long nNewDX, tools::Long nNewDY )
bool SvpSalVirtualDevice::SetSize( tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent )
{
if (nNewDX == 0)
nNewDX = 1;
@@ -78,7 +78,7 @@ bool SvpSalVirtualDevice::SetSize( tools::Long nNewDX, tools::Long nNewDY )
m_aFrameSize = basegfx::B2IVector(nNewDX, nNewDY);
if (m_bOwnsSurface)
bSuccess = CreateSurface(nNewDX, nNewDY);
bSuccess = CreateSurface(nNewDX, nNewDY, bAlphaMaskTransparent);
assert(m_pSurface);
@@ -112,7 +112,7 @@ bool SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long nNewDY,
return cairo_surface_status(m_pSurface) == CAIRO_STATUS_SUCCESS;
}
bool SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long nNewDY)
bool SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent)
{
if (m_pSurface)
{
@@ -132,11 +132,25 @@ bool SvpSalVirtualDevice::CreateSurface(tools::Long nNewDX, tools::Long nNewDY)
// in software (which should be fairly cheap for small surfaces anyway).
m_pSurface = cairo_surface_create_similar_image(m_pRefSurface, CAIRO_FORMAT_ARGB32, nNewDX, nNewDY);
dl_cairo_surface_set_device_scale(m_pSurface, fXScale, fYScale);
cairo_t* cr = cairo_create(m_pSurface);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_rectangle(cr, 0, 0, nNewDX, nNewDY);
cairo_set_source_rgba(cr, 0, 0, 0, bAlphaMaskTransparent ? 0 : 1);
cairo_fill(cr);
cairo_destroy(cr);
}
else
{
m_pSurface = cairo_surface_create_similar(m_pRefSurface, CAIRO_CONTENT_COLOR_ALPHA, nNewDX, nNewDY);
// Device scale is inherited in this case.
cairo_t* cr = cairo_create(m_pSurface);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_rectangle(cr, 0, 0, nNewDX, nNewDY);
cairo_set_source_rgba(cr, 1, 1, 1, bAlphaMaskTransparent ? 0 : 1);
cairo_fill(cr);
cairo_destroy(cr);
}
SAL_WARN_IF(cairo_surface_status(m_pSurface) != CAIRO_STATUS_SUCCESS, "vcl", "surface of size " << nNewDX << " by " << nNewDY << " creation failed with status of: " << cairo_status_to_string(cairo_surface_status(m_pSurface)));
+2 -1
View File
@@ -152,6 +152,7 @@ struct VCL_DLLPUBLIC CairoCommon
cairo_t* createTmpCompatibleCairoContext() const;
static void applyColor(cairo_t* cr, Color rColor, double fTransparency = 0.0);
static void applyColor2(cairo_t* cr, Color rColor);
void clipRegion(cairo_t* cr);
static void clipRegion(cairo_t* cr, const vcl::Region& rClipRegion);
@@ -224,7 +225,7 @@ struct VCL_DLLPUBLIC CairoCommon
bool bAntiAlias);
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight);
tools::Long nHeight, bool bWithoutAlpha);
static cairo_surface_t* createCairoSurface(const BitmapBuffer* pBuffer);
+1 -1
View File
@@ -93,7 +93,7 @@ public:
Color nMaskColor) override;
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight) override;
tools::Long nHeight, bool bWithoutAlpha) override;
Color getPixel(tools::Long nX, tools::Long nY) override;
+1 -1
View File
@@ -35,7 +35,7 @@ public:
SAL_DLLPRIVATE bool ImplCreate(const Size& rSize,
vcl::PixelFormat ePixelFormat,
const BitmapPalette& rPalette,
bool bClear);
bool bClear, bool bWithoutAlpha = false);
// SalBitmap
SAL_DLLPRIVATE virtual bool Create(const Size& rSize,
+2 -1
View File
@@ -135,7 +135,8 @@ public:
SAL_DLLPRIVATE virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat ) override;
DeviceFormat eFormat,
bool bAlphaMaskTransparent = false ) override;
// VirtualDevice
// nDX and nDY in Pixel
+3 -4
View File
@@ -36,7 +36,7 @@ class VCL_DLLPUBLIC SvpSalVirtualDevice : public SalVirtualDevice
std::vector< SvpSalGraphics* > m_aGraphics;
bool CreateSurface(tools::Long nNewDX, tools::Long nNewDY, sal_uInt8 *const pBuffer);
bool CreateSurface(tools::Long nNewDX, tools::Long nNewDY);
bool CreateSurface(tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent = false);
protected:
SvpSalGraphics* AddGraphics(SvpSalGraphics* aGraphics);
@@ -49,10 +49,9 @@ public:
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent ) override;
virtual bool SetSizeUsingBuffer( tools::Long nNewDX, tools::Long nNewDY,
sal_uInt8 * pBuffer
) override;
sal_uInt8 * pBuffer) override;
cairo_surface_t* GetSurface() const { return m_pSurface; }
+2 -1
View File
@@ -109,7 +109,8 @@ public:
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat ) override;
DeviceFormat eFormat,
bool bAlphaMaskTransparent = false ) override;
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long &nDX, tools::Long &nDY,
+1 -1
View File
@@ -122,7 +122,7 @@ public:
Color nMaskColor) override;
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight) override;
tools::Long nHeight, bool bWithoutAlpha) override;
Color getPixel(tools::Long nX, tools::Long nY) override;
+3 -3
View File
@@ -159,9 +159,9 @@ public:
bool bShow) override;
virtual void DestroyObject(SalObject* pObject) override;
virtual std::unique_ptr<SalVirtualDevice> CreateVirtualDevice(SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat) override;
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice(SalGraphics& rGraphics, tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat, bool bAlphaMaskTransparent = false) override;
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice(SalGraphics& rGraphics, tools::Long& nDX, tools::Long& nDY,
+2 -1
View File
@@ -44,7 +44,8 @@ public:
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics(SalGraphics* pGraphics) override;
virtual bool SetSize(tools::Long nNewDX, tools::Long nNewDY) override;
virtual bool SetSize(tools::Long nNewDX, tools::Long nNewDY,
bool bAlphaMaskTransparent) override;
// SalGeometryProvider
virtual tools::Long GetWidth() const override;
+5 -5
View File
@@ -146,13 +146,13 @@ struct AquaSharedAttributes
bool checkContext();
void setState();
bool isPenVisible() const
bool isPenActive() const
{
return maLineColor.IsVisible();
return maLineColor.IsActive();
}
bool isBrushVisible() const
bool isBrushActive() const
{
return maFillColor.IsVisible();
return maFillColor.IsActive();
}
void refreshRect(float lX, float lY, float lWidth, float lHeight)
@@ -331,7 +331,7 @@ public:
Color nMaskColor) override;
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight) override;
tools::Long nHeight, bool bWithoutAlpha) override;
Color getPixel(tools::Long nX, tools::Long nY) override;
+4 -2
View File
@@ -39,7 +39,8 @@ public:
RGBAColor( ::Color );
RGBAColor( float fRed, float fGreen, float fBlue, float fAlpha ); //NOTUSEDYET
const CGFloat* AsArray() const { return m_fRGBA; }
bool IsVisible() const { return m_fRGBA[3] > 0; }
bool IsActive() const { return m_bActive; }
void SetActive(bool b) { m_bActive = b; }
void SetAlpha( float fAlpha ) { m_fRGBA[3] = fAlpha; }
CGFloat GetRed() const { return m_fRGBA[0]; }
@@ -47,6 +48,7 @@ public:
CGFloat GetBlue() const { return m_fRGBA[2]; }
CGFloat GetAlpha() const { return m_fRGBA[3]; }
private:
bool m_bActive { true };
CGFloat m_fRGBA[4]; // red, green, blue, alpha
};
@@ -55,7 +57,7 @@ inline RGBAColor::RGBAColor( ::Color nColor )
m_fRGBA[0] = nColor.GetRed() * (1.0/255);
m_fRGBA[1] = nColor.GetGreen() * (1.0/255);
m_fRGBA[2] = nColor.GetBlue() * (1.0/255);
m_fRGBA[3] = 1.0; // opaque
m_fRGBA[3] = nColor.GetAlpha() * (1.0/255);
}
inline RGBAColor::RGBAColor( float fRed, float fGreen, float fBlue, float fAlpha )
+2 -2
View File
@@ -51,13 +51,13 @@ private:
void Destroy();
public:
AquaSalVirtualDevice( AquaSalGraphics* pGraphic, tools::Long nDX, tools::Long nDY, DeviceFormat eFormat );
AquaSalVirtualDevice( AquaSalGraphics* pGraphic, tools::Long nDX, tools::Long nDY, DeviceFormat eFormat, bool bAlphaMaskTransparent );
AquaSalVirtualDevice( tools::Long &nDX, tools::Long &nDY, DeviceFormat eFormat, const SystemGraphicsData& rData );
virtual ~AquaSalVirtualDevice() override;
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent ) override;
tools::Long GetWidth() const override
{
+5 -4
View File
@@ -274,7 +274,8 @@ public:
SAL_DLLPRIVATE std::shared_ptr<SalBitmap> GetBitmap(
tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight,
const OutputDevice& rOutDev );
const OutputDevice& rOutDev,
bool bWithoutAlpha );
SAL_DLLPRIVATE Color GetPixel(
tools::Long nX, tools::Long nY,
@@ -497,7 +498,7 @@ protected:
const SalBitmap& rSalBitmap,
Color nMaskColor ) = 0;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) = 0;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, bool bWithoutAlpha ) = 0;
virtual Color getPixel( tools::Long nX, tools::Long nY ) = 0;
@@ -812,9 +813,9 @@ public:
GetImpl()->drawMask(rPosAry, rSalBitmap, nMaskColor);
}
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight) override
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, bool bWithoutAlpha) override
{
return GetImpl()->getBitmap(nX, nY, nWidth, nHeight);
return GetImpl()->getBitmap(nX, nY, nWidth, nHeight, bWithoutAlpha);
}
Color getPixel(tools::Long nX, tools::Long nY) override
+1 -1
View File
@@ -163,7 +163,7 @@ public:
const SalBitmap& rSalBitmap,
Color nMaskColor ) = 0;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) = 0;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, bool bWithoutAlpha ) = 0;
virtual Color getPixel( tools::Long nX, tools::Long nY ) = 0;
+2 -3
View File
@@ -82,14 +82,12 @@ private:
css::uno::Reference<css::datatransfer::clipboard::XClipboard> m_clipboard;
protected:
bool m_bSupportsBitmap32 = false;
bool m_bSupportsOpenGL = false;
public:
SalInstance(std::unique_ptr<comphelper::SolarMutex> pMutex);
virtual ~SalInstance();
bool supportsBitmap32() const { return m_bSupportsBitmap32; }
bool supportsOpenGL() const { return m_bSupportsOpenGL; }
//called directly after Application::Init
@@ -114,7 +112,8 @@ public:
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat ) = 0;
DeviceFormat eFormat,
bool bAlphaMaskTransparent = false ) = 0;
// VirtualDevice
// nDX and nDY in pixels
+2 -2
View File
@@ -40,13 +40,13 @@ public:
virtual void ReleaseGraphics( SalGraphics* pGraphics ) = 0;
// Set new size, without saving the old contents
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY ) = 0;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent ) = 0;
// Set new size using a buffer at the given address
virtual bool SetSizeUsingBuffer( tools::Long /*nNewDX*/, tools::Long /*nNewDY*/,
sal_uInt8 * /*pBuffer*/)
{
// Only the headless virtual device has an implementation.
// Only the headless/svp virtual device has an implementation.
assert(false && "unsupported");
return false;
}
+16 -2
View File
@@ -139,7 +139,7 @@ public:
Color nMaskColor) override;
virtual std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight) override;
tools::Long nHeight, bool bWithoutAlpha) override;
virtual Color getPixel(tools::Long nX, tools::Long nY) override;
@@ -387,6 +387,8 @@ inline SkPaint SkiaSalGraphicsImpl::makePaintInternal() const
SkiaHelper::setBlenderInvert(&paint);
else if (mXorMode == XorMode::Xor)
SkiaHelper::setBlenderXor(&paint);
else
paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
return paint;
}
@@ -415,7 +417,19 @@ inline SkPaint SkiaSalGraphicsImpl::makeFillPaint(double transparency) const
return paint;
}
inline SkPaint SkiaSalGraphicsImpl::makeBitmapPaint() const { return makePaintInternal(); }
inline SkPaint SkiaSalGraphicsImpl::makeBitmapPaint() const
{
SkPaint paint;
// Invert could be done using a blend mode like invert() does, but
// intentionally use SkBlender to make sure it's not overwritten
// by a blend mode set later (which would be probably a mistake),
// and so that the drawing color does not actually matter.
if (mXorMode == XorMode::Invert)
SkiaHelper::setBlenderInvert(&paint);
else if (mXorMode == XorMode::Xor)
SkiaHelper::setBlenderXor(&paint);
return paint;
}
inline SkPaint SkiaSalGraphicsImpl::makeGradientPaint() const { return makePaintInternal(); }
+2 -1
View File
@@ -32,7 +32,7 @@ class VCL_PLUGIN_PUBLIC SkiaSalBitmap final : public SalBitmap
{
public:
SkiaSalBitmap();
SkiaSalBitmap(const sk_sp<SkImage>& image);
SkiaSalBitmap(const sk_sp<SkImage>& image, bool bWithoutAlpha);
virtual ~SkiaSalBitmap() override;
// SalBitmap methods
@@ -199,6 +199,7 @@ private:
BitmapPalette mPalette;
int mBitCount = 0; // bpp
bool m_bWithoutAlpha = false;
Size mSize;
// The contents of the bitmap may be stored in several different ways:
// As mBuffer buffer, which normally stores pixels in the given format.
+2 -1
View File
@@ -41,7 +41,8 @@ public:
virtual void ReleaseGraphics(SalGraphics* pGraphics) override;
// Set new size, without saving the old contents
virtual bool SetSize(tools::Long nNewDX, tools::Long nNewDY) override;
virtual bool SetSize(tools::Long nNewDX, tools::Long nNewDY,
bool bAlphaMaskTransparent) override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+2 -1
View File
@@ -248,7 +248,8 @@ public:
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics&,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat ) override;
DeviceFormat eFormat,
bool bAlphaMaskTransparent = false ) override;
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics&,
tools::Long &nDX, tools::Long &nDY,
+4 -2
View File
@@ -51,14 +51,16 @@ public:
/// Gtk vclplug needs to pass GtkSalGraphics to X11SalVirtualDevice, so create it, and pass as pNewGraphics.
static std::unique_ptr<SalVirtualDevice> CreateX11VirtualDevice(const SalGraphics& rGraphics, tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat, std::unique_ptr<X11SalGraphics> pNewGraphics);
DeviceFormat eFormat, std::unique_ptr<X11SalGraphics> pNewGraphics,
bool bAlphaMaskTransparent);
static std::unique_ptr<SalVirtualDevice> CreateX11VirtualDevice(const SalGraphics& rGraphics, tools::Long &nDX, tools::Long &nDY,
DeviceFormat eFormat, const SystemGraphicsData& rData, std::unique_ptr<X11SalGraphics> pNewGraphics);
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat ) override;
DeviceFormat eFormat,
bool bAlphaMaskTransparent = false ) override;
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long &nDX, tools::Long &nDY,
+1 -1
View File
@@ -73,7 +73,7 @@ public:
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
/// Set new size, without saving the old contents
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent ) override;
// SalGeometryProvider
virtual tools::Long GetWidth() const override { return nDX_; }
+1 -1
View File
@@ -262,7 +262,7 @@ protected:
const SalBitmap& rSalBitmap,
Color nMaskColor ) override;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight ) override;
virtual std::shared_ptr<SalBitmap> getBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, bool bWithoutAlpha ) override;
virtual Color getPixel( tools::Long nX, tools::Long nY ) override;
// invert --> ClipRegion (only Windows or VirDevs)
+2 -1
View File
@@ -52,7 +52,8 @@ public:
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat ) override;
DeviceFormat eFormat,
bool bAlphaMaskTransparent = false ) override;
virtual std::unique_ptr<SalVirtualDevice>
CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long &nDX, tools::Long &nDY,
+3 -2
View File
@@ -54,9 +54,10 @@ public:
virtual SalGraphics* AcquireGraphics() override;
virtual void ReleaseGraphics( SalGraphics* pGraphics ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY ) override;
virtual bool SetSize( tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent ) override;
static HBITMAP ImplCreateVirDevBitmap(HDC hDC, tools::Long nDX, tools::Long nDY, sal_uInt16 nBitCount, void **ppDummy);
static HBITMAP ImplCreateVirDevBitmap(HDC hDC, tools::Long nDX, tools::Long nDY, sal_uInt16 nBitCount,
void **ppDummy, bool bAlphaMaskTransparent = false);
// SalGeometryProvider
virtual tools::Long GetWidth() const override { return mnWidth; }
+2
View File
@@ -62,6 +62,8 @@ public:
virtual css::uno::Reference<css::rendering::XCanvas>
ImplGetCanvas(bool bSpriteCanvas) const override;
virtual bool HasAlpha() const override { return true; }
private:
virtual void InitClipRegion() override;
+22 -3
View File
@@ -126,7 +126,8 @@ void AquaGraphicsBackend::copyBits(const SalTwoRect &rPosAry, SalGraphics *pSrcG
mrShared.applyXorContext();
pSrcShared->applyXorContext();
std::shared_ptr<SalBitmap> pBitmap = pSrcGraphics->GetImpl()->getBitmap(rPosAry.mnSrcX, rPosAry.mnSrcY,
rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
rPosAry.mnSrcWidth, rPosAry.mnSrcHeight,
/*bWithoutAlpha*/false);
if (pBitmap)
{
SalTwoRect aPosAry(rPosAry);
@@ -460,7 +461,7 @@ void AquaSalVirtualDevice::Destroy()
}
}
bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY)
bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY, bool bAlphaMaskTransparent)
{
SAL_INFO("vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
" (" << nDX << "x" << nDY << ") mbForeignContext=" << (mbForeignContext ? "YES" : "NO"));
@@ -504,7 +505,7 @@ bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY)
mnBitmapDepth = 32;
aColorSpace = GetSalData()->mxRGBSpace;
nFlags = uint32_t(kCGImageAlphaNoneSkipFirst) | uint32_t(kCGBitmapByteOrder32Host);
nFlags = uint32_t(kCGImageAlphaPremultipliedFirst) | uint32_t(kCGBitmapByteOrder32Host);
}
if (SkiaHelper::isVCLSkiaEnabled())
@@ -520,6 +521,24 @@ bool AquaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY)
size_t nBytesPerRow = mnBitmapDepth * nScaledWidth / 8;
maBitmapContext.set(CGBitmapContextCreate(nullptr, nScaledWidth, nScaledHeight, 8, nBytesPerRow, aColorSpace, nFlags));
if (mnBitmapDepth == 32)
{
if (bAlphaMaskTransparent)
{
CGColorRef transparentCol = CGColorCreateGenericRGB(0, 0, 0, 0);
CGContextSetFillColorWithColor(maBitmapContext.get(), transparentCol);
CGContextFillRect(maBitmapContext.get(), CGRectMake(0, 0, nScaledWidth, nScaledHeight));
CGColorRelease(transparentCol);
}
else
{
CGColorRef opaqueCol = CGColorCreateGenericRGB(0, 0, 0, 1.0);
CGContextSetFillColorWithColor(maBitmapContext.get(), opaqueCol);
CGContextFillRect(maBitmapContext.get(), CGRectMake(0, 0, nScaledWidth, nScaledHeight));
CGColorRelease(opaqueCol);
}
}
SAL_INFO("vcl.virdev", "AquaSalVirtualDevice::SetSize() this=" << this <<
" fScale=" << fScale << " mnBitmapDepth=" << mnBitmapDepth);
+5 -7
View File
@@ -61,8 +61,6 @@ class BackendTest : public test::BootstrapFixture
}
}
bool is32bppSupported() { return ImplGetSVData()->mpDefInst->supportsBitmap32(); }
public:
BackendTest()
: BootstrapFixture(true, false)
@@ -543,7 +541,7 @@ public:
Bitmap aBitmap = aOutDevTest.setupDrawBitmap(vcl::PixelFormat::N32_BPP);
exportImage(u"09-01_bitmap_test_32bpp.png"_ustr, aBitmap);
auto eResult = vcl::test::OutputDeviceTestBitmap::checkTransformedBitmap(aBitmap);
if (SHOULD_ASSERT && is32bppSupported())
if (SHOULD_ASSERT)
CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
}
@@ -555,7 +553,7 @@ public:
Bitmap aBitmap = aOutDevTest.setupDrawTransformedBitmap(vcl::PixelFormat::N32_BPP);
auto eResult = vcl::test::OutputDeviceTestBitmap::checkTransformedBitmap(aBitmap);
exportImage(u"09-02_transformed_bitmap_test_32bpp.png"_ustr, aBitmap);
if (SHOULD_ASSERT && is32bppSupported())
if (SHOULD_ASSERT)
CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
}
@@ -567,7 +565,7 @@ public:
Bitmap aBitmap = aOutDevTest.setupDrawBitmapExWithAlpha(vcl::PixelFormat::N32_BPP);
auto eResult = vcl::test::OutputDeviceTestBitmap::checkBitmapExWithAlpha(aBitmap);
exportImage(u"09-03_bitmapex_with_alpha_test_32bpp.png"_ustr, aBitmap);
if (SHOULD_ASSERT && is32bppSupported())
if (SHOULD_ASSERT)
CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
}
@@ -579,7 +577,7 @@ public:
Bitmap aBitmap = aOutDevTest.setupDrawMask(vcl::PixelFormat::N32_BPP);
auto eResult = vcl::test::OutputDeviceTestBitmap::checkMask(aBitmap);
exportImage(u"09-04_mask_test_32bpp.png"_ustr, aBitmap);
if (SHOULD_ASSERT && is32bppSupported())
if (SHOULD_ASSERT)
CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
}
@@ -591,7 +589,7 @@ public:
BitmapEx aBitmapEx = aOutDevTest.setupDrawBlend(vcl::PixelFormat::N32_BPP);
auto eResult = vcl::test::OutputDeviceTestBitmap::checkBlend(aBitmapEx);
exportImage(u"09-05_blend_test_32bpp.png"_ustr, aBitmapEx);
if (SHOULD_ASSERT && is32bppSupported())
if (SHOULD_ASSERT)
CPPUNIT_ASSERT(eResult != vcl::test::TestResult::Failed);
}
-5
View File
@@ -58,11 +58,6 @@ void BitmapExTest::testGetPixelColor24_8()
void BitmapExTest::testGetPixelColor32()
{
// Check backend capabilities and return from the test successfully
// if the backend doesn't support 32-bit bitmap
if (!ImplGetSVData()->mpDefInst->supportsBitmap32())
return;
Bitmap aBitmap(Size(3, 3), vcl::PixelFormat::N32_BPP);
{
BitmapScopedWriteAccess pWriteAccess(aBitmap);
-7
View File
@@ -115,8 +115,6 @@ void BitmapTest::testCreation()
}
// Check backend capabilities and return from the test successfully
// if the backend doesn't support 32-bit bitmap
if (ImplGetSVData()->mpDefInst->supportsBitmap32())
{
Bitmap aBmp(Size(10, 10), vcl::PixelFormat::N32_BPP);
Size aSize = aBmp.GetSizePixel();
@@ -482,11 +480,6 @@ void BitmapTest::testErase()
void BitmapTest::testBitmap32()
{
// Check backend capabilities and return from the test successfully
// if the backend doesn't support 32-bit bitmap
if (!ImplGetSVData()->mpDefInst->supportsBitmap32())
return;
Bitmap aBitmap(Size(3, 3), vcl::PixelFormat::N32_BPP);
{
BitmapScopedWriteAccess pWriteAccess(aBitmap);
+1
View File
@@ -31,6 +31,7 @@ public:
void ReleaseGraphics(bool) override {}
bool UsePolyPolygonForComplexGradient() override { return false; }
bool CanAnimate() const override { return false; }
virtual bool HasAlpha() const override { return false; }
};
Animation createAnimation()
@@ -146,17 +146,9 @@ void BitmapRenderTest::testDrawAlphaBitmapEx()
BitmapEx aBitmapEx;
aPngReader.read(aBitmapEx);
// Check backend capabilities, if the backend support 32-bit bitmap
if (ImplGetSVData()->mpDefInst->supportsBitmap32())
{
CPPUNIT_ASSERT_EQUAL(vcl::PixelFormat::N32_BPP, aBitmapEx.GetBitmap().getPixelFormat());
}
else
{
CPPUNIT_ASSERT_EQUAL(vcl::PixelFormat::N24_BPP, aBitmapEx.GetBitmap().getPixelFormat());
CPPUNIT_ASSERT_EQUAL(true, aBitmapEx.IsAlpha());
CPPUNIT_ASSERT_EQUAL(vcl::PixelFormat::N8_BPP, aBitmapEx.GetAlphaMask().getPixelFormat());
}
CPPUNIT_ASSERT_EQUAL(vcl::PixelFormat::N24_BPP, aBitmapEx.GetBitmap().getPixelFormat());
CPPUNIT_ASSERT_EQUAL(true, aBitmapEx.IsAlpha());
CPPUNIT_ASSERT_EQUAL(vcl::PixelFormat::N8_BPP, aBitmapEx.GetAlphaMask().getPixelFormat());
// Check the bitmap has pixels we expect
CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0xFF, 0x00, 0x00, 0x00),
@@ -190,15 +182,21 @@ void BitmapRenderTest::testAlphaVirtualDevice()
// Set it up
pAlphaVirtualDevice->SetOutputSizePixel(Size(4, 4));
CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0xff, 0xff, 0xff, 0xff),
pAlphaVirtualDevice->GetPixel(Point(1, 1)));
pAlphaVirtualDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
pAlphaVirtualDevice->Erase();
// the backends use pre-multipled alpha, so pure transparency does not round-trip properly
CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00),
pAlphaVirtualDevice->GetPixel(Point(1, 1)));
// Get a BitmapEx from the VirDev -> Colors should have alpha
BitmapEx aBitmap = pAlphaVirtualDevice->GetBitmapEx(Point(), Size(4, 4));
CPPUNIT_ASSERT_EQUAL(tools::Long(4), aBitmap.GetSizePixel().Width());
CPPUNIT_ASSERT_EQUAL(tools::Long(4), aBitmap.GetSizePixel().Height());
Color aColor = aBitmap.GetPixelColor(1, 1);
CPPUNIT_ASSERT_EQUAL(COL_TRANSPARENT, aColor);
// the backends use pre-multipled alpha, so pure transparency does not round-trip properly
CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00, 0x00, 0x00, 0x00), aColor);
// Draw an opaque pixel to the VirDev
pAlphaVirtualDevice->DrawPixel(Point(1, 1), Color(0x0022ff55));
+1
View File
@@ -890,6 +890,7 @@ public:
void ReleaseGraphics(bool) override {}
bool UsePolyPolygonForComplexGradient() override { return false; }
bool CanAnimate() const override { return false; }
virtual bool HasAlpha() const override { return false; }
bool testShouldDrawWavePixelAsRect(tools::Long nLineWidth)
{
+2 -2
View File
@@ -365,7 +365,7 @@ void SkiaTest::testDelayedScale()
CPPUNIT_ASSERT_EQUAL(tools::Long(20), buffer1->mnHeight);
skiaBitmap1->ReleaseBuffer(buffer1, BitmapAccessMode::Read);
// Do scaling based on mImage.
SkiaSalBitmap skiaBitmap2(skiaBitmap1->GetSkImage());
SkiaSalBitmap skiaBitmap2(skiaBitmap1->GetSkImage(), /*bWithoutAlpha*/ false);
CPPUNIT_ASSERT(!skiaBitmap2.unittestHasBuffer());
CPPUNIT_ASSERT(skiaBitmap2.unittestHasImage());
CPPUNIT_ASSERT(skiaBitmap2.Scale(2, 3, BmpScaleFlag::Default));
@@ -388,7 +388,7 @@ void SkiaTest::testDelayedScaleAlphaImage()
CPPUNIT_ASSERT(bitmapTmp->Create(Size(10, 10), vcl::PixelFormat::N24_BPP, BitmapPalette()));
bitmapTmp->Erase(COL_RED);
// Create a bitmap that has only an image, not a pixel buffer.
SkiaSalBitmap bitmap(bitmapTmp->GetSkImage());
SkiaSalBitmap bitmap(bitmapTmp->GetSkImage(), /*bWithoutAlpha*/ false);
bitmapTmp.release();
CPPUNIT_ASSERT(!bitmap.unittestHasBuffer());
CPPUNIT_ASSERT(bitmap.unittestHasImage());
+2 -6
View File
@@ -136,13 +136,9 @@ BitmapBuffer* QtBitmap::AcquireBuffer(BitmapAccessMode /*nMode*/)
case 32:
{
#ifdef OSL_BIGENDIAN
pBuffer->meFormat = ImplGetSVData()->mpDefInst->supportsBitmap32()
? ScanlineFormat::N32BitTcArgb
: ScanlineFormat::N32BitTcXrgb;
pBuffer->meFormat = ScanlineFormat::N32BitTcArgb;
#else
pBuffer->meFormat = ImplGetSVData()->mpDefInst->supportsBitmap32()
? ScanlineFormat::N32BitTcBgra
: ScanlineFormat::N32BitTcBgrx;
pBuffer->meFormat = ScanlineFormat::N32BitTcBgra;
#endif
pBuffer->maPalette = aEmptyPalette;
break;
+4 -1
View File
@@ -523,8 +523,11 @@ void QtGraphicsBackend::drawMask(const SalTwoRect& rPosAry, const SalBitmap& /*r
}
std::shared_ptr<SalBitmap> QtGraphicsBackend::getBitmap(tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight)
tools::Long nWidth, tools::Long nHeight,
bool bWithoutAlpha)
{
assert(!bWithoutAlpha && "not supported here");
(void)bWithoutAlpha;
return std::make_shared<QtBitmap>(m_pQImage->copy(nX, nY, nWidth, nHeight));
}
+6 -5
View File
@@ -404,7 +404,8 @@ void QtInstance::DestroyObject(SalObject* pObject)
std::unique_ptr<SalVirtualDevice> QtInstance::CreateVirtualDevice(SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat /*eFormat*/)
DeviceFormat /*eFormat*/,
bool bAlphaMaskTransparent)
{
if (m_bUseCairo)
{
@@ -413,13 +414,13 @@ std::unique_ptr<SalVirtualDevice> QtInstance::CreateVirtualDevice(SalGraphics& r
// tdf#127529 see SvpSalInstance::CreateVirtualDevice for the rare case of a non-null pPreExistingTarget
std::unique_ptr<SalVirtualDevice> pVD(
new QtSvpVirtualDevice(pSvpSalGraphics->getSurface(), /*pPreExistingTarget*/ nullptr));
pVD->SetSize(nDX, nDY);
pVD->SetSize(nDX, nDY, bAlphaMaskTransparent);
return pVD;
}
else
{
std::unique_ptr<SalVirtualDevice> pVD(new QtVirtualDevice(/*scale*/ 1));
pVD->SetSize(nDX, nDY);
pVD->SetSize(nDX, nDY, bAlphaMaskTransparent);
return pVD;
}
}
@@ -436,13 +437,13 @@ QtInstance::CreateVirtualDevice(SalGraphics& rGraphics, tools::Long& nDX, tools:
cairo_surface_t* pPreExistingTarget = static_cast<cairo_surface_t*>(rGd.pSurface);
std::unique_ptr<SalVirtualDevice> pVD(
new QtSvpVirtualDevice(pSvpSalGraphics->getSurface(), pPreExistingTarget));
pVD->SetSize(nDX, nDY);
pVD->SetSize(nDX, nDY, /*bAlphaMaskTransparent*/ false);
return pVD;
}
else
{
std::unique_ptr<SalVirtualDevice> pVD(new QtVirtualDevice(/*scale*/ 1));
pVD->SetSize(nDX, nDY);
pVD->SetSize(nDX, nDY, /*bAlphaMaskTransparent*/ false);
return pVD;
}
}
+4 -1
View File
@@ -43,8 +43,11 @@ void QtVirtualDevice::ReleaseGraphics(SalGraphics* pGraphics)
delete pGraphics;
}
bool QtVirtualDevice::SetSize(tools::Long nNewDX, tools::Long nNewDY)
bool QtVirtualDevice::SetSize(tools::Long nNewDX, tools::Long nNewDY, bool bAlphaMaskTransparent)
{
assert(!bAlphaMaskTransparent && "TODO");
(void)bAlphaMaskTransparent;
if (nNewDX == 0)
nNewDX = 1;
if (nNewDY == 0)
+34 -24
View File
@@ -270,12 +270,12 @@ tools::Long AquaGraphicsBackend::GetGraphicsWidth() const
void AquaGraphicsBackend::SetLineColor()
{
mrShared.maLineColor.SetAlpha(0.0); // transparent
mrShared.maLineColor.SetActive(false);
if (mrShared.checkContext())
{
CGContextSetRGBStrokeColor(mrShared.maContextHolder.get(), mrShared.maLineColor.GetRed(),
mrShared.maLineColor.GetGreen(), mrShared.maLineColor.GetBlue(),
mrShared.maLineColor.GetAlpha());
0.0); // alpha, transparent
}
}
@@ -292,12 +292,12 @@ void AquaGraphicsBackend::SetLineColor(Color nColor)
void AquaGraphicsBackend::SetFillColor()
{
mrShared.maFillColor.SetAlpha(0.0); // transparent
mrShared.maFillColor.SetActive(false);
if (mrShared.checkContext())
{
CGContextSetRGBFillColor(mrShared.maContextHolder.get(), mrShared.maFillColor.GetRed(),
mrShared.maFillColor.GetGreen(), mrShared.maFillColor.GetBlue(),
mrShared.maFillColor.GetAlpha());
0.0); // alpha, transparent
}
}
@@ -444,7 +444,7 @@ void AquaGraphicsBackend::drawRect(tools::Long nX, tools::Long nY, tools::Long n
return;
CGRect aRect = CGRectMake(nX, nY, nWidth, nHeight);
if (mrShared.isPenVisible())
if (mrShared.isPenActive())
{
aRect.origin.x += 0.5;
aRect.origin.y += 0.5;
@@ -452,13 +452,22 @@ void AquaGraphicsBackend::drawRect(tools::Long nX, tools::Long nY, tools::Long n
aRect.size.height -= 1;
}
if (mrShared.isBrushVisible())
if (mrShared.isBrushActive() && mrShared.maFillColor.GetAlpha() == 0)
{
CGContextFillRect(mrShared.maContextHolder.get(), aRect);
CGContextSetBlendMode(mrShared.maContextHolder.get(), kCGBlendModeClear);
CGContextClearRect(mrShared.maContextHolder.get(), aRect);
CGContextSetBlendMode(mrShared.maContextHolder.get(), kCGBlendModeNormal);
}
if (mrShared.isPenVisible())
else
{
CGContextStrokeRect(mrShared.maContextHolder.get(), aRect);
if (mrShared.isBrushActive())
{
CGContextFillRect(mrShared.maContextHolder.get(), aRect);
}
if (mrShared.isPenActive())
{
CGContextStrokeRect(mrShared.maContextHolder.get(), aRect);
}
}
mrShared.refreshRect(nX, nY, nWidth, nHeight);
}
@@ -502,15 +511,15 @@ void AquaGraphicsBackend::drawPolygon(sal_uInt32 nPoints, const Point* pPointArr
getBoundRect(nPoints, pPointArray, nX, nY, nWidth, nHeight);
CGPathDrawingMode eMode;
if (mrShared.isBrushVisible() && mrShared.isPenVisible())
if (mrShared.isBrushActive() && mrShared.isPenActive())
{
eMode = kCGPathEOFillStroke;
}
else if (mrShared.isPenVisible())
else if (mrShared.isPenActive())
{
eMode = kCGPathStroke;
}
else if (mrShared.isBrushVisible())
else if (mrShared.isBrushActive())
{
eMode = kCGPathEOFill;
}
@@ -522,7 +531,7 @@ void AquaGraphicsBackend::drawPolygon(sal_uInt32 nPoints, const Point* pPointArr
CGContextBeginPath(mrShared.maContextHolder.get());
if (mrShared.isPenVisible())
if (mrShared.isPenActive())
{
float fX, fY;
alignLinePoint(pPointArray, fX, fY);
@@ -592,15 +601,15 @@ void AquaGraphicsBackend::drawPolyPolygon(sal_uInt32 nPolyCount, const sal_uInt3
// prepare drawing mode
CGPathDrawingMode eMode;
if (mrShared.isBrushVisible() && mrShared.isPenVisible())
if (mrShared.isBrushActive() && mrShared.isPenActive())
{
eMode = kCGPathEOFillStroke;
}
else if (mrShared.isPenVisible())
else if (mrShared.isPenActive())
{
eMode = kCGPathStroke;
}
else if (mrShared.isBrushVisible())
else if (mrShared.isBrushActive())
{
eMode = kCGPathEOFill;
}
@@ -612,7 +621,7 @@ void AquaGraphicsBackend::drawPolyPolygon(sal_uInt32 nPolyCount, const sal_uInt3
// convert to CGPath
CGContextBeginPath(mrShared.maContextHolder.get());
if (mrShared.isPenVisible())
if (mrShared.isPenActive())
{
for (sal_uInt32 nPoly = 0; nPoly < nPolyCount; nPoly++)
{
@@ -688,7 +697,7 @@ void AquaGraphicsBackend::drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectTo
// the transformation is not used here...)
for (auto const& rPolygon : std::as_const(aPolyPolygon))
{
AddPolygonToPath(xPath, rPolygon, true, !getAntiAlias(), mrShared.isPenVisible());
AddPolygonToPath(xPath, rPolygon, true, !getAntiAlias(), mrShared.isPenActive());
}
const CGRect aRefreshRect = CGPathGetBoundingBox(xPath);
@@ -697,15 +706,15 @@ void AquaGraphicsBackend::drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectTo
{
// prepare drawing mode
CGPathDrawingMode eMode;
if (mrShared.isBrushVisible() && mrShared.isPenVisible())
if (mrShared.isBrushActive() && mrShared.isPenActive())
{
eMode = kCGPathEOFillStroke;
}
else if (mrShared.isPenVisible())
else if (mrShared.isPenActive())
{
eMode = kCGPathStroke;
}
else if (mrShared.isBrushVisible())
else if (mrShared.isBrushActive())
{
eMode = kCGPathEOFill;
}
@@ -949,7 +958,8 @@ void AquaGraphicsBackend::drawMask(const SalTwoRect& rPosAry, const SalBitmap& r
}
std::shared_ptr<SalBitmap> AquaGraphicsBackend::getBitmap(tools::Long nX, tools::Long nY,
tools::Long nDX, tools::Long nDY)
tools::Long nDX, tools::Long nDY,
bool /*bWithoutAlpha*/)
{
SAL_WARN_IF(!mrShared.maLayer.isSet(), "vcl.quartz",
"AquaSalGraphics::getBitmap() with no layer this=" << this);
@@ -1006,7 +1016,7 @@ Color AquaGraphicsBackend::getPixel(tools::Long nX, tools::Long nY)
CGContextRelease(xOnePixelContext);
Color nColor(aPixel.r, aPixel.g, aPixel.b);
Color nColor(ColorAlpha, aPixel.a, aPixel.r, aPixel.g, aPixel.b);
return nColor;
}
@@ -1305,7 +1315,7 @@ bool AquaGraphicsBackend::drawAlphaRect(tools::Long nX, tools::Long nY, tools::L
CGContextSetAlpha(mrShared.maContextHolder.get(), (100 - nTransparency) * (1.0 / 100));
CGRect aRect = CGRectMake(nX, nY, nWidth - 1, nHeight - 1);
if (mrShared.isPenVisible())
if (mrShared.isPenActive())
{
aRect.origin.x += 0.5;
aRect.origin.y += 0.5;
+2 -4
View File
@@ -276,7 +276,7 @@ void QuartzSalBitmap::ConvertBitmapData( sal_uInt32 nWidth, sal_uInt32 nHeight,
aSrcBuf.mnBitCount = nSrcBits;
aSrcBuf.mnScanlineSize = nSrcBytesPerRow;
BitmapBuffer aDstBuf;
aDstBuf.meFormat = ImplGetSVData()->mpDefInst->supportsBitmap32() ? ScanlineFormat::N32BitTcArgb : ScanlineFormat::N32BitTcXrgb;
aDstBuf.meFormat = ScanlineFormat::N32BitTcArgb;
aDstBuf.mpBits = pDestData;
aDstBuf.mnBitCount = nDestBits;
aDstBuf.mnScanlineSize = nDestBytesPerRow;
@@ -439,10 +439,8 @@ BitmapBuffer* QuartzSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ )
pBuffer->meFormat = ScanlineFormat::N24BitTcBgr;
break;
case 32:
{
pBuffer->meFormat = ImplGetSVData()->mpDefInst->supportsBitmap32() ? ScanlineFormat::N32BitTcArgb : ScanlineFormat::N32BitTcXrgb;
pBuffer->meFormat = ScanlineFormat::N32BitTcArgb;
break;
}
default: assert(false);
}
+6 -5
View File
@@ -39,19 +39,20 @@
std::unique_ptr<SalVirtualDevice> AquaSalInstance::CreateVirtualDevice( SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat )
DeviceFormat eFormat,
bool bAlphaMaskTransparent)
{
// #i92075# can be called first in a thread
SalData::ensureThreadAutoreleasePool();
#ifdef IOS
(void)rGraphics;
std::unique_ptr<SalVirtualDevice> pNew(new AquaSalVirtualDevice( nullptr, nDX, nDY, eFormat ));
std::unique_ptr<SalVirtualDevice> pNew(new AquaSalVirtualDevice( nullptr, nDX, nDY, eFormat, bAlphaMaskTransparent ));
pNew->SetSize( nDX, nDY );
return pNew;
#else
return std::unique_ptr<SalVirtualDevice>(new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >(&rGraphics),
nDX, nDY, eFormat ));
nDX, nDY, eFormat, bAlphaMaskTransparent ));
#endif
}
@@ -69,7 +70,7 @@ std::unique_ptr<SalVirtualDevice> AquaSalInstance::CreateVirtualDevice( SalGraph
AquaSalVirtualDevice::AquaSalVirtualDevice(
AquaSalGraphics* pGraphic, tools::Long nDX, tools::Long nDY,
DeviceFormat eFormat )
DeviceFormat eFormat, bool bAlphaMaskTransparent )
: mbGraphicsUsed( false )
, mnBitmapDepth( 0 )
, mnWidth(0)
@@ -109,7 +110,7 @@ AquaSalVirtualDevice::AquaSalVirtualDevice(
#endif
if( nDX && nDY )
{
SetSize( nDX, nDY );
SetSize( nDX, nDY, bAlphaMaskTransparent );
}
// NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
}
+3 -2
View File
@@ -1452,7 +1452,8 @@ void SkiaSalGraphicsImpl::drawMask(const SalTwoRect& rPosAry, const SalBitmap& r
}
std::shared_ptr<SalBitmap> SkiaSalGraphicsImpl::getBitmap(tools::Long nX, tools::Long nY,
tools::Long nWidth, tools::Long nHeight)
tools::Long nWidth, tools::Long nHeight,
bool bWithoutAlpha)
{
SkiaZone zone;
checkSurface();
@@ -1464,7 +1465,7 @@ std::shared_ptr<SalBitmap> SkiaSalGraphicsImpl::getBitmap(tools::Long nX, tools:
// in blendAlphaBitmap(), where we could simply use the proper rect of the image.
sk_sp<SkImage> image = makeCheckedImageSnapshot(
mSurface, scaleRect(SkIRect::MakeXYWH(nX, nY, nWidth, nHeight), mScaling));
std::shared_ptr<SkiaSalBitmap> bitmap = std::make_shared<SkiaSalBitmap>(image);
std::shared_ptr<SkiaSalBitmap> bitmap = std::make_shared<SkiaSalBitmap>(image, bWithoutAlpha);
// If the surface is scaled for HiDPI, the bitmap needs to be scaled down, otherwise
// it would have incorrect size from the API point of view. The DirectImage::Yes handling
// in mergeCacheBitmaps() should access the original unscaled bitmap data to avoid
+13 -24
View File
@@ -58,16 +58,13 @@ SkiaSalBitmap::SkiaSalBitmap() {}
SkiaSalBitmap::~SkiaSalBitmap() {}
SkiaSalBitmap::SkiaSalBitmap(const sk_sp<SkImage>& image)
SkiaSalBitmap::SkiaSalBitmap(const sk_sp<SkImage>& image, bool bWithoutAlpha)
{
ResetAllData();
mImage = image;
mPalette = BitmapPalette();
#if SKIA_USE_BITMAP32
mBitCount = 32;
#else
mBitCount = 24;
#endif
m_bWithoutAlpha = bWithoutAlpha;
mSize = mPixelsSize = Size(image->width(), image->height());
ComputeScanlineSize();
mReadAccessCount = 0;
@@ -300,14 +297,16 @@ BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode nMode)
: ScanlineFormat::N24BitTcRgb;
break;
case 32:
#if SKIA_USE_BITMAP32
// this tracks the m_bSupportsBitmap32 field
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgra
: ScanlineFormat::N32BitTcRgba;
#else
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgrx
: ScanlineFormat::N32BitTcRgbx;
#endif
if (m_bWithoutAlpha)
{
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgrx
: ScanlineFormat::N32BitTcRgbx;
}
else
{
buffer->meFormat = kN32_SkColorTypeIsBGRA ? ScanlineFormat::N32BitTcBgra
: ScanlineFormat::N32BitTcRgba;
}
break;
default:
abort();
@@ -1125,12 +1124,8 @@ SkAlphaType SkiaSalBitmap::alphaType() const
{
if (mEraseColorSet)
return mEraseColor.IsTransparent() ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
#if SKIA_USE_BITMAP32
// The bitmap's alpha matters only if SKIA_USE_BITMAP32 is set, otherwise
// the alpha is in a separate bitmap.
if (mBitCount == 32)
return kPremul_SkAlphaType;
#endif
return kOpaque_SkAlphaType;
}
@@ -1251,18 +1246,12 @@ void SkiaSalBitmap::EnsureBitmapData()
// Try to fill mBuffer from mImage.
assert(mImage->colorType() == kN32_SkColorType);
SkiaZone zone;
// If the source image has no alpha, then use no alpha (faster to convert), otherwise
// use kUnpremul_SkAlphaType to make Skia convert from premultiplied alpha when reading
// from the SkImage (the alpha will be ignored if converting to bpp<32 formats, but
// the color channels must be unpremultiplied. Unless bpp==32 and SKIA_USE_BITMAP32,
// in which case use kPremul_SkAlphaType, since SKIA_USE_BITMAP32 implies premultiplied alpha.
// If the source image has no alpha, then use no alpha (faster to convert).
SkAlphaType alphaType = kUnpremul_SkAlphaType;
if (mImage->imageInfo().alphaType() == kOpaque_SkAlphaType)
alphaType = kOpaque_SkAlphaType;
#if SKIA_USE_BITMAP32
if (mBitCount == 32)
alphaType = kPremul_SkAlphaType;
#endif
SkBitmap bitmap;
SkPixmap pixmap;
if (imageSize(mImage) == mSize && mImage->imageInfo().alphaType() == alphaType
+3 -1
View File
@@ -78,8 +78,10 @@ SalGraphics* X11SkiaSalVirtualDevice::AcquireGraphics()
void X11SkiaSalVirtualDevice::ReleaseGraphics(SalGraphics*) { mbGraphicsAcquired = false; }
bool X11SkiaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY)
bool X11SkiaSalVirtualDevice::SetSize(tools::Long nDX, tools::Long nDY, bool bAlphaMaskTransparent)
{
assert(!bAlphaMaskTransparent && "TODO");
(void)bAlphaMaskTransparent;
if (!nDX)
nDX = 1;
if (!nDY)
+11 -2
View File
@@ -104,9 +104,18 @@ void BitmapEx::loadFromIconTheme( const OUString& rIconName )
}
BitmapEx::BitmapEx( const Bitmap& rBmp ) :
maBitmap ( rBmp ),
maBitmapSize ( maBitmap.GetSizePixel() )
maBitmapSize ( rBmp.GetSizePixel() )
{
if (rBmp.getPixelFormat() == vcl::PixelFormat::N32_BPP)
{
std::pair<Bitmap, AlphaMask> aPair = rBmp.SplitIntoColorAndAlpha();
maBitmap = std::move(aPair.first);
maAlphaMask = std::move(aPair.second);
}
else
{
maBitmap = rBmp;
}
}
BitmapEx::BitmapEx( const Bitmap& rBmp, const Bitmap& rMask ) :
-18
View File
@@ -53,8 +53,6 @@ BitmapReadAccess::BitmapReadAccess(const Bitmap& rBitmap, BitmapAccessMode nMode
BitmapReadAccess::~BitmapReadAccess() {}
bool Bitmap32IsPreMultipled() { return ImplGetSVData()->mpDefInst->supportsBitmap32(); }
FncGetPixel BitmapReadAccess::GetPixelFunction(ScanlineFormat nFormat)
{
switch (nFormat)
@@ -68,28 +66,20 @@ FncGetPixel BitmapReadAccess::GetPixelFunction(ScanlineFormat nFormat)
case ScanlineFormat::N24BitTcRgb:
return GetPixelForN24BitTcRgb;
case ScanlineFormat::N32BitTcAbgr:
assert(Bitmap32IsPreMultipled());
return GetPixelForN32BitTcAbgr;
case ScanlineFormat::N32BitTcXbgr:
assert(!Bitmap32IsPreMultipled());
return GetPixelForN32BitTcXbgr;
case ScanlineFormat::N32BitTcArgb:
assert(Bitmap32IsPreMultipled());
return GetPixelForN32BitTcArgb;
case ScanlineFormat::N32BitTcXrgb:
assert(!Bitmap32IsPreMultipled());
return GetPixelForN32BitTcXrgb;
case ScanlineFormat::N32BitTcBgra:
assert(Bitmap32IsPreMultipled());
return GetPixelForN32BitTcBgra;
case ScanlineFormat::N32BitTcBgrx:
assert(!Bitmap32IsPreMultipled());
return GetPixelForN32BitTcBgrx;
case ScanlineFormat::N32BitTcRgba:
assert(Bitmap32IsPreMultipled());
return GetPixelForN32BitTcRgba;
case ScanlineFormat::N32BitTcRgbx:
assert(!Bitmap32IsPreMultipled());
return GetPixelForN32BitTcRgbx;
default:
@@ -110,28 +100,20 @@ FncSetPixel BitmapReadAccess::SetPixelFunction(ScanlineFormat nFormat)
case ScanlineFormat::N24BitTcRgb:
return SetPixelForN24BitTcRgb;
case ScanlineFormat::N32BitTcAbgr:
assert(Bitmap32IsPreMultipled());
return SetPixelForN32BitTcAbgr;
case ScanlineFormat::N32BitTcXbgr:
assert(!Bitmap32IsPreMultipled());
return SetPixelForN32BitTcXbgr;
case ScanlineFormat::N32BitTcArgb:
assert(Bitmap32IsPreMultipled());
return SetPixelForN32BitTcArgb;
case ScanlineFormat::N32BitTcXrgb:
assert(!Bitmap32IsPreMultipled());
return SetPixelForN32BitTcXrgb;
case ScanlineFormat::N32BitTcBgra:
assert(Bitmap32IsPreMultipled());
return SetPixelForN32BitTcBgra;
case ScanlineFormat::N32BitTcBgrx:
assert(!Bitmap32IsPreMultipled());
return SetPixelForN32BitTcBgrx;
case ScanlineFormat::N32BitTcRgba:
assert(Bitmap32IsPreMultipled());
return SetPixelForN32BitTcRgba;
case ScanlineFormat::N32BitTcRgbx:
assert(!Bitmap32IsPreMultipled());
return SetPixelForN32BitTcRgbx;
default:
-8
View File
@@ -101,35 +101,27 @@ void BitmapWriteAccess::CopyScanline(tools::Long nY, ConstScanline aSrcScanline,
pFncGetPixel = GetPixelForN24BitTcRgb;
break;
case ScanlineFormat::N32BitTcAbgr:
assert(Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcAbgr;
break;
case ScanlineFormat::N32BitTcXbgr:
assert(!Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcXbgr;
break;
case ScanlineFormat::N32BitTcArgb:
assert(Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcArgb;
break;
case ScanlineFormat::N32BitTcXrgb:
assert(!Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcXrgb;
break;
case ScanlineFormat::N32BitTcBgra:
assert(Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcBgra;
break;
case ScanlineFormat::N32BitTcBgrx:
assert(!Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcBgrx;
break;
case ScanlineFormat::N32BitTcRgba:
assert(Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcRgba;
break;
case ScanlineFormat::N32BitTcRgbx:
assert(!Bitmap32IsPreMultipled());
pFncGetPixel = GetPixelForN32BitTcRgbx;
break;
+36
View File
@@ -1777,4 +1777,40 @@ const basegfx::SystemDependentDataHolder* Bitmap::accessSystemDependentDataHolde
return mxSalBmp.get();
}
std::pair<Bitmap, AlphaMask> Bitmap::SplitIntoColorAndAlpha() const
{
assert(getPixelFormat() == vcl::PixelFormat::N32_BPP && "only valid to call this when this is a 32-bit combined color+alpha bitmap");
Bitmap aColorBmp(GetSizePixel(), vcl::PixelFormat::N24_BPP);
AlphaMask aAlphaBmp(GetSizePixel());
// We will probably need to make this more efficient by pushing it down to the *SalBitmap implementations,
// but for now, do the simple and safe thing.
{
BitmapScopedReadAccess pThisAcc(*this);
BitmapScopedWriteAccess pColorAcc(aColorBmp);
BitmapScopedWriteAccess pAlphaAcc(aAlphaBmp);
const tools::Long nHeight(pThisAcc->Height());
const tools::Long nWidth(pThisAcc->Width());
for (tools::Long y = 0; y < nHeight; ++y)
{
Scanline pScanlineRead = pThisAcc->GetScanline( y );
Scanline pScanlineColor = pColorAcc->GetScanline( y );
Scanline pScanlineAlpha = pAlphaAcc->GetScanline( y );
for (tools::Long x = 0; x < nWidth; ++x)
{
BitmapColor aColor = pThisAcc->GetPixelFromData(pScanlineRead, x);
// write result back
pColorAcc->SetPixelOnData(pScanlineColor, x, aColor);
pAlphaAcc->SetPixelOnData(pScanlineAlpha, x, BitmapColor(aColor.GetAlpha()));
}
}
}
return { std::move(aColorBmp), std::move(aAlphaBmp) };
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+26 -95
View File
@@ -364,7 +364,6 @@ bool reader(SvStream& rStream, ImportOutput& rImportOutput,
BitmapScopedWriteAccess pWriteAccessInstance;
BitmapScopedWriteAccess pWriteAccessAlphaInstance;
const bool bFuzzing = comphelper::IsFuzzing();
const bool bSupportsBitmap32 = bFuzzing || ImplGetSVData()->mpDefInst->supportsBitmap32();
const bool bOnlyCreateBitmap
= static_cast<bool>(nImportFlags & GraphicFilterImportFlags::OnlyCreateBitmap);
const bool bUseExistingBitmap
@@ -462,14 +461,9 @@ bool reader(SvStream& rStream, ImportOutput& rImportOutput,
aBitmap = Bitmap(Size(width, height), vcl::PixelFormat::N24_BPP);
break;
case PNG_COLOR_TYPE_RGBA:
if (bSupportsBitmap32)
aBitmap = Bitmap(Size(width, height), vcl::PixelFormat::N32_BPP);
else
{
aBitmap = Bitmap(Size(width, height), vcl::PixelFormat::N24_BPP);
aBitmapAlpha = AlphaMask(Size(width, height), nullptr);
aBitmapAlpha.Erase(0); // opaque
}
aBitmap = Bitmap(Size(width, height), vcl::PixelFormat::N24_BPP);
aBitmapAlpha = AlphaMask(Size(width, height), nullptr);
aBitmapAlpha.Erase(0); // opaque
break;
case PNG_COLOR_TYPE_GRAY:
aBitmap = Bitmap(Size(width, height), vcl::PixelFormat::N8_BPP,
@@ -551,81 +545,43 @@ bool reader(SvStream& rStream, ImportOutput& rImportOutput,
else if (colorType == PNG_COLOR_TYPE_RGB_ALPHA)
{
size_t aRowSizeBytes = png_get_rowbytes(pPng, pInfo);
ScanlineFormat eFormat = pWriteAccess->GetScanlineFormat();
if (eFormat == ScanlineFormat::N24BitTcBgr)
png_set_bgr(pPng);
if (bSupportsBitmap32)
if (nNumberOfPasses == 1)
{
ScanlineFormat eFormat = pWriteAccess->GetScanlineFormat();
if (eFormat == ScanlineFormat::N32BitTcAbgr || eFormat == ScanlineFormat::N32BitTcBgra)
png_set_bgr(pPng);
for (int pass = 0; pass < nNumberOfPasses; pass++)
// optimise the common case, where we can use a buffer of only a single row
std::vector<png_byte> aRow(aRowSizeBytes, 0);
for (png_uint_32 y = 0; y < height; y++)
{
for (png_uint_32 y = 0; y < height; y++)
Scanline pScanline = pWriteAccess->GetScanline(y);
Scanline pScanAlpha = pWriteAccessAlpha->GetScanline(y);
png_bytep pRow = aRow.data();
png_read_row(pPng, pRow, nullptr);
size_t iAlpha = 0;
size_t iColor = 0;
for (size_t i = 0; i < aRowSizeBytes; i += 4)
{
Scanline pScanline = pWriteAccess->GetScanline(y);
png_read_row(pPng, pScanline, nullptr);
}
}
#if !ENABLE_WASM_STRIP_PREMULTIPLY
const vcl::bitmap::lookup_table& premultiply = vcl::bitmap::get_premultiply_table();
#endif
if (eFormat == ScanlineFormat::N32BitTcAbgr || eFormat == ScanlineFormat::N32BitTcArgb)
{ // alpha first and premultiply
for (png_uint_32 y = 0; y < height; y++)
{
Scanline pScanline = pWriteAccess->GetScanline(y);
for (size_t i = 0; i < aRowSizeBytes; i += 4)
{
const sal_uInt8 alpha = pScanline[i + 3];
#if ENABLE_WASM_STRIP_PREMULTIPLY
pScanline[i + 3] = vcl::bitmap::premultiply(pScanline[i + 2], alpha);
pScanline[i + 2] = vcl::bitmap::premultiply(pScanline[i + 1], alpha);
pScanline[i + 1] = vcl::bitmap::premultiply(pScanline[i], alpha);
#else
pScanline[i + 3] = premultiply[alpha][pScanline[i + 2]];
pScanline[i + 2] = premultiply[alpha][pScanline[i + 1]];
pScanline[i + 1] = premultiply[alpha][pScanline[i]];
#endif
pScanline[i] = alpha;
}
}
}
else
{ // keep alpha last, only premultiply
for (png_uint_32 y = 0; y < height; y++)
{
Scanline pScanline = pWriteAccess->GetScanline(y);
for (size_t i = 0; i < aRowSizeBytes; i += 4)
{
const sal_uInt8 alpha = pScanline[i + 3];
#if ENABLE_WASM_STRIP_PREMULTIPLY
pScanline[i] = vcl::bitmap::premultiply(pScanline[i], alpha);
pScanline[i + 1] = vcl::bitmap::premultiply(pScanline[i + 1], alpha);
pScanline[i + 2] = vcl::bitmap::premultiply(pScanline[i + 2], alpha);
#else
pScanline[i] = premultiply[alpha][pScanline[i]];
pScanline[i + 1] = premultiply[alpha][pScanline[i + 1]];
pScanline[i + 2] = premultiply[alpha][pScanline[i + 2]];
#endif
}
pScanline[iColor++] = pRow[i + 0];
pScanline[iColor++] = pRow[i + 1];
pScanline[iColor++] = pRow[i + 2];
pScanAlpha[iAlpha++] = pRow[i + 3];
}
}
}
else
{
ScanlineFormat eFormat = pWriteAccess->GetScanlineFormat();
if (eFormat == ScanlineFormat::N24BitTcBgr)
png_set_bgr(pPng);
if (nNumberOfPasses == 1)
std::vector<std::vector<png_byte>> aRows(height);
for (auto& rRow : aRows)
rRow.resize(aRowSizeBytes, 0);
for (int pass = 0; pass < nNumberOfPasses; pass++)
{
// optimise the common case, where we can use a buffer of only a single row
std::vector<png_byte> aRow(aRowSizeBytes, 0);
for (png_uint_32 y = 0; y < height; y++)
{
Scanline pScanline = pWriteAccess->GetScanline(y);
Scanline pScanAlpha = pWriteAccessAlpha->GetScanline(y);
png_bytep pRow = aRow.data();
png_bytep pRow = aRows[y].data();
png_read_row(pPng, pRow, nullptr);
size_t iAlpha = 0;
size_t iColor = 0;
@@ -638,31 +594,6 @@ bool reader(SvStream& rStream, ImportOutput& rImportOutput,
}
}
}
else
{
std::vector<std::vector<png_byte>> aRows(height);
for (auto& rRow : aRows)
rRow.resize(aRowSizeBytes, 0);
for (int pass = 0; pass < nNumberOfPasses; pass++)
{
for (png_uint_32 y = 0; y < height; y++)
{
Scanline pScanline = pWriteAccess->GetScanline(y);
Scanline pScanAlpha = pWriteAccessAlpha->GetScanline(y);
png_bytep pRow = aRows[y].data();
png_read_row(pPng, pRow, nullptr);
size_t iAlpha = 0;
size_t iColor = 0;
for (size_t i = 0; i < aRowSizeBytes; i += 4)
{
pScanline[iColor++] = pRow[i + 0];
pScanline[iColor++] = pRow[i + 1];
pScanline[iColor++] = pRow[i + 2];
pScanAlpha[iAlpha++] = pRow[i + 3];
}
}
}
}
}
}
else if (colorType == PNG_COLOR_TYPE_GRAY)
+27 -71
View File
@@ -72,21 +72,10 @@ static bool readWebp(SvStream& stream, Graphic& graphic)
if (width > SAL_MAX_INT32 / 8 || height > SAL_MAX_INT32 / 8)
return false; // avoid overflows later
const bool bFuzzing = comphelper::IsFuzzing();
const bool bSupportsBitmap32 = bFuzzing || ImplGetSVData()->mpDefInst->supportsBitmap32();
Bitmap bitmap;
AlphaMask bitmapAlpha;
if (bSupportsBitmap32 && has_alpha)
{
bitmap = Bitmap(Size(width, height), vcl::PixelFormat::N32_BPP);
}
else
{
bitmap = Bitmap(Size(width, height), vcl::PixelFormat::N24_BPP);
if (has_alpha)
bitmapAlpha = AlphaMask(Size(width, height));
}
Bitmap bitmap(Size(width, height), vcl::PixelFormat::N24_BPP);
if (has_alpha)
bitmapAlpha = AlphaMask(Size(width, height));
BitmapScopedWriteAccess access(bitmap);
if (!access)
@@ -104,25 +93,17 @@ static bool readWebp(SvStream& stream, Graphic& graphic)
config.output.width = width;
config.output.height = height;
config.output.is_external_memory = 1;
if (bSupportsBitmap32 && has_alpha)
if (has_alpha)
{
switch (access->GetScanlineFormat())
{
// Our bitmap32 code expects premultiplied.
case ScanlineFormat::N32BitTcRgba:
case ScanlineFormat::N32BitTcRgbx:
config.output.colorspace = MODE_rgbA;
pixelMode = PixelMode::DirectRead;
case ScanlineFormat::N24BitTcRgb:
config.output.colorspace = MODE_RGBA;
pixelMode = PixelMode::Split;
break;
case ScanlineFormat::N32BitTcBgra:
case ScanlineFormat::N32BitTcBgrx:
config.output.colorspace = MODE_bgrA;
pixelMode = PixelMode::DirectRead;
break;
case ScanlineFormat::N32BitTcArgb:
case ScanlineFormat::N32BitTcXrgb:
config.output.colorspace = MODE_Argb;
pixelMode = PixelMode::DirectRead;
case ScanlineFormat::N24BitTcBgr:
config.output.colorspace = MODE_BGRA;
pixelMode = PixelMode::Split;
break;
default:
config.output.colorspace = MODE_RGBA;
@@ -132,43 +113,23 @@ static bool readWebp(SvStream& stream, Graphic& graphic)
}
else
{
if (has_alpha)
switch (access->GetScanlineFormat())
{
switch (access->GetScanlineFormat())
{
case ScanlineFormat::N24BitTcRgb:
config.output.colorspace = MODE_RGBA;
pixelMode = PixelMode::Split;
break;
case ScanlineFormat::N24BitTcBgr:
config.output.colorspace = MODE_BGRA;
pixelMode = PixelMode::Split;
break;
default:
config.output.colorspace = MODE_RGBA;
pixelMode = PixelMode::SetPixel;
break;
}
}
else
{
switch (access->GetScanlineFormat())
{
case ScanlineFormat::N24BitTcRgb:
config.output.colorspace = MODE_RGB;
pixelMode = PixelMode::DirectRead;
break;
case ScanlineFormat::N24BitTcBgr:
config.output.colorspace = MODE_BGR;
pixelMode = PixelMode::DirectRead;
break;
default:
config.output.colorspace = MODE_RGB;
pixelMode = PixelMode::SetPixel;
break;
}
case ScanlineFormat::N24BitTcRgb:
config.output.colorspace = MODE_RGB;
pixelMode = PixelMode::DirectRead;
break;
case ScanlineFormat::N24BitTcBgr:
config.output.colorspace = MODE_BGR;
pixelMode = PixelMode::DirectRead;
break;
default:
config.output.colorspace = MODE_RGB;
pixelMode = PixelMode::SetPixel;
break;
}
}
if (pixelMode == PixelMode::DirectRead)
{
config.output.u.RGBA.rgba = access->GetBuffer();
@@ -286,15 +247,10 @@ static bool readWebp(SvStream& stream, Graphic& graphic)
}
access.reset(); // Flush BitmapScopedWriteAccess.
if (bSupportsBitmap32 && has_alpha)
graphic = BitmapEx(bitmap);
if (has_alpha)
graphic = BitmapEx(bitmap, bitmapAlpha);
else
{
if (has_alpha)
graphic = BitmapEx(bitmap, bitmapAlpha);
else
graphic = BitmapEx(bitmap);
}
graphic = BitmapEx(bitmap);
return success;
}
-10
View File
@@ -221,13 +221,6 @@ void Printer::DrawDeviceBitmapEx( const Point& rDestPt, const Size& rDestSize,
void Printer::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly,
sal_uInt16 nTransparencePercent )
{
// #110958# Disable alpha VDev, we perform the necessary
VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
// operation explicitly further below.
if( mpAlphaVDev )
mpAlphaVDev = nullptr;
GDIMetaFile* pOldMetaFile = mpMetaFile;
mpMetaFile = nullptr;
@@ -285,9 +278,6 @@ void Printer::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly,
Pop();
mpMetaFile = pOldMetaFile;
// #110958# Restore disabled alpha VDev
mpAlphaVDev = pOldAlphaVDev;
}
void Printer::DrawOutDev( const Point& /*rDestPt*/, const Size& /*rDestSize*/,
+2 -2
View File
@@ -681,11 +681,11 @@ void SalGraphics::DrawMask( const SalTwoRect& rPosAry,
drawMask( rPosAry, rSalBitmap, nMaskColor );
}
std::shared_ptr<SalBitmap> SalGraphics::GetBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice& rOutDev )
std::shared_ptr<SalBitmap> SalGraphics::GetBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice& rOutDev, bool bWithoutAlpha )
{
if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
mirror( nX, nWidth, rOutDev );
return getBitmap( nX, nY, nWidth, nHeight );
return getBitmap( nX, nY, nWidth, nHeight, bWithoutAlpha );
}
Color SalGraphics::GetPixel( tools::Long nX, tools::Long nY, const OutputDevice& rOutDev )
+4 -52
View File
@@ -203,21 +203,6 @@ void VirtualDevice::ImplInitVirDev( const OutputDevice* pOutDev,
if ( mpNext )
mpNext->mpPrev = this;
pSVData->maGDIData.mpFirstVirDev = this;
// initialise alpha layer
if (meFormatAndAlpha != DeviceFormat::WITHOUT_ALPHA)
{
mpAlphaVDev = VclPtr<VirtualDevice>::Create(*this, DeviceFormat::WITHOUT_ALPHA);
mpAlphaVDev->InnerImplSetOutputSizePixel(Size(nDX, nDY), bErase);
mpAlphaVDev->SetBackground( Wallpaper(COL_ALPHA_OPAQUE) );
mpAlphaVDev->Erase();
if( GetLineColor() != COL_TRANSPARENT )
mpAlphaVDev->SetLineColor( COL_ALPHA_OPAQUE );
if( GetFillColor() != COL_TRANSPARENT )
mpAlphaVDev->SetFillColor( COL_ALPHA_OPAQUE );
mpAlphaVDev->SetMapMode( GetMapMode() );
mpAlphaVDev->SetAntialiasing( GetAntialiasing() );
}
}
VirtualDevice::VirtualDevice(const OutputDevice* pCompDev, DeviceFormat eFormatAndAlpha,
@@ -269,7 +254,7 @@ void VirtualDevice::dispose()
OutputDevice::dispose();
}
bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase)
bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase, bool bAlphaMaskTransparent)
{
SAL_INFO( "vcl.virdev",
"VirtualDevice::InnerImplSetOutputSizePixel( " << rNewSize.Width() << ", "
@@ -296,7 +281,7 @@ bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bEra
if ( bErase )
{
bRet = mpVirDev->SetSize( nNewWidth, nNewHeight );
bRet = mpVirDev->SetSize( nNewWidth, nNewHeight, bAlphaMaskTransparent );
if ( bRet )
{
mnOutWidth = rNewSize.Width();
@@ -315,7 +300,7 @@ bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bEra
assert(mpGraphics);
pNewVirDev = pSVData->mpDefInst->CreateVirtualDevice(*mpGraphics, nNewWidth, nNewHeight, meFormatAndAlpha);
pNewVirDev = pSVData->mpDefInst->CreateVirtualDevice(*mpGraphics, nNewWidth, nNewHeight, meFormatAndAlpha, bAlphaMaskTransparent);
if ( pNewVirDev )
{
SalGraphics* pGraphics = pNewVirDev->AcquireGraphics();
@@ -368,40 +353,7 @@ void VirtualDevice::ImplFillOpaqueRectangle( const tools::Rectangle& rRect )
bool VirtualDevice::SetOutputSizePixel( const Size& rNewSize, bool bErase, bool bAlphaMaskTransparent )
{
if( InnerImplSetOutputSizePixel(rNewSize, bErase) )
{
if (meFormatAndAlpha != DeviceFormat::WITHOUT_ALPHA)
{
// #110958# Setup alpha bitmap
if(mpAlphaVDev && mpAlphaVDev->GetOutputSizePixel() != rNewSize)
{
mpAlphaVDev.disposeAndClear();
}
if( !mpAlphaVDev )
{
mpAlphaVDev = VclPtr<VirtualDevice>::Create(*this, DeviceFormat::WITHOUT_ALPHA);
mpAlphaVDev->InnerImplSetOutputSizePixel(rNewSize, bErase);
mpAlphaVDev->SetBackground( Wallpaper(bAlphaMaskTransparent ? COL_ALPHA_TRANSPARENT : COL_ALPHA_OPAQUE) );
mpAlphaVDev->Erase();
}
// TODO: copy full outdev state to new one, here. Also needed in outdev2.cxx:DrawOutDev
if( GetLineColor() != COL_TRANSPARENT )
mpAlphaVDev->SetLineColor( COL_ALPHA_OPAQUE );
if( GetFillColor() != COL_TRANSPARENT )
mpAlphaVDev->SetFillColor( COL_ALPHA_OPAQUE );
mpAlphaVDev->SetMapMode( GetMapMode() );
mpAlphaVDev->SetAntialiasing( GetAntialiasing() );
}
return true;
}
return false;
return InnerImplSetOutputSizePixel(rNewSize, bErase, bAlphaMaskTransparent);
}
void VirtualDevice::EnableRTL( bool bEnable )
-33
View File
@@ -26,51 +26,18 @@ Color OutputDevice::GetBackgroundColor() const
void OutputDevice::SetBackground()
{
maBackground = Wallpaper();
mbBackground = false;
if( mpAlphaVDev )
mpAlphaVDev->SetBackground();
}
void OutputDevice::SetBackground( const Wallpaper& rBackground )
{
maBackground = rBackground;
if( rBackground.GetStyle() == WallpaperStyle::NONE )
mbBackground = false;
else
mbBackground = true;
if( !mpAlphaVDev )
return;
// Some of these are probably wrong (e.g. if the gradient has transparency),
// but hopefully nobody uses that. If you do, feel free to implement it properly.
if( rBackground.GetStyle() == WallpaperStyle::NONE )
{
mpAlphaVDev->SetBackground( rBackground );
}
else if( rBackground.IsBitmap())
{
const BitmapEx& bitmap = rBackground.GetBitmap();
if( bitmap.IsAlpha())
mpAlphaVDev->SetBackground( Wallpaper( BitmapEx( bitmap.GetAlphaMask().GetBitmap() ) ) );
else
mpAlphaVDev->SetBackground( Wallpaper( COL_ALPHA_OPAQUE ));
}
else if( rBackground.IsGradient())
{
mpAlphaVDev->SetBackground( Wallpaper( COL_ALPHA_OPAQUE ));
}
else
{
// Color background.
int alpha = rBackground.GetColor().GetAlpha();
mpAlphaVDev->SetBackground( Wallpaper( Color( alpha, alpha, alpha )));
}
}
+25 -317
View File
@@ -180,12 +180,6 @@ void OutputDevice::DrawBitmap( const Point& rDestPt, const Size& rDestSize,
}
}
}
if( mpAlphaVDev )
{
// #i32109#: Make bitmap area opaque
mpAlphaVDev->ImplFillOpaqueRectangle( tools::Rectangle(rDestPt, rDestSize) );
}
}
Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
@@ -271,7 +265,12 @@ Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
if ( !bClipped )
{
std::shared_ptr<SalBitmap> pSalBmp = mpGraphics->GetBitmap( nX, nY, nWidth, nHeight, *this );
std::shared_ptr<SalBitmap> pSalBmp;
// if we are a virtual device, we might need to remove the unused alpha channel
bool bWithoutAlpha = false;
if (OUTDEV_VIRDEV == GetOutDevType())
bWithoutAlpha = static_cast<const VirtualDevice*>(this)->IsWithoutAlpha();
pSalBmp = mpGraphics->GetBitmap( nX, nY, nWidth, nHeight, *this, bWithoutAlpha );
if( pSalBmp )
{
@@ -333,36 +332,14 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
SalBitmap* pSalSrcBmp = bitmap.ImplGetSalBitmap().get();
SalBitmap* pSalAlphaBmp = alpha.GetBitmap().ImplGetSalBitmap().get();
// #i83087# Naturally, system alpha blending (SalGraphics::DrawAlphaBitmap) cannot work
// with separate alpha VDev
// try to blend the alpha bitmap with the alpha virtual device
if (mpAlphaVDev)
{
if (ImplLogicToDevicePixel(aOutSz).IsEmpty()) // nothing to draw
return;
Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aRelPt, aOutSz ) );
if (SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetSalBitmap().get())
{
if (mpGraphics->BlendAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, *this))
{
mpAlphaVDev->BlendBitmap(aTR, rAlpha.GetBitmap());
return;
}
}
}
else
{
if (mpGraphics->DrawAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *this))
return;
}
if (mpGraphics->DrawAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *this))
return;
// we need to make sure Skia never reaches this slow code path
// (but do not fail in no-op cases)
assert(!SkiaHelper::isVCLSkiaEnabled() || !SkiaHelper::isAlphaMaskBlendingEnabled()
|| tools::Rectangle(Point(), rBmp.GetSizePixel())
.Intersection(tools::Rectangle(rSrcPtPixel, rSrcSizePixel)).IsEmpty()
|| mpAlphaVDev->LogicToPixel(mpAlphaVDev->GetOutputSizePixel()).IsEmpty());
.Intersection(tools::Rectangle(rSrcPtPixel, rSrcSizePixel)).IsEmpty());
}
tools::Rectangle aBmpRect(Point(), rBmp.GetSizePixel());
@@ -375,7 +352,7 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
// HACK: The function is broken with alpha vdev and mirroring, mirror here.
Bitmap bitmap(rBmp);
AlphaMask alpha(rAlpha);
if(mpAlphaVDev && (bHMirr || bVMirr))
if(bHMirr || bVMirr)
{
bitmap.Mirror(mirrorFlags);
alpha.Mirror(mirrorFlags);
@@ -388,173 +365,6 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
namespace
{
struct LinearScaleContext
{
std::unique_ptr<sal_Int32[]> mpMapX;
std::unique_ptr<sal_Int32[]> mpMapY;
std::unique_ptr<sal_Int32[]> mpMapXOffset;
std::unique_ptr<sal_Int32[]> mpMapYOffset;
LinearScaleContext(tools::Rectangle const & aDstRect, tools::Rectangle const & aBitmapRect,
Size const & aOutSize, tools::Long nOffX, tools::Long nOffY)
: mpMapX(new sal_Int32[aDstRect.GetWidth()])
, mpMapY(new sal_Int32[aDstRect.GetHeight()])
, mpMapXOffset(new sal_Int32[aDstRect.GetWidth()])
, mpMapYOffset(new sal_Int32[aDstRect.GetHeight()])
{
const tools::Long nSrcWidth = aBitmapRect.GetWidth();
const tools::Long nSrcHeight = aBitmapRect.GetHeight();
generateSimpleMap(
nSrcWidth, aDstRect.GetWidth(), aBitmapRect.Left(),
aOutSize.Width(), nOffX, mpMapX.get(), mpMapXOffset.get());
generateSimpleMap(
nSrcHeight, aDstRect.GetHeight(), aBitmapRect.Top(),
aOutSize.Height(), nOffY, mpMapY.get(), mpMapYOffset.get());
}
private:
static void generateSimpleMap(tools::Long nSrcDimension, tools::Long nDstDimension, tools::Long nDstLocation,
tools::Long nOutDimension, tools::Long nOffset, sal_Int32* pMap, sal_Int32* pMapOffset)
{
const double fReverseScale = (std::abs(nOutDimension) > 1) ? (nSrcDimension - 1) / double(std::abs(nOutDimension) - 1) : 0.0;
tools::Long nSampleRange = std::max(tools::Long(0), nSrcDimension - 2);
for (tools::Long i = 0; i < nDstDimension; i++)
{
double fTemp = std::abs((nOffset + i) * fReverseScale);
pMap[i] = std::clamp(nDstLocation + tools::Long(fTemp), tools::Long(0), nSampleRange);
pMapOffset[i] = static_cast<tools::Long>((fTemp - pMap[i]) * 128.0);
}
}
public:
bool blendBitmap(
const BitmapWriteAccess* pDestination,
const BitmapReadAccess* pSource,
const BitmapReadAccess* pSourceAlpha,
const tools::Long nDstWidth,
const tools::Long nDstHeight)
{
if (!pSource || !pSourceAlpha || !pDestination)
return false;
ScanlineFormat nSourceFormat = pSource->GetScanlineFormat();
ScanlineFormat nDestinationFormat = pDestination->GetScanlineFormat();
switch (nSourceFormat)
{
case ScanlineFormat::N24BitTcRgb:
case ScanlineFormat::N24BitTcBgr:
{
if ( (nSourceFormat == ScanlineFormat::N24BitTcBgr && nDestinationFormat == ScanlineFormat::N32BitTcBgra)
|| (nSourceFormat == ScanlineFormat::N24BitTcRgb && nDestinationFormat == ScanlineFormat::N32BitTcRgba))
{
blendBitmap24(pDestination, pSource, pSourceAlpha, nDstWidth, nDstHeight);
return true;
}
}
break;
default: break;
}
return false;
}
void blendBitmap24(
const BitmapWriteAccess* pDestination,
const BitmapReadAccess* pSource,
const BitmapReadAccess* pSourceAlpha,
const tools::Long nDstWidth,
const tools::Long nDstHeight)
{
Scanline pLine0, pLine1;
Scanline pLineAlpha0, pLineAlpha1;
Scanline pColorSample1, pColorSample2;
Scanline pDestScanline;
tools::Long nColor1Line1, nColor2Line1, nColor3Line1;
tools::Long nColor1Line2, nColor2Line2, nColor3Line2;
tools::Long nAlphaLine1, nAlphaLine2;
sal_uInt8 nColor1, nColor2, nColor3, nAlpha;
for (tools::Long nY = 0; nY < nDstHeight; nY++)
{
const tools::Long nMapY = mpMapY[nY];
const tools::Long nMapFY = mpMapYOffset[nY];
pLine0 = pSource->GetScanline(nMapY);
// tdf#95481 guard nMapY + 1 to be within bounds
pLine1 = (nMapY + 1 < pSource->Height()) ? pSource->GetScanline(nMapY + 1) : pLine0;
pLineAlpha0 = pSourceAlpha->GetScanline(nMapY);
// tdf#95481 guard nMapY + 1 to be within bounds
pLineAlpha1 = (nMapY + 1 < pSourceAlpha->Height()) ? pSourceAlpha->GetScanline(nMapY + 1) : pLineAlpha0;
pDestScanline = pDestination->GetScanline(nY);
for (tools::Long nX = 0; nX < nDstWidth; nX++)
{
const tools::Long nMapX = mpMapX[nX];
const tools::Long nMapFX = mpMapXOffset[nX];
pColorSample1 = pLine0 + 3 * nMapX;
pColorSample2 = (nMapX + 1 < pSource->Width()) ? pColorSample1 + 3 : pColorSample1;
nColor1Line1 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1++;
pColorSample2++;
nColor2Line1 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1++;
pColorSample2++;
nColor3Line1 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1 = pLine1 + 3 * nMapX;
pColorSample2 = (nMapX + 1 < pSource->Width()) ? pColorSample1 + 3 : pColorSample1;
nColor1Line2 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1++;
pColorSample2++;
nColor2Line2 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1++;
pColorSample2++;
nColor3Line2 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1 = pLineAlpha0 + nMapX;
pColorSample2 = (nMapX + 1 < pSourceAlpha->Width()) ? pColorSample1 + 1 : pColorSample1;
nAlphaLine1 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
pColorSample1 = pLineAlpha1 + nMapX;
pColorSample2 = (nMapX + 1 < pSourceAlpha->Width()) ? pColorSample1 + 1 : pColorSample1;
nAlphaLine2 = (static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
nColor1 = (nColor1Line1 + nMapFY * ((nColor1Line2 >> 7) - (nColor1Line1 >> 7))) >> 7;
nColor2 = (nColor2Line1 + nMapFY * ((nColor2Line2 >> 7) - (nColor2Line1 >> 7))) >> 7;
nColor3 = (nColor3Line1 + nMapFY * ((nColor3Line2 >> 7) - (nColor3Line1 >> 7))) >> 7;
nAlpha = (nAlphaLine1 + nMapFY * ((nAlphaLine2 >> 7) - (nAlphaLine1 >> 7))) >> 7;
*pDestScanline = color::ColorChannelMerge(*pDestScanline, nColor1, nAlpha);
pDestScanline++;
*pDestScanline = color::ColorChannelMerge(*pDestScanline, nColor2, nAlpha);
pDestScanline++;
*pDestScanline = color::ColorChannelMerge(*pDestScanline, nColor3, nAlpha);
pDestScanline++;
pDestScanline++;
}
}
}
};
struct TradScaleContext
{
std::unique_ptr<sal_Int32[]> mpMapX;
@@ -608,11 +418,6 @@ void OutputDevice::DrawDeviceAlphaBitmapSlowPath(const Bitmap& rBitmap,
{
assert(!is_double_buffered_window());
VirtualDevice* pOldVDev = mpAlphaVDev;
const bool bHMirr = aOutSize.Width() < 0;
const bool bVMirr = aOutSize.Height() < 0;
// The scaling in this code path produces really ugly results - it
// does the most trivial scaling with no smoothing.
GDIMetaFile* pOldMetaFile = mpMetaFile;
@@ -661,45 +466,12 @@ void OutputDevice::DrawDeviceAlphaBitmapSlowPath(const Bitmap& rBitmap,
{
Bitmap aNewBitmap;
if (mpAlphaVDev)
{
aNewBitmap = BlendBitmapWithAlpha(
aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
aDstRect,
nOffY, nDstHeight,
nOffX, nDstWidth,
aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
}
else
{
LinearScaleContext aLinearContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
if (aLinearContext.blendBitmap( BitmapScopedWriteAccess(aBmp).get(), pBitmapReadAccess.get(), pAlphaReadAccess.get(),
nDstWidth, nDstHeight))
{
aNewBitmap = std::move(aBmp);
}
else
{
aNewBitmap = BlendBitmap(
aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
nOffY, nDstHeight,
nOffX, nDstWidth,
aBmpRect, aOutSize,
bHMirr, bVMirr,
aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
}
}
// #110958# Disable alpha VDev, we're doing the necessary
// stuff explicitly further below
if (mpAlphaVDev)
mpAlphaVDev = nullptr;
aNewBitmap = BlendBitmapWithAlpha(
aBmp, pBitmapReadAccess.get(), pAlphaReadAccess.get(),
nDstHeight,
nDstWidth,
aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
DrawBitmap(aDstRect.TopLeft(), aNewBitmap);
// #110958# Enable alpha VDev again
mpAlphaVDev = pOldVDev;
}
mbMap = bOldMap;
@@ -759,23 +531,22 @@ namespace
const tools::Long nMapY,
BitmapReadAccess const * pP,
BitmapReadAccess const * pA,
BitmapReadAccess const * pB,
BitmapWriteAccess const * pAlphaW,
sal_uInt8& nResAlpha )
BitmapReadAccess const * pB)
{
BitmapColor aDstCol,aSrcCol;
aSrcCol = pP->GetColor( nMapY, nMapX );
aDstCol = pB->GetColor( nY, nX );
const sal_uInt8 nSrcAlpha = pA->GetPixelIndex( nMapY, nMapX );
const sal_uInt8 nDstAlpha = pAlphaW->GetPixelIndex( nY, nX );
const sal_uInt8 nDstAlpha = aDstCol.GetAlpha();
// Perform porter-duff compositing 'over' operation
// Co = Cs + Cd*(1-As)
// Ad = As + Ad*(1-As)
nResAlpha = static_cast<int>(nSrcAlpha) + static_cast<int>(nDstAlpha) - static_cast<int>(nDstAlpha)*nSrcAlpha/255;
sal_uInt8 nResAlpha = static_cast<int>(nSrcAlpha) + static_cast<int>(nDstAlpha)
- static_cast<int>(nDstAlpha) * nSrcAlpha / 255;
aDstCol.SetAlpha(nResAlpha);
aDstCol.SetRed( CalcColor( aSrcCol.GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetRed() ) );
aDstCol.SetBlue( CalcColor( aSrcCol.GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetBlue() ) );
aDstCol.SetGreen( CalcColor( aSrcCol.GetGreen(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.GetGreen() ) );
@@ -795,88 +566,29 @@ Bitmap OutputDevice::BlendBitmapWithAlpha(
Bitmap& aBmp,
BitmapReadAccess const * pP,
BitmapReadAccess const * pA,
const tools::Rectangle& aDstRect,
const sal_Int32 nOffY,
const sal_Int32 nDstHeight,
const sal_Int32 nOffX,
const sal_Int32 nDstWidth,
const sal_Int32* pMapX,
const sal_Int32* pMapY )
{
BitmapColor aDstCol;
Bitmap res;
int nX, nY;
sal_uInt8 nResAlpha;
SAL_WARN_IF( !mpAlphaVDev, "vcl.gdi", "BlendBitmapWithAlpha(): call me only with valid alpha VirtualDevice!" );
bool bOldMapMode( mpAlphaVDev->IsMapModeEnabled() );
mpAlphaVDev->EnableMapMode(false);
Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aDstRect.TopLeft(), aDstRect.GetSize() ) );
BitmapScopedWriteAccess pAlphaW(aAlphaBitmap);
if( GetBitCount() <= 8 )
{
Bitmap aDither(aBmp.GetSizePixel(), vcl::PixelFormat::N8_BPP);
BitmapColor aIndex( 0 );
BitmapScopedReadAccess pB(aBmp);
BitmapScopedWriteAccess pW(aDither);
if (pB && pP && pA && pW && pAlphaW)
{
int nOutY;
for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
{
const tools::Long nMapY = pMapY[ nY ];
const tools::Long nModY = ( nOutY & 0x0FL ) << 4;
int nOutX;
Scanline pScanline = pW->GetScanline(nY);
Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
{
const tools::Long nMapX = pMapX[ nX ];
const sal_uLong nD = nVCLDitherLut[ nModY | ( nOutX & 0x0FL ) ];
aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.get(), pAlphaW.get(), nResAlpha );
aIndex.SetIndex( static_cast<sal_uInt8>( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16 ] +
nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16 ] +
nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16 ] ) );
pW->SetPixelOnData( pScanline, nX, aIndex );
aIndex.SetIndex( static_cast<sal_uInt8>( nVCLRLut[ ( nVCLLut[ nResAlpha ] + nD ) >> 16 ] +
nVCLGLut[ ( nVCLLut[ nResAlpha ] + nD ) >> 16 ] +
nVCLBLut[ ( nVCLLut[ nResAlpha ] + nD ) >> 16 ] ) );
pAlphaW->SetPixelOnData( pScanlineAlpha, nX, aIndex );
}
}
}
pB.reset();
pW.reset();
res = std::move(aDither);
}
else
{
BitmapScopedWriteAccess pB(aBmp);
if (pB && pP && pA && pAlphaW)
if (pB && pP && pA)
{
for( nY = 0; nY < nDstHeight; nY++ )
for( int nY = 0; nY < nDstHeight; nY++ )
{
const tools::Long nMapY = pMapY[ nY ];
Scanline pScanlineB = pB->GetScanline(nY);
Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
for( nX = 0; nX < nDstWidth; nX++ )
for( int nX = 0; nX < nDstWidth; nX++ )
{
const tools::Long nMapX = pMapX[ nX ];
aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.get(), pAlphaW.get(), nResAlpha );
BitmapColor aDstCol = AlphaBlend(nX, nY, nMapX, nMapY, pP, pA, pB.get());
pB->SetPixelOnData(pScanlineB, nX, pB->GetBestMatchingColor(aDstCol));
pAlphaW->SetPixelOnData(pScanlineAlpha, nX, pB->GetBestMatchingColor(Color(nResAlpha, nResAlpha, nResAlpha)));
pB->SetPixelOnData(pScanlineB, nX, aDstCol);
}
}
}
@@ -884,10 +596,6 @@ Bitmap OutputDevice::BlendBitmapWithAlpha(
res = aBmp;
}
pAlphaW.reset();
mpAlphaVDev->DrawBitmap( aDstRect.TopLeft(), aAlphaBitmap );
mpAlphaVDev->EnableMapMode( bOldMapMode );
return res;
}
+3 -34
View File
@@ -150,16 +150,7 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
BitmapEx OutputDevice::GetBitmapEx( const Point& rSrcPt, const Size& rSize ) const
{
if (!mpAlphaVDev)
return BitmapEx(GetBitmap(rSrcPt, rSize));
// #110958# Extract alpha value from VDev, if any
Bitmap aAlphaBitmap(mpAlphaVDev->GetBitmap(rSrcPt, rSize));
if (aAlphaBitmap.getPixelFormat() > vcl::PixelFormat::N8_BPP)
aAlphaBitmap.Convert(BmpConversion::N8BitNoConversion);
return BitmapEx(GetBitmap(rSrcPt, rSize), AlphaMask(aAlphaBitmap));
return BitmapEx(GetBitmap( rSrcPt, rSize ));
}
void OutputDevice::DrawDeviceBitmapEx( const Point& rDestPt, const Size& rDestSize,
@@ -198,12 +189,6 @@ void OutputDevice::DrawDeviceBitmapEx( const Point& rDestPt, const Size& rDestSi
&& "I removed some code here that will need to be restored");
mpGraphics->DrawBitmap(aPosAry, *pSalSrcBmp, *this);
if (mpAlphaVDev)
{
// #i32109#: Make bitmap area opaque
mpAlphaVDev->ImplFillOpaqueRectangle(tools::Rectangle(rDestPt, rDestSize));
}
}
bool OutputDevice::DrawTransformBitmapExDirect(
@@ -224,33 +209,17 @@ bool OutputDevice::DrawTransformBitmapExDirect(
{
aAlphaBitmap = rBitmapEx.GetAlphaMask();
}
else if (mpAlphaVDev)
{
aAlphaBitmap = AlphaMask(rBitmapEx.GetSizePixel());
aAlphaBitmap.Erase(0); // opaque
}
SalBitmap* pSalAlphaBmp = aAlphaBitmap.GetBitmap().ImplGetSalBitmap().get();
if (!mpGraphics->DrawTransformedBitmap(
return mpGraphics->DrawTransformedBitmap(
aNull,
aTopX,
aTopY,
*pSalSrcBmp,
pSalAlphaBmp,
fAlpha,
*this))
return false;
if (mpAlphaVDev)
{
// Merge bitmap alpha to alpha device
AlphaMask aAlpha(rBitmapEx.GetSizePixel());
aAlpha.Erase( ( 1 - fAlpha ) * 255 );
mpAlphaVDev->DrawTransformBitmapExDirect(aFullTransform, BitmapEx(aAlpha.GetBitmap(), aAlphaBitmap));
}
return true;
*this);
};
bool OutputDevice::TransformAndReduceBitmapExToTargetRange(
-18
View File
@@ -45,9 +45,6 @@ void OutputDevice::SetClipRegion()
mpMetaFile->AddAction( new MetaClipRegionAction( vcl::Region(), false ) );
SetDeviceClipRegion( nullptr );
if( mpAlphaVDev )
mpAlphaVDev->SetClipRegion();
}
void OutputDevice::SetClipRegion( const vcl::Region& rRegion )
@@ -65,9 +62,6 @@ void OutputDevice::SetClipRegion( const vcl::Region& rRegion )
vcl::Region aRegion = LogicToPixel( rRegion );
SetDeviceClipRegion( &aRegion );
}
if( mpAlphaVDev )
mpAlphaVDev->SetClipRegion( rRegion );
}
bool OutputDevice::SelectClipRegion( const vcl::Region& rRegion, SalGraphics* pGraphics )
@@ -88,7 +82,6 @@ bool OutputDevice::SelectClipRegion( const vcl::Region& rRegion, SalGraphics* pG
void OutputDevice::MoveClipRegion( tools::Long nHorzMove, tools::Long nVertMove )
{
if ( mbClipRegion )
{
if( mpMetaFile )
@@ -98,14 +91,10 @@ void OutputDevice::MoveClipRegion( tools::Long nHorzMove, tools::Long nVertMove
ImplLogicHeightToDevicePixel( nVertMove ) );
mbInitClipRegion = true;
}
if( mpAlphaVDev )
mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove );
}
void OutputDevice::IntersectClipRegion( const tools::Rectangle& rRect )
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
@@ -113,14 +102,10 @@ void OutputDevice::IntersectClipRegion( const tools::Rectangle& rRect )
maRegion.Intersect( aRect );
mbClipRegion = true;
mbInitClipRegion = true;
if( mpAlphaVDev )
mpAlphaVDev->IntersectClipRegion( rRect );
}
void OutputDevice::IntersectClipRegion( const vcl::Region& rRegion )
{
if(!rRegion.IsNull())
{
if ( mpMetaFile )
@@ -131,9 +116,6 @@ void OutputDevice::IntersectClipRegion( const vcl::Region& rRegion )
mbClipRegion = true;
mbInitClipRegion = true;
}
if( mpAlphaVDev )
mpAlphaVDev->IntersectClipRegion( rRegion );
}
void OutputDevice::InitClipRegion()
-12
View File
@@ -64,9 +64,6 @@ void OutputDevice::DrawEllipse( const tools::Rectangle& rRect )
mpGraphics->DrawPolygon( aRectPoly.GetSize(), pPtAry, *this );
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawEllipse( rRect );
}
void OutputDevice::DrawArc( const tools::Rectangle& rRect,
@@ -106,9 +103,6 @@ void OutputDevice::DrawArc( const tools::Rectangle& rRect,
Point* pPtAry = aArcPoly.GetPointAry();
mpGraphics->DrawPolyLine( aArcPoly.GetSize(), pPtAry, *this );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawArc( rRect, rStartPt, rEndPt );
}
void OutputDevice::DrawPie( const tools::Rectangle& rRect,
@@ -155,9 +149,6 @@ void OutputDevice::DrawPie( const tools::Rectangle& rRect,
mpGraphics->DrawPolygon( aPiePoly.GetSize(), pPtAry, *this );
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawPie( rRect, rStartPt, rEndPt );
}
void OutputDevice::DrawChord( const tools::Rectangle& rRect,
@@ -204,9 +195,6 @@ void OutputDevice::DrawChord( const tools::Rectangle& rRect,
mpGraphics->DrawPolygon( aChordPoly.GetSize(), pPtAry, *this );
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawChord( rRect, rStartPt, rEndPt );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-3
View File
@@ -75,9 +75,6 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
return bDrawn;
}
-10
View File
@@ -28,7 +28,6 @@
void OutputDevice::SetFillColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaFillColorAction( Color(), false ) );
@@ -38,9 +37,6 @@ void OutputDevice::SetFillColor()
mbFillColor = false;
maFillColor = COL_TRANSPARENT;
}
if( mpAlphaVDev )
mpAlphaVDev->SetFillColor();
}
void OutputDevice::SetFillColor( const Color& rColor )
@@ -56,12 +52,6 @@ void OutputDevice::SetFillColor( const Color& rColor )
mbFillColor = true;
maFillColor = aColor;
}
if( mpAlphaVDev )
{
sal_uInt8 nAlpha = rColor.GetAlpha();
mpAlphaVDev->SetFillColor( Color(nAlpha, nAlpha, nAlpha) );
}
}
void OutputDevice::InitFillColor()
-18
View File
@@ -82,21 +82,6 @@ void OutputDevice::SetFont( const vcl::Font& rNewFont )
}
maFont = aFont;
mbNewFont = true;
if( !mpAlphaVDev )
return;
// #i30463#
// Since SetFont might change the text color, apply that only
// selectively to alpha vdev (which normally paints opaque text
// with COL_BLACK)
if( aFont.GetColor() != COL_TRANSPARENT )
{
mpAlphaVDev->SetTextColor( COL_ALPHA_OPAQUE );
aFont.SetColor( COL_TRANSPARENT );
}
mpAlphaVDev->SetFont( aFont );
}
FontMetric OutputDevice::GetFontMetricFromCollection(int nDevFontIndex) const
@@ -148,9 +133,6 @@ bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFo
if( !bRC )
return false;
if( mpAlphaVDev )
mpAlphaVDev->AddTempDevFont( rFileURL, rFontName );
return true;
}
-8
View File
@@ -143,14 +143,6 @@ void OutputDevice::DrawGradient( const tools::PolyPolygon& rPolyPoly,
}
}
}
if( mpAlphaVDev )
{
mpAlphaVDev->Push(vcl::PushFlags::FILLCOLOR);
mpAlphaVDev->SetFillColor( COL_ALPHA_OPAQUE );
mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
mpAlphaVDev->Pop();
}
}
void OutputDevice::ClipAndDrawGradientMetafile ( const Gradient &rGradient, const tools::PolyPolygon &rPolyPoly )
-3
View File
@@ -92,9 +92,6 @@ void OutputDevice::DrawHatch( const tools::PolyPolygon& rPolyPoly, const Hatch&
EnableMapMode( bOldMap );
mpMetaFile = pOldMetaFile;
}
if( mpAlphaVDev )
mpAlphaVDev->DrawHatch( rPolyPoly, rHatch );
}
void OutputDevice::AddHatchActions( const tools::PolyPolygon& rPolyPoly, const Hatch& rHatch,
-13
View File
@@ -36,7 +36,6 @@
void OutputDevice::SetLineColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaLineColorAction( Color(), false ) );
@@ -46,9 +45,6 @@ void OutputDevice::SetLineColor()
mbLineColor = false;
maLineColor = COL_TRANSPARENT;
}
if( mpAlphaVDev )
mpAlphaVDev->SetLineColor();
}
void OutputDevice::SetLineColor( const Color& rColor )
@@ -76,9 +72,6 @@ void OutputDevice::SetLineColor( const Color& rColor )
maLineColor = aColor;
}
}
if( mpAlphaVDev )
mpAlphaVDev->SetLineColor( COL_ALPHA_OPAQUE );
}
void OutputDevice::InitLineColor()
@@ -152,9 +145,6 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
{
mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), *this );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
}
void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
@@ -214,9 +204,6 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), *this );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawLine( rStartPt, rEndPt );
}
void OutputDevice::drawLine( basegfx::B2DPolyPolygon aLinePolyPolygon, const LineInfo& rInfo )
-16
View File
@@ -620,14 +620,10 @@ vcl::Region OutputDevice::ImplPixelToDevicePixel( const vcl::Region& rRegion ) c
void OutputDevice::EnableMapMode( bool bEnable )
{
mbMap = bEnable;
if( mpAlphaVDev )
mpAlphaVDev->EnableMapMode( bEnable );
}
void OutputDevice::SetMapMode()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
@@ -648,9 +644,6 @@ void OutputDevice::SetMapMode()
// #i75163#
ImplInvalidateViewTransform();
}
if( mpAlphaVDev )
mpAlphaVDev->SetMapMode();
}
void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
@@ -667,9 +660,6 @@ void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
if ( maMapMode == rNewMapMode )
return;
if( mpAlphaVDev )
mpAlphaVDev->SetMapMode( rNewMapMode );
// if default MapMode calculate nothing
bool bOldMap = mbMap;
mbMap = !rNewMapMode.IsDefault();
@@ -815,9 +805,6 @@ void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX );
mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY );
if( mpAlphaVDev )
mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
}
// #i75163#
@@ -1867,9 +1854,6 @@ void OutputDevice::SetPixelOffset( const Size& rOffset )
maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX );
mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY );
if( mpAlphaVDev )
mpAlphaVDev->SetPixelOffset( rOffset );
}
-17
View File
@@ -140,23 +140,6 @@ void OutputDevice::DrawDeviceMask( const Bitmap& rMask, const Color& rMaskColor,
}
}
// TODO: Use mask here
if( !mpAlphaVDev )
return;
const Bitmap aAlphaMask( rMask.CreateMask( rMaskColor ) );
// #i25167# Restrict mask painting to _opaque_ areas
// of the mask, otherwise we spoil areas where no
// bitmap content was ever visible. Interestingly
// enough, this can be achieved by taking the mask as
// the transparency mask of itself
mpAlphaVDev->DrawBitmapEx( rDestPt,
rDestSize,
rSrcPtPixel,
rSrcSizePixel,
BitmapEx( aAlphaMask, rMask ) );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+12 -63
View File
@@ -70,7 +70,6 @@ OutputDevice::OutputDevice(OutDevType eOutDevType) :
mpFontInstance = nullptr;
mpForcedFallbackInstance = nullptr;
mpFontFaceCollection = nullptr;
mpAlphaVDev = nullptr;
mpExtOutDevData = nullptr;
mnOutOffX = 0;
mnOutOffY = 0;
@@ -178,7 +177,6 @@ void OutputDevice::dispose()
// release ImplFontList specific to this OutputDevice
mxFontCollection.reset();
mpAlphaVDev.disposeAndClear();
mpPrevGraphics.reset();
mpNextGraphics.reset();
VclReferenceBase::dispose();
@@ -217,9 +215,6 @@ void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
void OutputDevice::SetSettings( const AllSettings& rSettings )
{
*moSettings = rSettings;
if( mpAlphaVDev )
mpAlphaVDev->SetSettings( rSettings );
}
SystemGraphicsData OutputDevice::GetSystemGfxData() const
@@ -307,9 +302,6 @@ void OutputDevice::SetRefPoint()
mbRefPoint = false;
maRefPoint.setX(0);
maRefPoint.setY(0);
if( mpAlphaVDev )
mpAlphaVDev->SetRefPoint();
}
void OutputDevice::SetRefPoint( const Point& rRefPoint )
@@ -319,9 +311,6 @@ void OutputDevice::SetRefPoint( const Point& rRefPoint )
mbRefPoint = true;
maRefPoint = rRefPoint;
if( mpAlphaVDev )
mpAlphaVDev->SetRefPoint( rRefPoint );
}
void OutputDevice::SetRasterOp( RasterOp eRasterOp )
@@ -340,17 +329,11 @@ void OutputDevice::SetRasterOp( RasterOp eRasterOp )
mpGraphics->SetXORMode( (RasterOp::Invert == meRasterOp) || (RasterOp::Xor == meRasterOp), RasterOp::Invert == meRasterOp );
}
}
if( mpAlphaVDev )
mpAlphaVDev->SetRasterOp( eRasterOp );
}
void OutputDevice::EnableOutput( bool bEnable )
{
mbOutput = bEnable;
if( mpAlphaVDev )
mpAlphaVDev->EnableOutput( bEnable );
}
void OutputDevice::SetAntialiasing( AntialiasingFlags nMode )
@@ -363,17 +346,11 @@ void OutputDevice::SetAntialiasing( AntialiasingFlags nMode )
if (mpGraphics)
mpGraphics->setAntiAlias(bool(mnAntialiasing & AntialiasingFlags::Enable));
}
if( mpAlphaVDev )
mpAlphaVDev->SetAntialiasing( nMode );
}
void OutputDevice::SetDrawMode(DrawModeFlags nDrawMode)
{
mnDrawMode = nDrawMode;
if (mpAlphaVDev)
mpAlphaVDev->SetDrawMode(nDrawMode);
}
sal_uInt16 OutputDevice::GetBitCount() const
@@ -469,9 +446,6 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
mpGraphics->CopyBits(aPosAry, *this);
}
if( mpAlphaVDev )
mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize );
}
void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
@@ -489,16 +463,8 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
if ( mpMetaFile )
{
if (rOutDev.mpAlphaVDev)
{
const BitmapEx aBmpEx(rOutDev.GetBitmapEx(rSrcPt, rSrcSize));
mpMetaFile->AddAction(new MetaBmpExScaleAction(rDestPt, rDestSize, aBmpEx));
}
else
{
const Bitmap aBmp(rOutDev.GetBitmap(rSrcPt, rSrcSize));
mpMetaFile->AddAction(new MetaBmpScaleAction(rDestPt, rDestSize, aBmp));
}
const BitmapEx aBmpEx(rOutDev.GetBitmapEx(rSrcPt, rSrcSize));
mpMetaFile->AddAction(new MetaBmpExScaleAction(rDestPt, rDestSize, aBmpEx));
}
if ( !IsDeviceOutputNecessary() )
@@ -514,28 +480,17 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
if ( mbOutputClipped )
return;
if (rOutDev.mpAlphaVDev)
{
// alpha-blend source over destination
DrawBitmapEx(rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize));
}
else
{
SalTwoRect aPosAry(rOutDev.ImplLogicXToDevicePixel(rSrcPt.X()),
rOutDev.ImplLogicYToDevicePixel(rSrcPt.Y()),
rOutDev.ImplLogicWidthToDevicePixel(rSrcSize.Width()),
rOutDev.ImplLogicHeightToDevicePixel(rSrcSize.Height()),
ImplLogicXToDevicePixel(rDestPt.X()),
ImplLogicYToDevicePixel(rDestPt.Y()),
ImplLogicWidthToDevicePixel(rDestSize.Width()),
ImplLogicHeightToDevicePixel(rDestSize.Height()));
SalTwoRect aPosAry(rOutDev.ImplLogicXToDevicePixel(rSrcPt.X()),
rOutDev.ImplLogicYToDevicePixel(rSrcPt.Y()),
rOutDev.ImplLogicWidthToDevicePixel(rSrcSize.Width()),
rOutDev.ImplLogicHeightToDevicePixel(rSrcSize.Height()),
ImplLogicXToDevicePixel(rDestPt.X()),
ImplLogicYToDevicePixel(rDestPt.Y()),
ImplLogicWidthToDevicePixel(rDestSize.Width()),
ImplLogicHeightToDevicePixel(rDestSize.Height()));
drawOutDevDirect(rOutDev, aPosAry);
// #i32109#: make destination rectangle opaque - source has no alpha
if (mpAlphaVDev)
mpAlphaVDev->ImplFillOpaqueRectangle(tools::Rectangle(rDestPt, rDestSize));
}
// if we have alpha, this will blend source over destination
drawOutDevDirect(rOutDev, aPosAry);
}
void OutputDevice::CopyArea( const Point& rDestPt,
@@ -576,9 +531,6 @@ void OutputDevice::CopyArea( const Point& rDestPt,
}
SetRasterOp( eOldRop );
if( mpAlphaVDev )
mpAlphaVDev->CopyArea( rDestPt, rSrcPt, rSrcSize, bWindowInvalidate );
}
// Direct OutputDevice drawing protected function
@@ -654,9 +606,6 @@ tools::Rectangle OutputDevice::GetBackgroundComponentBounds() const
void OutputDevice::EnableRTL( bool bEnable )
{
mbEnableRTL = bEnable;
if( mpAlphaVDev )
mpAlphaVDev->EnableRTL( bEnable );
}
bool OutputDevice::ImplIsAntiparallel() const
-15
View File
@@ -40,12 +40,6 @@ Color OutputDevice::GetPixel(const Point& rPoint) const
const tools::Long nX = ImplLogicXToDevicePixel(rPoint.X());
const tools::Long nY = ImplLogicYToDevicePixel(rPoint.Y());
aColor = mpGraphics->GetPixel(nX, nY, *this);
if (mpAlphaVDev)
{
Color aAlphaColor = mpAlphaVDev->GetPixel(rPoint);
aColor.SetAlpha(aAlphaColor.GetBlue());
}
}
}
return aColor;
@@ -77,9 +71,6 @@ void OutputDevice::DrawPixel( const Point& rPt )
InitLineColor();
mpGraphics->DrawPixel( aPt.X(), aPt.Y(), *this );
if( mpAlphaVDev )
mpAlphaVDev->DrawPixel( rPt );
}
void OutputDevice::DrawPixel( const Point& rPt, const Color& rColor )
@@ -107,12 +98,6 @@ void OutputDevice::DrawPixel( const Point& rPt, const Color& rColor )
return;
mpGraphics->DrawPixel( aPt.X(), aPt.Y(), aColor, *this );
if (mpAlphaVDev)
{
Color aAlphaColor(rColor.GetAlpha(), rColor.GetAlpha(), rColor.GetAlpha());
mpAlphaVDev->DrawPixel(rPt, aAlphaColor);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-15
View File
@@ -105,11 +105,7 @@ void OutputDevice::DrawPolyPolygon( const tools::PolyPolygon& rPolyPoly )
}
if(bSuccess)
{
if( mpAlphaVDev )
mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
return;
}
}
if ( nPoly == 1 )
@@ -133,8 +129,6 @@ void OutputDevice::DrawPolyPolygon( const tools::PolyPolygon& rPolyPoly )
// ImplLogicToDevicePixel calls
ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
}
void OutputDevice::DrawPolygon( const basegfx::B2DPolygon& rB2DPolygon)
@@ -218,11 +212,7 @@ void OutputDevice::DrawPolygon( const tools::Polygon& rPoly )
}
if(bSuccess)
{
if( mpAlphaVDev )
mpAlphaVDev->DrawPolygon( rPoly );
return;
}
}
tools::Polygon aPoly = ImplLogicToDevicePixel( rPoly );
@@ -243,8 +233,6 @@ void OutputDevice::DrawPolygon( const tools::Polygon& rPoly )
{
mpGraphics->DrawPolygon( nPoints, pPtAry, *this );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawPolygon( rPoly );
}
// Caution: This method is nearly the same as
@@ -338,9 +326,6 @@ void OutputDevice::ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyP
const tools::PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel(aToolsPolyPolygon);
ImplDrawPolyPolygon(aPixelPolyPolygon.Count(), aPixelPolyPolygon);
}
if (mpAlphaVDev)
mpAlphaVDev->ImplDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
}
// #100127# Extracted from OutputDevice::DrawPolyPolygon()
+2 -19
View File
@@ -99,9 +99,6 @@ void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly )
mpGraphics->DrawPolyLine( nPoints, pPtAry, *this );
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawPolyLine( rPoly );
}
void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly, const LineInfo& rLineInfo )
@@ -298,9 +295,6 @@ void OutputDevice::drawPolyLine(const tools::Polygon& rPoly, const LineInfo& rLi
mpGraphics->DrawPolyLine(nPoints, aPoly.GetPointAry(), *this);
}
if( mpAlphaVDev )
mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
}
bool OutputDevice::DrawPolyLineDirect(
@@ -374,12 +368,11 @@ bool OutputDevice::DrawPolyLineDirectInternal(
const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation() * rObjectTransform);
const bool bPixelSnapHairline((mnAntialiasing & AntialiasingFlags::PixelSnapHairline) && rB2DPolygon.count() < 1000);
const double fAdjustedTransparency = mpAlphaVDev ? 0 : fTransparency;
// draw the polyline
bool bDrawSuccess = mpGraphics->DrawPolyLine(
return mpGraphics->DrawPolyLine(
aTransform,
rB2DPolygon,
fAdjustedTransparency,
fTransparency,
fLineWidth, // tdf#124848 use LineWidth direct, do not try to solve for zero-case (aka hairline)
pStroke, // MM01
eLineJoin,
@@ -387,16 +380,6 @@ bool OutputDevice::DrawPolyLineDirectInternal(
fMiterMinimumAngle,
bPixelSnapHairline,
*this);
if( bDrawSuccess )
{
if (mpAlphaVDev)
mpAlphaVDev->DrawPolyLineDirect(rObjectTransform, rB2DPolygon, fLineWidth,
fTransparency, pStroke, eLineJoin, eLineCap,
fMiterMinimumAngle);
return true;
}
}
return false;
}
-9
View File
@@ -81,9 +81,6 @@ void OutputDevice::DrawRect( const tools::Rectangle& rRect )
InitFillColor();
mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), *this );
if( mpAlphaVDev )
mpAlphaVDev->DrawRect( rRect );
}
void OutputDevice::DrawRect( const tools::Rectangle& rRect,
@@ -140,9 +137,6 @@ void OutputDevice::DrawRect( const tools::Rectangle& rRect,
mpGraphics->DrawPolygon( aRoundRectPoly.GetSize(), pPtAry, *this );
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawRect( rRect, nHorzRound, nVertRound );
}
void OutputDevice::Invert( const tools::Rectangle& rRect, InvertFlags nFlags )
@@ -332,9 +326,6 @@ void OutputDevice::DrawGrid( const tools::Rectangle& rRect, const Size& rDist, D
}
EnableMapMode( bOldMap );
if( mpAlphaVDev )
mpAlphaVDev->DrawGrid( rRect, rDist, nFlags );
}
BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
-6
View File
@@ -83,9 +83,6 @@ void OutputDevice::Push(vcl::PushFlags nFlags)
if (nFlags & vcl::PushFlags::REFPOINT && mbRefPoint)
rState.mpRefPoint = maRefPoint;
if (mpAlphaVDev)
mpAlphaVDev->Push();
}
void OutputDevice::Pop()
@@ -103,9 +100,6 @@ void OutputDevice::Pop()
}
const vcl::State& rState = maOutDevStateStack.back();
if( mpAlphaVDev )
mpAlphaVDev->Pop();
if ( rState.mnFlags & vcl::PushFlags::LINECOLOR )
{
if ( rState.mpLineColor )
-41
View File
@@ -56,9 +56,6 @@ void OutputDevice::SetLayoutMode( vcl::text::ComplexTextLayoutFlags nTextLayoutM
mpMetaFile->AddAction( new MetaLayoutModeAction( nTextLayoutMode ) );
mnTextLayoutMode = nTextLayoutMode;
if( mpAlphaVDev )
mpAlphaVDev->SetLayoutMode( nTextLayoutMode );
}
void OutputDevice::SetDigitLanguage( LanguageType eTextLanguage )
@@ -67,9 +64,6 @@ void OutputDevice::SetDigitLanguage( LanguageType eTextLanguage )
mpMetaFile->AddAction( new MetaTextLanguageAction( eTextLanguage ) );
meTextLanguage = eTextLanguage;
if( mpAlphaVDev )
mpAlphaVDev->SetDigitLanguage( eTextLanguage );
}
void OutputDevice::ImplInitTextColor()
@@ -483,14 +477,10 @@ void OutputDevice::SetTextColor( const Color& rColor )
maTextColor = aColor;
mbInitTextColor = true;
}
if( mpAlphaVDev )
mpAlphaVDev->SetTextColor( COL_ALPHA_OPAQUE );
}
void OutputDevice::SetTextFillColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaTextFillColorAction( Color(), false ) );
@@ -499,9 +489,6 @@ void OutputDevice::SetTextFillColor()
}
if ( !maFont.IsTransparent() )
maFont.SetTransparent( true );
if( mpAlphaVDev )
mpAlphaVDev->SetTextFillColor();
}
void OutputDevice::SetTextFillColor( const Color& rColor )
@@ -515,9 +502,6 @@ void OutputDevice::SetTextFillColor( const Color& rColor )
maFont.SetFillColor( aColor );
if ( maFont.IsTransparent() != rColor.IsTransparent() )
maFont.SetTransparent( rColor.IsTransparent() );
if( mpAlphaVDev )
mpAlphaVDev->SetTextFillColor( COL_ALPHA_OPAQUE );
}
Color OutputDevice::GetTextFillColor() const
@@ -530,7 +514,6 @@ Color OutputDevice::GetTextFillColor() const
void OutputDevice::SetTextAlign( TextAlign eAlign )
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaTextAlignAction( eAlign ) );
@@ -539,9 +522,6 @@ void OutputDevice::SetTextAlign( TextAlign eAlign )
maFont.SetAlignment( eAlign );
mbNewFont = true;
}
if( mpAlphaVDev )
mpAlphaVDev->SetTextAlign( eAlign );
}
vcl::Region OutputDevice::GetOutputBoundsClipRegion() const
@@ -635,9 +615,6 @@ void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
{
ImplDrawText( *pSalLayout );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawText( rStartPt, rStr, nIndex, nLen, pVector, pDisplayText );
}
tools::Long OutputDevice::GetTextWidth( const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen,
@@ -740,12 +717,6 @@ void OutputDevice::DrawPartialTextArray(const Point& rStartPt, const OUString& r
{
ImplDrawText(*pSalLayout);
}
if (mpAlphaVDev)
{
mpAlphaVDev->DrawPartialTextArray(rStartPt, rStr, pDXArray, pKashidaArray, nIndex, nLen,
nPartIndex, nPartLen, flags, pLayoutCache);
}
}
void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr,
@@ -778,9 +749,6 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr,
{
ImplDrawText( *pSalLayout );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawTextArray( rStartPt, rStr, pDXAry, pKashidaAry, nIndex, nLen, flags );
}
double
@@ -992,9 +960,6 @@ void OutputDevice::DrawStretchText( const Point& rStartPt, sal_Int32 nWidth,
{
ImplDrawText( *pSalLayout );
}
if( mpAlphaVDev )
mpAlphaVDev->DrawStretchText( rStartPt, nWidth, rStr, nIndex, nLen );
}
vcl::text::ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
@@ -1790,9 +1755,6 @@ void OutputDevice::DrawText( const tools::Rectangle& rRect, const OUString& rOri
// and enable again
mpMetaFile = pMtf;
if( mpAlphaVDev )
mpAlphaVDev->DrawText( rRect, rOrigStr, nStyle, pVector, pDisplayText );
}
tools::Rectangle OutputDevice::GetTextRect( const tools::Rectangle& rRect,
@@ -2041,9 +2003,6 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
SetTextColor( *oOldTextColor );
if (oOldTextFillColor)
SetTextFillColor(*oOldTextFillColor);
if( mpAlphaVDev )
mpAlphaVDev->DrawCtrlText( rPos, rStr, nIndex, nLen, nStyle, pVector, pDisplayText );
}
tools::Long OutputDevice::GetCtrlTextWidth( const OUString& rStr, const SalLayoutGlyphs* pGlyphs ) const
-20
View File
@@ -919,14 +919,10 @@ void OutputDevice::ImplDrawMnemonicLine( tools::Long nX, tools::Long nY, tools::
void OutputDevice::SetTextLineColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaTextLineColorAction( Color(), false ) );
maTextLineColor = COL_TRANSPARENT;
if( mpAlphaVDev )
mpAlphaVDev->SetTextLineColor();
}
void OutputDevice::SetTextLineColor( const Color& rColor )
@@ -937,21 +933,14 @@ void OutputDevice::SetTextLineColor( const Color& rColor )
mpMetaFile->AddAction( new MetaTextLineColorAction( aColor, true ) );
maTextLineColor = aColor;
if( mpAlphaVDev )
mpAlphaVDev->SetTextLineColor( COL_ALPHA_OPAQUE );
}
void OutputDevice::SetOverlineColor()
{
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaOverlineColorAction( Color(), false ) );
maOverlineColor = COL_TRANSPARENT;
if( mpAlphaVDev )
mpAlphaVDev->SetOverlineColor();
}
void OutputDevice::SetOverlineColor( const Color& rColor )
@@ -962,9 +951,6 @@ void OutputDevice::SetOverlineColor( const Color& rColor )
mpMetaFile->AddAction( new MetaOverlineColorAction( aColor, true ) );
maOverlineColor = aColor;
if( mpAlphaVDev )
mpAlphaVDev->SetOverlineColor( COL_ALPHA_OPAQUE );
}
void OutputDevice::DrawTextLine( const Point& rPos, tools::Long nWidth,
@@ -1002,9 +988,6 @@ void OutputDevice::DrawTextLine( const Point& rPos, tools::Long nWidth,
double fWidth = ImplLogicWidthToDeviceSubPixel(nWidth);
aPos += Point( mnTextOffX, mnTextOffY );
ImplDrawTextLine( aPos.X(), aPos.X(), 0, fWidth, fWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove );
if( mpAlphaVDev )
mpAlphaVDev->DrawTextLine( rPos, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove );
}
void OutputDevice::DrawWaveLine(const Point& rStartPos, const Point& rEndPos, tools::Long nLineWidth, tools::Long nWaveHeight)
@@ -1149,9 +1132,6 @@ void OutputDevice::ImplDrawWaveLineBezier(tools::Long nStartX, tools::Long nStar
basegfx::deg2rad(15.0),
bPixelSnapHairline,
*this);
if( mpAlphaVDev )
mpAlphaVDev->ImplDrawWaveLineBezier(nStartX, nStartY, nEndX, nEndY, nWaveHeight, fOrientation, nLineWidth);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+3 -31
View File
@@ -128,14 +128,13 @@ void OutputDevice::DrawTransparent(
const basegfx::B2DHomMatrix aFullTransform(ImplGetDeviceTransformation() * rObjectTransform);
// TODO: this must not drop transparency for mpAlphaVDev case, but instead use premultiplied
// alpha... but that requires using premultiplied alpha also for already drawn data
const double fAdjustedTransparency = mpAlphaVDev ? 0 : fTransparency;
if (IsFillColor())
{
mpGraphics->DrawPolyPolygon(
aFullTransform,
aB2DPolyPolygon,
fAdjustedTransparency,
fTransparency,
*this);
}
@@ -148,7 +147,7 @@ void OutputDevice::DrawTransparent(
mpGraphics->DrawPolyLine(
aFullTransform,
rPolygon,
fAdjustedTransparency,
fTransparency,
0.0, // tdf#124848 hairline
nullptr, // MM01
basegfx::B2DLineJoin::NONE,
@@ -170,9 +169,6 @@ void OutputDevice::DrawTransparent(
static_cast< sal_uInt16 >(fTransparency * 100.0)));
}
if (mpAlphaVDev)
mpAlphaVDev->DrawTransparent(rObjectTransform, rB2DPolyPoly, fTransparency);
return;
}
@@ -273,13 +269,6 @@ bool OutputDevice::DrawTransparentNatively ( const tools::PolyPolygon& rPolyPoly
void OutputDevice::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly,
sal_uInt16 nTransparencePercent )
{
// #110958# Disable alpha VDev, we perform the necessary
VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
// operation explicitly further below.
if( mpAlphaVDev )
mpAlphaVDev = nullptr;
GDIMetaFile* pOldMetaFile = mpMetaFile;
mpMetaFile = nullptr;
@@ -297,9 +286,7 @@ void OutputDevice::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly,
// #i66849# Added fast path for exactly rectangular
// polygons
// #i83087# Naturally, system alpha blending cannot
// work with separate alpha VDev
if( !mpAlphaVDev && aPolyPoly.IsRect() )
if( aPolyPoly.IsRect() )
{
// setup Graphics only here (other cases delegate
// to basic OutDev methods)
@@ -500,9 +487,6 @@ void OutputDevice::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly,
}
mpMetaFile = pOldMetaFile;
// #110958# Restore disabled alpha VDev
mpAlphaVDev = pOldAlphaVDev;
}
void OutputDevice::DrawTransparent( const tools::PolyPolygon& rPolyPoly,
@@ -539,18 +523,6 @@ void OutputDevice::DrawTransparent( const tools::PolyPolygon& rPolyPoly,
if (!bDrawn)
EmulateDrawTransparent( rPolyPoly, nTransparencePercent );
// #110958# Apply alpha value also to VDev alpha channel
if( mpAlphaVDev )
{
const Color aFillCol( mpAlphaVDev->GetFillColor() );
sal_uInt8 nAlpha = 255 - sal::static_int_cast<sal_uInt8>(255*nTransparencePercent/100);
mpAlphaVDev->SetFillColor( Color(nAlpha, nAlpha, nAlpha) );
mpAlphaVDev->DrawTransparent( rPolyPoly, nTransparencePercent );
mpAlphaVDev->SetFillColor( aFillCol );
}
}
void OutputDevice::DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos,
-9
View File
@@ -54,9 +54,6 @@ void OutputDevice::DrawWallpaper( const tools::Rectangle& rRect,
rWallpaper );
}
}
if( mpAlphaVDev )
mpAlphaVDev->DrawWallpaper( rRect, rWallpaper );
}
void OutputDevice::DrawWallpaper( tools::Long nX, tools::Long nY,
@@ -117,9 +114,6 @@ void OutputDevice::Erase()
if ( eRasterOp != RasterOp::OverPaint )
SetRasterOp( eRasterOp );
}
// If we went into the "if ( mbBackground )" section, then we have already erased the mpAlphaDev.
else if( mpAlphaVDev )
mpAlphaVDev->Erase();
}
void OutputDevice::Erase(const tools::Rectangle& rRect)
@@ -130,9 +124,6 @@ void OutputDevice::Erase(const tools::Rectangle& rRect)
DrawWallpaper(rRect, GetBackground());
if ( eRasterOp != RasterOp::OverPaint )
SetRasterOp( eRasterOp );
if (mpAlphaVDev)
mpAlphaVDev->Erase(rRect);
}
void OutputDevice::DrawBitmapWallpaper( tools::Long nX, tools::Long nY,
-3
View File
@@ -1639,9 +1639,6 @@ void Window::Erase(vcl::RenderContext& rRenderContext)
if (eRasterOp != RasterOp::OverPaint)
rRenderContext.SetRasterOp(eRasterOp);
}
if (GetOutDev()->mpAlphaVDev)
GetOutDev()->mpAlphaVDev->Erase();
}
void Window::ImplScroll( const tools::Rectangle& rRect,
-4
View File
@@ -78,10 +78,6 @@ X11SalInstance::X11SalInstance(std::unique_ptr<SalYieldMutex> pMutex)
m_bSupportsOpenGL = true;
#if HAVE_FEATURE_SKIA
X11SkiaSalGraphicsImpl::prepareSkia();
#if SKIA_USE_BITMAP32
if (SkiaHelper::isVCLSkiaEnabled())
m_bSupportsBitmap32 = true;
#endif
#endif
}
@@ -186,9 +186,10 @@ void X11CairoSalGraphicsImpl::drawMask(const SalTwoRect& rTR, const SalBitmap& r
std::shared_ptr<SalBitmap> X11CairoSalGraphicsImpl::getBitmap(tools::Long nX, tools::Long nY,
tools::Long nWidth,
tools::Long nHeight)
tools::Long nHeight,
bool bWithoutAlpha)
{
return mrCairoCommon.getBitmap(nX, nY, nWidth, nHeight);
return mrCairoCommon.getBitmap(nX, nY, nWidth, nHeight, bWithoutAlpha);
}
bool X11CairoSalGraphicsImpl::drawPolyLineBezier(sal_uInt32, const Point*, const PolyFlags*)
@@ -149,7 +149,7 @@ public:
Color nMaskColor) override;
std::shared_ptr<SalBitmap> getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth,
tools::Long nHeight) override;
tools::Long nHeight, bool bWithoutAlpha) override;
bool drawPolyLineBezier(sal_uInt32 nPoints, const Point* pPtAry,
const PolyFlags* pFlgAry) override;
+6 -4
View File
@@ -36,8 +36,9 @@
std::unique_ptr<SalVirtualDevice> X11SalInstance::CreateX11VirtualDevice(const SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY, DeviceFormat eFormat,
std::unique_ptr<X11SalGraphics> pNewGraphics)
std::unique_ptr<X11SalGraphics> pNewGraphics, bool bAlphaMaskTransparent)
{
assert(!bAlphaMaskTransparent && "TODO"); (void)bAlphaMaskTransparent;
assert(pNewGraphics);
#if HAVE_FEATURE_SKIA
if (SkiaHelper::isVCLSkiaEnabled())
@@ -61,9 +62,9 @@ std::unique_ptr<SalVirtualDevice> X11SalInstance::CreateX11VirtualDevice(const S
}
std::unique_ptr<SalVirtualDevice> X11SalInstance::CreateVirtualDevice(SalGraphics& rGraphics,
tools::Long nDX, tools::Long nDY, DeviceFormat eFormat)
tools::Long nDX, tools::Long nDY, DeviceFormat eFormat, bool bAlphaMaskTransparent)
{
return CreateX11VirtualDevice(rGraphics, nDX, nDY, eFormat, std::make_unique<X11SalGraphics>());
return CreateX11VirtualDevice(rGraphics, nDX, nDY, eFormat, std::make_unique<X11SalGraphics>(), bAlphaMaskTransparent);
}
std::unique_ptr<SalVirtualDevice> X11SalInstance::CreateVirtualDevice(SalGraphics& rGraphics,
@@ -229,8 +230,9 @@ SalGraphics* X11SalVirtualDevice::AcquireGraphics()
void X11SalVirtualDevice::ReleaseGraphics( SalGraphics* )
{ bGraphics_ = false; }
bool X11SalVirtualDevice::SetSize( tools::Long nDX, tools::Long nDY )
bool X11SalVirtualDevice::SetSize( tools::Long nDX, tools::Long nDY, bool bAlphaMaskTransparent )
{
assert(!bAlphaMaskTransparent && "TODO"); (void)bAlphaMaskTransparent;
if( bExternPixmap_ )
return false;
+4 -3
View File
@@ -370,14 +370,15 @@ void GtkYieldMutex::ThreadsLeave()
std::unique_ptr<SalVirtualDevice> GtkInstance::CreateVirtualDevice( SalGraphics &rG,
tools::Long nDX, tools::Long nDY,
DeviceFormat /*eFormat*/ )
DeviceFormat /*eFormat*/,
bool bAlphaMaskTransparent )
{
EnsureInit();
SvpSalGraphics *pSvpSalGraphics = dynamic_cast<SvpSalGraphics*>(&rG);
assert(pSvpSalGraphics);
// tdf#127529 see SvpSalInstance::CreateVirtualDevice for the rare case of a non-null pPreExistingTarget
std::unique_ptr<SalVirtualDevice> xNew(new SvpSalVirtualDevice(pSvpSalGraphics->getSurface(), /*pPreExistingTarget*/nullptr));
if (!xNew->SetSize(nDX, nDY))
if (!xNew->SetSize(nDX, nDY, bAlphaMaskTransparent))
xNew.reset();
return xNew;
}
@@ -393,7 +394,7 @@ std::unique_ptr<SalVirtualDevice> GtkInstance::CreateVirtualDevice( SalGraphics
// tdf#127529 see SvpSalInstance::CreateVirtualDevice for the rare case of a non-null pPreExistingTarget
cairo_surface_t* pPreExistingTarget = static_cast<cairo_surface_t*>(rGd.pSurface);
std::unique_ptr<SalVirtualDevice> xNew(new SvpSalVirtualDevice(pSvpSalGraphics->getSurface(), pPreExistingTarget));
if (!xNew->SetSize(nDX, nDY))
if (!xNew->SetSize(nDX, nDY, /*bAlphaMaskTransparent*/false))
xNew.reset();
return xNew;
}
-4
View File
@@ -406,10 +406,6 @@ WinSalInstance::WinSalInstance()
pSVData->maAppData.mxToolkitName = OUString("win");
m_bSupportsOpenGL = true;
WinSkiaSalGraphicsImpl::prepareSkia();
#if SKIA_USE_BITMAP32
if (SkiaHelper::isVCLSkiaEnabled())
m_bSupportsBitmap32 = true;
#endif
}
WinSalInstance::~WinSalInstance()
+137 -35
View File
@@ -34,6 +34,7 @@
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <comphelper/windowserrorstring.hxx>
#include <win/wincomp.hxx>
#include <win/saldata.hxx>
#include <win/salgdi.h>
@@ -54,6 +55,7 @@
#include <gdiplus.h>
#include <gdiplusenums.h>
#include <gdipluscolor.h>
#include <Gdipluspixelformats.h>
#include <postwin.h>
@@ -717,7 +719,7 @@ void WinSalGraphicsImpl::drawMask(const SalTwoRect& rPosAry,
ImplDrawBitmap( hDC, aPosAry, rSalBitmap, false, 0x00B8074AUL );// raster operation PSDPxax
}
std::shared_ptr<SalBitmap> WinSalGraphicsImpl::getBitmap( tools::Long nX, tools::Long nY, tools::Long nDX, tools::Long nDY )
std::shared_ptr<SalBitmap> WinSalGraphicsImpl::getBitmap( tools::Long nX, tools::Long nY, tools::Long nDX, tools::Long nDY, bool bWithoutAlpha )
{
SAL_WARN_IF( mrParent.isPrinter(), "vcl", "No ::GetBitmap() from printer possible!" );
@@ -727,12 +729,34 @@ std::shared_ptr<SalBitmap> WinSalGraphicsImpl::getBitmap( tools::Long nX, tools:
nDY = std::abs( nDY );
HDC hDC = mrParent.getHDC();
HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
bool bRet;
HBITMAP hBmpBitmap;
if (bWithoutAlpha && GetBitCount() == 32)
{
BITMAPINFO aBitmapInfo;
aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
aBitmapInfo.bmiHeader.biWidth = nDX;
aBitmapInfo.bmiHeader.biHeight = -nDY; // negative for top down
aBitmapInfo.bmiHeader.biPlanes = 1;
aBitmapInfo.bmiHeader.biBitCount = 24;
aBitmapInfo.bmiHeader.biCompression = BI_RGB;
aBitmapInfo.bmiHeader.biSizeImage = 0;
aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
aBitmapInfo.bmiHeader.biClrUsed = 0;
aBitmapInfo.bmiHeader.biClrImportant = 0;
void* pData;
hBmpBitmap = CreateDIBSection( hDC, &aBitmapInfo,
DIB_RGB_COLORS, &pData, nullptr,
0 );
SAL_WARN_IF( !hBmpBitmap, "vcl", "CreateDIBSection failed: " << comphelper::WindowsErrorString( GetLastError() ) );
}
else
hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY );
bool bRet;
{
ScopedCachedHDC<CACHED_HDC_1> hBmpDC(hBmpBitmap);
bRet = BitBlt(hBmpDC.get(), 0, 0,
static_cast<int>(nDX), static_cast<int>(nDY), hDC,
static_cast<int>(nX), static_cast<int>(nY), SRCCOPY) ? TRUE : FALSE;
@@ -758,14 +782,38 @@ std::shared_ptr<SalBitmap> WinSalGraphicsImpl::getBitmap( tools::Long nX, tools:
Color WinSalGraphicsImpl::getPixel( tools::Long nX, tools::Long nY )
{
COLORREF aWinCol = ::GetPixel( mrParent.getHDC(), static_cast<int>(nX), static_cast<int>(nY) );
// The only way to read a pixel color with alpha is via GDI+
// This is all hideously inefficient, but we only really use it for unit tests.
Gdiplus::Bitmap screenPixel(1, 1, PixelFormat32bppARGB);
Gdiplus::Graphics gdest(&screenPixel);
auto hDestDC = gdest.GetHDC();
BOOL retval = BitBlt(hDestDC, 0, 0, 1, 1,
mrParent.getHDC(), static_cast<int>(nX), static_cast<int>(nY),
SRCCOPY);
gdest.ReleaseHDC(hDestDC);
if ( CLR_INVALID == aWinCol )
return Color( 0, 0, 0 );
if (!retval)
{
SAL_WARN("vcl", "GetPixel failed1");
return Color(0, 0, 0);
}
Gdiplus::Color nGdiColor;
if (screenPixel.GetPixel(0, 0, &nGdiColor) != Gdiplus::Ok)
{
SAL_WARN("vcl", "GetPixel failed2");
return Color(0, 0, 0);
}
// seems to be returning premultiplied color, despite the pixel format that I pass in the constructor
if (nGdiColor.GetAlpha() == 0)
return Color(ColorAlpha, nGdiColor.GetAlpha(),
nGdiColor.GetRed(),
nGdiColor.GetGreen(),
nGdiColor.GetBlue());
else
return Color( GetRValue( aWinCol ),
GetGValue( aWinCol ),
GetBValue( aWinCol ) );
return Color(ColorAlpha, nGdiColor.GetAlpha(),
nGdiColor.GetRed() * 255 / nGdiColor.GetAlpha(),
nGdiColor.GetGreen() * 255 / nGdiColor.GetAlpha(),
nGdiColor.GetBlue() * 255 / nGdiColor.GetAlpha());
}
namespace
@@ -1379,11 +1427,42 @@ void WinSalGraphicsImpl::drawPixel( tools::Long nX, tools::Long nY )
void WinSalGraphicsImpl::drawPixel( tools::Long nX, tools::Long nY, Color nColor )
{
COLORREF nCol = RGB( nColor.GetRed(),
COLORREF nColorRef = RGB( nColor.GetRed(),
nColor.GetGreen(),
nColor.GetBlue() );
DrawPixelImpl( nX, nY, nCol );
if (nColor.GetAlpha() != 255)
{
const HDC hDC = mrParent.getHDC();
if (!mbXORMode)
{
// the only way to draw a pixel with alpha is via GDI+
Gdiplus::Graphics g (hDC);
g.SetCompositingMode(Gdiplus::CompositingModeSourceCopy);
Gdiplus::SolidBrush brush(Gdiplus::Color(nColor.GetAlpha(), nColor.GetRed(), nColor.GetGreen(), nColor.GetBlue()));
g.FillRectangle(&brush, static_cast<int>(nX), static_cast<int>(nY), 1, 1);
}
else
{
assert(false && "I am not even sure what it would mean to use alpha in this mode");
ScopedSelectedHBRUSH hBrush(hDC, CreateSolidBrush(nColorRef));
PatBlt(hDC, static_cast<int>(nX), static_cast<int>(nY), int(1), int(1), PATINVERT);
}
}
else
{
const HDC hDC = mrParent.getHDC();
if (!mbXORMode)
{
SetPixel(hDC, static_cast<int>(nX), static_cast<int>(nY), nColorRef);
return;
}
ScopedSelectedHBRUSH hBrush(hDC, CreateSolidBrush(nColorRef));
PatBlt(hDC, static_cast<int>(nX), static_cast<int>(nY), int(1), int(1), PATINVERT);
}
}
void WinSalGraphicsImpl::drawLine( tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2 )
@@ -1403,8 +1482,24 @@ void WinSalGraphicsImpl::drawRect( tools::Long nX, tools::Long nY, tools::Long n
{
if ( !mrParent.isPrinter() )
{
PatBlt( mrParent.getHDC(), static_cast<int>(nX), static_cast<int>(nY), static_cast<int>(nWidth), static_cast<int>(nHeight),
mbXORMode ? PATINVERT : PATCOPY );
if (maFillColor.GetAlpha() == 255)
{
PatBlt( mrParent.getHDC(), static_cast<int>(nX), static_cast<int>(nY), static_cast<int>(nWidth), static_cast<int>(nHeight),
mbXORMode ? PATINVERT : PATCOPY );
}
else if (mbXORMode)
assert(false && "don't even know what this would mean");
else
{
// the only way to draw with alpha is via GDI+
Gdiplus::Graphics g(mrParent.getHDC());
if (g.SetCompositingMode(Gdiplus::CompositingModeSourceCopy) != Gdiplus::Ok)
SAL_WARN("vcl", "SetCompositingMode failed");
Gdiplus::SolidBrush brush(
Gdiplus::Color(maFillColor.GetAlpha(), maFillColor.GetRed(),
maFillColor.GetGreen(), maFillColor.GetBlue()));
g.FillRectangle(&brush, static_cast<int>(nX), static_cast<int>(nY), nWidth, nHeight);
}
}
else
{
@@ -1417,7 +1512,25 @@ void WinSalGraphicsImpl::drawRect( tools::Long nX, tools::Long nY, tools::Long n
}
}
else
Rectangle( mrParent.getHDC(), static_cast<int>(nX), static_cast<int>(nY), static_cast<int>(nX+nWidth), static_cast<int>(nY+nHeight) );
{
if (maFillColor.GetAlpha() == 255)
Rectangle(mrParent.getHDC(), static_cast<int>(nX), static_cast<int>(nY),
static_cast<int>(nX + nWidth), static_cast<int>(nY + nHeight));
else if (mbXORMode)
assert(false && "don't even know what this would mean");
else
{
// the only way to draw with alpha is via GDI+
Gdiplus::Graphics g(mrParent.getHDC());
if (g.SetCompositingMode(Gdiplus::CompositingModeSourceCopy) != Gdiplus::Ok)
SAL_WARN("vcl", "SetCompositingMode failed");
Gdiplus::SolidBrush brush(
Gdiplus::Color(maFillColor.GetAlpha(), maFillColor.GetRed(),
maFillColor.GetGreen(), maFillColor.GetBlue()));
g.FillRectangle(&brush, static_cast<int>(nX), static_cast<int>(nY), nWidth,
nHeight);
}
}
}
void WinSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const Point* pPtAry )
@@ -2266,30 +2379,15 @@ static void paintToGdiPlus(
const SalTwoRect& rTR,
Gdiplus::Bitmap& rBitmap)
{
// only parts of source are used
Gdiplus::PointF aDestPoints[3];
Gdiplus::ImageAttributes aAttributes;
// define target region as parallelogram
aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX);
aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY);
aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth);
aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY);
aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX);
aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight);
aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
Gdiplus::Rect aDestRect{ INT(rTR.mnDestX), INT(rTR.mnDestY),
INT(rTR.mnDestWidth), INT(rTR.mnDestHeight) };
rGraphics.DrawImage(
&rBitmap,
aDestPoints,
3,
Gdiplus::REAL(rTR.mnSrcX),
Gdiplus::REAL(rTR.mnSrcY),
Gdiplus::REAL(rTR.mnSrcWidth),
Gdiplus::REAL(rTR.mnSrcHeight),
aDestRect,
rTR.mnSrcX, rTR.mnSrcY, rTR.mnSrcWidth, rTR.mnSrcHeight,
Gdiplus::UnitPixel,
&aAttributes);
nullptr);
}
static void setInterpolationMode(
@@ -2374,6 +2472,10 @@ bool WinSalGraphicsImpl::drawAlphaBitmap(
if(!rTR.mnSrcWidth || !rTR.mnSrcHeight || !rTR.mnDestWidth || !rTR.mnDestHeight)
return false;
// neither GDI nor GDI+ can properly blend to a surface that has alpha
if (GetBitCount() == 32)
return false;
assert(dynamic_cast<const WinSalBitmap*>(&rSrcBitmap));
assert(dynamic_cast<const WinSalBitmap*>(&rAlphaBmp));

Some files were not shown because too many files have changed in this diff Show More