Redesigned work with the alpha mask

This commit is contained in:
Kirill Polyakov
2023-12-04 19:37:38 +03:00
parent 09ab798f0d
commit a0d3d402a3
13 changed files with 188 additions and 467 deletions

View File

@ -1,69 +1,61 @@
#include "AlphaMask.h"
#include "AlphaMask_private.h"
namespace Aggplus
{
CAlphaMask::CAlphaMask()
: m_internal(new CAlphaMask_private())
: m_pBuffer(NULL)
{}
CAlphaMask::CAlphaMask(BYTE *pBuffer, EMaskDataType eDataType, bool bExternalBuffer)
: m_pBuffer(pBuffer), m_enDataType(eDataType), m_bExternalBuffer(bExternalBuffer)
{}
CAlphaMask::~CAlphaMask()
{
RELEASEOBJECT(m_internal)
if (!m_bExternalBuffer)
RELEASEARRAYOBJECTS(m_pBuffer);
}
void CAlphaMask::Clear()
BYTE *CAlphaMask::GetBuffer()
{
m_internal->Clear();
return m_pBuffer;
}
StatusAlphaMask CAlphaMask::GetStatus() const
EMaskDataType CAlphaMask::GetDataType() const
{
return m_internal->GetStatus();
}
AMaskDataType CAlphaMask::GetDataType() const
{
return m_internal->GetDataType();
return m_enDataType;
}
Status CAlphaMask::CreateImageBuffer(UINT unWidth, UINT unHeight)
UINT CAlphaMask::GetStep() const
{
return m_internal->Create(unWidth, unHeight, ImageBuffer);
switch(m_enDataType)
{
case EMaskDataType::ImageBuffer: return 4;
case EMaskDataType::AlphaBuffer: return 1;
}
}
Status CAlphaMask::CreateAlphaBuffer(UINT unWidth, UINT unHeight)
Status CAlphaMask::Create(UINT unWidth, UINT unHeight, EMaskDataType eDataType)
{
return m_internal->Create(unWidth, unHeight, AlphaBuffer);
if (0 == unWidth || 0 == unHeight)
return InvalidParameter;
m_enDataType = eDataType;
m_bExternalBuffer = false;
m_pBuffer = new BYTE[unWidth * unHeight * GetStep()];
if (NULL == m_pBuffer)
return OutOfMemory;
return Ok;
}
Status CAlphaMask::LoadFromAlphaBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer)
Status CAlphaMask::LoadFromBuffer(BYTE *pBuffer, EMaskDataType eDataType, bool bExternalBuffer)
{
return m_internal->LoadFromBuffer(pBuffer, unWidth, unHeight, AlphaBuffer, bExternalBuffer);
}
Status CAlphaMask::LoadFromImageBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer)
{
return m_internal->LoadFromBuffer(pBuffer, unWidth, unHeight, ImageBuffer, bExternalBuffer);
}
Status CAlphaMask::LoadFromFile(const std::wstring &wsFilePath)
{
return m_internal->LoadFromFile(wsFilePath);
}
Status CAlphaMask::LoadFromImage(IGrObject *pGrObject, bool bCopy)
{
return m_internal->LoadFromImage(pGrObject, bCopy);
}
BYTE *CAlphaMask::GetMask()
{
return m_internal->GetMask();
}
CAlphaMask &CAlphaMask::operator=(const CAlphaMask &oAlphaMask)
{
*m_internal = *oAlphaMask.m_internal;
return *this;
m_pBuffer = pBuffer;
m_enDataType = eDataType;
m_bExternalBuffer = bExternalBuffer;
return Ok;
}
}

View File

