summaryrefslogtreecommitdiff
path: root/canvas/source/tools/image.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'canvas/source/tools/image.cxx')
-rw-r--r--canvas/source/tools/image.cxx2394
1 files changed, 0 insertions, 2394 deletions
diff --git a/canvas/source/tools/image.cxx b/canvas/source/tools/image.cxx
deleted file mode 100644
index 4b8a2a334873..000000000000
--- a/canvas/source/tools/image.cxx
+++ /dev/null
@@ -1,2394 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_canvas.hxx"
-
-#include <canvas/debug.hxx>
-#include <tools/diagnose_ex.h>
-
-#include <canvas/canvastools.hxx>
-#include <canvas/parametricpolypolygon.hxx>
-
-#include <com/sun/star/rendering/RepaintResult.hpp>
-#include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
-
-#include <vcl/canvastools.hxx>
-#include <vcl/bitmapex.hxx>
-#include <vcl/bmpacc.hxx>
-
-#include <basegfx/range/b2drange.hxx>
-#include <basegfx/point/b2dpoint.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
-#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
-#include <basegfx/polygon/b2dpolygontriangulator.hxx>
-#include <basegfx/polygon/b2dpolypolygontools.hxx>
-#include <basegfx/polygon/b2dpolygontools.hxx>
-#include <basegfx/polygon/b2dpolygonclipper.hxx>
-#include <basegfx/tools/canvastools.hxx>
-#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
-#include <basegfx/polygon/b2dpolygonclipper.hxx>
-
-#include "image.hxx"
-
-#define CANVAS_IMAGE_CXX
-#include "image_sysprereq.h"
-
-//////////////////////////////////////////////////////////////////////////////////
-// platform-dependend includes [wrapped into their own namepsaces]
-//////////////////////////////////////////////////////////////////////////////////
-
-#if defined(WNT)
-# if defined _MSC_VER
-# pragma warning(push,1)
-# endif
-
- namespace win32
- {
- #undef DECLARE_HANDLE
- #undef WB_LEFT
- #undef WB_RIGHT
- #undef APIENTRY
- #define WIN32_LEAN_AND_MEAN
- #define NOMINMAX
- #include <windows.h>
- }
-
-# if defined _MSC_VER
-# pragma warning(pop)
-# endif
-#elif defined(OS2)
- namespace os2
- {
- #include <svpm.h>
- }
-#else
-#if !defined(QUARTZ)
- namespace unx
- {
- #include <X11/Xlib.h>
- }
-#endif
-#endif
-
-#include <algorithm>
-
-using namespace ::com::sun::star;
-
-namespace canvas { namespace
-{
- //////////////////////////////////////////////////////////////////////////////////
- // TransAffineFromAffineMatrix
- //////////////////////////////////////////////////////////////////////////////////
-
- ::agg::trans_affine transAffineFromAffineMatrix( const geometry::AffineMatrix2D& m )
- {
- return agg::trans_affine(m.m00,
- m.m10,
- m.m01,
- m.m11,
- m.m02,
- m.m12);
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // TransAffineFromB2DHomMatrix
- //////////////////////////////////////////////////////////////////////////////////
-
- ::agg::trans_affine transAffineFromB2DHomMatrix( const ::basegfx::B2DHomMatrix& m )
- {
- return agg::trans_affine(m.get(0,0),
- m.get(1,0),
- m.get(0,1),
- m.get(1,1),
- m.get(0,2),
- m.get(1,2));
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // ARGB
- //////////////////////////////////////////////////////////////////////////////////
-
- struct ARGBColor
- {
- sal_uInt8 a;
- sal_uInt8 r;
- sal_uInt8 g;
- sal_uInt8 b;
- };
-
- /// ARGB color
- union ARGB
- {
- ARGBColor Color;
- sal_uInt32 color;
-
- ARGB() :
- color(0)
- {
- }
-
- explicit ARGB( sal_uInt32 _color ) :
- color(_color)
- {
- }
-
- ARGB( sal_uInt8 _a,
- sal_uInt8 _r,
- sal_uInt8 _g,
- sal_uInt8 _b )
- {
- Color.a = _a;
- Color.r = _r;
- Color.g = _g;
- Color.b = _b;
- }
-
- ARGB( sal_uInt32 default_color,
- const ::com::sun::star::uno::Sequence< double >& sequence ) :
- color(default_color)
- {
- if(sequence.getLength() > 2)
- {
- Color.r = static_cast<sal_uInt8>(255.0f*sequence[0]);
- Color.g = static_cast<sal_uInt8>(255.0f*sequence[1]);
- Color.b = static_cast<sal_uInt8>(255.0f*sequence[2]);
- if(sequence.getLength() > 3)
- Color.a = static_cast<sal_uInt8>(255.0f*sequence[3]);
- }
- }
-
- ARGB( const ARGB& rhs ) :
- color( rhs.color )
- {
- }
-
- ARGB &operator=( const ARGB &rhs )
- {
- color=rhs.color;
- return *this;
- }
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // setupState
- //////////////////////////////////////////////////////////////////////////////////
-
- /// Calc common output state from XCanvas parameters
- void setupState( ::basegfx::B2DHomMatrix& o_rViewTransform,
- ::basegfx::B2DHomMatrix& o_rRenderTransform,
- ::std::auto_ptr< ::basegfx::B2DPolyPolygon >& o_rViewClip,
- ::std::auto_ptr< ::basegfx::B2DPolyPolygon >& o_rRenderClip,
- ARGB& o_rRenderColor,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
- {
- ::basegfx::unotools::homMatrixFromAffineMatrix(o_rRenderTransform,
- renderState.AffineTransform);
- ::basegfx::unotools::homMatrixFromAffineMatrix(o_rViewTransform,
- viewState.AffineTransform);
-
- o_rRenderColor = ARGB(0xFFFFFFFF,
- renderState.DeviceColor);
-
- // TODO(F3): handle compositing modes
-
- if( viewState.Clip.is() )
- {
- ::basegfx::B2DPolyPolygon aViewClip(
- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( viewState.Clip ));
-
- if(aViewClip.areControlPointsUsed())
- aViewClip = ::basegfx::tools::adaptiveSubdivideByAngle(aViewClip);
-
- o_rViewClip.reset( new ::basegfx::B2DPolyPolygon( aViewClip ) );
- }
-
- if( renderState.Clip.is() )
- {
- ::basegfx::B2DPolyPolygon aRenderClip(
- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( viewState.Clip ) );
-
- if(aRenderClip.areControlPointsUsed())
- aRenderClip = ::basegfx::tools::adaptiveSubdivideByAngle(aRenderClip);
-
- o_rRenderClip.reset( new ::basegfx::B2DPolyPolygon( aRenderClip ) );
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // clipAndTransformPolygon
- //////////////////////////////////////////////////////////////////////////////////
-
- /** Clip and transform given polygon
-
- @param io_rClippee
- Polygon to clip
-
- @param bIsFilledPolyPolygon
- When true, the polygon is clipped as if it was to be rendered
- with fill, when false, the polygon is clipped as if it was to
- be rendered with stroking.
- */
- void clipAndTransformPolygon( ::basegfx::B2DPolyPolygon& io_rClippee,
- bool bIsFilledPolyPolygon,
- const ::basegfx::B2DHomMatrix& rViewTransform,
- const ::basegfx::B2DHomMatrix& rRenderTransform,
- const ::basegfx::B2DPolyPolygon* pViewClip,
- const ::basegfx::B2DPolyPolygon* pRenderClip )
- {
- ::basegfx::B2DPolyPolygon aPolyPolygon(io_rClippee);
- io_rClippee.clear();
-
- // clip contour against renderclip
- if( pRenderClip )
- {
- // AW: Simplified
- aPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
- aPolyPolygon, *pRenderClip, true, !bIsFilledPolyPolygon);
- }
-
- if( !aPolyPolygon.count() )
- return;
-
- // transform result into view space
- aPolyPolygon.transform(rRenderTransform);
-
- // clip contour against viewclip
- if( pViewClip )
- {
- // AW: Simplified
- aPolyPolygon = basegfx::tools::clipPolyPolygonOnPolyPolygon(
- aPolyPolygon, *pViewClip, true, !bIsFilledPolyPolygon);
- }
-
- if(!(aPolyPolygon.count()))
- return;
-
- // transform result into device space
- aPolyPolygon.transform(rViewTransform);
-
- io_rClippee = aPolyPolygon;
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // setupPolyPolygon
- //////////////////////////////////////////////////////////////////////////////////
-
- void setupPolyPolygon( ::basegfx::B2DPolyPolygon& io_rClippee,
- bool bIsFilledPolyPolygon,
- ARGB& o_rRenderColor,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
- {
- ::basegfx::B2DHomMatrix aViewTransform;
- ::basegfx::B2DHomMatrix aRenderTransform;
- ::std::auto_ptr< ::basegfx::B2DPolyPolygon > pViewClip;
- ::std::auto_ptr< ::basegfx::B2DPolyPolygon > pRenderClip;
-
- setupState( aViewTransform,
- aRenderTransform,
- pViewClip,
- pRenderClip,
- o_rRenderColor,
- viewState,
- renderState );
-
- clipAndTransformPolygon( io_rClippee,
- bIsFilledPolyPolygon,
- aViewTransform,
- aRenderTransform,
- pViewClip.get(),
- pRenderClip.get() );
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // RawABGRBitmap
- //////////////////////////////////////////////////////////////////////////////////
-
- // Raw ABGR [AABBGGRR] 32bit continous
- struct RawABGRBitmap
- {
- sal_Int32 mnWidth;
- sal_Int32 mnHeight;
- sal_uInt8* mpBitmapData;
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // vclBitmapEx2Raw
- //////////////////////////////////////////////////////////////////////////////////
-
- void vclBitmapEx2Raw( const ::BitmapEx& rBmpEx, RawABGRBitmap& rBmpData )
- {
- Bitmap aBitmap( rBmpEx.GetBitmap() );
-
- ScopedBitmapReadAccess pReadAccess( aBitmap.AcquireReadAccess(),
- aBitmap );
-
- const sal_Int32 nWidth( rBmpData.mnWidth );
- const sal_Int32 nHeight( rBmpData.mnHeight );
-
- ENSURE_OR_THROW( pReadAccess.get() != NULL,
- "vclBitmapEx2Raw(): "
- "Unable to acquire read acces to bitmap" );
-
- if( rBmpEx.IsTransparent())
- {
- if( rBmpEx.IsAlpha() )
- {
- // 8bit alpha mask
- Bitmap aAlpha( rBmpEx.GetAlpha().GetBitmap() );
-
- ScopedBitmapReadAccess pAlphaReadAccess( aAlpha.AcquireReadAccess(),
- aAlpha );
-
- // By convention, the access buffer always has
- // one of the following formats:
- //
- // BMP_FORMAT_1BIT_MSB_PAL
- // BMP_FORMAT_4BIT_MSN_PAL
- // BMP_FORMAT_8BIT_PAL
- // BMP_FORMAT_16BIT_TC_LSB_MASK
- // BMP_FORMAT_24BIT_TC_BGR
- // BMP_FORMAT_32BIT_TC_MASK
- //
- // and is always BMP_FORMAT_BOTTOM_UP
- //
- // This is the way
- // WinSalBitmap::AcquireBuffer() sets up the
- // buffer
-
- ENSURE_OR_THROW( pAlphaReadAccess.get() != NULL,
- "vclBitmapEx2Raw(): "
- "Unable to acquire read acces to alpha" );
-
- ENSURE_OR_THROW( pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ||
- pAlphaReadAccess->GetScanlineFormat() == BMP_FORMAT_8BIT_TC_MASK,
- "vclBitmapEx2Raw(): "
- "Unsupported alpha scanline format" );
-
- BitmapColor aCol;
- sal_uInt8* pCurrOutput( rBmpData.mpBitmapData );
- int x, y;
-
- for( y=0; y<nHeight; ++y )
- {
- switch( pReadAccess->GetScanlineFormat() )
- {
- case BMP_FORMAT_8BIT_PAL:
- {
- Scanline pScan = pReadAccess->GetScanline( y );
- Scanline pAScan = pAlphaReadAccess->GetScanline( y );
-
- for( x=0; x<nWidth; ++x )
- {
- aCol = pReadAccess->GetPaletteColor( *pScan++ );
-
- *pCurrOutput++ = aCol.GetBlue();
- *pCurrOutput++ = aCol.GetGreen();
- *pCurrOutput++ = aCol.GetRed();
-
- // out notion of alpha is
- // different from the rest
- // of the world's
- *pCurrOutput++ = 255 - (sal_uInt8)*pAScan++;
- }
- }
- break;
-
- case BMP_FORMAT_24BIT_TC_BGR:
- {
- Scanline pScan = pReadAccess->GetScanline( y );
- Scanline pAScan = pAlphaReadAccess->GetScanline( y );
-
- for( x=0; x<nWidth; ++x )
- {
- // store as RGBA
- *pCurrOutput++ = *pScan++;
- *pCurrOutput++ = *pScan++;
- *pCurrOutput++ = *pScan++;
-
- // out notion of alpha is
- // different from the rest
- // of the world's
- *pCurrOutput++ = 255 - (sal_uInt8)*pAScan++;
- }
- }
- break;
-
- // TODO(P2): Might be advantageous
- // to hand-formulate the following
- // formats, too.
- case BMP_FORMAT_1BIT_MSB_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_4BIT_MSN_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_16BIT_TC_LSB_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_MASK:
- {
- Scanline pAScan = pAlphaReadAccess->GetScanline( y );
-
- // using fallback for those
- // seldom formats
- for( x=0; x<nWidth; ++x )
- {
- // yes. x and y are swapped on Get/SetPixel
- aCol = pReadAccess->GetColor(y,x);
-
- *pCurrOutput++ = aCol.GetBlue();
- *pCurrOutput++ = aCol.GetGreen();
- *pCurrOutput++ = aCol.GetRed();
-
- // out notion of alpha is
- // different from the rest
- // of the world's
- *pCurrOutput++ = 255 - (sal_uInt8)*pAScan++;
- }
- }
- break;
-
- case BMP_FORMAT_1BIT_LSB_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_4BIT_LSN_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_8BIT_TC_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_24BIT_TC_RGB:
- // FALLTHROUGH intended
- case BMP_FORMAT_24BIT_TC_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_16BIT_TC_MSB_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_ABGR:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_ARGB:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_BGRA:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_RGBA:
- // FALLTHROUGH intended
- default:
- ENSURE_OR_THROW( false,
- "vclBitmapEx2Raw(): "
- "Unexpected scanline format - has "
- "WinSalBitmap::AcquireBuffer() changed?" );
- }
- }
- }
- else
- {
- // 1bit alpha mask
- Bitmap aMask( rBmpEx.GetMask() );
-
- ScopedBitmapReadAccess pMaskReadAccess( aMask.AcquireReadAccess(),
- aMask );
-
- // By convention, the access buffer always has
- // one of the following formats:
- //
- // BMP_FORMAT_1BIT_MSB_PAL
- // BMP_FORMAT_4BIT_MSN_PAL
- // BMP_FORMAT_8BIT_PAL
- // BMP_FORMAT_16BIT_TC_LSB_MASK
- // BMP_FORMAT_24BIT_TC_BGR
- // BMP_FORMAT_32BIT_TC_MASK
- //
- // and is always BMP_FORMAT_BOTTOM_UP
- //
- // This is the way
- // WinSalBitmap::AcquireBuffer() sets up the
- // buffer
-
- ENSURE_OR_THROW( pMaskReadAccess.get() != NULL,
- "vclBitmapEx2Raw(): "
- "Unable to acquire read acces to mask" );
-
- ENSURE_OR_THROW( pMaskReadAccess->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL,
- "vclBitmapEx2Raw(): "
- "Unsupported mask scanline format" );
-
- BitmapColor aCol;
- int nCurrBit;
- const int nMask( 1L );
- const int nInitialBit(7);
- sal_uInt32 *pBuffer = reinterpret_cast<sal_uInt32 *>(rBmpData.mpBitmapData);
- int x, y;
-
- // mapping table, to get from mask index color to
- // alpha value (which depends on the mask's palette)
- sal_uInt8 aColorMap[2];
-
- const BitmapColor& rCol0( pMaskReadAccess->GetPaletteColor( 0 ) );
- const BitmapColor& rCol1( pMaskReadAccess->GetPaletteColor( 1 ) );
-
- // shortcut for true luminance calculation
- // (assumes that palette is grey-level). Note the
- // swapped the indices here, to account for the
- // fact that VCL's notion of alpha is inverted to
- // the rest of the world's.
- aColorMap[0] = rCol1.GetRed();
- aColorMap[1] = rCol0.GetRed();
-
- for( y=0; y<nHeight; ++y )
- {
- switch( pReadAccess->GetScanlineFormat() )
- {
- case BMP_FORMAT_8BIT_PAL:
- {
- Scanline pScan = pReadAccess->GetScanline( y );
- Scanline pMScan = pMaskReadAccess->GetScanline( y );
-
- for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
- {
- aCol = pReadAccess->GetPaletteColor( *pScan++ );
-
- // RGB -> ABGR
- unsigned int color = aCol.GetRed();
- color |= aCol.GetGreen()<<8;
- color |= aCol.GetBlue()<<16;
- color |= aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ]<<24;
- *pBuffer++ = color;
- nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
- }
- }
- break;
-
- case BMP_FORMAT_24BIT_TC_BGR:
- {
- Scanline pScan = pReadAccess->GetScanline( y );
- Scanline pMScan = pMaskReadAccess->GetScanline( y );
-
- for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
- {
- // BGR -> ABGR
- unsigned int color = (*pScan++)<<16;
- color |= (*pScan++)<<8;
- color |= (*pScan++);
- color |= (aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ])<<24;
- *pBuffer++ = color;
- nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
- }
- }
- break;
-
- // TODO(P2): Might be advantageous
- // to hand-formulate the following
- // formats, too.
- case BMP_FORMAT_1BIT_MSB_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_4BIT_MSN_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_16BIT_TC_LSB_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_MASK:
- {
- Scanline pMScan = pMaskReadAccess->GetScanline( y );
-
- // using fallback for those
- // seldom formats
- for( x=0, nCurrBit=nInitialBit; x<nWidth; ++x )
- {
- // yes. x and y are swapped on Get/SetPixel
- aCol = pReadAccess->GetColor(y,x);
-
- // -> ABGR
- unsigned int color = aCol.GetBlue()<<16;
- color |= aCol.GetGreen()<<8;
- color |= aCol.GetRed();
- color |= (aColorMap[ (pMScan[ (x & ~7L) >> 3L ] >> nCurrBit ) & nMask ])<<24;
- *pBuffer++ = color;
- nCurrBit = ((nCurrBit - 1) % 8L) & 7L;
- }
- }
- break;
-
- case BMP_FORMAT_1BIT_LSB_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_4BIT_LSN_PAL:
- // FALLTHROUGH intended
- case BMP_FORMAT_8BIT_TC_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_24BIT_TC_RGB:
- // FALLTHROUGH intended
- case BMP_FORMAT_24BIT_TC_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_16BIT_TC_MSB_MASK:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_ABGR:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_ARGB:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_BGRA:
- // FALLTHROUGH intended
- case BMP_FORMAT_32BIT_TC_RGBA:
- // FALLTHROUGH intended
- default:
- ENSURE_OR_THROW( false,
- "vclBitmapEx2Raw(): "
- "Unexpected scanline format - has "
- "WinSalBitmap::AcquireBuffer() changed?" );
- }
- }
- }
- }
- else
- {
- // *no* alpha mask
- sal_uIntPtr nFormat = pReadAccess->GetScanlineFormat();
- sal_uInt8 *pBuffer = reinterpret_cast<sal_uInt8 *>(rBmpData.mpBitmapData);
-
- switch(nFormat)
- {
- case BMP_FORMAT_24BIT_TC_BGR:
-
- {
- sal_Int32 height = pReadAccess->Height();
- for(sal_Int32 y=0; y<height; ++y)
- {
- sal_uInt8 *pScanline=pReadAccess->GetScanline(y);
- sal_Int32 width = pReadAccess->Width();
- for(sal_Int32 x=0; x<width; ++x)
- {
- // BGR -> RGB
- sal_uInt8 b(*pScanline++);
- sal_uInt8 g(*pScanline++);
- sal_uInt8 r(*pScanline++);
- *pBuffer++ = r;
- *pBuffer++ = g;
- *pBuffer++ = b;
- }
- }
- }
- break;
-
- case BMP_FORMAT_24BIT_TC_RGB:
-
- {
- sal_Int32 height = pReadAccess->Height();
- for(sal_Int32 y=0; y<height; ++y)
- {
- sal_uInt8 *pScanline=pReadAccess->GetScanline(y);
- sal_Int32 width = pReadAccess->Width();
- for(sal_Int32 x=0; x<width; ++x)
- {
- // RGB -> RGB
- sal_uInt8 r(*pScanline++);
- sal_uInt8 g(*pScanline++);
- sal_uInt8 b(*pScanline++);
- *pBuffer++ = r;
- *pBuffer++ = g;
- *pBuffer++ = b;
- }
- }
- }
- break;
-
- case BMP_FORMAT_1BIT_MSB_PAL:
- case BMP_FORMAT_1BIT_LSB_PAL:
- case BMP_FORMAT_4BIT_MSN_PAL:
- case BMP_FORMAT_4BIT_LSN_PAL:
- case BMP_FORMAT_8BIT_PAL:
-
- {
- sal_Int32 height = pReadAccess->Height();
- for(sal_Int32 y=0; y<height; ++y)
- {
- sal_uInt8 *pScanline=pReadAccess->GetScanline(y);
- sal_Int32 width = pReadAccess->Width();
- for(sal_Int32 x=0; x<width; ++x)
- {
- BitmapColor aCol(pReadAccess->GetPaletteColor(*pScanline++));
-
- *pBuffer++ = aCol.GetRed();
- *pBuffer++ = aCol.GetGreen();
- *pBuffer++ = aCol.GetBlue();
- }
- }
- }
- break;
- }
- }
- }
-
- //////////////////////////////////////////////////////////////////////////////////
- // color_generator_linear
- //////////////////////////////////////////////////////////////////////////////////
-
- template<typename T> struct color_generator_linear
- {
- typedef typename T::value_type value_type;
-
- color_generator_linear( const T &c1,
- const T &c2,
- unsigned int aSteps ) : maSteps(aSteps),
- maColor1(c1),
- maColor2(c2)
- {
- }
-
- unsigned size() const { return maSteps; }
- const T operator [] (unsigned v) const
- {
- const double w = double(v)/maSteps;
- return T( static_cast<value_type>(maColor1.r+(maColor2.r-maColor1.r)*w),
- static_cast<value_type>(maColor1.g+(maColor2.g-maColor1.g)*w),
- static_cast<value_type>(maColor1.b+(maColor2.b-maColor1.b)*w),
- static_cast<value_type>(maColor1.a+(maColor2.a-maColor1.a)*w));
- }
-
- unsigned int maSteps;
- const T maColor1;
- const T maColor2;
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // color_generator_axial
- //////////////////////////////////////////////////////////////////////////////////
-
- template<typename T> struct color_generator_axial
- {
- typedef typename T::value_type value_type;
-
- color_generator_axial( const T &c1,
- const T &c2,
- unsigned int aSteps ) : maSteps(aSteps),
- maColor1(c1),
- maColor2(c2)
- {
- }
-
- unsigned size() const { return maSteps; }
- const T operator [] (unsigned v) const
- {
- const double aHalfSteps = maSteps/2.0;
- const double w = (v >= aHalfSteps) ?
- 1.0-((double(v)-aHalfSteps)/aHalfSteps) :
- (double(v)*2.0)/maSteps;
- return T( static_cast<value_type>(maColor1.r+(maColor2.r-maColor1.r)*w),
- static_cast<value_type>(maColor1.g+(maColor2.g-maColor1.g)*w),
- static_cast<value_type>(maColor1.b+(maColor2.b-maColor1.b)*w),
- static_cast<value_type>(maColor1.a+(maColor2.a-maColor1.a)*w));
- }
-
- unsigned int maSteps;
- const T maColor1;
- const T maColor2;
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // color_generator_adaptor
- //////////////////////////////////////////////////////////////////////////////////
-
- template<typename T> struct color_generator_adaptor
- {
- color_generator_adaptor( const T &c1,
- const T &c2,
- unsigned int aSteps ) : linear_generator(c1,c2,aSteps),
- axial_generator(c1,c2,aSteps),
- mbLinear(true) {}
- void set_linear( bool bLinear ) { mbLinear=bLinear; }
- unsigned size() const { return mbLinear ? linear_generator.size() : axial_generator.size(); }
- const T operator [] (unsigned v) const
- {
- return mbLinear ?
- linear_generator.operator [] (v) :
- axial_generator.operator [] (v);
- }
-
- color_generator_linear<T> linear_generator;
- color_generator_axial<T> axial_generator;
- bool mbLinear;
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // gradient_polymorphic_wrapper_base
- //////////////////////////////////////////////////////////////////////////////////
-
- struct gradient_polymorphic_wrapper_base
- {
- virtual int calculate(int x, int y, int) const = 0;
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // gradient_polymorphic_wrapper
- //////////////////////////////////////////////////////////////////////////////////
-
- template<class GradientF> struct gradient_polymorphic_wrapper :
- public gradient_polymorphic_wrapper_base
- {
- virtual int calculate(int x, int y, int d) const
- {
- return m_gradient.calculate(x, y, d);
- }
- GradientF m_gradient;
- };
-
- //////////////////////////////////////////////////////////////////////////////////
- // gradient_rect
- //////////////////////////////////////////////////////////////////////////////////
-
- class gradient_rect
- {
- public:
-
- int width;
- int height;
-
- inline int calculate(int x, int y, int d) const
- {
- int ax = abs(x);
- int ay = abs(y);
- int clamp_x = height>width ? 0 : (width-height);
- int clamp_y = height>width ? (height-width) : 0;
- int value_x = (ax-clamp_x)*d/(width-clamp_x);
- int value_y = (ay-clamp_y)*d/(height-clamp_y);
- if(ax < (clamp_x))
- value_x = 0;
- if(ay < (clamp_y))
- value_y = 0;
- return value_x > value_y ? value_x : value_y;
- }
- };
-
- sal_uInt32 getBytesPerPixel( IColorBuffer::Format eFormat )
- {
- switch(eFormat)
- {
- default:
- OSL_ENSURE(false, "Unexpected pixel format");
- // FALLTHROUGH intended
- case IColorBuffer::FMT_R8G8B8:
- return 3L;
- case IColorBuffer::FMT_A8R8G8B8:
- return 4L;
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawLinePolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-template<class pixel_format>
-void Image::drawLinePolyPolygonImpl( const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- double fStrokeWidth,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- ::basegfx::B2DPolyPolygon aPolyPolygon( rPolyPolygon );
- ARGB aRenderColor;
-
- setupPolyPolygon( aPolyPolygon, false, aRenderColor, viewState, renderState );
-
- if( !aPolyPolygon.count() )
- return;
-
- // Class template pixel_formats_rgb24 has full knowledge about this
- // particular pixel format in memory. The only template parameter
- // can be order_rgb24 or order_bgr24 that determines the order of color channels.
- //typedef agg::pixfmt_rgba32 pixel_format;
- pixel_format pixf(maRenderingBuffer);
-
- // There are two basic renderers with almost the same functionality:
- // renderer_base and renderer_mclip. The first one is used most often
- // and it performs low level clipping.
- // This simply adds clipping to the graphics buffer, the clip rect
- // will be initialized to the area of the framebuffer.
- typedef agg::renderer_base<pixel_format> renderer_base;
- agg::renderer_base<pixel_format> renb(pixf);
-
- // To draw Anti-Aliased primitives one shoud *rasterize* them first.
- // The primary rasterization technique in AGG is scanline based.
- // That is, a polygon is converted into a number of horizontal
- // scanlines and then the scanlines are being rendered one by one.
- // To transfer information from a rasterizer to the scanline renderer
- // there scanline containers are used. A scanline consists of a
- // number of horizontal, non-intersecting spans. All spans must be ordered by X.
- // --> *packed* scanline container
- agg::scanline_p8 sl;
-
- typedef agg::renderer_outline_aa<renderer_base> renderer_type;
- typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
- agg::line_profile_aa profile;
- profile.width(fStrokeWidth);
- renderer_type ren(renb, profile);
- rasterizer_type ras(ren);
-
- const agg::rgba8 fillcolor(aRenderColor.Color.r,
- aRenderColor.Color.g,
- aRenderColor.Color.b,
- aRenderColor.Color.a);
- ren.color(fillcolor);
-
- agg::path_storage path;
- agg::conv_curve<agg::path_storage> curve(path);
-
- for(sal_uInt32 nPolygon=0; nPolygon<aPolyPolygon.count(); ++nPolygon)
- {
- const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(nPolygon));
- const sal_uInt32 nPointCount(aPolygon.count());
-
- if(nPointCount)
- {
- if(aPolygon.areControlPointsUsed())
- {
- // prepare edge-based loop
- basegfx::B2DPoint aCurrentPoint(aPolygon.getB2DPoint(0));
- const sal_uInt32 nEdgeCount(aPolygon.isClosed() ? nPointCount - 1 : nPointCount);
-
- // first vertex
- path.move_to(aCurrentPoint.getX(), aCurrentPoint.getY());
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- // access next point
- const sal_uInt32 nNextIndex((a + 1) % nPointCount);
- const basegfx::B2DPoint aNextPoint(aPolygon.getB2DPoint(nNextIndex));
-
- // get control points
- const basegfx::B2DPoint aControlNext(aPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aControlPrev(aPolygon.getPrevControlPoint(nNextIndex));
-
- // specify first cp, second cp, next vertex
- path.curve4(
- aControlNext.getX(), aControlNext.getY(),
- aControlPrev.getX(), aControlPrev.getY(),
- aNextPoint.getX(), aNextPoint.getY());
-
- // prepare next step
- aCurrentPoint = aNextPoint;
- }
- }
- else
- {
- const basegfx::B2DPoint aStartPoint(aPolygon.getB2DPoint(0));
- ras.move_to_d(aStartPoint.getX(), aStartPoint.getY());
-
- for(sal_uInt32 a(1); a < nPointCount; a++)
- {
- const basegfx::B2DPoint aVertexPoint(aPolygon.getB2DPoint(a));
- ras.line_to_d(aVertexPoint.getX(), aVertexPoint.getY());
- }
-
- ras.render(aPolygon.isClosed());
- }
- }
- }
-
- ras.add_path(curve);
- ras.render(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawLinePolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::drawLinePolyPolygon( const ::basegfx::B2DPolyPolygon& rPoly,
- double fStrokeWidth,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- switch(maDesc.eFormat)
- {
- case FMT_R8G8B8:
- drawLinePolyPolygonImpl<agg::pixfmt_rgb24>(rPoly,fStrokeWidth,viewState,renderState);
- break;
- case FMT_A8R8G8B8:
- drawLinePolyPolygonImpl<agg::pixfmt_rgba32>(rPoly,fStrokeWidth,viewState,renderState);
- break;
- default:
- OSL_ENSURE(false, "Unexpected pixel format");
- break;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::implDrawBitmap
-//////////////////////////////////////////////////////////////////////////////////
-
-/** internal utility function to draw one image into another one.
- the source image will be drawn with respect to the given
- transform and clip settings.
- */
-ImageCachedPrimitiveSharedPtr Image::implDrawBitmap(
- const Image& rBitmap,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- ::basegfx::B2DPolyPolygon aPoly(
- ::basegfx::tools::createPolygonFromRect(
- ::basegfx::B2DRange(0.0, 0.0,
- rBitmap.maDesc.nWidth,
- rBitmap.maDesc.nHeight ) ) );
- ARGB aFillColor;
-
- setupPolyPolygon( aPoly, true, aFillColor, viewState, renderState );
-
- if( !aPoly.count() )
- return ImageCachedPrimitiveSharedPtr();
-
- ::basegfx::B2DHomMatrix aViewTransform;
- ::basegfx::B2DHomMatrix aRenderTransform;
- ::basegfx::B2DHomMatrix aTextureTransform;
-
- ::basegfx::unotools::homMatrixFromAffineMatrix(aRenderTransform,
- renderState.AffineTransform);
- ::basegfx::unotools::homMatrixFromAffineMatrix(aViewTransform,
- viewState.AffineTransform);
- aTextureTransform *= aRenderTransform;
-
- // TODO(F2): Fill in texture
- rendering::Texture aTexture;
-
- return fillTexturedPolyPolygon( rBitmap,
- aPoly,
- aTextureTransform,
- aViewTransform,
- aTexture );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// cachedPrimitiveFTPP [cachedPrimitive for [F]ill[T]extured[P]oly[P]olygon]
-//////////////////////////////////////////////////////////////////////////////////
-
-#if AGG_VERSION >= 2400
-template<class pixel_format_dst,class span_gen_type>
-#else
-template<class pixel_format,class span_gen_type>
-#endif
-class cachedPrimitiveFTPP : public ImageCachedPrimitive
-{
- public:
-
- cachedPrimitiveFTPP( const ::basegfx::B2DHomMatrix &rTransform,
- const ::basegfx::B2DHomMatrix &rViewTransform,
- agg::rendering_buffer &dst,
- const agg::rendering_buffer& src ) :
- aTransform(rTransform),
- inter(tm),
- filter(filter_kernel),
-#if AGG_VERSION >= 2400
- pixs(const_cast<agg::rendering_buffer&>(src)),
- source(pixs),
- sg(source,inter,filter),
- pixd(dst),
- rb(pixd),
- ren(rb,sa,sg)
-#else
- sg(sa,src,inter,filter),
- pixf(dst),
- rb(pixf),
- ren(rb,sg)
-#endif
- {
- ::basegfx::B2DHomMatrix aFinalTransform(aTransform);
- aFinalTransform *= rViewTransform;
- tm = transAffineFromB2DHomMatrix(aFinalTransform);
- tm.invert();
- }
-
- virtual void setImage( const ::boost::shared_ptr< class Image >& rTargetImage )
- {
- pImage=rTargetImage;
- }
-
- virtual sal_Int8 redraw( const ::com::sun::star::rendering::ViewState& aState ) const
- {
- ::basegfx::B2DHomMatrix aViewTransform;
- ::basegfx::unotools::homMatrixFromAffineMatrix(aViewTransform,aState.AffineTransform);
- ::basegfx::B2DHomMatrix aFinalTransform(aTransform);
- aFinalTransform *= aViewTransform;
- tm = transAffineFromB2DHomMatrix(aFinalTransform);
- tm.invert();
- redraw();
- return ::com::sun::star::rendering::RepaintResult::REDRAWN;
- }
-
- inline void redraw() const { agg::render_scanlines(ras, sl, ren); }
-
- mutable agg::rasterizer_scanline_aa<> ras;
-
- private:
-
- typedef agg::span_interpolator_linear<> interpolator_type;
-#if AGG_VERSION >= 2400
- typedef agg::renderer_base<pixel_format_dst> renderer_base;
- typedef agg::span_allocator< typename span_gen_type::color_type > span_alloc_type;
- typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type;
- typedef typename span_gen_type::source_type source_type;
- typedef typename span_gen_type::source_type::pixfmt_type pixel_format_src;
-#else
- typedef agg::renderer_base<pixel_format> renderer_base;
- typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type;
-#endif
-
- ::basegfx::B2DHomMatrix aTransform;
- interpolator_type inter;
- agg::image_filter_bilinear filter_kernel;
- agg::image_filter_lut filter;
-#if AGG_VERSION >= 2400
- span_alloc_type sa;
- pixel_format_src pixs;
- source_type source;
-#else
- agg::span_allocator< typename span_gen_type::color_type > sa;
-#endif
- span_gen_type sg;
-#if AGG_VERSION >= 2400
- pixel_format_dst pixd;
-#else
- pixel_format pixf;
-#endif
- renderer_base rb;
- mutable renderer_type ren;
- mutable agg::scanline_p8 sl;
- mutable agg::trans_affine tm;
- ImageSharedPtr pImage;
-};
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillTexturedPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-template<class pixel_format,class span_gen_type>
-ImageCachedPrimitiveSharedPtr Image::fillTexturedPolyPolygonImpl(
- const Image& rTexture,
- const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- const ::basegfx::B2DHomMatrix& rOverallTransform,
- const ::basegfx::B2DHomMatrix& rViewTransform,
- const rendering::Texture& )
-{
- // calculate final overall transform.
- ::basegfx::B2DHomMatrix aOverallTransform(rOverallTransform);
- aOverallTransform *= rViewTransform;
-
- // instead of always using the full-blown solution we
- // first check to see if this is a simple rectangular
- // 1-to-1 copy from source to destination image.
- ::basegfx::B2DTuple aTranslate(aOverallTransform.get(0,2),aOverallTransform.get(1,2));
- ::basegfx::B2DTuple aSize(rTexture.maDesc.nWidth,rTexture.maDesc.nHeight);
- ::basegfx::B2DRange aRange(aTranslate,aTranslate+aSize);
- ::basegfx::B2DPolyPolygon aPolyPolygon(rPolyPolygon);
- aPolyPolygon.transform(aOverallTransform);
- if(::basegfx::tools::isPolyPolygonEqualRectangle(aPolyPolygon,aRange))
- {
- // yes, we can take the shortcut.
- // but we need to clip the destination rectangle
- // against the boundary of the destination image.
- sal_Int32 dwSrcX(0);
- sal_Int32 dwSrcY(0);
- sal_Int32 dwDstX(static_cast<sal_Int32>(aTranslate.getX()));
- sal_Int32 dwDstY(static_cast<sal_Int32>(aTranslate.getY()));
- sal_Int32 dwWidth(rTexture.maDesc.nWidth);
- sal_Int32 dwHeight(rTexture.maDesc.nHeight);
-
- // prevent fast copy if destination position is not an
- // integer coordinate. otherwise we would most probably
- // introduce visual glitches while combining this with
- // high-accuracy rendering stuff.
- if( ::basegfx::fTools::equalZero(aTranslate.getX()-dwDstX) &&
- ::basegfx::fTools::equalZero(aTranslate.getY()-dwDstY))
- {
- // clip against destination boundary. shrink size if
- // necessary, modify destination position if we need to.
- if(dwDstX < 0) { dwWidth-=dwDstX; dwSrcX=-dwDstX; dwDstX=0; }
- if(dwDstY < 0) { dwHeight-=dwDstY; dwSrcY=-dwDstY; dwDstY=0; }
- const sal_Int32 dwRight(dwDstX+dwWidth);
- const sal_Int32 dwBottom(dwDstY+dwHeight);
- if(dwRight > dwWidth)
- dwWidth -= dwRight-dwWidth;
- if(dwBottom > dwHeight)
- dwHeight -= dwBottom-dwHeight;
-
- // calculate source buffer
- const Description &srcDesc = rTexture.maDesc;
- const sal_uInt32 dwSrcBytesPerPixel(getBytesPerPixel(srcDesc.eFormat));
- const sal_uInt32 dwSrcPitch(srcDesc.nWidth*dwSrcBytesPerPixel+srcDesc.nStride);
- sal_uInt8 *pSrcBuffer = rTexture.maDesc.pBuffer+(dwSrcPitch*dwSrcX)+(dwSrcBytesPerPixel*dwSrcY);
-
- // calculate destination buffer
- const Description &dstDesc = maDesc;
- const sal_uInt32 dwDstBytesPerPixel(getBytesPerPixel(dstDesc.eFormat));
- const sal_uInt32 dwDstPitch(dstDesc.nWidth*dwDstBytesPerPixel+dstDesc.nStride);
- sal_uInt8 *pDstBuffer = maDesc.pBuffer+(dwDstPitch*dwDstY)+(dwDstBytesPerPixel*dwDstX);
-
- // if source and destination format match, we can simply
- // copy whole scanlines.
- if(srcDesc.eFormat == dstDesc.eFormat)
- {
- const sal_Size dwNumBytesPerScanline(dwSrcBytesPerPixel*dwWidth);
- for(sal_Int32 y=0; y<dwHeight; ++y)
- {
- rtl_copyMemory(pDstBuffer,pSrcBuffer,dwNumBytesPerScanline);
- pSrcBuffer += dwSrcPitch;
- pDstBuffer += dwDstPitch;
- }
- }
- else
- {
- // otherwise [formats do not match], we need to copy
- // each pixel one by one and convert from source to destination format.
- if(srcDesc.eFormat == FMT_A8R8G8B8 && dstDesc.eFormat == FMT_R8G8B8)
- {
- for(sal_Int32 y=0; y<dwHeight; ++y)
- {
- sal_uInt8 *pSrc=pSrcBuffer;
- sal_uInt8 *pDst=pDstBuffer;
- for(sal_Int32 x=0; x<dwWidth; ++x)
- {
- sal_uInt8 r(*pSrc++);
- sal_uInt8 g(*pSrc++);
- sal_uInt8 b(*pSrc++);
- sal_uInt8 Alpha(*pSrc++);
- sal_uInt8 OneMinusAlpha(0xFF-Alpha);
- *pDst=(((r*Alpha)+((*pDst)*OneMinusAlpha))/0xFF);
- ++pDst;
- *pDst=(((g*Alpha)+((*pDst)*OneMinusAlpha))/0xFF);
- ++pDst;
- *pDst=(((b*Alpha)+((*pDst)*OneMinusAlpha))/0xFF);
- ++pDst;
- }
- pSrcBuffer += dwSrcPitch;
- pDstBuffer += dwDstPitch;
- }
- }
- else if(srcDesc.eFormat == FMT_R8G8B8 && dstDesc.eFormat == FMT_A8R8G8B8)
- {
- for(sal_Int32 y=0; y<dwHeight; ++y)
- {
- sal_uInt8 *pSrc=pSrcBuffer;
- sal_uInt8 *pDst=pDstBuffer;
- for(sal_Int32 x=0; x<dwWidth; ++x)
- {
- sal_uInt8 r(*pSrc++);
- sal_uInt8 g(*pSrc++);
- sal_uInt8 b(*pSrc++);
- *pDst++=r;
- *pDst++=g;
- *pDst++=b;
- *pDst++=0xFF;
- }
- pSrcBuffer += dwSrcPitch;
- pDstBuffer += dwDstPitch;
- }
- }
- }
-
- return ImageCachedPrimitiveSharedPtr();
- }
- }
-
- typedef cachedPrimitiveFTPP<pixel_format,span_gen_type> cachedPrimitive_t;
- cachedPrimitive_t *pPrimitive = new cachedPrimitive_t( rOverallTransform,
- rViewTransform,
- maRenderingBuffer,
- rTexture.maRenderingBuffer);
-
- agg::path_storage path;
- agg::conv_curve<agg::path_storage> curve(path);
-
- for(sal_uInt32 nPolygon(0); nPolygon < rPolyPolygon.count(); nPolygon++)
- {
- const basegfx::B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(nPolygon));
- const sal_uInt32 nPointCount(aPolygon.count());
-
- if(nPointCount)
- {
- if(aPolygon.areControlPointsUsed())
- {
- // prepare edge-based loop
- basegfx::B2DPoint aCurrentPoint(aPolygon.getB2DPoint(0));
- const sal_uInt32 nEdgeCount(aPolygon.isClosed() ? nPointCount - 1 : nPointCount);
-
- // first vertex
- path.move_to(aCurrentPoint.getX(), aCurrentPoint.getY());
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- // access next point
- const sal_uInt32 nNextIndex((a + 1) % nPointCount);
- const basegfx::B2DPoint aNextPoint(aPolygon.getB2DPoint(nNextIndex));
-
- // get control points
- const basegfx::B2DPoint aControlNext(aPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aControlPrev(aPolygon.getPrevControlPoint(nNextIndex));
-
- // specify first cp, second cp, next vertex
- path.curve4(
- aControlNext.getX(), aControlNext.getY(),
- aControlPrev.getX(), aControlPrev.getY(),
- aNextPoint.getX(), aNextPoint.getY());
-
- // prepare next step
- aCurrentPoint = aNextPoint;
- }
- }
- else
- {
- const basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(0));
- pPrimitive->ras.move_to_d(aPoint.getX(), aPoint.getY());
-
- for(sal_uInt32 a(1); a < nPointCount; a++)
- {
- const basegfx::B2DPoint aVertexPoint(aPolygon.getB2DPoint(a));
- pPrimitive->ras.line_to_d(aVertexPoint.getX(), aVertexPoint.getY());
- }
-
- if(aPolygon.isClosed())
- {
- pPrimitive->ras.close_polygon();
- }
- }
- }
- }
-
- pPrimitive->ras.add_path(curve);
- pPrimitive->redraw();
-
- return ImageCachedPrimitiveSharedPtr(pPrimitive);
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillTexturedPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::fillTexturedPolyPolygon(
- const Image& rTexture,
- const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- const ::basegfx::B2DHomMatrix& rOverallTransform,
- const ::basegfx::B2DHomMatrix& rViewTransform,
- const rendering::Texture& texture )
-{
- typedef agg::wrap_mode_repeat wrap_x_type;
- typedef agg::wrap_mode_repeat wrap_y_type;
- typedef agg::pixfmt_rgb24 pixfmt_rgb24;
- typedef agg::pixfmt_rgba32 pixfmt_rgba32;
-#if AGG_VERSION >= 2400
- typedef agg::image_accessor_wrap< pixfmt_rgba32, wrap_x_type, wrap_y_type > img_source_type_rgba;
- typedef agg::image_accessor_wrap< pixfmt_rgb24, wrap_x_type, wrap_y_type > img_source_type_rgb;
-
- typedef agg::span_image_resample_rgba_affine< img_source_type_rgba > span_gen_type_rgba;
- typedef agg::span_image_resample_rgb_affine< img_source_type_rgb > span_gen_type_rgb;
-#else
- typedef agg::span_pattern_resample_rgba_affine< pixfmt_rgba32::color_type,
- pixfmt_rgba32::order_type,
- wrap_x_type,
- wrap_y_type> span_gen_type_rgba;
- typedef agg::span_pattern_resample_rgb_affine< pixfmt_rgb24::color_type,
- pixfmt_rgb24::order_type,
- wrap_x_type,
- wrap_y_type> span_gen_type_rgb;
-#endif
-
- const Format nDest = maDesc.eFormat;
- const Format nSource = rTexture.maDesc.eFormat;
-
- if(nDest == FMT_R8G8B8 && nSource == FMT_R8G8B8)
- {
- return fillTexturedPolyPolygonImpl< agg::pixfmt_rgb24,
- span_gen_type_rgb >(
- rTexture,
- rPolyPolygon,
- rOverallTransform,
- rViewTransform,
- texture );
- }
- else if(nDest == FMT_R8G8B8 && nSource == FMT_A8R8G8B8)
- {
- return fillTexturedPolyPolygonImpl< agg::pixfmt_rgb24,
- span_gen_type_rgba >(
- rTexture,
- rPolyPolygon,
- rOverallTransform,
- rViewTransform,
- texture );
- }
- else if(nDest == FMT_A8R8G8B8 && nSource == FMT_R8G8B8)
- {
- return fillTexturedPolyPolygonImpl< agg::pixfmt_rgba32,
- span_gen_type_rgb >(
- rTexture,
- rPolyPolygon,
- rOverallTransform,
- rViewTransform,
- texture );
- }
- else if(nDest == FMT_A8R8G8B8 && nSource == FMT_A8R8G8B8)
- {
- return fillTexturedPolyPolygonImpl< agg::pixfmt_rgba32,
- span_gen_type_rgba >(
- rTexture,
- rPolyPolygon,
- rOverallTransform,
- rViewTransform,
- texture );
- }
- else
- {
- OSL_ENSURE(false, "Unexpected pixel format");
- }
-
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillGradient
-//////////////////////////////////////////////////////////////////////////////////
-
-template<class pixel_format>
-void Image::fillGradientImpl( const ParametricPolyPolygon::Values& rValues,
- const uno::Sequence< double >& rUnoColor1,
- const uno::Sequence< double >& rUnoColor2,
- const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- const ::basegfx::B2DHomMatrix& rOverallTransform,
- const rendering::Texture& )
-{
- const ARGB aColor1(0xFFFFFFFF,
- rUnoColor1);
- const ARGB aColor2(0xFFFFFFFF,
- rUnoColor2);
-
- // first of all we need to provide the framebuffer we want to render to.
- // the properties of the framebuffer are
- // 1) memory & layout [width, height, stride]
- // 2) pixelformat
- // 3) clipping
-
- // Class template pixel_formats_rgb24 has full knowledge about this
- // particular pixel format in memory. The only template parameter
- // can be order_rgb24 or order_bgr24 that determines the order of color channels.
- pixel_format pixf(maRenderingBuffer);
-
- // There are two basic renderers with almost the same functionality:
- // renderer_base and renderer_mclip. The first one is used most often
- // and it performs low level clipping.
- // This simply adds clipping to the graphics buffer, the clip rect
- // will be initialized to the area of the framebuffer.
- typedef agg::renderer_base<pixel_format> renderer_base;
- renderer_base rb(pixf);
-
- // bounding rectangle of untransformed polypolygon
- const ::basegfx::B2DRange& rBounds(::basegfx::tools::getRange(rPolyPolygon));
-
- // the color generator produces a specific color from
- // some given interpolation value.
- // number of steps for color interpolation
- typedef typename pixel_format::color_type color_type;
- color_type color1(agg::rgba8(aColor1.Color.r,
- aColor1.Color.g,
- aColor1.Color.b,
- 255));
- color_type color2(agg::rgba8(aColor2.Color.r,
- aColor2.Color.g,
- aColor2.Color.b,
- 255));
- typedef color_generator_adaptor<color_type> color_generator_type;
- unsigned int dwNumSteps = static_cast<unsigned int>(rBounds.getWidth());
- color_generator_type colors(color1,color2,dwNumSteps);
- colors.set_linear(true);
-
- // color = f(x,y)
- gradient_polymorphic_wrapper<agg::gradient_x> gf_x;
- gradient_polymorphic_wrapper<agg::gradient_radial> gf_radial;
- gradient_polymorphic_wrapper<gradient_rect> gf_rectangular;
- gf_rectangular.m_gradient.width = static_cast<int>(rBounds.getWidth())<<4;
- gf_rectangular.m_gradient.height = static_cast<int>(rBounds.getHeight())<<4;
- const gradient_polymorphic_wrapper_base *gf[] = { &gf_x, // GRADIENT_LINEAR
- &gf_x, // GRADIENT_AXIAL
- &gf_radial, // GRADIENT_ELLIPTICAL
- &gf_rectangular // GRADIENT_RECTANGULAR
- };
-
- // how do texture coordinates change when the pixel coordinate change?
- typedef agg::span_interpolator_linear<> interpolator_type;
- agg::trans_affine tm;
- tm *= agg::trans_affine_scaling(1.0f/rBounds.getWidth(),
- 1.0f/rBounds.getHeight());
- if(rValues.meType == ParametricPolyPolygon::GRADIENT_ELLIPTICAL ||
- rValues.meType == ParametricPolyPolygon::GRADIENT_RECTANGULAR)
- {
- //tm *= trans_affine_scaling(mnAspectRatio,+1.0f);
- //const double fAspect = aBounds.getWidth()/aBounds.getHeight();
- //tm *= trans_affine_scaling(+0.5f,+0.5f*(1.0f/fAspect));
- //tm *= trans_affine_translation(+0.5f,+0.5f);
- tm *= agg::trans_affine_scaling(+0.5f,+0.5f);
- tm *= agg::trans_affine_translation(+0.5f,+0.5f);
- }
- tm *= transAffineFromB2DHomMatrix(rOverallTransform);
- tm.invert();
- interpolator_type inter(tm);
-
- // spanline allocators reserve memory for the color values
- // filled up by the spanline generators.
- typedef agg::span_allocator<color_type> gradient_span_alloc;
- gradient_span_alloc span_alloc;
-
- // scanline generators create the actual color values for
- // some specific coordinate range of a scanline.
- typedef agg::span_gradient<color_type,
- interpolator_type,
- gradient_polymorphic_wrapper_base,
- color_generator_type > gradient_span_gen;
-#if AGG_VERSION >= 2400
- gradient_span_gen span_gen(inter,
- *gf[rValues.meType],
- colors,
- 0,
- dwNumSteps);
-#else
- gradient_span_gen span_gen(span_alloc,
- inter,
- *gf[rValues.meType],
- colors,
- 0,
- dwNumSteps);
-#endif
-
- // To draw Anti-Aliased primitives one shoud *rasterize* them first.
- // The primary rasterization technique in AGG is scanline based.
- // That is, a polygon is converted into a number of horizontal
- // scanlines and then the scanlines are being rendered one by one.
- // To transfer information from a rasterizer to the scanline renderer
- // there scanline containers are used. A scanline consists of a
- // number of horizontal, non-intersecting spans. All spans must be ordered by X.
- // --> packed scanline container
- agg::scanline_p8 sl;
-
- // antialiased scanline renderer with pattern filling capability
- // [in contrast to solid renderers, that is]
- // the instance of this particular renderer combines the
- // renderbuffer [i.e. destination] and the spanline generator [i.e. source]
-#if AGG_VERSION >= 2400
- typedef agg::renderer_scanline_aa<renderer_base, gradient_span_alloc, gradient_span_gen> renderer_gradient;
- renderer_gradient r1(rb, span_alloc, span_gen);
-#else
- typedef agg::renderer_scanline_aa<renderer_base, gradient_span_gen> renderer_gradient;
- renderer_gradient r1(rb, span_gen);
-#endif
-
- // instantiate the rasterizer and feed the incoming polypolygon.
- agg::rasterizer_scanline_aa<> ras;
- agg::path_storage path;
- agg::conv_curve<agg::path_storage> curve(path);
-
- for(sal_uInt32 nPolygon(0); nPolygon < rPolyPolygon.count(); nPolygon++)
- {
- const basegfx::B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(nPolygon));
- const sal_uInt32 nPointCount(aPolygon.count());
-
- if(nPointCount)
- {
- if(aPolygon.areControlPointsUsed())
- {
- // prepare edge-based loop
- basegfx::B2DPoint aCurrentPoint(aPolygon.getB2DPoint(0));
- const sal_uInt32 nEdgeCount(aPolygon.isClosed() ? nPointCount - 1 : nPointCount);
-
- // first vertex
- path.move_to(aCurrentPoint.getX(), aCurrentPoint.getY());
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- // access next point
- const sal_uInt32 nNextIndex((a + 1) % nPointCount);
- const basegfx::B2DPoint aNextPoint(aPolygon.getB2DPoint(nNextIndex));
-
- // get control points
- const basegfx::B2DPoint aControlNext(aPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aControlPrev(aPolygon.getPrevControlPoint(nNextIndex));
-
- // specify first cp, second cp, next vertex
- path.curve4(
- aControlNext.getX(), aControlNext.getY(),
- aControlPrev.getX(), aControlPrev.getY(),
- aNextPoint.getX(), aNextPoint.getY());
-
- // prepare next step
- aCurrentPoint = aNextPoint;
- }
- }
- else
- {
- const basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(0));
- ras.move_to_d(aPoint.getX(), aPoint.getY());
-
- for(sal_uInt32 a(1); a < nPointCount; a++)
- {
- const basegfx::B2DPoint aVertexPoint(aPolygon.getB2DPoint(a));
- ras.line_to_d(aVertexPoint.getX(), aVertexPoint.getY());
- }
-
- if(aPolygon.isClosed())
- {
- ras.close_polygon();
- }
- }
- }
- }
-
- // everything is up and running, go...
- ras.add_path(curve);
- render_scanlines(ras,sl,r1);
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillGradient
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::fillGradient( const ParametricPolyPolygon::Values& rValues,
- const uno::Sequence< double >& rUnoColor1,
- const uno::Sequence< double >& rUnoColor2,
- const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- const ::basegfx::B2DHomMatrix& rOverallTransform,
- const rendering::Texture& texture )
-{
- switch(maDesc.eFormat)
- {
- case FMT_R8G8B8:
- fillGradientImpl<agg::pixfmt_rgb24>(rValues,rUnoColor1,rUnoColor2,rPolyPolygon,rOverallTransform,texture);
- break;
- case FMT_A8R8G8B8:
- fillGradientImpl<agg::pixfmt_rgba32>(rValues,rUnoColor1,rUnoColor2,rPolyPolygon,rOverallTransform,texture);
- break;
- default:
- OSL_ENSURE(false, "Unexpected pixel format");
- break;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fromVCLBitmap
-//////////////////////////////////////////////////////////////////////////////////
-
-bool Image::fromVCLBitmap( ::BitmapEx& rBmpEx )
-{
- const ::Size aBmpSize( rBmpEx.GetSizePixel() );
- Image::Description desc;
- desc.eFormat = rBmpEx.IsTransparent() ? FMT_A8R8G8B8 : FMT_R8G8B8;
- desc.nWidth = aBmpSize.Width();
- desc.nHeight = aBmpSize.Height();
- desc.nStride = 0;
- const sal_uInt32 nPitch(desc.nWidth*getBytesPerPixel(desc.eFormat)+desc.nStride);
- desc.pBuffer = new sal_uInt8 [nPitch*desc.nHeight];
- maDesc = desc;
- mbBufferHasUserOwnership = false;
- maRenderingBuffer.attach(static_cast<agg::int8u *>(desc.pBuffer),
- desc.nWidth,
- desc.nHeight,
- nPitch);
- RawABGRBitmap aBmpData;
- aBmpData.mnWidth = aBmpSize.Width();
- aBmpData.mnHeight = aBmpSize.Height();
- aBmpData.mpBitmapData = static_cast<sal_uInt8 *>(desc.pBuffer);
- vclBitmapEx2Raw(rBmpEx,aBmpData);
-
- return true;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::Image
-//////////////////////////////////////////////////////////////////////////////////
-
-Image::Image( const Description& rDesc ) :
- maDesc( rDesc ),
- maRenderingBuffer(),
- mbBufferHasUserOwnership( rDesc.pBuffer != NULL )
-{
-#if defined(PROFILER)
- for(int i=0; i<TIMER_MAX; ++i)
- maElapsedTime[i]=0.0;
-#endif
-
- // allocate own buffer memory, if not provided
- sal_uInt8* pBuffer = maDesc.pBuffer;
- const sal_uInt32 nWidth(maDesc.nWidth);
- const sal_uInt32 nHeight(maDesc.nHeight);
- const sal_uInt32 nStride(maDesc.nStride);
- const sal_uInt32 nPitch(nWidth*getBytesPerPixel(maDesc.eFormat)
- + nStride);
-
- if( !pBuffer )
- pBuffer = new sal_uInt8 [nPitch*nHeight];
-
- maDesc.pBuffer = pBuffer;
-
- // attach graphics buffer
- maRenderingBuffer.attach(
- static_cast<agg::int8u *>(pBuffer),
- nWidth,
- nHeight,
- nPitch );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::Image
-//////////////////////////////////////////////////////////////////////////////////
-
-Image::Image( const uno::Reference< rendering::XBitmap >& xBitmap ) :
- maDesc(),
- maRenderingBuffer(),
- mbBufferHasUserOwnership( false )
-{
-#if defined(PROFILER)
- for(int i=0; i<TIMER_MAX; ++i)
- maElapsedTime[i]=0.0;
-#endif
-
- // TODO(F1): Add support for floating point bitmap formats
- uno::Reference<rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap,
- uno::UNO_QUERY_THROW);
- ::BitmapEx aBmpEx = ::vcl::unotools::bitmapExFromXBitmap(xIntBmp);
- if( !!aBmpEx )
- fromVCLBitmap(aBmpEx);
-
- // TODO(F2): Fallback to XIntegerBitmap interface for import
- OSL_ENSURE(false,
- "Image::Image(): Cannot retrieve bitmap data!" );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::~Image
-//////////////////////////////////////////////////////////////////////////////////
-
-Image::~Image()
-{
-#if defined(PROFILER)
-
- double aAccumulatedTime(0.0);
- for(int i=0; i<TIMER_MAX; ++i)
- aAccumulatedTime += maElapsedTime[i];
-
- OSL_TRACE("Image %d - %d %d %d %d %d\n",(int)(aAccumulatedTime*1000.0),
- (int)(maElapsedTime[TIMER_FILLTEXTUREDPOLYPOLYGON]*1000.0),
- (int)(maElapsedTime[TIMER_FILLB2DPOLYPOLYGON]*1000.0),
- (int)(maElapsedTime[TIMER_DRAWPOLYPOLYGON]*1000.0),
- (int)(maElapsedTime[TIMER_FILLPOLYPOLYGON]*1000.0),
- (int)(maElapsedTime[TIMER_DRAWBITMAP]*1000.0));
-
-#endif
-
- if( !mbBufferHasUserOwnership )
- delete [] maDesc.pBuffer;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::clear
-//////////////////////////////////////////////////////////////////////////////////
-
-template<class pixel_format>
-void Image::clearImpl( sal_uInt8 a,
- sal_uInt8 r,
- sal_uInt8 g,
- sal_uInt8 b )
-{
- pixel_format pixf(maRenderingBuffer);
- agg::renderer_base<pixel_format> renb(pixf);
-
- renb.clear(agg::rgba8(r,g,b,a));
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::clear
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::clear( sal_uInt8 a,
- sal_uInt8 r,
- sal_uInt8 g,
- sal_uInt8 b )
-{
- switch(maDesc.eFormat)
- {
- case FMT_R8G8B8:
- return clearImpl<agg::pixfmt_rgb24>(a,r,g,b);
- case FMT_A8R8G8B8:
- return clearImpl<agg::pixfmt_rgba32>(a,r,g,b);
- default:
- OSL_ENSURE(false, "Unexpected pixel format");
- break;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillB2DPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::fillB2DPolyPolygon(
- const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
-#if defined(PROFILER)
- ScopeTimer aTimer(TIMER_FILLB2DPOLYPOLYGON,this);
-#endif
-
- switch(maDesc.eFormat)
- {
- case FMT_R8G8B8:
- fillPolyPolygonImpl<agg::pixfmt_rgb24>(rPolyPolygon,viewState,renderState);
- break;
- case FMT_A8R8G8B8:
- fillPolyPolygonImpl<agg::pixfmt_rgba32>(rPolyPolygon,viewState,renderState);
- break;
- default:
- OSL_ENSURE(false, "Unexpected pixel format");
- break;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::lock
-//////////////////////////////////////////////////////////////////////////////////
-
-sal_uInt8* Image::lock() const
-{
- return maDesc.pBuffer;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::unlock
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::unlock() const
-{
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::getWidth
-//////////////////////////////////////////////////////////////////////////////////
-
-sal_uInt32 Image::getWidth() const
-{
- return maDesc.nWidth;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::getHeight
-//////////////////////////////////////////////////////////////////////////////////
-
-sal_uInt32 Image::getHeight() const
-{
- return maDesc.nHeight;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::getStride
-//////////////////////////////////////////////////////////////////////////////////
-
-sal_uInt32 Image::getStride() const
-{
- return maDesc.nWidth*getBytesPerPixel(maDesc.eFormat)+maDesc.nStride;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::getFormat
-//////////////////////////////////////////////////////////////////////////////////
-
-IColorBuffer::Format Image::getFormat() const
-{
- return maDesc.eFormat;
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawPoint
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::drawPoint( const geometry::RealPoint2D& /*aPoint*/,
- const rendering::ViewState& /*viewState*/,
- const rendering::RenderState& /*renderState*/ )
-{
- OSL_ENSURE(false,
- "Image::drawPoint(): NYI" );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawLine
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::drawLine( const geometry::RealPoint2D& aStartPoint,
- const geometry::RealPoint2D& aEndPoint,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- ::basegfx::B2DPolygon aLinePoly;
- aLinePoly.append(
- ::basegfx::unotools::b2DPointFromRealPoint2D( aStartPoint ) );
- aLinePoly.append(
- ::basegfx::unotools::b2DPointFromRealPoint2D( aEndPoint ) );
-
- drawLinePolyPolygon( ::basegfx::B2DPolyPolygon( aLinePoly ),
- 1.0,
- viewState,
- renderState );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawBezier
-//////////////////////////////////////////////////////////////////////////////////
-
-void Image::drawBezier( const geometry::RealBezierSegment2D& aBezierSegment,
- const geometry::RealPoint2D& aEndPoint,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- basegfx::B2DPolygon aBezierPoly;
-
- aBezierPoly.append(basegfx::B2DPoint(aBezierSegment.Px, aBezierSegment.Py));
- aBezierPoly.appendBezierSegment(
- basegfx::B2DPoint(aBezierSegment.C1x, aBezierSegment.C1y),
- basegfx::B2DPoint(aBezierSegment.C2x, aBezierSegment.C2y),
- basegfx::unotools::b2DPointFromRealPoint2D(aEndPoint));
-
- drawLinePolyPolygon( ::basegfx::B2DPolyPolygon( aBezierPoly ),
- 1.0,
- viewState,
- renderState );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::drawPolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
-#if defined(PROFILER)
- ScopeTimer aTimer(TIMER_DRAWPOLYPOLYGON,this);
-#endif
-
- if( !xPolyPolygon.is() )
- return ImageCachedPrimitiveSharedPtr();
-
- drawLinePolyPolygon( ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( xPolyPolygon ),
- 1.0,
- viewState,
- renderState );
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::strokePolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::strokePolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState,
- const rendering::StrokeAttributes& strokeAttributes )
-{
- if( !xPolyPolygon.is() )
- return ImageCachedPrimitiveSharedPtr();
-
- drawLinePolyPolygon( ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( xPolyPolygon ),
- strokeAttributes.StrokeWidth,
- viewState,
- renderState );
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::strokeTexturedPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::strokeTexturedPolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
- const rendering::ViewState& /*viewState*/,
- const rendering::RenderState& /*renderState*/,
- const uno::Sequence< rendering::Texture >& /*textures*/,
- const ::std::vector< ::boost::shared_ptr<Image> >& /*textureAnnotations*/,
- const rendering::StrokeAttributes& /*strokeAttributes*/ )
-{
- OSL_ENSURE(false,
- "Image::strokeTexturedPolyPolygon(): NYI" );
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::strokeTextureMappedPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::strokeTextureMappedPolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
- const rendering::ViewState& /*viewState*/,
- const rendering::RenderState& /*renderState*/,
- const uno::Sequence< rendering::Texture >& /*textures*/,
- const ::std::vector< ::boost::shared_ptr<Image> >& /*textureAnnotations*/,
- const uno::Reference< geometry::XMapping2D >& /*xMapping*/,
- const rendering::StrokeAttributes& /*strokeAttributes*/ )
-{
- OSL_ENSURE(false,
- "Image::strokeTextureMappedPolyPolygon(): NYI" );
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-template<class pixel_format>
-ImageCachedPrimitiveSharedPtr Image::fillPolyPolygonImpl(
- const ::basegfx::B2DPolyPolygon& rPolyPolygon,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
-#if defined(PROFILER)
- ScopeTimer aTimer(TIMER_FILLPOLYPOLYGON,this);
-#endif
-
- ARGB aFillColor;
-
- ::basegfx::B2DPolyPolygon aPolyPolygon(rPolyPolygon);
- setupPolyPolygon( aPolyPolygon, true, aFillColor, viewState, renderState );
-
- if( !aPolyPolygon.count() )
- return ImageCachedPrimitiveSharedPtr();
-
- pixel_format pixf(maRenderingBuffer);
- agg::renderer_base<pixel_format> renb(pixf);
-
- // Scanline renderer for solid filling.
- agg::renderer_scanline_aa_solid<agg::renderer_base<pixel_format> > ren(renb);
-
- // Rasterizer & scanline
- agg::rasterizer_scanline_aa<> ras;
- agg::scanline_p8 sl;
-
- agg::path_storage path;
- agg::conv_curve<agg::path_storage> curve(path);
-
- for(sal_uInt32 nPolygon(0); nPolygon < aPolyPolygon.count(); nPolygon++)
- {
- const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(nPolygon));
- const sal_uInt32 nPointCount(aPolygon.count());
-
- if(nPointCount)
- {
- if(aPolygon.areControlPointsUsed())
- {
- // prepare edge-based loop
- basegfx::B2DPoint aCurrentPoint(aPolygon.getB2DPoint(0));
- const sal_uInt32 nEdgeCount(aPolygon.isClosed() ? nPointCount - 1 : nPointCount);
-
- // first vertex
- path.move_to(aCurrentPoint.getX(), aCurrentPoint.getY());
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- // access next point
- const sal_uInt32 nNextIndex((a + 1) % nPointCount);
- const basegfx::B2DPoint aNextPoint(aPolygon.getB2DPoint(nNextIndex));
-
- // get control points
- const basegfx::B2DPoint aControlNext(aPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aControlPrev(aPolygon.getPrevControlPoint(nNextIndex));
-
- // specify first cp, second cp, next vertex
- path.curve4(
- aControlNext.getX(), aControlNext.getY(),
- aControlPrev.getX(), aControlPrev.getY(),
- aNextPoint.getX(), aNextPoint.getY());
-
- // prepare next step
- aCurrentPoint = aNextPoint;
- }
- }
- else
- {
- const basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(0));
- ras.move_to_d(aPoint.getX(), aPoint.getY());
-
- for(sal_uInt32 a(1); a < nPointCount; a++)
- {
- const basegfx::B2DPoint aVertexPoint(aPolygon.getB2DPoint(a));
- ras.line_to_d(aVertexPoint.getX(), aVertexPoint.getY());
- }
-
- if(aPolygon.isClosed())
- {
- ras.close_polygon();
- }
- }
- }
- }
-
- ras.add_path(curve);
- agg::rgba8 fillcolor(aFillColor.Color.r,aFillColor.Color.g,aFillColor.Color.b,aFillColor.Color.a);
- ren.color(fillcolor);
- agg::render_scanlines(ras, sl, ren);
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::fillPolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- if( !xPolyPolygon.is() )
- return ImageCachedPrimitiveSharedPtr();
-
- ::basegfx::B2DPolyPolygon aPoly(
- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( xPolyPolygon ) );
-
- switch(maDesc.eFormat)
- {
- case FMT_R8G8B8:
- return fillPolyPolygonImpl<agg::pixfmt_rgb24>(aPoly,viewState,renderState);
- case FMT_A8R8G8B8:
- return fillPolyPolygonImpl<agg::pixfmt_rgba32>(aPoly,viewState,renderState);
- default:
- OSL_ENSURE(false, "Unexpected pixel format");
- break;
- }
-
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillTexturedPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::fillTexturedPolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState,
- const uno::Sequence< rendering::Texture >& textures,
- const ::std::vector< ::boost::shared_ptr<Image> >& textureAnnotations )
-{
-#if defined(PROFILER)
- ScopeTimer aTimer(TIMER_FILLTEXTUREDPOLYPOLYGON,this);
-#endif
-
- if( !xPolyPolygon.is() )
- return ImageCachedPrimitiveSharedPtr();
-
- ::basegfx::B2DPolyPolygon aPoly(
- ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D( xPolyPolygon ) );
- ARGB aFillColor;
-
- setupPolyPolygon( aPoly, true, aFillColor, viewState, renderState );
-
- if( !aPoly.count() )
- return ImageCachedPrimitiveSharedPtr();
-
- ::basegfx::B2DHomMatrix aViewTransform;
- ::basegfx::B2DHomMatrix aRenderTransform;
- ::basegfx::B2DHomMatrix aTextureTransform;
-
- ::basegfx::unotools::homMatrixFromAffineMatrix(aTextureTransform,
- textures[0].AffineTransform);
- ::basegfx::unotools::homMatrixFromAffineMatrix(aRenderTransform,
- renderState.AffineTransform);
- ::basegfx::unotools::homMatrixFromAffineMatrix(aViewTransform,
- viewState.AffineTransform);
- aTextureTransform *= aRenderTransform;
-
- // TODO(F1): Multi-texturing
- if( textures[0].Gradient.is() )
- {
- aTextureTransform *= aViewTransform;
-
- // try to cast XParametricPolyPolygon2D reference to
- // our implementation class.
- ::canvas::ParametricPolyPolygon* pGradient =
- dynamic_cast< ::canvas::ParametricPolyPolygon* >( textures[0].Gradient.get() );
-
- if( pGradient )
- {
- const ParametricPolyPolygon::Values& rValues(
- pGradient->getValues() );
-
- // TODO: use all the colors and place them on given positions/stops
- // TODO(E1): Return value
- // TODO(F1): FillRule
- fillGradient( rValues,
- rValues.maColors [0],
- rValues.maColors [rValues.maColors.getLength () - 1],
- aPoly,
- aTextureTransform,
- textures[0] );
- }
- }
- else if( textures[0].Bitmap.is() )
- {
- ImageSharedPtr pTexture;
-
- if( textureAnnotations[0].get() != NULL )
- pTexture = textureAnnotations[0];
- else
- pTexture.reset( new Image( textures[0].Bitmap ) );
-
- const sal_uInt32 nWidth(pTexture->maDesc.nWidth);
- const sal_uInt32 nHeight(pTexture->maDesc.nHeight);
-
- // scale texture into one-by-one unit rect.
- aTextureTransform.scale(1.0f/nWidth,
- 1.0f/nHeight);
-
- // TODO(E1): Return value
- // TODO(F1): FillRule
- return fillTexturedPolyPolygon( *pTexture,
- aPoly,
- aTextureTransform,
- aViewTransform,
- textures[0] );
- }
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::fillTextureMappedPolyPolygon
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::fillTextureMappedPolyPolygon(
- const uno::Reference< rendering::XPolyPolygon2D >& /*xPolyPolygon*/,
- const rendering::ViewState& /*viewState*/,
- const rendering::RenderState& /*renderState*/,
- const uno::Sequence< rendering::Texture >& /*textures*/,
- const ::std::vector< ::boost::shared_ptr<Image> >& /*textureAnnotations*/,
- const uno::Reference< geometry::XMapping2D >& /*xMapping*/ )
-{
- OSL_ENSURE(false,
- "Image::fillTextureMappedPolyPolygon(): NYI" );
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawBitmap
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::drawBitmap(
- const uno::Reference< rendering::XBitmap >& xBitmap,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
-#if defined(PROFILER)
- ScopeTimer aTimer(TIMER_DRAWBITMAP,this);
-#endif
-
- // TODO(P3): Implement bitmap caching
- if( !xBitmap.is() )
- return ImageCachedPrimitiveSharedPtr();
-/*
- XBitmapAccessor accessor( xBitmap );
- if(accessor.isValid())
- {
- Image aImage( accessor.getDesc() );
-
- implDrawBitmap( aImage,
- viewState,
- renderState );
-
- // TODO(F2): Implement sensible ImageCachedPrimitive
- return ImageCachedPrimitiveSharedPtr();
- }
-*/
- Image aImage( xBitmap );
-
- return implDrawBitmap( aImage,viewState,renderState );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawBitmap
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::drawBitmap(
- const ImageSharedPtr& rImage,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
-#if defined(PROFILER)
- ScopeTimer aTimer(TIMER_DRAWBITMAP,this);
-#endif
-
- // TODO(P3): Implement bitmap caching
- if( !rImage )
- return ImageCachedPrimitiveSharedPtr();
-
- return implDrawBitmap( *rImage,
- viewState,
- renderState );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawBitmapModulated
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::drawBitmapModulated(
- const uno::Reference< rendering::XBitmap >& xBitmap,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- // TODO(P3): Implement bitmap caching
- if( !xBitmap.is() )
- return ImageCachedPrimitiveSharedPtr();
-
- Image aImage( xBitmap );
-
- // TODO(F2): Distinguish modulated and unmodulated bitmap output
- return implDrawBitmap( aImage,viewState,renderState );
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-// Image::drawBitmapModulated
-//////////////////////////////////////////////////////////////////////////////////
-
-ImageCachedPrimitiveSharedPtr Image::drawBitmapModulated(
- const ImageSharedPtr& rImage,
- const rendering::ViewState& viewState,
- const rendering::RenderState& renderState )
-{
- // TODO(P3): Implement bitmap caching
- if( !rImage )
- return ImageCachedPrimitiveSharedPtr();
-
- // TODO(F2): Distinguish modulated and unmodulated bitmap output
- return implDrawBitmap( *rImage,viewState,renderState );
-}
-
-}