From 2d213df8afee4ea0e90a101aace9721101884ba0 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 12 Jul 2024 18:25:11 +0300 Subject: [PATCH] Create CSoftMask --- .../agg-2.4/include/agg_alpha_mask_u8.h | 6 - DesktopEditor/graphics/AlphaMask.cpp | 121 ++++++++++++- DesktopEditor/graphics/AlphaMask.h | 53 +++++- DesktopEditor/graphics/Graphics.cpp | 163 +++++------------- DesktopEditor/graphics/Graphics.h | 11 +- DesktopEditor/graphics/GraphicsRenderer.cpp | 24 +-- DesktopEditor/graphics/GraphicsRenderer.h | 5 - DesktopEditor/graphics/IRenderer.h | 10 -- DesktopEditor/graphics/pro/Graphics.h | 3 - 9 files changed, 217 insertions(+), 179 deletions(-) diff --git a/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h b/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h index eee19400e3..78148e221e 100644 --- a/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h +++ b/DesktopEditor/agg-2.4/include/agg_alpha_mask_u8.h @@ -31,12 +31,6 @@ namespace agg static unsigned calculate(const int8u* p) { return *p; } }; - //===================================================four_component_mask_u8 - struct four_component_mask_u8 - { - static unsigned calculate(const int8u* p) { return p[3]; } - }; - //=====================================================rgb_to_gray_mask_u8 template diff --git a/DesktopEditor/graphics/AlphaMask.cpp b/DesktopEditor/graphics/AlphaMask.cpp index 1bda9d866f..982189d019 100644 --- a/DesktopEditor/graphics/AlphaMask.cpp +++ b/DesktopEditor/graphics/AlphaMask.cpp @@ -37,11 +37,6 @@ namespace Aggplus } } - void CAlphaMask::SetDataType(EMaskDataType oType) - { - m_enDataType = oType; - } - Status CAlphaMask::Create(UINT unWidth, UINT unHeight, EMaskDataType eDataType) { if (0 == unWidth || 0 == unHeight) @@ -69,4 +64,120 @@ namespace Aggplus m_bExternalBuffer = bExternalBuffer; return Ok; } + + + + CSoftMask::CSoftMask() : m_pImageData(NULL), m_pAlphaBufferData(NULL) {} + CSoftMask::CSoftMask(BYTE* pBuffer, UINT unWidth, UINT unHeight, EMaskDataType enDataType, bool bExternalBuffer) + { + m_pImageData = NULL; + m_pAlphaBufferData = NULL; + + LoadFromBuffer(pBuffer, unWidth, unHeight, enDataType, bExternalBuffer); + } + CSoftMask::~CSoftMask() + { + BYTE *pBuffer = m_oRenderingBuffer.buf(); + if (NULL != pBuffer) + { + if (!m_bExternalBuffer) + RELEASEARRAYOBJECTS(pBuffer); + + m_oRenderingBuffer.attach(NULL, 0, 0, 0); + } + + RELEASEOBJECT(m_pImageData) + RELEASEOBJECT(m_pAlphaBufferData) + } + + EMaskDataType CSoftMask::GetDataType() const { return m_enDataType; } + UINT CSoftMask::GetStep() const + { + switch(m_enDataType) + { + case EMaskDataType::ImageBuffer: return 4; + case EMaskDataType::AlphaBuffer: return 1; + case EMaskDataType::Alpha4Buffer: return 4; + } + } + + Status CSoftMask::Create(UINT unWidth, UINT unHeight, EMaskDataType enDataType) + { + if (0 == unWidth || 0 == unHeight) + return InvalidParameter; + + m_bExternalBuffer = false; + + UINT unSize = unWidth * unHeight * GetStep(); + BYTE* pAlphaBufffer = new BYTE[unSize]; + if (!pAlphaBufffer) + return OutOfMemory; + + memset(pAlphaBufffer, 0x00, unSize); + + Set(pAlphaBufffer, unWidth, unHeight, enDataType); + + return Ok; + } + + Status CSoftMask::LoadFromBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, EMaskDataType enDataType, bool bExternalBuffer) + { + if (NULL == pBuffer || 0 == unWidth || 0 == unHeight) + return InvalidParameter; + + m_bExternalBuffer = bExternalBuffer; + + Set(pBuffer, unWidth, unHeight, enDataType); + + return Ok; + } + + RenBaseBGRA32& CSoftMask::GetRendererBaseImage() + { + return m_pImageData->m_oRendererBase; + } + + ScanlineBGRA32Gray& CSoftMask::GetScanlineImage() + { + return m_pImageData->m_oScanLine; + } + + ScanlineBGRA32A& CSoftMask::GetScanlineABuffer() + { + return m_pAlphaBufferData->m_oScanLine; + } + + BYTE* CSoftMask::GetBuffer() + { + return m_oRenderingBuffer.buf(); + } + + agg::rendering_buffer& CSoftMask::GetRenderingBuffer() + { + return m_oRenderingBuffer; + } + + void CSoftMask::Set(BYTE* pBuffer, UINT unWidth, UINT unHeight, EMaskDataType enDataType) + { + m_enDataType = enDataType; + m_oRenderingBuffer.attach(pBuffer, unWidth, unHeight, GetStep() * unWidth); + + switch (enDataType) + { + case EMaskDataType::ImageBuffer: + { + m_pImageData = new AMaskFromImage(m_oRenderingBuffer); + m_pImageData->m_oRendererBase.attach(m_pImageData->m_oPixfmt); + m_pImageData->m_oAlphaMask.attach(m_oRenderingBuffer); + break; + } + case EMaskDataType::Alpha4Buffer: + { + m_pAlphaBufferData = new AMaskFromABuffer(m_oRenderingBuffer); + m_pAlphaBufferData->m_oRendererBase.attach(m_pAlphaBufferData->m_oPixfmt); + m_pAlphaBufferData->m_oAlphaMask.attach(m_oRenderingBuffer); + break; + } + } + } } diff --git a/DesktopEditor/graphics/AlphaMask.h b/DesktopEditor/graphics/AlphaMask.h index df13409e3e..46b6fd1163 100644 --- a/DesktopEditor/graphics/AlphaMask.h +++ b/DesktopEditor/graphics/AlphaMask.h @@ -6,6 +6,8 @@ #include "../common/IGrObject.h" #include "./config.h" +#include "../agg-2.4/include/agg_renderer_base.h" +#include "../agg-2.4/include/agg_pixfmt_rgba.h" #include "../agg-2.4/include/agg_scanline_u.h" #include "../agg-2.4/include/agg_alpha_mask_u8.h" @@ -17,7 +19,6 @@ namespace Aggplus AlphaBuffer, Alpha4Buffer }; - typedef agg::scanline_u8_am ScanlineRGBA32A; class GRAPHICS_DECL CAlphaMask : public IGrObject { @@ -30,16 +31,60 @@ namespace Aggplus EMaskDataType GetDataType() const; UINT GetStep() const; - void SetDataType(EMaskDataType oType); Status Create(UINT unWidth, UINT unHeight, EMaskDataType eDataType); Status LoadFromBuffer(BYTE* pBuffer, EMaskDataType eDataType, bool bExternalBuffer = true); - - ScanlineRGBA32A GetScanline(); private: BYTE *m_pBuffer; EMaskDataType m_enDataType; bool m_bExternalBuffer; }; + + template + struct TAlphaMaskData + { + TAlphaMaskData(agg::rendering_buffer& oRenderingBuffer) : m_oPixfmt(oRenderingBuffer), m_oScanLine(m_oAlphaMask) {}; + + PixelFormat m_oPixfmt; + agg::renderer_base m_oRendererBase; + AlphaMask m_oAlphaMask; + agg::scanline_u8_am m_oScanLine; + }; + + typedef agg::renderer_base RenBaseBGRA32; + typedef agg::scanline_u8_am ScanlineBGRA32Gray; + typedef agg::scanline_u8_am ScanlineBGRA32A; + + class GRAPHICS_DECL CSoftMask : public IGrObject + { + public: + CSoftMask(); + CSoftMask(BYTE* pBuffer, UINT unWidth, UINT unHeight, EMaskDataType enDataType, bool bExternalBuffer = true); + virtual ~CSoftMask(); + + EMaskDataType GetDataType() const; + UINT GetStep() const; + + Status Create(UINT unWidth, UINT unHeight, EMaskDataType enDataType); + Status LoadFromBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, EMaskDataType enDataType, bool bExternalBuffer = true); + + agg::rendering_buffer& GetRenderingBuffer(); + RenBaseBGRA32& GetRendererBaseImage(); + ScanlineBGRA32Gray& GetScanlineImage(); + ScanlineBGRA32A& GetScanlineABuffer(); + BYTE* GetBuffer(); + private: + void Set(BYTE* pBuffer, UINT unWidth, UINT unHeight, EMaskDataType enDataType); + + agg::rendering_buffer m_oRenderingBuffer; + EMaskDataType m_enDataType; + bool m_bExternalBuffer; + public: + typedef TAlphaMaskData AMaskFromImage; + typedef TAlphaMaskData AMaskFromABuffer; + + AMaskFromImage* m_pImageData; + AMaskFromABuffer* m_pAlphaBufferData; + }; } #endif // _BUILD_ALPHAMASK_H_ diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 294e91fef9..77788139c5 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -68,7 +68,7 @@ namespace Aggplus m_dDpiTile = -1; m_pAlphaMask = NULL; - m_pPDFAlphaMask = NULL; + m_pSoftMask = NULL; m_nTextRenderMode = FT_RENDER_MODE_NORMAL; m_nBlendMode = agg::comp_op_src_over; @@ -107,7 +107,7 @@ namespace Aggplus m_dDpiTile = -1; m_pAlphaMask = NULL; - m_pPDFAlphaMask = NULL; + m_pSoftMask = NULL; m_nTextRenderMode = FT_RENDER_MODE_NORMAL; m_nBlendMode = agg::comp_op_src_over; @@ -151,7 +151,7 @@ namespace Aggplus m_dDpiTile = -1; m_pAlphaMask = NULL; - m_pPDFAlphaMask = NULL; + m_pSoftMask = NULL; m_nTextRenderMode = FT_RENDER_MODE_NORMAL; m_nBlendMode = agg::comp_op_src_over; @@ -167,6 +167,7 @@ namespace Aggplus #endif RELEASEINTERFACE(m_pAlphaMask); + RELEASEINTERFACE(m_pSoftMask); while (!m_arLayers.empty()) { @@ -1276,6 +1277,42 @@ namespace Aggplus return Ok; } + Status CGraphics::CreateSoftMask() + { + if (m_arLayers.empty()) + return WrongState; + + CGraphicsLayer *pCurrentGraphicsLayer = m_arLayers.top(); + m_arLayers.pop(); + + if (pCurrentGraphicsLayer->Empty()) + return GenericError; + + BYTE* pBuffer = pCurrentGraphicsLayer->GetBuffer(); + + pCurrentGraphicsLayer->ClearBuffer(false); + + RELEASEINTERFACE(pCurrentGraphicsLayer); + RELEASEINTERFACE(m_pSoftMask); + + m_pSoftMask = new CSoftMask(pBuffer, m_frame_buffer.ren_buf().width(), m_frame_buffer.ren_buf().height(), EMaskDataType::Alpha4Buffer, false); + + if (!m_arLayers.empty()) + pBuffer = m_arLayers.top()->GetBuffer(); + else + pBuffer = m_pPixels; + + if (!pBuffer) + { + RELEASEINTERFACE(pCurrentGraphicsLayer); + return WrongState; + } + + m_frame_buffer.ren_buf().attach(pBuffer, m_frame_buffer.ren_buf().width(), m_frame_buffer.ren_buf().height(), m_frame_buffer.ren_buf().stride()); + + return Ok; + } + Status CGraphics::AddLayer(CGraphicsLayer *pGraphicsLayer) { if (NULL == pGraphicsLayer || pGraphicsLayer->Empty()) @@ -1358,11 +1395,6 @@ namespace Aggplus Aggplus::BlendTo(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pAlphaMask->GetBuffer(), m_pAlphaMask->GetStep()); break; } - case EMaskDataType::Alpha4Buffer: - { - Aggplus::BlendTo(pCurrentGraphicsLayer, m_frame_buffer.pixfmt(), m_pAlphaMask->GetBuffer(), m_pAlphaMask->GetStep()); - break; - } } } @@ -1420,100 +1452,6 @@ namespace Aggplus return Ok; } - Status CGraphics::SetLayerIsolated(bool bIsolated) - { - if (m_arLayers.empty()) - return WrongState; - - UINT unSize = m_frame_buffer.ren_buf().width() * m_frame_buffer.ren_buf().height() * m_frame_buffer.pix_size; - if (bIsolated) - memset(m_arLayers.top()->GetBuffer(), 0x00, unSize); - else - memcpy(m_arLayers.top()->GetBuffer(), m_pPixels, unSize); - - return Ok; - } - - Status CGraphics::SetAlphaMaskIsolated(bool bIsolated) - { - if (m_arLayers.empty()) - return WrongState; - - UINT unSize = m_frame_buffer.ren_buf().width() * m_frame_buffer.ren_buf().height() * m_frame_buffer.pix_size; - if (bIsolated) - { - memset(m_arLayers.top()->GetBuffer(), 0x00, unSize); - } - else - { - BYTE* pBuffer = m_arLayers.top()->GetBuffer(); - for (unsigned int i = 0; i < unSize; i = i + 4) - { - pBuffer[i + 0] = 0x00; - pBuffer[i + 1] = 0x00; - pBuffer[i + 2] = 0x00; - pBuffer[i + 3] = 0xFF; - } - } - - return Ok; - } - - void CGraphics::TEST(int i, CBrush* pBrush, CGraphicsPath* pPath) - { - if (i == 1) - { - EndCreatingAlphaMask(); - RemoveLayer(); - } - if (i == 2) - { - // FillPath - if (NULL == pBrush) - return; - - m_rasterizer.get_rasterizer().reset(); - - agg::path_storage p2(pPath->m_internal->m_agg_ps); - typedef agg::conv_transform trans_type; - - trans_type* ptrans = NULL; - agg::trans_affine* paffine = NULL; - if (!m_bIntegerGrid) - ptrans = new trans_type(p2, m_oFullTransform.m_internal->m_agg_mtx); - else - { - paffine = new agg::trans_affine(); - ptrans = new trans_type(p2, *paffine); - } - - typedef agg::conv_curve conv_crv_type; - conv_crv_type c_c_path(*ptrans); - - m_rasterizer.get_rasterizer().add_path(c_c_path); - - m_rasterizer.get_rasterizer().filling_rule(pPath->m_internal->m_bEvenOdd ? agg::fill_even_odd : agg::fill_non_zero); - - // DoFillPath - CColor clr; - ((CBrushSolid*)pBrush)->GetColor(&clr); - - // TEST - agg::rendering_buffer g_alpha_mask_rbuf; - g_alpha_mask_rbuf.attach(m_pAlphaMask->GetBuffer(), m_frame_buffer.ren_buf().width(), m_frame_buffer.ren_buf().height(), m_frame_buffer.ren_buf().stride()); - agg::alpha_mask_rgba32a am(g_alpha_mask_rbuf); - agg::scanline_u8_am sl(am); - - // DoFillPathSolid - typedef agg::renderer_scanline_aa_solid solid_renderer_type; - solid_renderer_type ren_fine(m_frame_buffer.ren_base()); - ren_fine.color(clr.GetAggColor()); - - // render_scanlines - agg::render_scanlines(m_rasterizer.get_rasterizer(), sl, ren_fine); - } - } - void CGraphics::CalculateFullTransform() { m_oFullTransform = m_oCoordTransform; @@ -1525,25 +1463,18 @@ namespace Aggplus return m_oClip.IsClip(); } - unsigned int CGraphics::GetLayerW() - { - return m_frame_buffer.ren_buf().width(); - } - - unsigned int CGraphics::GetLayerH() - { - return m_frame_buffer.ren_buf().height(); - } - template void CGraphics::render_scanlines(Renderer& ren) { if (!m_oClip.IsClip()) { - //if (m_pPDFAlphaMask) - //{ - // return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pPDFAlphaMask.GetScanline(), ren); - //} + if (m_pSoftMask) + { + if (m_pSoftMask->GetDataType() == EMaskDataType::ImageBuffer) + return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pSoftMask->GetScanlineImage(), ren); + if (m_pSoftMask->GetDataType() == EMaskDataType::Alpha4Buffer) + return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pSoftMask->GetScanlineABuffer(), ren); + } agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren); } else diff --git a/DesktopEditor/graphics/Graphics.h b/DesktopEditor/graphics/Graphics.h index 5b42d1a654..d8ec4e579f 100644 --- a/DesktopEditor/graphics/Graphics.h +++ b/DesktopEditor/graphics/Graphics.h @@ -282,7 +282,7 @@ protected: CClipMulti m_oClip; CAlphaMask* m_pAlphaMask; - CAlphaMask* m_pPDFAlphaMask; + CSoftMask* m_pSoftMask; std::stack m_arLayers; @@ -403,11 +403,12 @@ public: //Работа с альфа-маской Status SetAlphaMask(CAlphaMask* pAlphaMask); - inline CAlphaMask* GetAlphaMask() { return m_pAlphaMask; } Status StartCreatingAlphaMask(); Status EndCreatingAlphaMask(); Status ResetAlphaMask(); + Status CreateSoftMask(); + //Работа со слоями Status AddLayer(CGraphicsLayer* pGraphicsLayer); Status CreateLayer(); @@ -416,10 +417,6 @@ public: Status SetLayerSettings(const TGraphicsLayerSettings& oSettings); Status SetLayerOpacity(double dOpacity); - Status SetLayerIsolated(bool bIsolated); - Status SetAlphaMaskIsolated(bool bIsolated); - - void TEST(int i, CBrush* pBrush = NULL, CGraphicsPath* pPath = NULL); void CalculateFullTransform(); bool IsClip(); @@ -429,8 +426,6 @@ public: inline double GetPixW() { return m_dWidthPix; } inline double GetPixH() { return m_dHeightPix; } - unsigned int GetLayerW(); - unsigned int GetLayerH(); protected: diff --git a/DesktopEditor/graphics/GraphicsRenderer.cpp b/DesktopEditor/graphics/GraphicsRenderer.cpp index 6a9d9d5ebc..c18ff7ae37 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.cpp +++ b/DesktopEditor/graphics/GraphicsRenderer.cpp @@ -1416,26 +1416,11 @@ void CGraphicsRenderer::SetAlphaMask(Aggplus::CAlphaMask *pAlphaMask) m_pRenderer->SetAlphaMask(pAlphaMask); } -Aggplus::CAlphaMask* CGraphicsRenderer::GetAlphaMask() -{ - return m_pRenderer->GetAlphaMask(); -} - HRESULT CGraphicsRenderer::put_LayerOpacity(double dValue) { return m_pRenderer->SetLayerOpacity(dValue); } -HRESULT CGraphicsRenderer::put_LayerIsolated(bool bIsolated) -{ - return m_pRenderer->SetLayerIsolated(bIsolated); -} - -HRESULT CGraphicsRenderer::put_AlphaMaskIsolated(bool bIsolated) -{ - return m_pRenderer->SetAlphaMaskIsolated(bIsolated); -} - void CGraphicsRenderer::TEST() { m_pRenderer->CreateLayer(); @@ -1451,7 +1436,7 @@ void CGraphicsRenderer::TEST() DrawPath(c_nWindingFillMode); - m_pRenderer->TEST(1); + m_pRenderer->CreateSoftMask(); m_pPath->Reset(); @@ -1460,16 +1445,11 @@ void CGraphicsRenderer::TEST() m_pPath->LineTo(150, 150); m_pPath->LineTo(150, 50); m_pPath->CloseFigure(); - m_pPath->SetRuler(false); m_oBrush.Color1 = 255; m_oBrush.Alpha1 = 255; - Aggplus::CBrush* pBrush = CreateBrush(&m_oBrush); - - m_pRenderer->TEST(2, pBrush, m_pPath); - - RELEASEOBJECT(pBrush); + DrawPath(c_nWindingFillMode); } void CGraphicsRenderer::put_GlobalAlphaEnabled(const bool& bEnabled, const double& dVal) diff --git a/DesktopEditor/graphics/GraphicsRenderer.h b/DesktopEditor/graphics/GraphicsRenderer.h index 249ea6009d..d2381bff2c 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.h +++ b/DesktopEditor/graphics/GraphicsRenderer.h @@ -348,17 +348,12 @@ public: inline double GetPixW() { return m_pRenderer->GetPixW(); } inline double GetPixH() { return m_pRenderer->GetPixH(); } - inline unsigned int GetLayerW() override { return m_pRenderer->GetLayerW(); } - inline unsigned int GetLayerH() override { return m_pRenderer->GetLayerH(); } // alpha mask methods void SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask); - Aggplus::CAlphaMask* GetAlphaMask(); // layer methods virtual HRESULT put_LayerOpacity(double dValue) override; - virtual HRESULT put_LayerIsolated(bool bIsolated) override; - virtual HRESULT put_AlphaMaskIsolated(bool bIsolated) override; virtual void TEST() override; diff --git a/DesktopEditor/graphics/IRenderer.h b/DesktopEditor/graphics/IRenderer.h index 7d03a7fbc4..d8273d734e 100644 --- a/DesktopEditor/graphics/IRenderer.h +++ b/DesktopEditor/graphics/IRenderer.h @@ -403,16 +403,6 @@ public: UNUSED_VARIABLE(dValue); return S_FALSE; } - virtual HRESULT put_LayerIsolated(bool bIsolated) - { - UNUSED_VARIABLE(bIsolated); - return S_FALSE; - } - virtual HRESULT put_AlphaMaskIsolated(bool bIsolated) - { - UNUSED_VARIABLE(bIsolated); - return S_FALSE; - } }; #define PROPERTY_RENDERER(NameBase, Name, Type) \ diff --git a/DesktopEditor/graphics/pro/Graphics.h b/DesktopEditor/graphics/pro/Graphics.h index 8ff3f21285..2827e14a8d 100644 --- a/DesktopEditor/graphics/pro/Graphics.h +++ b/DesktopEditor/graphics/pro/Graphics.h @@ -117,12 +117,9 @@ namespace NSGraphics virtual void Stroke() = 0; virtual double GetPixW() = 0; virtual double GetPixH() = 0; - virtual unsigned int GetLayerW() = 0; - virtual unsigned int GetLayerH() = 0; //alpha mask methods virtual void SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask) = 0; - virtual Aggplus::CAlphaMask* GetAlphaMask() = 0; virtual void TEST() = 0; // smart methods