@ -8,45 +8,29 @@
namespace Aggplus
{
enum StatusAlphaMask
{
EmptyAlphaMask,
GenerationAlphaMask,
ApplyingAlphaMask
};
enum AMaskDataType
enum class EMaskDataType
{
ImageBuffer,
AlphaBuffer
};
class CAlphaMask_private;
class GRAPHICS_DECL CAlphaMask : public IGrObject
{
public:
CAlphaMask();
CAlphaMask(BYTE* pBuffer, EMaskDataType eDataType, bool bExternalBuffer = true);
virtual ~CAlphaMask();
StatusAlphaMask GetStatus() const;
AMaskDataType GetDataType() const;
void Clear();
Status CreateImageBuffer(UINT unWidth, UINT unHeight);
Status CreateAlphaBuffer(UINT unWidth, UINT unHeight);
Status LoadFromAlphaBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer = true);
Status LoadFromImageBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, bool bExternalBuffer = true);
Status LoadFromFile(const std::wstring& wsFilePath);
Status LoadFromImage(IGrObject* pGrObject, bool bCopy = true);
BYTE* GetMask();
CAlphaMask& operator=(const CAlphaMask& oAlphaMask);
public:
CAlphaMask_private *m_internal;
BYTE* GetBuffer();
EMaskDataType GetDataType() const;
UINT GetStep() const;
Status Create(UINT unWidth, UINT unHeight, EMaskDataType eDataType);
Status LoadFromBuffer(BYTE* pBuffer, EMaskDataType eDataType, bool bExternalBuffer = true);
private:
BYTE *m_pBuffer;
EMaskDataType m_enDataType;
bool m_bExternalBuffer;
};
}

View File

