diff options
Diffstat (limited to 'core/fxge/dib')
-rw-r--r-- | core/fxge/dib/cfx_dibitmap.cpp | 113 | ||||
-rw-r--r-- | core/fxge/dib/cfx_dibitmap.h | 22 |
2 files changed, 97 insertions, 38 deletions
diff --git a/core/fxge/dib/cfx_dibitmap.cpp b/core/fxge/dib/cfx_dibitmap.cpp index 9fa9776df0..15e821cf11 100644 --- a/core/fxge/dib/cfx_dibitmap.cpp +++ b/core/fxge/dib/cfx_dibitmap.cpp @@ -197,50 +197,87 @@ bool CFX_DIBitmap::TransferBitmap(int dest_left, FXDIB_Format dest_format = GetFormat(); FXDIB_Format src_format = pSrcBitmap->GetFormat(); - if (dest_format == src_format) { - if (GetBPP() == 1) { - for (int row = 0; row < height; row++) { - uint8_t* dest_scan = m_pBuffer.Get() + (dest_top + row) * m_Pitch; - const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); - for (int col = 0; col < width; col++) { - if (src_scan[(src_left + col) / 8] & - (1 << (7 - (src_left + col) % 8))) { - dest_scan[(dest_left + col) / 8] |= 1 - << (7 - (dest_left + col) % 8); - } else { - dest_scan[(dest_left + col) / 8] &= - ~(1 << (7 - (dest_left + col) % 8)); - } - } - } - } else { - int Bpp = GetBPP() / 8; - for (int row = 0; row < height; row++) { - uint8_t* dest_scan = - m_pBuffer.Get() + (dest_top + row) * m_Pitch + dest_left * Bpp; - const uint8_t* src_scan = - pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; - memcpy(dest_scan, src_scan, width * Bpp); - } - } - } else { - if (m_pPalette) - return false; + if (dest_format != src_format) { + return TransferWithUnequalFormats(dest_format, dest_left, dest_top, width, + height, pSrcBitmap, src_left, src_top); + } - if (m_bpp == 8) - dest_format = FXDIB_8bppMask; + if (GetBPP() != 1) { + TransferWithMultipleBPP(dest_left, dest_top, width, height, pSrcBitmap, + src_left, src_top); + return true; + } - uint8_t* dest_buf = - m_pBuffer.Get() + dest_top * m_Pitch + dest_left * GetBPP() / 8; - std::unique_ptr<uint32_t, FxFreeDeleter> d_plt; - if (!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, - pSrcBitmap, src_left, src_top, &d_plt)) { - return false; - } + TransferEqualFormatsOneBPP(dest_left, dest_top, width, height, pSrcBitmap, + src_left, src_top); + return true; +} + +bool CFX_DIBitmap::TransferWithUnequalFormats( + FXDIB_Format dest_format, + int dest_left, + int dest_top, + int width, + int height, + const RetainPtr<CFX_DIBSource>& pSrcBitmap, + int src_left, + int src_top) { + if (m_pPalette) + return false; + + if (m_bpp == 8) + dest_format = FXDIB_8bppMask; + + uint8_t* dest_buf = + m_pBuffer.Get() + dest_top * m_Pitch + dest_left * GetBPP() / 8; + std::unique_ptr<uint32_t, FxFreeDeleter> d_plt; + if (!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, pSrcBitmap, + src_left, src_top, &d_plt)) { + return false; } return true; } +void CFX_DIBitmap::TransferWithMultipleBPP( + int dest_left, + int dest_top, + int width, + int height, + const RetainPtr<CFX_DIBSource>& pSrcBitmap, + int src_left, + int src_top) { + int Bpp = GetBPP() / 8; + for (int row = 0; row < height; ++row) { + uint8_t* dest_scan = + m_pBuffer.Get() + (dest_top + row) * m_Pitch + dest_left * Bpp; + const uint8_t* src_scan = + pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp; + memcpy(dest_scan, src_scan, width * Bpp); + } +} + +void CFX_DIBitmap::TransferEqualFormatsOneBPP( + int dest_left, + int dest_top, + int width, + int height, + const RetainPtr<CFX_DIBSource>& pSrcBitmap, + int src_left, + int src_top) { + for (int row = 0; row < height; ++row) { + uint8_t* dest_scan = m_pBuffer.Get() + (dest_top + row) * m_Pitch; + const uint8_t* src_scan = pSrcBitmap->GetScanline(src_top + row); + for (int col = 0; col < width; ++col) { + int src_idx = src_left + col; + int dest_idx = dest_left + col; + if (src_scan[(src_idx) / 8] & (1 << (7 - (src_idx) % 8))) + dest_scan[(dest_idx) / 8] |= 1 << (7 - (dest_idx) % 8); + else + dest_scan[(dest_idx) / 8] &= ~(1 << (7 - (dest_idx) % 8)); + } + } +} + bool CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, const RetainPtr<CFX_DIBSource>& pSrcBitmap, FXDIB_Channel srcChannel) { diff --git a/core/fxge/dib/cfx_dibitmap.h b/core/fxge/dib/cfx_dibitmap.h index 00a145af68..105a22d76e 100644 --- a/core/fxge/dib/cfx_dibitmap.h +++ b/core/fxge/dib/cfx_dibitmap.h @@ -124,6 +124,28 @@ class CFX_DIBitmap : public CFX_DIBSource { private: void ConvertBGRColorScale(uint32_t forecolor, uint32_t backcolor); void ConvertCMYKColorScale(uint32_t forecolor, uint32_t backcolor); + bool TransferWithUnequalFormats(FXDIB_Format dest_format, + int dest_left, + int dest_top, + int width, + int height, + const RetainPtr<CFX_DIBSource>& pSrcBitmap, + int src_left, + int src_top); + void TransferWithMultipleBPP(int dest_left, + int dest_top, + int width, + int height, + const RetainPtr<CFX_DIBSource>& pSrcBitmap, + int src_left, + int src_top); + void TransferEqualFormatsOneBPP(int dest_left, + int dest_top, + int width, + int height, + const RetainPtr<CFX_DIBSource>& pSrcBitmap, + int src_left, + int src_top); }; #endif // CORE_FXGE_DIB_CFX_DIBITMAP_H_ |