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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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)));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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_; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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; }
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ) :
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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*/,
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -75,9 +75,6 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
|
||||
}
|
||||
}
|
||||
|
||||
if( mpAlphaVDev )
|
||||
mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
|
||||
|
||||
return bDrawn;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user