From 86af95cf4714b8d169107de804dc12be53af51df Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Fri, 14 Mar 2014 10:38:44 +0000 Subject: [PATCH] git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@54934 954022d7-b5bf-4e40-9824-e11837661b57 --- .../agg-2.4/include/agg_span_hatch.h | 104 ++++++++++++++++-- DesktopEditor/graphics/Brush.cpp | 17 +++ DesktopEditor/graphics/Brush.h | 18 +++ DesktopEditor/graphics/Graphics.cpp | 90 +++++++++++++-- DesktopEditor/graphics/Graphics.h | 5 +- DesktopEditor/graphics/GraphicsRenderer.cpp | 16 ++- 6 files changed, 233 insertions(+), 17 deletions(-) diff --git a/DesktopEditor/agg-2.4/include/agg_span_hatch.h b/DesktopEditor/agg-2.4/include/agg_span_hatch.h index 1fee194fff..37b50dd521 100644 --- a/DesktopEditor/agg-2.4/include/agg_span_hatch.h +++ b/DesktopEditor/agg-2.4/include/agg_span_hatch.h @@ -10,6 +10,7 @@ namespace agg { #define HATCH_TX_SIZE 8 + #define HATCH_TX_SIZE_MASK 7 #define HATCH_TX_COUNT 54 // 8 * 8 * 54 @@ -614,6 +615,26 @@ namespace agg L"zigZag" }; + template + static void GetHatchPattern(const std::wstring& name, color_type* data, const color_type& c1, const color_type& c2) + { + int offset = 0; + int size = HATCH_TX_SIZE * HATCH_TX_SIZE; + + for (int i = 0; i < HATCH_TX_COUNT; ++i) + { + if (c_resource_hatches_names[i] == name) + { + offset = i * size; + break; + } + } + for (int i = 0; i < size; ++i) + { + *data++ = (c_resource_hatches[offset + i] == 1) ? c2 : c1; + } + } + template class agg_span_hatch { @@ -635,16 +656,33 @@ namespace agg color_type m_color1; color_type m_color2; + double Ax; + double Bx; + double Cx; + + double Ay; + double By; + double Cy; + public: agg_span_hatch() : m_state( StateInit ), - m_offset( 0 ), + m_offset( 0 ) { + Ax = 0; + Bx = 0; + Cx = 0; + + Ay = 0; + By = 0; + Cy = 0; } - void SetDirection(const std::wstring& name, const agg::trans_affine& trans) + void SetDirection(const std::wstring& name, const rect_d& bounds, const agg::trans_affine& trans, const color_type& color1, const color_type& color2) { m_trans = trans; + m_color1 = color1; + m_color2 = color2; for (int i = 0; i < HATCH_TX_COUNT; ++i) { @@ -654,6 +692,47 @@ namespace agg break; } } + + double x0 = bounds.x1; + double y0 = bounds.y1; + + double x1 = bounds.x2; + double y1 = y0; + + double x2 = x0; + double y2 = bounds.y2; + + trans.transform(&x0, &y0); + trans.transform(&x1, &y1); + trans.transform(&x2, &y2); + + double dFactor1 = _hypot(x1 - x0, y1 - y0); + if (dFactor1 < FLT_EPSILON) + { + Ax = 0; + Bx = 0; + Cx = 0; + } + else + { + Ax = (y1 - y0) / dFactor1; + Bx = (x0 - x1) / dFactor1; + Cx = (y0 * (x1 - x0) - x0 * (y1 - y0)) / dFactor1; + } + + double dFactor2 = _hypot(x2 - x0, y2 - y0); + if (dFactor2 < FLT_EPSILON) + { + Ay = 0; + By = 0; + Cy = 0; + } + else + { + Ay = (y2 - y0) / dFactor2; + By = (x0 - x2) / dFactor2; + Cy = (y0 * (x2 - x0) - x0 * (y2 - y0)) / dFactor2; + } } void prepare() @@ -661,19 +740,30 @@ namespace agg if( m_state != StateReady ) { m_state = StateReady; - memset( m_valid_table, 0, sizeof m_valid_table ); } } void generate( color_type* span, int x, int y, unsigned len) { + double plusX = Bx * y + Cx; + double plusY = By * y + Cy; + for( unsigned count = 0; count < len; ++count, ++x ) { - double _x = x; - double _y = y; - m_trans.transform(&_x, &_y); +#if 1 // NN + int _x = (int)(Ax * x + plusX + 0.5); + int _y = (int)(Ay * x + plusY + 0.5); + _x = _x & HATCH_TX_SIZE_MASK; + _y = _y & HATCH_TX_SIZE_MASK; - // TODO: + BYTE val = c_resource_hatches[m_offset + (_y << 3) + _x]; + + if (val) + *span++ = m_color2; + else + *span++ = m_color1; +#endif + } } }; diff --git a/DesktopEditor/graphics/Brush.cpp b/DesktopEditor/graphics/Brush.cpp index 068009cd15..f0dbd4f6b1 100644 --- a/DesktopEditor/graphics/Brush.cpp +++ b/DesktopEditor/graphics/Brush.cpp @@ -32,6 +32,23 @@ namespace Aggplus void CBrushSolid::GetColor(CColor* color) const { *color = m_dwColor; } void CBrushSolid::SetColor(const CColor &color) { m_dwColor = color; } + + //////////////////////////////////////////////////////////////////////////////// + + CBrushHatch::CBrushHatch() : CBrush(BrushTypeHatchFill) + { + } + CBrushHatch::~CBrushHatch() + { + } + CBrush* CBrushHatch::Clone() const + { + CBrushHatch* clone = new CBrushHatch(); + clone->m_name = m_name; + clone->m_dwColor1 = m_dwColor1; + clone->m_dwColor2 = m_dwColor2; + return clone; + } //////////////////////////////////////////////////////////////////////////////// diff --git a/DesktopEditor/graphics/Brush.h b/DesktopEditor/graphics/Brush.h index 6f4fac4437..6e2eb54f2d 100644 --- a/DesktopEditor/graphics/Brush.h +++ b/DesktopEditor/graphics/Brush.h @@ -44,6 +44,24 @@ protected: CColor m_dwColor; }; +class CBrushHatch : public CBrush +{ +public: + CBrushHatch(); + virtual ~CBrushHatch(); + virtual CBrush *Clone() const; + + inline CDoubleRect& GetBounds() { return Bounds; } + + +public: + std::wstring m_name; + CColor m_dwColor1; + CColor m_dwColor2; + + CDoubleRect Bounds; +}; + class CBrushLinearGradient : public CBrush { diff --git a/DesktopEditor/graphics/Graphics.cpp b/DesktopEditor/graphics/Graphics.cpp index 788f003de1..fb0ba2d3f5 100644 --- a/DesktopEditor/graphics/Graphics.cpp +++ b/DesktopEditor/graphics/Graphics.cpp @@ -816,10 +816,6 @@ namespace Aggplus brushMatrix.Multiply(&m_oFullTransform, MatrixOrderAppend); ptxBrush->SetTransform(&brushMatrix); } - else if( pBrush->GetType() == Aggplus::BrushTypePathGradient ) - { - - } DoFillPath(pBrush); @@ -1112,7 +1108,7 @@ namespace Aggplus render_scanlines(ren_fine); } - void CGraphics::DoFillPathGradient(CBrushLinearGradient *pBrush, const agg::trans_affine* pGlobalTransform) + void CGraphics::DoFillPathGradient(CBrushLinearGradient *pBrush) { CDoubleRect& oBounds = pBrush->GetBounds(); @@ -1181,7 +1177,7 @@ namespace Aggplus if( pSubBlends ) delete [] pSubBlends; } - void CGraphics::DoFillPathGradient2(CBrushLinearGradient *pBrush, const agg::trans_affine* pGlobalTransform) + void CGraphics::DoFillPathGradient2(CBrushLinearGradient *pBrush) { CDoubleRect& oBounds = pBrush->GetBounds(); @@ -1250,6 +1246,86 @@ namespace Aggplus if( pSubBlends ) delete [] pSubBlends; } + void CGraphics::DoFillPathHatch(CBrushHatch *pBrush) + { +#if 0 + CDoubleRect& oBounds = pBrush->GetBounds(); + + CMatrix oMatrix; + + agg::rect_d rect; + if (oBounds.GetWidth() > FLT_EPSILON || oBounds.GetHeight() > FLT_EPSILON) + { + rect.x1 = oBounds.left; + rect.y1 = oBounds.top; + rect.x2 = oBounds.right; + rect.y2 = oBounds.bottom; + + oMatrix = m_oFullTransform; + } + else + { + int x = m_rasterizer.get_rasterizer().min_x(); + int y = m_rasterizer.get_rasterizer().min_y(); + int width = m_rasterizer.get_rasterizer().max_x() - m_rasterizer.get_rasterizer().min_x(); + int height = m_rasterizer.get_rasterizer().max_y() - m_rasterizer.get_rasterizer().min_y(); + + rect.x1 = x; + rect.x2 = x + width; + rect.y1 = y; + rect.y2 = y + height; + } + + typedef agg::agg_span_hatch hatch_span_gen; + hatch_span_gen span_gen; + + agg::rgba8 c1 = agg::rgba8(pBrush->m_dwColor1.GetB(), pBrush->m_dwColor1.GetG(), pBrush->m_dwColor1.GetR(), pBrush->m_dwColor1.GetA()); + agg::rgba8 c2 = agg::rgba8(pBrush->m_dwColor2.GetB(), pBrush->m_dwColor2.GetG(), pBrush->m_dwColor2.GetR(), pBrush->m_dwColor2.GetA()); + + span_gen.SetDirection(pBrush->m_name, rect, oMatrix.m_agg_mtx, c1, c2); + + typedef agg::span_allocator hatch_span_alloc; + hatch_span_alloc span_alloc; + + typedef agg::renderer_scanline_aa renderer_hatch_type; + renderer_hatch_type ren_hatch( m_frame_buffer.ren_base(), span_alloc, span_gen ); + + render_scanlines(ren_hatch); +#else + agg::rgba8 c1 = agg::rgba8(pBrush->m_dwColor1.GetB(), pBrush->m_dwColor1.GetG(), pBrush->m_dwColor1.GetR(), pBrush->m_dwColor1.GetA()); + agg::rgba8 c2 = agg::rgba8(pBrush->m_dwColor2.GetB(), pBrush->m_dwColor2.GetG(), pBrush->m_dwColor2.GetR(), pBrush->m_dwColor2.GetA()); + + BYTE* pPattern = new BYTE[HATCH_TX_SIZE * HATCH_TX_SIZE * 4]; + agg::GetHatchPattern(pBrush->m_name, (agg::rgba8*)pPattern, c1, c2); + + agg::trans_affine mtx_Work(m_oTransform.m_agg_mtx); + mtx_Work.invert(); + + span_alloc_type span_allocator; + interpolator_type_linear interpolator(mtx_Work); + + agg::rendering_buffer PatRendBuff; + PatRendBuff.attach(pPattern, HATCH_TX_SIZE, HATCH_TX_SIZE, HATCH_TX_SIZE << 2); + + typedef agg::pixfmt_bgra32 pixfmt; + //image_accessor_wrap + typedef agg::wrap_mode_repeat wrap_x_type; + typedef agg::wrap_mode_repeat wrap_y_type; + typedef agg::image_accessor_wrap img_source_type; + typedef agg::span_image_filter_rgba_bilinear span_gen_type; + typedef agg::renderer_scanline_aa renderer_type; + + pixfmt img_pixf(PatRendBuff); + img_source_type img_src(img_pixf); + span_gen_type sg(img_src, interpolator); + renderer_type ri(m_frame_buffer.ren_base(), span_allocator, sg); + + render_scanlines(ri); + + RELEASEARRAYOBJECTS(pPattern); +#endif + } + void CGraphics::DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride) { span_alloc_type span_allocator; // Span Allocator @@ -1341,7 +1417,7 @@ namespace Aggplus } else if (Brush->GetType() == BrushTypeHatchFill) { - return; + DoFillPathHatch((Aggplus::CBrushHatch*)Brush); } else if (Brush->GetType() == BrushTypeTextureFill) { diff --git a/DesktopEditor/graphics/Graphics.h b/DesktopEditor/graphics/Graphics.h index 7ee6b96eb4..dba545fe13 100644 --- a/DesktopEditor/graphics/Graphics.h +++ b/DesktopEditor/graphics/Graphics.h @@ -301,8 +301,9 @@ protected: void render_scanlines(Rasterizer& ras, Renderer& ren); void DoFillPathSolid(CColor dwColor); - void DoFillPathGradient(CBrushLinearGradient *pBrush, const agg::trans_affine* pGlobalTransform = NULL); - void DoFillPathGradient2(CBrushLinearGradient *pBrush, const agg::trans_affine* pGlobalTransform = NULL); + void DoFillPathGradient(CBrushLinearGradient *pBrush); + void DoFillPathGradient2(CBrushLinearGradient *pBrush); + void DoFillPathHatch(CBrushHatch *pBrush); void DoFillPathTextureClampSz(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride); void DoFillPathTextureClampSz2(const CMatrix &mImgMtx, const void *pImgBuff, DWORD dwImgWidth, DWORD dwImgHeight, int nImgStride); void DoFillPath(const CBrush* Brush); diff --git a/DesktopEditor/graphics/GraphicsRenderer.cpp b/DesktopEditor/graphics/GraphicsRenderer.cpp index 48e81e4cbf..7b26c35b6a 100644 --- a/DesktopEditor/graphics/GraphicsRenderer.cpp +++ b/DesktopEditor/graphics/GraphicsRenderer.cpp @@ -9,7 +9,7 @@ namespace Aggplus return NULL; LONG Type = pBrush->Type; - if ((0 == Type) || (c_BrushTypeSolid == Type) || (c_BrushTypeHatch1 <= Type && c_BrushTypeHatch53 >= Type)) + if ((0 == Type) || (c_BrushTypeSolid == Type)) { Aggplus::CColor oColor((BYTE)pBrush->Alpha1, pBrush->Color1); Aggplus::CBrushSolid* pNew = new Aggplus::CBrushSolid(oColor); @@ -69,6 +69,20 @@ namespace Aggplus return pNew; } + else if (c_BrushTypeHatch1 == Type) + { + Aggplus::CColor o1((BYTE)pBrush->Alpha1, pBrush->Color1); + Aggplus::CColor o2((BYTE)pBrush->Alpha2, pBrush->Color2); + + Aggplus::CBrushHatch* pNew = new Aggplus::CBrushHatch(); + pNew->m_dwColor1 = o1; + pNew->m_dwColor2 = o2; + pNew->m_name = pBrush->TexturePath; + + pNew->Bounds = pBrush->Bounds; + + return pNew; + } else { Aggplus::CBrushTexture* pNew = new Aggplus::CBrushTexture(pBrush->TexturePath, /*(Aggplus::WrapMode)TextureMode*/Aggplus::WrapModeClamp);