@ -1,218 +0,0 @@
#include "AlphaMask_private.h"
#include "../raster/BgraFrame.h"
namespace Aggplus
{
CAlphaMask_private::CAlphaMask_private()
: m_enStatus(EmptyAlphaMask), m_pImageData(NULL), m_pAlphaBufferData(NULL)
{}
CAlphaMask_private::~CAlphaMask_private()
{
Clear();
}
StatusAlphaMask CAlphaMask_private::GetStatus() const
{
return m_enStatus;
}
AMaskDataType CAlphaMask_private::GetDataType() const
{
return m_enDataType;
}
void CAlphaMask_private::Clear()
{
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)
m_enStatus = EmptyAlphaMask;
}
Status CAlphaMask_private::Create(UINT unWidth, UINT unHeight, AMaskDataType enDataType)
{
if (0 == unWidth || 0 == unHeight)
return InvalidParameter;
BYTE* pAlphaBufffer = new BYTE[unWidth * unHeight * ((enDataType == ImageBuffer) ? 4 : 1)];
if (NULL == pAlphaBufffer)
return OutOfMemory;
Set(pAlphaBufffer, unWidth, unHeight, enDataType);
if (enDataType == ImageBuffer)
m_pImageData->m_oRendererBase.clear(agg::rgba8(0, 0, 0));
else if (enDataType == AlphaBuffer)
m_pAlphaBufferData->m_oRendererBase.clear(agg::gray8(0));
m_enStatus = GenerationAlphaMask;
m_bExternalBuffer = false;
return Ok;
}
Status CAlphaMask_private::LoadFromBuffer(BYTE *pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enBufferType, bool bExternalBuffer)
{
if (NULL == pBuffer || 0 == unWidth || 0 == unHeight)
return InvalidParameter;
Set(pBuffer, unWidth, unHeight, enBufferType);
m_enStatus = ApplyingAlphaMask;
m_bExternalBuffer = bExternalBuffer;
return Ok;
}
Status CAlphaMask_private::LoadFromFile(const std::wstring &wsFilePath)
{
if (wsFilePath.empty())
return InvalidParameter;
CBgraFrame oFrame;
if (!oFrame.OpenFile(wsFilePath))
return GenericError;
UINT unWidth = oFrame.get_Width();
UINT unHeight = oFrame.get_Height();
Set(oFrame.get_Data(), unWidth, unHeight, ImageBuffer);
oFrame.put_Data(NULL);
m_enStatus = ApplyingAlphaMask;
m_bExternalBuffer = false;
return Ok;
}
Status CAlphaMask_private::LoadFromImage(IGrObject *pGrObject, bool bCopy)
{
if (NULL == pGrObject)
return InvalidParameter;
CImage *pImage = (CImage*)pGrObject;
if (Ok != pImage->GetLastStatus())
return GenericError;
UINT unWidth = pImage->GetWidth();
UINT unHeight = pImage->GetHeight();
BYTE *pBuffer = NULL;
if (bCopy)
{
const UINT unSize = 4 * unWidth * unWidth;
pBuffer = new BYTE[unSize];
memcpy(pBuffer, pImage->GetData(), unSize);
}
else
pBuffer = pImage->GetData();
Set(pBuffer, unWidth, unHeight, ImageBuffer);
return Ok;
}
RenBaseBGRA32 &CAlphaMask_private::GetRendererBaseImage()
{
return m_pImageData->m_oRendererBase;
}
ScanlineBGRA32Gray &CAlphaMask_private::GetScanlineImage()
{
return m_pImageData->m_oScanLine;
}
ScanlineGray8 &CAlphaMask_private::GetScanlineABuffer()
{
return m_pAlphaBufferData->m_oScanLine;
}
BYTE *CAlphaMask_private::GetMask()
{
return m_oRenderingBuffer.buf();
}
void CAlphaMask_private::StartApplying()
{
m_enStatus = ApplyingAlphaMask;
}
CAlphaMask_private &CAlphaMask_private::operator=(const CAlphaMask_private &oAlphaMask)
{
Clear();
m_enDataType = oAlphaMask.m_enDataType;
m_enStatus = oAlphaMask.m_enStatus;
m_bExternalBuffer = false;
if (EmptyAlphaMask == m_enStatus)
return *this;
const UINT unSize = oAlphaMask.m_oRenderingBuffer.width() * oAlphaMask.m_oRenderingBuffer.height() * ((m_enDataType == ImageBuffer) ? 4 : 1);
BYTE* pBuffer = new BYTE[unSize];
memcpy(pBuffer, oAlphaMask.m_oRenderingBuffer.buf(), unSize);
Set(pBuffer, oAlphaMask.m_oRenderingBuffer.width(), oAlphaMask.m_oRenderingBuffer.height(), m_enDataType);
return *this;
}
void CAlphaMask_private::Set(BYTE *pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enDataType)
{
Clear();
m_enDataType = enDataType;
switch (enDataType)
{
case ImageBuffer:
{
m_oRenderingBuffer.attach(pBuffer, unWidth, unHeight, 4 * unWidth);
m_pImageData = new AMaskFromImage(m_oRenderingBuffer);
m_pImageData->m_oPixfmt.attach(m_oRenderingBuffer);
m_pImageData->m_oRendererBase.attach(m_pImageData->m_oPixfmt);
m_pImageData->m_oAlphaMask.attach(m_oRenderingBuffer);
break;
}
case AlphaBuffer:
{
m_oRenderingBuffer.attach(pBuffer, unWidth, unHeight, unWidth);
m_pAlphaBufferData = new AMaskFromABuffer(m_oRenderingBuffer);
m_pAlphaBufferData->m_oPixfmt.attach(m_oRenderingBuffer);
m_pAlphaBufferData->m_oRendererBase.attach(m_pAlphaBufferData->m_oPixfmt);
m_pAlphaBufferData->m_oAlphaMask.attach(m_oRenderingBuffer);
break;
}
}
}
agg::rendering_buffer &CAlphaMask_private::GetRenderingBuffer()
{
return m_oRenderingBuffer;
}
}

View File

