summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/salbmp.hxx2
-rw-r--r--vcl/inc/skia/salbmp.hxx12
-rw-r--r--vcl/skia/gdiimpl.cxx8
-rw-r--r--vcl/skia/salbmp.cxx29
-rw-r--r--vcl/source/bitmap/salbmp.cxx43
5 files changed, 85 insertions, 9 deletions
diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx
index b952c8ce4f61..ecb1a1b7d7bf 100644
--- a/vcl/inc/salbmp.hxx
+++ b/vcl/inc/salbmp.hxx
@@ -105,6 +105,8 @@ protected:
// helper function to convert data in 1,2,4 bpp formats to a 24bpp format
static std::unique_ptr< sal_uInt8[] > convertDataTo24Bpp( const sal_uInt8* src,
int width, int height, int bitCount, int bytesPerRow, const BitmapPalette& palette, bool toBgr );
+ static std::unique_ptr< sal_uInt8[] > convertDataTo32Bpp( const sal_uInt8* src,
+ int width, int height, int bitCount, int bytesPerRow, const BitmapPalette& palette, bool toBgra );
};
#endif
diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx
index 005e83be76fc..63a54a8555be 100644
--- a/vcl/inc/skia/salbmp.hxx
+++ b/vcl/inc/skia/salbmp.hxx
@@ -59,18 +59,26 @@ public:
sal_uInt8 nTol) override;
virtual bool ConvertToGreyscale() override;
+ // Accesses the internal SkBitmap. If the bit count is one that Skia does
+ // not support natively, data from the internal buffer is converted
+ // to a 32bpp SkBitmap.
+ const SkBitmap& GetSkBitmap() const;
+
#ifdef DBG_UTIL
void dump(const char* file) const;
#endif
private:
+ void ResetCachedBitmap();
+
SkBitmap mBitmap;
BitmapPalette mPalette;
int mBitCount; // bpp
Size mSize;
- std::unique_ptr<sal_uInt8[]> mBuffer; // for 1bpp and 4bpp, Skia doesn't support those
+ // Skia does not natively support 1bpp and 4bpp, so such bitmaps are stored
+ // in a buffer (and converted to 32bpp SkBitmap on-demand using GetSkBitmap()).
+ std::unique_ptr<sal_uInt8[]> mBuffer;
int mScanlineSize; // size of one row in mBuffer
- friend class SkiaSalGraphicsImpl; // TODO
};
#endif // INCLUDED_VCL_INC_OPENGL_SALBMP_H
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index b397abd6af66..a80bf73c0cbe 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -228,7 +228,7 @@ void SkiaSalGraphicsImpl::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap&
return;
assert(dynamic_cast<const SkiaSalBitmap*>(&rSalBitmap));
mSurface->getCanvas()->drawBitmapRect(
- static_cast<const SkiaSalBitmap&>(rSalBitmap).mBitmap,
+ static_cast<const SkiaSalBitmap&>(rSalBitmap).GetSkBitmap(),
SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth,
rPosAry.mnDestHeight),
@@ -314,11 +314,9 @@ bool SkiaSalGraphicsImpl::drawAlphaBitmap(const SalTwoRect& rPosAry, const SalBi
SkCanvas canvas(tmpBitmap);
SkPaint paint;
paint.setBlendMode(SkBlendMode::kDst);
- canvas.drawBitmap(static_cast<const SkiaSalBitmap&>(rSourceBitmap).mBitmap, 0, 0,
- &paint); // TODO bpp < 8?
+ canvas.drawBitmap(static_cast<const SkiaSalBitmap&>(rSourceBitmap).GetSkBitmap(), 0, 0, &paint);
paint.setBlendMode(SkBlendMode::kSrcIn);
- canvas.drawBitmap(static_cast<const SkiaSalBitmap&>(rAlphaBitmap).mBitmap, 0, 0,
- &paint); // TODO bpp < 8?
+ canvas.drawBitmap(static_cast<const SkiaSalBitmap&>(rAlphaBitmap).GetSkBitmap(), 0, 0, &paint);
mSurface->getCanvas()->drawBitmapRect(
tmpBitmap,
SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index ff0a9ed1897b..88677b6132ad 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -215,12 +215,13 @@ BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode nMode)
void SkiaSalBitmap::ReleaseBuffer(BitmapBuffer* pBuffer, BitmapAccessMode nMode)
{
mPalette = pBuffer->maPalette;
- (void)nMode; // TODO?
// Are there any more ground movements underneath us ?
assert(pBuffer->mnWidth == mSize.Width());
assert(pBuffer->mnHeight == mSize.Height());
assert(pBuffer->mnBitCount == mBitCount);
delete pBuffer;
+ if (nMode == BitmapAccessMode::Write) // TODO something more?
+ ResetCachedBitmap();
}
bool SkiaSalBitmap::GetSystemData(BitmapSystemData& rData)
@@ -249,10 +250,34 @@ bool SkiaSalBitmap::Replace(const Color& rSearchColor, const Color& rReplaceColo
bool SkiaSalBitmap::ConvertToGreyscale() { return false; }
+const SkBitmap& SkiaSalBitmap::GetSkBitmap() const
+{
+ if (mBuffer && mBitmap.drawsNothing())
+ {
+ assert(mBitCount == 1 || mBitCount == 2 || mBitCount == 4);
+ std::unique_ptr<sal_uInt8[]> data = convertDataTo32Bpp(
+ mBuffer.get(), mSize.Width(), mSize.Height(), mBitCount, mScanlineSize, mPalette,
+ kN32_SkColorType == kBGRA_8888_SkColorType); // TODO
+ if (!const_cast<SkBitmap&>(mBitmap).installPixels(
+ SkImageInfo::MakeS32(mSize.Width(), mSize.Height(), kOpaque_SkAlphaType),
+ data.release(), mSize.Width() * 4,
+ [](void* addr, void*) { delete[] static_cast<sal_uInt8*>(addr); }, nullptr))
+ abort();
+ }
+ return mBitmap;
+}
+
+// Reset the cached bitmap allocatd in GetSkBitmap().
+void SkiaSalBitmap::ResetCachedBitmap()
+{
+ if (mBuffer)
+ mBitmap.reset();
+}
+
#ifdef DBG_UTIL
void SkiaSalBitmap::dump(const char* file) const
{
- sk_sp<SkImage> image = SkImage::MakeFromBitmap(mBitmap);
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(GetSkBitmap());
sk_sp<SkData> data = image->encodeToData();
std::ofstream ostream(file, std::ios::binary);
ostream.write(static_cast<const char*>(data->data()), data->size());
diff --git a/vcl/source/bitmap/salbmp.cxx b/vcl/source/bitmap/salbmp.cxx
index 0cf6fd3ab93a..c7183e117598 100644
--- a/vcl/source/bitmap/salbmp.cxx
+++ b/vcl/source/bitmap/salbmp.cxx
@@ -184,4 +184,47 @@ std::unique_ptr< sal_uInt8[] > SalBitmap::convertDataTo24Bpp( const sal_uInt8* s
return data;
}
+std::unique_ptr< sal_uInt8[] > SalBitmap::convertDataTo32Bpp( const sal_uInt8* src,
+ int width, int height, int bitCount, int bytesPerRow, const BitmapPalette& palette, bool toBgra )
+{
+ std::unique_ptr< sal_uInt8[] > data( new sal_uInt8[width * height * 4] );
+ std::unique_ptr<ImplPixelFormat> pSrcFormat(ImplPixelFormat::GetFormat(bitCount, palette));
+
+ const sal_uInt8* pSrcData = src;
+ sal_uInt8* pDstData = data.get();
+
+ sal_uInt32 nY = height;
+ while( nY-- )
+ {
+ pSrcFormat->StartLine( pSrcData );
+
+ sal_uInt32 nX = width;
+ if (toBgra)
+ {
+ while( nX-- )
+ {
+ const BitmapColor& c = pSrcFormat->ReadPixel();
+ *pDstData++ = c.GetBlue();
+ *pDstData++ = c.GetGreen();
+ *pDstData++ = c.GetRed();
+ *pDstData++ = 0xff;
+ }
+ }
+ else // RGBA
+ {
+ while( nX-- )
+ {
+ const BitmapColor& c = pSrcFormat->ReadPixel();
+ *pDstData++ = c.GetRed();
+ *pDstData++ = c.GetGreen();
+ *pDstData++ = c.GetBlue();
+ *pDstData++ = 0xff;
+ }
+ }
+
+ pSrcData += bytesPerRow;
+ }
+ return data;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */