20#include <config_features.h>
22#include <osl/diagnose.h>
53 const Point& rSrcPtPixel,
const Size& rSrcSizePixel,
62 const Point& rSrcPtPixel,
const Size& rSrcSizePixel,
90 Color aCol( cCmpVal, cCmpVal, cCmpVal );
119 rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp ) );
151 aBmp.
Mirror( nMirrFlags );
171 if ( nScaleX < 1.0 || nScaleY < 1.0 )
173 aBmp.
Scale(nScaleX, nScaleY);
206 bool bClipped =
false;
245 if ( aVDev->SetOutputSizePixel( aRect.
GetSize() ) )
247 if ( aVDev->mpGraphics || aVDev->AcquireGraphics() )
249 if ( (nWidth > 0) && (nHeight > 0) )
255 aVDev->mpGraphics->CopyBits(aPosAry, *
mpGraphics, *
this, *
this);
259 OSL_ENSURE(
false,
"CopyBits with zero or negative width or height");
262 aBmp = aVDev->GetBitmap(
Point(), aVDev->GetOutputSizePixel() );
273 std::shared_ptr<SalBitmap> pSalBmp =
mpGraphics->
GetBitmap( nX, nY, nWidth, nHeight, *
this );
287 const Point& rDestPt,
const Size& rDestSize,
288 const Point& rSrcPtPixel,
const Size& rSrcSizePixel )
296 const bool bHMirr = aOutSz.
Width() < 0;
297 const bool bVMirr = aOutSz.
Height() < 0;
305 aOutPt.AdjustX( -(aOutSz.
Width() - 1) );
312 aOutPt.AdjustY( -(aOutSz.
Height() - 1) );
322 rSrcPtPixel.X(), rSrcPtPixel.Y(),
324 aRelPt.X(), aRelPt.Y(),
331 bitmap.
Mirror(mirrorFlags);
332 alpha.
Mirror(mirrorFlags);
379 bitmap.
Mirror(mirrorFlags);
380 alpha.
Mirror(mirrorFlags);
390struct LinearScaleContext
392 std::unique_ptr<sal_Int32[]> mpMapX;
393 std::unique_ptr<sal_Int32[]> mpMapY;
395 std::unique_ptr<sal_Int32[]> mpMapXOffset;
396 std::unique_ptr<sal_Int32[]> mpMapYOffset;
401 : mpMapX(new sal_Int32[aDstRect.GetWidth()])
402 , mpMapY(new sal_Int32[aDstRect.GetHeight()])
403 , mpMapXOffset(new sal_Int32[aDstRect.GetWidth()])
404 , mpMapYOffset(new sal_Int32[aDstRect.GetHeight()])
411 aOutSize.
Width(), nOffX, mpMapX.get(), mpMapXOffset.get());
415 aOutSize.
Height(), nOffY, mpMapY.get(), mpMapYOffset.get());
424 const double fReverseScale = (std::abs(nOutDimension) > 1) ? (nSrcDimension - 1) / double(std::abs(nOutDimension) - 1) : 0.0;
430 double fTemp = std::abs((nOffset + i) * fReverseScale);
433 pMapOffset[
i] =
static_cast<tools::Long>((fTemp - pMap[
i]) * 128.0);
445 if (pSource && pSourceAlpha && pDestination)
450 switch (nSourceFormat)
458 blendBitmap24(pDestination, pSource, pSourceAlpha, nDstWidth, nDstHeight);
478 Scanline pColorSample1, pColorSample2;
481 tools::Long nColor1Line1, nColor2Line1, nColor3Line1;
482 tools::Long nColor1Line2, nColor2Line2, nColor3Line2;
485 sal_uInt8 nColor1, nColor2, nColor3, nAlpha;
494 pLine1 = (nMapY + 1 < pSource->
Height()) ? pSource->
GetScanline(nMapY + 1) : pLine0;
498 pLineAlpha1 = (nMapY + 1 < pSourceAlpha->
Height()) ? pSourceAlpha->
GetScanline(nMapY + 1) : pLineAlpha0;
507 pColorSample1 = pLine0 + 3 * nMapX;
508 pColorSample2 = (nMapX + 1 < pSource->
Width()) ? pColorSample1 + 3 : pColorSample1;
509 nColor1Line1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
513 nColor2Line1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
517 nColor3Line1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
519 pColorSample1 = pLine1 + 3 * nMapX;
520 pColorSample2 = (nMapX + 1 < pSource->
Width()) ? pColorSample1 + 3 : pColorSample1;
521 nColor1Line2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
525 nColor2Line2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
529 nColor3Line2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
531 pColorSample1 = pLineAlpha0 + nMapX;
532 pColorSample2 = (nMapX + 1 < pSourceAlpha->
Width()) ? pColorSample1 + 1 : pColorSample1;
533 nAlphaLine1 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
535 pColorSample1 = pLineAlpha1 + nMapX;
536 pColorSample2 = (nMapX + 1 < pSourceAlpha->
Width()) ? pColorSample1 + 1 : pColorSample1;
537 nAlphaLine2 = (
static_cast<tools::Long>(*pColorSample1) << 7) + nMapFX * (
static_cast<tools::Long>(*pColorSample2) - *pColorSample1);
539 nColor1 = (nColor1Line1 + nMapFY * ((nColor1Line2 >> 7) - (nColor1Line1 >> 7))) >> 7;
540 nColor2 = (nColor2Line1 + nMapFY * ((nColor2Line2 >> 7) - (nColor2Line1 >> 7))) >> 7;
541 nColor3 = (nColor3Line1 + nMapFY * ((nColor3Line2 >> 7) - (nColor3Line1 >> 7))) >> 7;
543 nAlpha = (nAlphaLine1 + nMapFY * ((nAlphaLine2 >> 7) - (nAlphaLine1 >> 7))) >> 7;
557struct TradScaleContext
559 std::unique_ptr<sal_Int32[]> mpMapX;
560 std::unique_ptr<sal_Int32[]> mpMapY;
565 : mpMapX(new sal_Int32[aDstRect.GetWidth()])
566 , mpMapY(new sal_Int32[aDstRect.GetHeight()])
571 const bool bHMirr = aOutSize.
Width() < 0;
572 const bool bVMirr = aOutSize.
Height() < 0;
576 aOutSize.
Width(), nOffX, bHMirr, mpMapX.get());
580 aOutSize.
Height(), nOffY, bVMirr, mpMapY.get());
591 nMirrorOffset = (nDstLocation << 1) + nSrcDimension - 1;
595 pMap[
i] = nDstLocation + nOffset * nSrcDimension / nOutDimension;
597 pMap[
i] = nMirrorOffset - pMap[
i];
612 const bool bHMirr = aOutSize.
Width() < 0;
613 const bool bVMirr = aOutSize.
Height() < 0;
618 const bool bOldMap =
mbMap;
646 : aDstRect.
Left() - aOutPoint.X();
650 TradScaleContext aTradContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
656 "OutputDevice::ImplDrawAlpha(): non-8bit alpha no longer supported!" );
666 aBmp, pBitmapReadAccess.
get(), pAlphaReadAccess.
get(),
670 aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
674 LinearScaleContext aLinearContext(aDstRect, aBmpRect, aOutSize, nOffX, nOffY);
677 nDstWidth, nDstHeight))
684 aBmp, pBitmapReadAccess.
get(), pAlphaReadAccess.
get(),
689 aTradContext.mpMapX.get(), aTradContext.mpMapY.get() );
732 bool bIsSizeValid = !rSize.
IsEmpty();
736 Image& rNonConstImage =
const_cast<Image&
>(rImage);
738 rNonConstImage.
Draw(
this, rPos, nStyle, &rSize);
740 rNonConstImage.
Draw(
this, rPos, nStyle);
751 int c = nResAlpha ? (
static_cast<int>(nSourceAlpha)*nSourceColor +
static_cast<int>(nDstAlpha)*nDestColor -
752 static_cast<int>(nDstAlpha)*nDestColor*nSourceAlpha/255 ) /
static_cast<int>(nResAlpha) : 0;
766 aSrcCol = pP->
GetColor( nMapY, nMapX );
777 nResAlpha =
static_cast<int>(nSrcAlpha) +
static_cast<int>(nDstAlpha) -
static_cast<int>(nDstAlpha)*nSrcAlpha/255;
779 aDstCol.
SetRed( CalcColor( aSrcCol.
GetRed(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.
GetRed() ) );
780 aDstCol.
SetBlue( CalcColor( aSrcCol.
GetBlue(), nSrcAlpha, nDstAlpha, nResAlpha, aDstCol.
GetBlue() ) );
799 const sal_Int32 nOffY,
800 const sal_Int32 nDstHeight,
801 const sal_Int32 nOffX,
802 const sal_Int32 nDstWidth,
803 const sal_Int32* pMapX,
804 const sal_Int32* pMapY )
812 SAL_WARN_IF( !
mpAlphaVDev,
"vcl.gdi",
"BlendBitmapWithAlpha(): call me only with valid alpha VirtualDevice!" );
827 if (pB && pP && pA && pW && pAlphaW)
831 for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
837 Scanline pScanline = pW->GetScanline(nY);
838 Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
839 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
844 aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.
get(), pAlphaW.
get(), nResAlpha );
849 pW->SetPixelOnData( pScanline, nX,
aIndex );
854 pAlphaW->SetPixelOnData( pScanlineAlpha, nX,
aIndex );
865 if (pB && pP && pA && pAlphaW)
867 for( nY = 0; nY < nDstHeight; nY++ )
870 Scanline pScanlineB = pB->GetScanline(nY);
871 Scanline pScanlineAlpha = pAlphaW->GetScanline(nY);
873 for( nX = 0; nX < nDstWidth; nX++ )
876 aDstCol = AlphaBlend( nX, nY, nMapX, nMapY, pP, pA, pB.
get(), pAlphaW.
get(), nResAlpha );
878 pB->SetPixelOnData(pScanlineB, nX, pB->GetBestMatchingColor(aDstCol));
879 pAlphaW->SetPixelOnData(pScanlineAlpha, nX, pB->GetBestMatchingColor(
Color(255L-nResAlpha, 255L-nResAlpha, 255L-nResAlpha)));
898 const sal_Int32 nOffY,
899 const sal_Int32 nDstHeight,
900 const sal_Int32 nOffX,
901 const sal_Int32 nDstWidth,
906 const sal_Int32* pMapX,
907 const sal_Int32* pMapY )
920 if( pB && pP && pA && pW )
924 for( nY = 0, nOutY = nOffY; nY < nDstHeight; nY++, nOutY++ )
929 nMapY = aBmpRect.
Bottom() - nMapY;
934 Scanline pScanline = pW->GetScanline(nY);
936 for( nX = 0, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ )
941 nMapX = aBmpRect.
Right() - nMapX;
950 pW->SetPixelOnData( pScanline, nX,
aIndex );
963 bool bFastBlend =
false;
964 if( pP && pA && pB && !bHMirr && !bVMirr )
972 if( pP && pA && pB && !bFastBlend )
978 for( nY = 0; nY < nDstHeight; nY++ )
983 nMapY = aBmpRect.
Bottom() - nMapY;
987 Scanline pBScan = pB->GetScanline( nY );
989 for( nX = 0; nX < nDstWidth; nX++ )
995 nMapX = aBmpRect.
Right() - nMapX;
997 aDstCol = pB->GetPixelFromData( pBScan, nX );
999 pB->SetPixelOnData( pBScan, nX, aDstCol );
1008 for( nY = 0; nY < nDstHeight; nY++ )
1014 nMapY = aBmpRect.
Bottom() - nMapY;
1017 Scanline pBScan = pB->GetScanline(nY);
1018 for( nX = 0; nX < nDstWidth; nX++ )
1024 nMapX = aBmpRect.
Right() - nMapX;
1026 aDstCol = pB->GetPixelFromData( pBScan, nX );
1027 aDstCol.
Merge( pP->
GetColor( nMapY, nMapX ), pAScan[ nMapX ] );
1028 pB->SetPixelOnData( pBScan, nX, aDstCol );
bool ImplFastBitmapBlending(BitmapWriteAccess const &rDstWA, const BitmapReadAccess &rSrcRA, const BitmapReadAccess &rMskRA, const SalTwoRect &rTR)
tools::Long Height() const
tools::Long Width() const
ScanlineFormat GetScanlineFormat() const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
sal_uInt8 GetPixelIndex(tools::Long nY, tools::Long nX) const
BitmapColor GetColor(tools::Long nY, tools::Long nX) const
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
Scanline GetScanline(tools::Long nY) const
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
SAL_DLLPRIVATE void ImplSetSalBitmap(const std::shared_ptr< SalBitmap > &xImpBmp)
bool Convert(BmpConversion eConversion)
Convert bitmap format.
Size GetSizePixel() const
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
Scale the bitmap.
bool Mirror(BmpMirrorFlags nMirrorFlags)
Mirror the bitmap.
sal_uInt8 GetBlue() const
void SetGreen(sal_uInt8 nGreen)
void SetRed(sal_uInt8 nRed)
void Merge(const Color &rMergeColor, sal_uInt8 cTransparency)
sal_uInt8 GetGreen() const
void SetBlue(sal_uInt8 nBlue)
void Draw(OutputDevice *pOutDev, const Point &rPos, DrawImageFlags nStyle, const Size *pSize=nullptr)
virtual void InitClipRegion()
SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel(tools::Long nY) const
Convert a logical Y coordinate to a device pixel's Y coordinate.
void EnableMapMode(bool bEnable=true)
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)
SAL_DLLPRIVATE bool is_double_buffered_window() const
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames)
SAL_DLLPRIVATE void DrawDeviceAlphaBitmap(const Bitmap &rBmp, const AlphaMask &rAlpha, const Point &rDestPt, const Size &rDestSize, const Point &rSrcPtPixel, const Size &rSrcSizePixel)
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Size GetOutputSizePixel() const
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
void DrawRect(const tools::Rectangle &rRect)
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
bool HasFastDrawTransformedBitmap() const
Return true if DrawTransformedBitmapEx() is fast.
virtual void ClipToPaintRegion(tools::Rectangle &rDstRect)
virtual sal_uInt16 GetBitCount() const
SalGraphics * mpGraphics
Graphics context to draw on.
void DrawBitmap(const Point &rDestPt, const Bitmap &rBitmap)
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool IsRTLEnabled() const
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
virtual bool CanSubsampleBitmap() const
virtual Bitmap GetBitmap(const Point &rSrcPt, const Size &rSize) const
bool IsDeviceOutputNecessary() const
VclPtr< VirtualDevice > mpAlphaVDev
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
SAL_DLLPRIVATE void DrawDeviceAlphaBitmapSlowPath(const Bitmap &rBitmap, const AlphaMask &rAlpha, tools::Rectangle aDstRect, tools::Rectangle aBmpRect, Size const &aOutSz, Point const &aOutPt)
SAL_DLLPRIVATE tools::Long ImplLogicXToDevicePixel(tools::Long nX) const
Convert a logical X coordinate to a device pixel's X coordinate.
bool IsMapModeEnabled() const
SAL_DLLPRIVATE void BlendBitmap(const SalTwoRect &rPosAry, const Bitmap &rBmp)
std::shared_ptr< SalBitmap > GetBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
bool BlendAlphaBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalSrcBitmap, const SalBitmap &rSalMaskBitmap, const SalBitmap &rSalAlphaBitmap, const OutputDevice &rOutDev)
bool HasFastDrawTransformedBitmap() const
void DrawBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, const OutputDevice &rOutDev)
virtual bool ShouldDownscaleIconsAtSurface(double *pScaleOut) const
bool BlendBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, const OutputDevice &rOutDev)
bool DrawAlphaBitmap(const SalTwoRect &, const SalBitmap &rSourceBitmap, const SalBitmap &rAlphaBitmap, const OutputDevice &rOutDev)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SAL_DLLPRIVATE void ImplFillOpaqueRectangle(const tools::Rectangle &rRect)
Used for alpha VDev, to set areas to opaque.
#define DBG_ASSERT(sCon, aError)
std::deque< AttacherIndex_Impl > aIndex
const sal_uLong nVCLLut[256]
const sal_uLong nVCLBLut[6]
const sal_uLong nVCLGLut[6]
const sal_uLong nVCLRLut[6]
const sal_uLong nVCLDitherLut[256]
std::enable_if< std::is_signed< T >::value||std::is_floating_point< T >::value, long >::type MinMax(T nVal, tools::Long nMin, tools::Long nMax)
#define SAL_WARN_IF(condition, area, stream)
VCL_DLLPUBLIC bool isVCLSkiaEnabled()
constexpr sal_uInt8 ColorChannelMerge(sal_uInt8 nDst, sal_uInt8 nSrc, sal_uInt8 nSrcTrans)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
BmpMirrorFlags AdjustTwoRect(SalTwoRect &rTwoRect, const Size &rSizePix)