@ -1,78 +0,0 @@
#ifndef _BUILD_ALPHAMASK_PRIVATE_H_
#define _BUILD_ALPHAMASK_PRIVATE_H_
#include <string>
#include "aggplustypes.h"
#include "./AlphaMask.h"
#include "../agg-2.4/include/agg_alpha_mask_u8.h"
#include "../agg-2.4/include/agg_renderer_base.h"
#include "../agg-2.4/include/agg_pixfmt_gray.h"
#include "../agg-2.4/include/agg_pixfmt_rgba.h"
#include "../agg-2.4/include/agg_scanline_u.h"
namespace Aggplus
{
template <class PixelFormat, class AlphaMask>
struct TAlphaMaskData
{
TAlphaMaskData(agg::rendering_buffer& oRenderingBuffer)
: m_oPixfmt(oRenderingBuffer), m_oScanLine(m_oAlphaMask)
{};
PixelFormat m_oPixfmt;
agg::renderer_base<PixelFormat> m_oRendererBase;
AlphaMask m_oAlphaMask;
agg::scanline_u8_am<AlphaMask> m_oScanLine; // Используется для применения альфа маски
};
typedef agg::renderer_base<agg::pixfmt_bgra32> RenBaseBGRA32;
typedef agg::scanline_u8_am<agg::alpha_mask_bgra32gray> ScanlineBGRA32Gray;
typedef agg::scanline_u8_am<agg::alpha_mask_gray8> ScanlineGray8;
class CAlphaMask_private
{
public:
CAlphaMask_private();
~CAlphaMask_private();
StatusAlphaMask GetStatus() const;
AMaskDataType GetDataType() const;
void Clear();
Status Create(UINT unWidth, UINT unHeight, AMaskDataType enDataType);
Status LoadFromBuffer(BYTE* pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enBufferType, bool bExternalBuffer = true);
Status LoadFromFile(const std::wstring& wsFilePath);
Status LoadFromImage(IGrObject* pGrObject, bool bCopy = true);
agg::rendering_buffer& GetRenderingBuffer();
RenBaseBGRA32& GetRendererBaseImage();
ScanlineBGRA32Gray& GetScanlineImage();
ScanlineGray8& GetScanlineABuffer();
BYTE* GetMask();
void StartApplying();
CAlphaMask_private& operator=(const CAlphaMask_private& oAlphaMask);
private:
void Set(BYTE* pBuffer, UINT unWidth, UINT unHeight, AMaskDataType enDataType);
agg::rendering_buffer m_oRenderingBuffer;
StatusAlphaMask m_enStatus;
AMaskDataType m_enDataType;
bool m_bExternalBuffer;
public:
typedef TAlphaMaskData<agg::pixfmt_bgra32, agg::alpha_mask_bgra32gray> AMaskFromImage;
typedef TAlphaMaskData<agg::pixfmt_gray8, agg::alpha_mask_gray8> AMaskFromABuffer;
AMaskFromImage *m_pImageData;
AMaskFromABuffer *m_pAlphaBufferData;
};
}
#endif // _BUILD_ALPHAMASK_PRIVATE_H_

View File

@ -32,7 +32,6 @@
#include "Graphics.h"
#include <algorithm>
#include "../fontengine/FontFile.h"
#include "AlphaMask_private.h"
namespace Aggplus
{
@ -463,7 +462,7 @@ namespace Aggplus
m_rasterizer.get_rasterizer().reset_clipping();
m_rasterizer.get_rasterizer().clip_box(m_dClipLeft, m_dClipTop, m_dClipWidth + m_dClipLeft, m_dClipHeight + m_dClipTop);
GetRendererBase().clip_box((int)m_dClipLeft, (int)m_dClipTop, (int)(m_dClipWidth + m_dClipLeft), (int)(m_dClipHeight + m_dClipTop));
m_frame_buffer.ren_base().clip_box((int)m_dClipLeft, (int)m_dClipTop, (int)(m_dClipWidth + m_dClipLeft), (int)(m_dClipHeight + m_dClipTop));
m_oClip.Reset();
@ -1006,7 +1005,7 @@ namespace Aggplus
if(width == 0.00 || height == 0.00)
return InvalidParameter;
CGraphicsPath oPath;
oPath.MoveTo(x, y);
oPath.LineTo(x+width, y);
@ -1222,37 +1221,51 @@ namespace Aggplus
return TRUE;
}
Status CGraphics::SetAlphaMask(CAlphaMask* pAlphaMask)
Status CGraphics::SetAlphaMask(CAlphaMask *pAlphaMask)
{
RELEASEINTERFACE(m_pAlphaMask);
m_pAlphaMask = pAlphaMask;
if (m_pAlphaMask)
{
m_pAlphaMask->AddRef();
m_pAlphaMask->m_internal->StartApplying();
}
return Ok;
return CreateLayer();
}
Status CGraphics::CreateAlphaMask()
Status CGraphics::StartCreatingAlphaMask()
{
return CreateLayer();
}
Status CGraphics::EndCreatingAlphaMask()
{
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_pAlphaMask);
m_pAlphaMask = new CAlphaMask();
return m_pAlphaMask->CreateImageBuffer(m_frame_buffer.width(), m_frame_buffer.height());
m_pAlphaMask = new CAlphaMask(pBuffer, EMaskDataType::ImageBuffer, false);
return CreateLayer();
}
Status CGraphics::ResetAlphaMask()
{
BlendLayer();
RELEASEINTERFACE(m_pAlphaMask);
return Ok;
}
Status CGraphics::StartApplyingAlphaMask()
{
m_pAlphaMask->m_internal->StartApplying();
return Ok;
}
Status CGraphics::AddLayer(CGraphicsLayer *pGraphicsLayer)
{
if (NULL == pGraphicsLayer || pGraphicsLayer->Empty())
@ -1307,11 +1320,26 @@ namespace Aggplus
return WrongState;
}
agg::rendering_buffer *pRenBuffer = &GetRenderingBuffer();
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());
pRenBuffer->attach(pBuffer, m_frame_buffer.ren_buf().width(), m_frame_buffer.ren_buf().height(), pRenBuffer->stride());
pCurrentGraphicsLayer->BlendTo(m_frame_buffer.pixfmt());
if (NULL == m_pAlphaMask)
pCurrentGraphicsLayer->BlendTo(m_frame_buffer.pixfmt());
else
{
switch((int)m_pAlphaMask->GetDataType())
{
case (int)EMaskDataType::ImageBuffer:
{
pCurrentGraphicsLayer->BlendTo<agg::rgb_to_gray_mask_u8<2, 1, 0>>(m_frame_buffer.pixfmt(), m_pAlphaMask->GetBuffer(), m_pAlphaMask->GetStep());
break;
}
case (int)EMaskDataType::AlphaBuffer:
{
pCurrentGraphicsLayer->BlendTo<agg::one_component_mask_u8>(m_frame_buffer.pixfmt(), m_pAlphaMask->GetBuffer(), m_pAlphaMask->GetStep());
break;
}
}
}
RELEASEINTERFACE(pCurrentGraphicsLayer);
return Ok;
@ -1363,36 +1391,12 @@ namespace Aggplus
return m_oClip.IsClip();
}
agg::rendering_buffer& CGraphics::GetRenderingBuffer()
{
if (m_pAlphaMask && GenerationAlphaMask == m_pAlphaMask->m_internal->GetStatus())
return m_pAlphaMask->m_internal->GetRenderingBuffer();
return m_frame_buffer.ren_buf();
}
base_renderer_type& CGraphics::GetRendererBase()
{
if (m_pAlphaMask && GenerationAlphaMask == m_pAlphaMask->GetStatus() && ImageBuffer == m_pAlphaMask->GetDataType())
return (base_renderer_type&)m_pAlphaMask->m_internal->GetRendererBaseImage();
return m_frame_buffer.ren_base();
}
template<class Renderer>
void CGraphics::render_scanlines(Renderer& ren)
{
if (!m_oClip.IsClip())
{
if (m_pAlphaMask && ApplyingAlphaMask == m_pAlphaMask->GetStatus())
{
if (ImageBuffer == m_pAlphaMask->GetDataType())
return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pAlphaMask->m_internal->GetScanlineImage(), ren);
else if (AlphaBuffer == m_pAlphaMask->GetDataType())
return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_pAlphaMask->m_internal->GetScanlineABuffer(), ren);
}
return agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren);
agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ren);
}
else
{
@ -1444,13 +1448,13 @@ namespace Aggplus
{
if (!m_oClip.IsClip())
{
if (m_pAlphaMask && ApplyingAlphaMask == m_pAlphaMask->GetStatus())
{
if (ImageBuffer == m_pAlphaMask->GetDataType())
return agg::render_scanlines(ras, m_pAlphaMask->m_internal->GetScanlineImage(), ren);
else if (AlphaBuffer == m_pAlphaMask->GetDataType())
return agg::render_scanlines(ras, m_pAlphaMask->m_internal->GetScanlineABuffer(), ren);
}
// if (m_pAlphaMask && ApplyingAlphaMask == m_pAlphaMask->GetStatus())
// {
// if (ImageBuffer == m_pAlphaMask->GetDataType())
// return agg::render_scanlines(ras, m_pAlphaMask->m_internal->GetScanlineImage(), ren);
// else if (AlphaBuffer == m_pAlphaMask->GetDataType())
// return agg::render_scanlines(ras, m_pAlphaMask->m_internal->GetScanlineABuffer(), ren);
// }
return agg::render_scanlines(ras, m_rasterizer.get_scanline(), ren);
}
@ -1492,7 +1496,7 @@ namespace Aggplus
comp_renderer_type ren_base;
pixfmt_type_comp pixfmt;
pixfmt.attach(GetRenderingBuffer());
pixfmt.attach(m_frame_buffer.ren_buf());
pixfmt.comp_op(m_nBlendMode);
ren_base.attach(pixfmt);
ren_solid.attach(ren_base);
@ -1503,7 +1507,7 @@ namespace Aggplus
else
{
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(GetRendererBase());
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(dwColor.GetAggColor());
render_scanlines(ren_fine);
@ -1574,7 +1578,7 @@ namespace Aggplus
gradient_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, gradient_span_alloc, gradient_span_gen> renderer_gradient_type;
renderer_gradient_type ren_gradient( GetRendererBase(), span_alloc, span_gen );
renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
@ -1655,7 +1659,7 @@ namespace Aggplus
gradient_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, gradient_span_alloc, gradient_span_gen> renderer_gradient_type;
renderer_gradient_type ren_gradient( GetRendererBase(), span_alloc, span_gen );
renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
@ -1714,7 +1718,7 @@ namespace Aggplus
hatch_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, hatch_span_alloc, hatch_span_gen> renderer_hatch_type;
renderer_hatch_type ren_hatch( GetRendererBase(), span_alloc, span_gen );
renderer_hatch_type ren_hatch( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
@ -1756,7 +1760,7 @@ namespace Aggplus
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{
@ -1794,7 +1798,7 @@ namespace Aggplus
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf, agg::rgba(0, 0, 0, 0));
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
//agg::render_scanlines(m_rasterizer.get_rasterizer(), m_rasterizer.get_scanline(), ri);
render_scanlines(ri);
}
@ -1826,7 +1830,7 @@ namespace Aggplus
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1835,7 +1839,7 @@ namespace Aggplus
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1846,7 +1850,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1857,7 +1861,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1868,7 +1872,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1879,7 +1883,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1902,7 +1906,7 @@ namespace Aggplus
typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1911,7 +1915,7 @@ namespace Aggplus
typedef agg::span_image_filter_rgba_bilinear<img_source_type, interpolator_type_linear> span_gen_type;
typedef agg::renderer_scanline_aa<base_renderer_type, span_alloc_type, span_gen_type> renderer_type;
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1922,7 +1926,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bicubic(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1933,7 +1937,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_spline16(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1944,7 +1948,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_blackman256(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1955,7 +1959,7 @@ namespace Aggplus
agg::image_filter_lut filter;
filter.calculate(agg::image_filter_bilinear(), false);
span_gen_type sg(img_src, interpolator, filter);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
render_scanlines_alpha(ri, Alpha);
break;
}
@ -1997,7 +2001,7 @@ namespace Aggplus
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
@ -2023,7 +2027,7 @@ namespace Aggplus
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
@ -2049,7 +2053,7 @@ namespace Aggplus
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
@ -2075,7 +2079,7 @@ namespace Aggplus
pixfmt img_pixf(PatRendBuff);
img_source_type img_src(img_pixf);
span_gen_type sg(img_src, interpolator);
renderer_type ri(GetRendererBase(), span_allocator, sg);
renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg);
double dAlpha = m_dGlobalAlpha * Alpha / 255.0;
if (fabs(dAlpha - 1.0) < FLT_EPSILON)
@ -2216,7 +2220,7 @@ namespace Aggplus
((CBrushSolid*)pBrush)->GetColor(&clr);
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(GetRendererBase());
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(clr.GetAggColor());
//agg::render_scanlines(storage, m_rasterizer.get_scanline(), ren_fine);
@ -2231,7 +2235,7 @@ namespace Aggplus
((CBrushSolid*)pBrush)->GetColor(&clr);
typedef agg::renderer_scanline_aa_solid<base_renderer_type> solid_renderer_type;
solid_renderer_type ren_fine(GetRendererBase());
solid_renderer_type ren_fine(m_frame_buffer.ren_base());
ren_fine.color(clr.GetAggColor());
if (m_nTextRenderMode == FT_RENDER_MODE_LCD)
@ -2364,7 +2368,7 @@ namespace Aggplus
gradient_span_alloc span_alloc;
typedef agg::renderer_scanline_aa<base_renderer_type, gradient_span_alloc, gradient_span_gen> renderer_gradient_type;
renderer_gradient_type ren_gradient( GetRendererBase(), span_alloc, span_gen );
renderer_gradient_type ren_gradient( m_frame_buffer.ren_base(), span_alloc, span_gen );
if (fabs(m_dGlobalAlpha - 1.0) < FLT_EPSILON)
{

View File

@ -402,9 +402,9 @@ public:
//Работа с альфа-маской
Status SetAlphaMask(CAlphaMask* pAlphaMask);
Status CreateAlphaMask();
Status StartCreatingAlphaMask();
Status EndCreatingAlphaMask();
Status ResetAlphaMask();
Status StartApplyingAlphaMask();
//Работа со слоями
Status AddLayer(CGraphicsLayer* pGraphicsLayer);
@ -433,9 +433,6 @@ protected:
template<class Renderer>
void render_scanlines_alpha(Renderer& ren, BYTE Alpha);
agg::rendering_buffer& GetRenderingBuffer();
base_renderer_type& GetRendererBase();
void DoFillPathSolid(CColor dwColor);
void DoFillPathGradient(CBrushLinearGradient *pBrush);
void DoFillPathGradient2(CBrushLinearGradient *pBrush);

View File

@ -10,8 +10,7 @@ namespace Aggplus
CGraphicsLayer::~CGraphicsLayer()
{
if (!m_bExternalBuffer)
RELEASEARRAYOBJECTS(m_pBuffer);
ClearBuffer();
}
bool CGraphicsLayer::Empty() const
@ -28,6 +27,14 @@ namespace Aggplus
{
m_oSettings.m_dOpacity = 1.;
}
void CGraphicsLayer::ClearBuffer(bool bDeleteData)
{
if (bDeleteData && !m_bExternalBuffer)
RELEASEARRAYOBJECTS(m_pBuffer);
m_pBuffer = NULL;
}
void CGraphicsLayer::SetSettings(const TGraphicsLayerSettings &oSettings)
{

View File

@ -22,6 +22,7 @@ namespace Aggplus
BYTE* GetBuffer();
void SetDefaultSettings();
void ClearBuffer(bool bDeleteData = true);
void SetSettings(const TGraphicsLayerSettings& oSettings);
const TGraphicsLayerSettings& GetSettings() const;
@ -31,7 +32,7 @@ namespace Aggplus
template <class SrcPixelFormatRenderer>
void BlendTo(SrcPixelFormatRenderer& oSrc)
{
if (NULL == m_pBuffer)
if (NULL == m_pBuffer || 0 == oSrc.width() || 0 == oSrc.height())
return;
typedef typename SrcPixelFormatRenderer::order_type order_type;
@ -71,6 +72,40 @@ namespace Aggplus
}
}
}
template <class AlphaMaskFunction, class SrcPixelFormatRenderer>
void BlendTo(SrcPixelFormatRenderer& oSrc, BYTE* pAlphaMaskBuffer, UINT unAlphaMaskStep)
{
if (NULL == m_pBuffer || 0 == oSrc.width() || 0 == oSrc.height())
return;
typedef typename SrcPixelFormatRenderer::order_type order_type;
typedef typename SrcPixelFormatRenderer::value_type value_type;
int nStep = 4;
BYTE* pSrcBuffer = m_pBuffer;
value_type* pDstBuffer = NULL;
BYTE* pSrcAlphaMaskBuffer = pAlphaMaskBuffer;
unsigned int unSrcW = oSrc.width();
unsigned int unSrcH = oSrc.height();
for (unsigned int unY = 0; unY < unSrcH; ++unY)
{
pDstBuffer = oSrc.row_ptr(unY);
for (unsigned int unX = 0; unX < unSrcW; ++unX)
{
pDstBuffer[order_type::R] = pSrcBuffer[order_type::R];
pDstBuffer[order_type::G] = pSrcBuffer[order_type::G];
pDstBuffer[order_type::B] = pSrcBuffer[order_type::B];
pDstBuffer[order_type::A] = ((SrcPixelFormatRenderer::base_mask + (value_type)m_oSettings.m_dOpacity * pSrcBuffer[order_type::A] * AlphaMaskFunction::calculate(pSrcAlphaMaskBuffer)) >> 8);;
pSrcBuffer += nStep;
pDstBuffer += nStep;
pSrcAlphaMaskBuffer += unAlphaMaskStep;
}
}
}
private:
BYTE* m_pBuffer;
bool m_bExternalBuffer;

View File

@ -796,7 +796,7 @@ HRESULT CGraphicsRenderer::BeginCommand(const DWORD& lType)
}
case c_nMaskType:
{
m_pRenderer->CreateAlphaMask();
m_pRenderer->StartCreatingAlphaMask();
break;
}
case c_nLayerType:
@ -835,7 +835,7 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType)
}
case c_nMaskType:
{
m_pRenderer->StartApplyingAlphaMask();
m_pRenderer->EndCreatingAlphaMask();
break;
}
case c_nResetMaskType:
@ -845,7 +845,7 @@ HRESULT CGraphicsRenderer::EndCommand(const DWORD& lType)
}
case c_nLayerType:
{
m_pRenderer->BlendLayer();
m_pRenderer->BlendLayer();
break;
}
default:
@ -1411,7 +1411,7 @@ void CGraphicsRenderer::CreateFlip(BYTE* pPixels, const Aggplus::CDoubleRect& oR
m_pRenderer->SetPageUnit(Aggplus::UnitMillimeter);
}
void CGraphicsRenderer::SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask)
void CGraphicsRenderer::SetAlphaMask(Aggplus::CAlphaMask *pAlphaMask)
{
m_pRenderer->SetAlphaMask(pAlphaMask);
}

View File

@ -350,7 +350,7 @@ public:
inline double GetPixH() { return m_pRenderer->GetPixH(); }
// alpha mask methods
void SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask);
void SetAlphaMask(Aggplus::CAlphaMask* pAlphaMask);
// layer methods
HRESULT put_LayerOpacity(double dValue);

View File

@ -56,11 +56,9 @@ SOURCES += \
# alpha mask
HEADERS += \
./../AlphaMask_private.h \
./../AlphaMask.h
SOURCES += \
./../AlphaMask_private.cpp \
./../AlphaMask.cpp
# grapgics layer

View File

@ -71,7 +71,9 @@ int main(int argc, char *argv[])
{
Aggplus::CAlphaMask* pAlphaMask = new Aggplus::CAlphaMask();
BYTE* pAlphaBuffer = new BYTE[unWidth * unHeight];
pAlphaMask->Create(unWidth, unHeight, Aggplus::EMaskDataType::AlphaBuffer);
BYTE* pAlphaBuffer = pAlphaMask->GetBuffer();
BYTE uchAlphaValue = 0;
@ -84,8 +86,6 @@ int main(int argc, char *argv[])
uchAlphaValue += 25;
}
pAlphaMask->LoadFromAlphaBuffer(pAlphaBuffer, unWidth, unHeight, false);
pRasterRenderer->SetAlphaMask(pAlphaMask);
pAlphaMask->Release();

View File

@ -87,10 +87,10 @@ namespace SVG
void CRect::ApplyStyle(IRenderer *pRenderer, const TSvgStyles *pStyles, const CSvgFile *pFile, int &nTypePath) const
{
if (ApplyStroke(pRenderer, &pStyles->m_oStroke))
if (ApplyStroke(pRenderer, &pStyles->m_oStroke))
nTypePath += c_nStroke;
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true))
if (ApplyFill(pRenderer, &pStyles->m_oFill, pFile, true))
nTypePath += c_nWindingFillMode;
}