summaryrefslogtreecommitdiff
path: root/basebmp
diff options
context:
space:
mode:
Diffstat (limited to 'basebmp')
-rw-r--r--basebmp/inc/basebmp/accessor.hxx74
-rw-r--r--basebmp/inc/basebmp/accessoradapters.hxx271
-rw-r--r--basebmp/inc/basebmp/bitmapdevice.hxx381
-rw-r--r--basebmp/inc/basebmp/clippedlinerenderer.hxx370
-rw-r--r--basebmp/inc/basebmp/color.hxx80
-rw-r--r--basebmp/inc/basebmp/debug.hxx58
-rw-r--r--basebmp/inc/basebmp/drawmodes.hxx76
-rw-r--r--basebmp/inc/basebmp/linerenderer.hxx186
-rw-r--r--basebmp/inc/basebmp/metafunctions.hxx79
-rw-r--r--basebmp/inc/basebmp/packedpixeliterator.hxx676
-rw-r--r--basebmp/inc/basebmp/paletteimageaccessor.hxx141
-rw-r--r--basebmp/inc/basebmp/pixeliterator.hxx362
-rw-r--r--basebmp/inc/basebmp/scanlineformats.hxx82
-rw-r--r--basebmp/inc/basebmp/stridedarrayiterator.hxx102
-rw-r--r--basebmp/prj/build.lst4
-rw-r--r--basebmp/prj/d.lst10
-rw-r--r--basebmp/source/bitmapdevice.cxx1023
-rw-r--r--basebmp/source/debug.cxx117
-rw-r--r--basebmp/source/makefile.mk54
-rw-r--r--basebmp/test/basictest.cxx133
-rw-r--r--basebmp/test/bmpdemo.cxx1278
-rw-r--r--basebmp/test/export.map42
-rw-r--r--basebmp/test/filltest.cxx113
-rw-r--r--basebmp/test/linetest.cxx178
-rw-r--r--basebmp/test/makefile.mk110
-rw-r--r--basebmp/util/basebmp.flt4
-rw-r--r--basebmp/util/makefile.mk74
27 files changed, 6078 insertions, 0 deletions
diff --git a/basebmp/inc/basebmp/accessor.hxx b/basebmp/inc/basebmp/accessor.hxx
new file mode 100644
index 000000000000..2718ad1bf5e9
--- /dev/null
+++ b/basebmp/inc/basebmp/accessor.hxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accessor.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:41 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_ACCESSOR_HXX
+#define INCLUDED_BASEBMP_ACCESSOR_HXX
+
+namespace basebmp
+{
+
+template<typename ValueType> class StandardAccessor
+{
+public:
+ typedef ValueType value_type;
+ typedef ValueType data_type;
+
+ template< class Iterator >
+ value_type operator()(Iterator const& i) const { return i.get(); }
+ value_type operator()(value_type const* i) const { return *i; }
+
+ template< class Iterator, class Difference >
+ value_type operator()(Iterator const& i, Difference const& diff) const
+ {
+ return i.get(diff);
+ }
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ i.set( vigra::detail::RequiresExplicitCast<value_type>::cast(value) );
+ }
+
+ template< typename V, class Iterator, class Difference >
+ void set(V const& value, Iterator const& i, Difference const& diff) const
+ {
+ i.set( vigra::detail::RequiresExplicitCast<value_type>::cast(value),
+ diff );
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_ACCESSOR_HXX */
diff --git a/basebmp/inc/basebmp/accessoradapters.hxx b/basebmp/inc/basebmp/accessoradapters.hxx
new file mode 100644
index 000000000000..63c7e2ad25bc
--- /dev/null
+++ b/basebmp/inc/basebmp/accessoradapters.hxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accessoradapters.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:41 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX
+#define INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX
+
+#include "metafunctions.hxx"
+#include "packedpixeliterator.hxx"
+#include "paletteimageaccessor.hxx"
+
+namespace basebmp
+{
+
+/** Interpose given accessor's set methods with a binary function,
+ taking both old and new value.
+ */
+template< class WrappedAccessor, typename Functor > class BinarySetterFunctionAccessorAdapter :
+ public WrappedAccessor
+{
+private:
+ Functor maFunctor;
+
+public:
+ BinarySetterFunctionAccessorAdapter() :
+ WrappedAccessor(),
+ maFunctor()
+ {}
+
+ explicit BinarySetterFunctionAccessorAdapter( WrappedAccessor accessor ) :
+ WrappedAccessor( accessor ),
+ maFunctor()
+ {}
+
+ BinarySetterFunctionAccessorAdapter( WrappedAccessor accessor,
+ Functor functor ) :
+ WrappedAccessor( accessor ),
+ maFunctor( functor )
+ {}
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ WrappedAccessor::set(
+ maFunctor(WrappedAccessor::operator()(i),
+ value),
+ i );
+ }
+
+ template< typename V, class Iterator, class Difference >
+ void set(V const& value, Iterator const& i, Difference const& diff) const
+ {
+ WrappedAccessor::set(
+ maFunctor(WrappedAccessor::operator()(i,diff),
+ value),
+ i,
+ diff );
+ }
+};
+
+/** Read from two input iterators, pipe that through given functor, and write result
+ to the first iterator
+
+ Note: iterator type is fixed, to facilitate type-safe mask
+ optimizations (see below)
+ */
+template< class WrappedAccessor1,
+ class WrappedAccessor2,
+ class Iterator1,
+ class Iterator2,
+ typename Functor > class BinaryInputAccessorAdapter
+{
+private:
+ WrappedAccessor1 ma1stAccessor;
+ WrappedAccessor2 ma2ndAccessor;
+ Functor maFunctor;
+
+public:
+ typedef typename WrappedAccessor1::value_type value_type;
+
+ BinaryInputAccessorAdapter() :
+ ma1stAccessor(),
+ ma2ndAccessor(),
+ maFunctor()
+ {}
+
+ explicit BinaryInputAccessorAdapter( WrappedAccessor1 accessor1 ) :
+ ma1stAccessor( accessor1 ),
+ ma2ndAccessor(),
+ maFunctor()
+ {}
+
+ BinaryInputAccessorAdapter( WrappedAccessor1 accessor1,
+ WrappedAccessor2 accessor2 ) :
+ ma1stAccessor( accessor1 ),
+ ma2ndAccessor( accessor2 ),
+ maFunctor()
+ {}
+
+ BinaryInputAccessorAdapter( WrappedAccessor1 accessor1,
+ WrappedAccessor2 accessor2,
+ Functor func ) :
+ ma1stAccessor( accessor1 ),
+ ma2ndAccessor( accessor2 ),
+ maFunctor( func )
+ {}
+
+ value_type operator()(Iterator1 const& i, Iterator2 const& j) const
+ {
+ return maFunctor(ma1stAccessor(i),
+ ma2ndAccessor(j));
+ }
+ template< class Difference >
+ value_type operator()(Iterator1 const& i, Iterator2 const& j, Difference const& diff) const
+ {
+ return maFunctor(ma1stAccessor(i,diff),
+ ma2ndAccessor(j,diff));
+ }
+
+ template< typename V >
+ void set(V const& value, Iterator1 const& i, Iterator2 const& j) const
+ {
+ ma1stAccessor.set(
+ maFunctor(ma1stAccessor(i),
+ ma2ndAccessor(j)),
+ i );
+ }
+
+ template< typename V, class Difference >
+ void set(V const& value, Iterator1 const& i, Iterator2 const& j, Difference const& diff) const
+ {
+ ma1stAccessor.set(
+ maFunctor(ma1stAccessor(i,diff),
+ ma2ndAccessor(j,diff)),
+ i,
+ diff );
+ }
+};
+
+// Some common accessor wrappers
+// ------------------------------------------------------------
+
+// XOR
+template< typename T > struct XorFunctor
+{
+ T operator()( T v1, T v2 ) const { return v1 ^ v2; }
+};
+template< class WrappedAccessor > struct xorAccessor
+{
+ typedef BinarySetterFunctionAccessorAdapter< WrappedAccessor,
+ XorFunctor< typename WrappedAccessor::value_type > >
+ type;
+};
+
+// Mask
+template< typename T > struct MaskFunctor
+{
+ /** Mask v with state of m
+
+ @return v, if m != 0, and vigra::NumericTraits<T>::zero
+ otherwise.
+ */
+ T operator()( T v, T m ) const
+ {
+ // TODO(Q3): use traits to get unsigned type for T (if
+ // not already)
+
+ // mask will be 0, iff m == 0, and 1 otherwise
+ const T mask( static_cast<unsigned int>(m | -m) >> (sizeof(unsigned int)*8 - 1) );
+ return mask*v;
+ }
+};
+// Faster mask (assuming mask accessor output is already either 0 or 1)
+template< typename T > struct FastMaskFunctor
+{
+ T operator()( T v, T m ) const
+ {
+ return m*v;
+ }
+};
+// Chosen function crucially depends on iterator - we can choose the
+// faster direkt masking for 1bpp packed pixel iterators
+template< class WrappedAccessor,
+ class MaskAccessor,
+ class Iterator,
+ class MaskIterator > struct maskedAccessor
+{
+ typedef BinaryInputAccessorAdapter< WrappedAccessor,
+ MaskAccessor,
+ Iterator,
+ MaskIterator,
+ MaskFunctor< typename WrappedAccessor::value_type > >
+ type;
+};
+// partial specialization, to use fast 1bpp mask function for
+// corresponding iterator type
+template< class WrappedAccessor,
+ class MaskAccessor,
+ class Iterator > struct maskedAccessor< WrappedAccessor,
+ MaskAccessor,
+ Iterator,
+ PackedPixelIterator< typename MaskAccessor::data_type,
+ typename MaskAccessor::value_type,
+ 1,
+ true > >
+{
+ typedef BinaryInputAccessorAdapter< WrappedAccessor,
+ MaskAccessor,
+ Iterator,
+ PackedPixelIterator< typename MaskAccessor::data_type,
+ typename MaskAccessor::value_type,
+ 1,
+ true >,
+ FastMaskFunctor< typename WrappedAccessor::value_type > >
+ type;
+};
+template< class WrappedAccessor,
+ class MaskAccessor,
+ class Iterator > struct maskedAccessor< WrappedAccessor,
+ MaskAccessor,
+ Iterator,
+ PackedPixelIterator< typename MaskAccessor::data_type,
+ typename MaskAccessor::value_type,
+ 1,
+ false > >
+{
+ typedef BinaryInputAccessorAdapter< WrappedAccessor,
+ MaskAccessor,
+ Iterator,
+ PackedPixelIterator< typename MaskAccessor::data_type,
+ typename MaskAccessor::value_type,
+ 1,
+ false >,
+ FastMaskFunctor< typename WrappedAccessor::value_type > >
+ type;
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX */
diff --git a/basebmp/inc/basebmp/bitmapdevice.hxx b/basebmp/inc/basebmp/bitmapdevice.hxx
new file mode 100644
index 000000000000..3fd6401a6be6
--- /dev/null
+++ b/basebmp/inc/basebmp/bitmapdevice.hxx
@@ -0,0 +1,381 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmapdevice.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_BITMAPDEVICE_HXX
+#define INCLUDED_BASEBMP_BITMAPDEVICE_HXX
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+#ifndef INCLUDED_BASEBMP_DRAWMODES_HXX
+#include "drawmodes.hxx"
+#endif
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+
+
+/* What to do first:
+
+ 1,8,24 bpp, with blt, fill/drawPolygon, drawLine & get/setPixel
+
+ Then:
+
+ all other formats, top down vs. bottom up
+
+ Last:
+
+ Modulation, clip
+
+ */
+
+namespace basegfx
+{
+ class B2IPoint;
+ class B2DPoint;
+ class B2IVector;
+ class B2IRange;
+ class B2DPolygon;
+ class B2DPolyPolygon;
+}
+
+namespace basebmp
+{
+
+// Temporary. Use like the tools color object
+class Color;
+typedef boost::shared_ptr< class BitmapDevice > BitmapDeviceSharedPtr;
+typedef boost::shared_ptr< sal_uInt8 > RawMemorySharedPtr;
+
+struct ImplBitmapDevice;
+
+/** Definition of BitmapDevice interface
+
+ Use createBitmapDevice() factory method to create one instance.
+
+ Implementation note: the clip mask and bitmap parameter instances
+ of BitmapDevice that are passed to individual BitmapDevice
+ instances work best with 1 bit MSB masks for the clip and a format
+ matching that of the target BitmapDevice for the other
+ parameters. Everything else is accepted, but potentially slow.
+ */
+class BitmapDevice : private boost::noncopyable
+{
+public:
+ /** Query size of device in pixel
+ */
+ basegfx::B2IVector getSize() const;
+
+ /** Query whether buffer starts with 0th scanline
+
+ @return true, if the buffer memory starts with the 0th
+ scanline, and false if it starts with the last
+ */
+ bool isTopDown() const;
+
+ /** Query type of scanline memory format
+ */
+ sal_Int32 getScanlineFormat() const;
+
+ /** Query byte offset to get from scanline n to scanline n+1
+
+ @return the scanline stride in bytes. In the case of
+ bottom-first formats, this offset will be negative.
+ */
+ sal_Int32 getScanlineStride() const;
+
+ /** Get pointer to frame buffer
+ */
+ RawMemorySharedPtr getBuffer() const;
+
+ /** Get pointer to palette
+
+ @return pointer to array of getPaletteEntryCount() Color
+ entries, if this is a palette format. If not, NULL is
+ returned.
+ */
+ const Color* getPalette() const;
+
+ /** Query number of palette entries
+ */
+ const sal_Int32 getPaletteEntryCount() const;
+
+ /** Clear whole device with given color
+ */
+ void clear( Color fillColor );
+
+ /** Set given pixel to specified color
+
+ @param rPt
+ Pixel to set
+
+ @param pixelColor
+ Color value to set the pixel to
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+ */
+ void setPixel( const basegfx::B2IPoint& rPt,
+ Color pixelColor,
+ DrawMode drawMode );
+
+ /** Set given pixel to specified color
+
+ @param rPt
+ Pixel to set
+
+ @param pixelColor
+ Color value to set the pixel to
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+
+ @param rClip
+ Clip mask to use. If the clip mask is 0 at the given pixel
+ position, no change will happen.
+ */
+ void setPixel( const basegfx::B2IPoint& rPt,
+ Color pixelColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ /** Get color value at given pixel
+ */
+ Color getPixel( const basegfx::B2IPoint& rPt );
+
+ /** Draw a line
+
+ @param rPt1
+ Start point of the line
+
+ @param rPt2
+ End point of the line. If the analytical line from rP1 to rPt2
+ (with the actual pixel positions are assumed to be the center
+ of the pixel) is exactly in the middle between two pixel, this
+ method always selects the pixel closer to rPt1.
+
+ @param lineColor
+ Color value to draw the line with
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+ */
+ void drawLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode );
+
+ /** Draw a line
+
+ @param rPt1
+ Start point of the line
+
+ @param rPt2
+ End point of the line. If the analytical line from rP1 to rPt2
+ (with the actual pixel positions are assumed to be the center
+ of the pixel) is exactly in the middle between two pixel, this
+ method always selects the pixel closer to rPt1.
+
+ @param lineColor
+ Color value to draw the line with
+
+ @param drawMode
+ Draw mode to use when changing the pixel value
+
+ @param rClip
+ Clip mask to use. Pixel where the corresponding clip mask
+ pixel is 0 will not be touched.
+ */
+ void drawLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ void drawPolygon( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode );
+ void drawPolygon( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ void fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode );
+ void fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode );
+ void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+ void drawMaskedColor( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint );
+ void drawMaskedColor( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint,
+ const BitmapDeviceSharedPtr& rClip );
+
+ void drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode );
+ void drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip );
+
+protected:
+ BitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat,
+ sal_Int32 nScanlineStride,
+ const RawMemorySharedPtr& rMem );
+
+ virtual ~BitmapDevice();
+
+private:
+ virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const = 0;
+ virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const = 0;
+ virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const = 0;
+
+ virtual const Color* getPalette_i() const = 0;
+ virtual const sal_Int32 getPaletteEntryCount_i() const = 0;
+
+ virtual void clear_i( Color fillColor ) = 0;
+
+ virtual void setPixel_i( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode ) = 0;
+ virtual void setPixel_i( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ virtual Color getPixel_i( const basegfx::B2IPoint& rPt ) = 0;
+
+ virtual void drawLine_i( const basegfx::B2DPoint& rPt1,
+ const basegfx::B2DPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode ) = 0;
+ virtual void drawLine_i( const basegfx::B2DPoint& rPt1,
+ const basegfx::B2DPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ virtual void drawPolygon_i( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode ) = 0;
+ virtual void drawPolygon_i( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ virtual void fillPolyPolygon_i( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const basegfx::B2IRange& rBounds ) = 0;
+ virtual void fillPolyPolygon_i( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const basegfx::B2IRange& rBounds,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode ) = 0;
+ virtual void drawBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawMaskedColor_i( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint ) = 0;
+ virtual void drawMaskedColor_i( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawMaskedBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode ) = 0;
+ virtual void drawMaskedBitmap_i( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip ) = 0;
+
+ boost::scoped_ptr< ImplBitmapDevice > mpImpl;
+};
+
+/** Factory method to create a BitmapDevice for given scanline format
+ */
+BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat );
+
+}
+
+#endif /* INCLUDED_BASEBMP_BITMAPDEVICE_HXX */
diff --git a/basebmp/inc/basebmp/clippedlinerenderer.hxx b/basebmp/inc/basebmp/clippedlinerenderer.hxx
new file mode 100644
index 000000000000..92be0308a5c7
--- /dev/null
+++ b/basebmp/inc/basebmp/clippedlinerenderer.hxx
@@ -0,0 +1,370 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: clippedlinerenderer.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:41 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX
+#define INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX
+
+#include <basegfx/tools/rectcliptools.hxx>
+
+namespace basebmp
+{
+
+// factored-out bresenham setup code, which is used from two different
+// places in renderClippedLine() below. Admittedly messy for the long
+// parameter list...
+inline bool prepareClip( sal_Int32 a1,
+ sal_Int32 a2,
+ sal_Int32 b1,
+ sal_Int32 da,
+ sal_Int32 db,
+ sal_Int32& o_as,
+ sal_Int32& o_bs,
+ int sa,
+ int sb,
+ sal_Int32& io_rem,
+ int& o_n,
+ sal_uInt32 clipCode1,
+ sal_uInt32 clipCount1,
+ sal_uInt32 clipCode2,
+ sal_uInt32 clipCount2,
+ sal_Int32 aMin,
+ sal_uInt32 aMinFlag,
+ sal_Int32 aMax,
+ sal_uInt32 aMaxFlag,
+ sal_Int32 bMin,
+ sal_uInt32 bMinFlag,
+ sal_Int32 bMax,
+ sal_uInt32 bMaxFlag,
+ bool bRoundTowardsPt2 )
+{
+ int ca, cb;
+ if( clipCode1 )
+ {
+ if( clipCode1 & aMinFlag )
+ {
+ ca = 2*db*(aMin - a1);
+ o_as = aMin;
+ }
+ else if( clipCode1 & aMaxFlag )
+ {
+ ca = 2*db*(a1 - aMax);
+ o_as = aMax;
+ }
+
+ if( clipCode1 & bMinFlag )
+ {
+ cb = 2*da*(bMin - b1);
+ o_bs = bMin;
+ }
+ else if( clipCode1 & bMaxFlag )
+ {
+ cb = 2*da*(b1 - bMax);
+ o_bs = bMax;
+ }
+
+ if( clipCount1 == 2 )
+ clipCode1 &= (ca + da < cb + !bRoundTowardsPt2) ? ~(aMin|aMax) : ~(bMin|bMax);
+
+ if( clipCode1 & (aMin|aMax) )
+ {
+ cb = (ca + da - !bRoundTowardsPt2) / (2*da);
+
+ if( sb >= 0 )
+ {
+ o_bs = b1 + cb;
+ if( o_bs > bMax )
+ return;
+ }
+ else
+ {
+ o_bs = b1 - cb;
+ if( o_bs < bMin )
+ return;
+ }
+
+ io_rem += ca - 2*da*cb;
+ }
+ else
+ {
+ ca = (cb - da + 2*db - bRoundTowardsPt2) / (2*db);
+ if( sa >= 0 )
+ {
+ o_as = a1 + ca;
+ if( o_as > aMax )
+ return;
+ }
+ else
+ {
+ o_as = a1 - ca;
+ if( o_as < aMin )
+ return;
+ }
+
+ io_rem += 2*db*ca - cb;
+ }
+ }
+ else
+ {
+ o_as = a1; o_bs = b1;
+ }
+
+ bool bRetVal = false;
+ if( clipCode2 )
+ {
+ if( clipCount2 == 2 )
+ {
+ ca = 2*db*((clipCode2 & aMin) ? a1 - aMin : aMax - a1);
+ cb = 2*da*((clipCode2 & bMin) ? b1 - bMin : bMax - b1);
+ clipCode2 &= (cb + da < ca + bRoundTowardsPt2) ? ~(aMin|aMax) : ~(bMin|bMax);
+ }
+
+ if( clipCode2 & (aMin|aMax) )
+ o_n = (clipCode2 & aMin) ? o_as - aMin : aMax - o_as;
+ else
+ {
+ o_n = (clipCode2 & bMin) ? o_bs - bMin : bMax - o_bs;
+ bRetVal = true;
+ }
+ }
+ else
+ o_n = (a2 >= o_as) ? a2 - o_as : o_as - a2;
+
+ return bRetVal;
+}
+
+
+/** Render line to image iterators, clip against given rectangle
+
+ This method renders a line from aPt1 to aPt2, clipped against
+ rClipRect (the clipping will take place pixel-perfect, i.e. as if
+ the original bresenham-rendered line would have been clipped each
+ pixel individually. No slight shifts compared to unclipped lines).
+
+ @param aPt1
+ Start point of the line
+
+ @param aPt2
+ End point of the line
+
+ @param rClipRect
+ Rectangle to clip against
+
+ @param color
+ Color value to render the line with
+
+ @param begin
+ left-top image iterator
+
+ @param end
+ right-bottom image iterator
+
+ @param acc
+ Image accessor
+
+ @param bRoundTowardsPt2
+ Rounding mode to use. Giving false here results in line pixel tend
+ towards pt1, i.e. when a pixel exactly hits the middle between two
+ pixel, the pixel closer to pt1 will be chosen. Giving true here
+ makes renderClippedLine() choose pt2 in those cases.
+ */
+template< class Iterator, class Accessor >
+void renderClippedLine( basegfx::B2IPoint aPt1,
+ basegfx::B2IPoint aPt2,
+ const basegfx::B2IRange& rClipRect,
+ typename Accessor::value_type color,
+ Iterator begin,
+ Iterator end,
+ Accessor acc,
+ bool bRoundTowardsPt2=false )
+{
+ // Algorithm according to Steven Eker's 'Pixel-perfect line clipping',
+ // Graphics Gems V, pp. 314-322
+ sal_uInt32 clipCode1 = basegfx::tools::getCohenSutherlandClipFlags(aPt1,
+ rClipRect);
+ sal_uInt32 clipCode2 = basegfx::tools::getCohenSutherlandClipFlags(aPt2,
+ rClipRect);
+
+ if( clipCode1 & clipCode2 )
+ return; // line fully clipped away
+
+ sal_uInt32 clipCount1 = basegfx::tools::getNumberOfClipPlanes(clipCode1);
+ sal_uInt32 clipCount2 = basegfx::tools::getNumberOfClipPlanes(clipCode2);
+
+ if( (clipCode1 != 0 && clipCode2 == 0)
+ || (clipCount1 == 2 && clipCount2 == 1) )
+ {
+ std::swap(clipCount2,clipCount1);
+ std::swap(clipCode2,clipCode1);
+ std::swap(aPt1,aPt2);
+ bRoundTowardsPt2 = !bRoundTowardsPt2;
+ }
+
+ const sal_Int32 x1 = aPt1.getX();
+ const sal_Int32 x2 = aPt2.getX();
+ const sal_Int32 y1 = aPt1.getY();
+ const sal_Int32 y2 = aPt2.getY();
+
+ // TODO(E1): This might overflow
+ sal_Int32 adx = x2 - x1;
+ int sx = 1;
+ if( adx < 0 )
+ {
+ adx *= -1;
+ sx = -1;
+ }
+
+ // TODO(E1): This might overflow
+ sal_Int32 ady = y2 - y1;
+ int sy = 1;
+ if( ady < 0 )
+ {
+ ady *= -1;
+ sy = -1;
+ }
+
+ int n = 0;
+ sal_Int32 xs = x1;
+ sal_Int32 ys = y1;
+ if( adx >= ady )
+ {
+ // semi-horizontal line
+ sal_Int32 rem = 2*ady - adx - !bRoundTowardsPt2;
+
+ const bool bUseAlternateBresenham(
+ prepareClip(x1, x2, y1, adx, ady, xs, ys, sx, sy,
+ rem, n, clipCode1, clipCount1, clipCode1, clipCount2,
+ rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
+ rClipRect.getMaxX(), basegfx::tools::RectClipFlags::RIGHT,
+ rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
+ rClipRect.getMaxY(), basegfx::tools::RectClipFlags::BOTTOM,
+ bRoundTowardsPt2 ));
+ const sal_Int32 diff = 2*(ady - adx);
+ if( bUseAlternateBresenham )
+ {
+ while(true)
+ {
+ plot(xs,ys);
+
+ if( rem >= 0 )
+ {
+ if( --n < 0 )
+ break;
+ rem += diff;
+ ys += sy;
+ }
+ else
+ rem += 2*ady;
+
+ xs += sx;
+ }
+ }
+ else
+ {
+ while(true)
+ {
+ plot(xs,ys);
+
+ if( --n < 0 )
+ break;
+ if( rem >= 0 )
+ {
+ rem += diff;
+ ys += sy;
+ }
+ else
+ rem += 2*ady;
+
+ xs += sx;
+ }
+ }
+ }
+ else
+ {
+ // semi-vertical line
+ sal_Int32 rem = 2*adx - ady - !bRoundTowardsPt2;
+
+ const bool bUseAlternateBresenham(
+ prepareClip(y1, y2, x1, ady, adx, ys, xs, sy, sx,
+ rem, clipCode1, clipCount1, clipCode1, clipCount2,
+ rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP,
+ rClipRect.getMaxY(), basegfx::tools::RectClipFlags::BOTTOM,
+ rClipRect.getMinX(), basegfx::tools::RectClipFlags::LEFT,
+ rClipRect.getMaxX(), basegfx::tools::RectClipFlags::RIGHT,
+ bRoundTowardsPt2 ));
+ const sal_Int32 diff = 2*(ady - adx);
+ if( bUseAlternateBresenham )
+ {
+ while(true)
+ {
+ plot(xy,ys);
+
+ if( rem >= 0 )
+ {
+ if( --n < 0 )
+ break;
+ rem += diff;
+ xs += sx;
+ }
+ else
+ rem += 2*adx;
+
+ ys += sy;
+ }
+ }
+ else
+ {
+ while(true)
+ {
+ plot(xs,ys);
+
+ if( --n < 0 )
+ break;
+ if( rem >= 0 )
+ {
+ rem += diff;
+ xs += sx;
+ }
+ else
+ rem += 2*adx;
+
+ ys += sy;
+ }
+ }
+ }
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX */
diff --git a/basebmp/inc/basebmp/color.hxx b/basebmp/inc/basebmp/color.hxx
new file mode 100644
index 000000000000..21ae86e897dd
--- /dev/null
+++ b/basebmp/inc/basebmp/color.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: color.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:41 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_COLOR_HXX
+#define INCLUDED_BASEBMP_COLOR_HXX
+
+#ifndef _SAL_TYPES_H_
+#include <sal/types.h>
+#endif
+#include <math.h>
+
+namespace basebmp
+{
+
+class Color
+{
+private:
+ sal_uInt32 mnColor;
+
+public:
+ Color() : mnColor(0) {}
+ Color( sal_uInt32 nVal ) : mnColor(nVal) {}
+ Color( sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue ) :
+ mnColor( (nRed << 16) | (nGreen << 8) | nBlue )
+ {}
+
+ void setRed( sal_uInt8 nRed ) { mnColor |= nRed << 16; mnColor &= ~((sal_uInt32)nRed << 16); }
+ void setGreen( sal_uInt8 nGreen ) { mnColor |= nGreen << 8; mnColor &= ~((sal_uInt32)nGreen << 8); }
+ void setBlue( sal_uInt8 nBlue ) { mnColor |= nBlue; mnColor &= ~(sal_uInt32)nBlue; }
+
+ sal_uInt8 getRed() const { return (mnColor & 0x00FF0000U) >> 16; }
+ sal_uInt8 getGreen() const { return (mnColor & 0x0000FF00U) >> 8; }
+ sal_uInt8 getBlue() const { return mnColor & 0x000000FFU; }
+
+ sal_uInt32 getValue() const { return mnColor; }
+ operator sal_uInt32() const { return mnColor; }
+
+ Color operator-( Color col ) const { return Color(getRed()-col.getRed(),
+ getGreen()-col.getGreen(),
+ getBlue()-col.getBlue()); }
+ double magnitude() const { return sqrt(getRed()*getRed()
+ + getGreen()*getGreen()
+ + getBlue()*getBlue()); }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_COLOR_HXX */
diff --git a/basebmp/inc/basebmp/debug.hxx b/basebmp/inc/basebmp/debug.hxx
new file mode 100644
index 000000000000..62cc8eaeb646
--- /dev/null
+++ b/basebmp/inc/basebmp/debug.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: debug.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:42 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_DEBUG_HXX
+#define INCLUDED_BASEBMP_DEBUG_HXX
+
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+
+namespace basebmp
+{
+ class BitmapDevice;
+
+ /** Dump content of BitmapDevice to given output stream.
+
+ @param rDevice
+ Device whose content should be dumped.
+
+ @param rOutputStream
+ Stream to write output to.
+ */
+ void debugDump( const boost::shared_ptr< BitmapDevice >& rDevice,
+ ::std::ostream& rOutputStream );
+}
+
+#endif /* INCLUDED_BASEBMP_DEBUG_HXX */
diff --git a/basebmp/inc/basebmp/drawmodes.hxx b/basebmp/inc/basebmp/drawmodes.hxx
new file mode 100644
index 000000000000..f09d5c221383
--- /dev/null
+++ b/basebmp/inc/basebmp/drawmodes.hxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * $RCSfile: drawmodes.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:42 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_DRAWMODES_HXX
+#define INCLUDED_BASEBMP_DRAWMODES_HXX
+
+/* Definition of Draw modes */
+
+namespace basebmp
+{
+ enum DrawMode
+ {
+ DrawMode_PAINT,
+ DrawMode_XOR
+ };
+}
+
+#endif /* INCLUDED_BASEBMP_DRAWMODES_HXX */
diff --git a/basebmp/inc/basebmp/linerenderer.hxx b/basebmp/inc/basebmp/linerenderer.hxx
new file mode 100644
index 000000000000..0493e9571b8a
--- /dev/null
+++ b/basebmp/inc/basebmp/linerenderer.hxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: linerenderer.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:42 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_LINERENDERER_HXX
+#define INCLUDED_BASEBMP_LINERENDERER_HXX
+
+#ifndef _BGFX_POINT_B2IPOINT_HXX
+#include <basegfx/point/b2ipoint.hxx>
+#endif
+
+/* Scan-converting lines */
+
+namespace basebmp
+{
+
+/** Render line with Bresenham
+
+ This function renders the line given by rPt1 and rPt2 using the
+ Bresenham algorithm with the specified color value. Make sure rPt1
+ and rPt1 are valid coordinates in the image given by begin and
+ end, since no clipping takes place.
+
+ @param aPt1
+ Start point of the line
+
+ @param aPt2
+ End point of the line
+
+ @param color
+ Color value to render the line with
+
+ @param begin
+ left-top image iterator
+
+ @param end
+ right-bottom image iterator
+
+ @param acc
+ Image accessor
+
+ @param bRoundTowardsPt2
+ Rounding mode to use. Giving false here results in line pixel tend
+ towards pt1, i.e. when a pixel exactly hits the middle between two
+ pixel, the pixel closer to pt1 will be chosen. Giving true here
+ makes renderClippedLine() choose pt2 in those cases.
+ */
+template< class Iterator, class Accessor >
+void renderLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ typename Accessor::value_type color,
+ Iterator begin,
+ Iterator end,
+ Accessor acc,
+ bool bRoundTowardsPt2=false )
+{
+ // code inspired by Paul Heckbert's Digital Line Drawing
+ // (Graphics Gems, Academic Press 1990)
+ const sal_Int32 x1 = rPt1.getX();
+ const sal_Int32 x2 = rPt2.getX();
+ const sal_Int32 y1 = rPt1.getY();
+ const sal_Int32 y2 = rPt2.getY();
+
+ // TODO(E1): This might overflow
+ sal_Int32 adx = x2 - x1;
+ int sx = 1;
+ if( adx < 0 )
+ {
+ adx *= -1;
+ sx = -1;
+ }
+
+ // TODO(E1): This might overflow
+ sal_Int32 ady = y2 - y1;
+ int sy = 1;
+ if( ady < 0 )
+ {
+ ady *= -1;
+ sy = -1;
+ }
+
+ // TODO(P3): handle horizontal and vertical lines specially
+ sal_Int32 xs = x1;
+ sal_Int32 ys = y1;
+ if( adx >= ady )
+ {
+ // semi-horizontal line
+ sal_Int32 rem = 2*ady - adx - !bRoundTowardsPt2;
+ adx *= 2;
+ ady *= 2;
+
+ Iterator currIter( begin + vigra::Diff2D(0,ys) );
+ typename Iterator::row_iterator rowIter( currIter.rowIterator() + xs );
+ while(true)
+ {
+ acc.set(color, rowIter);
+
+ if( xs == x2 )
+ return;
+
+ if( rem >= 0 )
+ {
+ ys += sy;
+ xs += sx;
+ currIter.y += sy;
+ rowIter = currIter.rowIterator() + xs;
+ rem -= adx;
+ }
+ else
+ {
+ xs += sx;
+ rowIter += sx;
+ }
+
+ rem += ady;
+ }
+ }
+ else
+ {
+ // semi-vertical line
+ sal_Int32 rem = 2*adx - ady - !bRoundTowardsPt2;
+ adx *= 2;
+ ady *= 2;
+
+ Iterator currIter( begin + vigra::Diff2D(xs,0) );
+ typename Iterator::column_iterator colIter( currIter.columnIterator() + ys );
+ while(true)
+ {
+ acc.set(color, colIter);
+
+ if( ys == y2 )
+ return;
+
+ if( rem >= 0 )
+ {
+ xs += sx;
+ ys += sy;
+ currIter.x += sx;
+ colIter = currIter.columnIterator() + ys;
+ rem -= ady;
+ }
+ else
+ {
+ ys += sy;
+ colIter += sy;
+ }
+
+ rem += adx;
+ }
+ }
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_LINERENDERER_HXX */
diff --git a/basebmp/inc/basebmp/metafunctions.hxx b/basebmp/inc/basebmp/metafunctions.hxx
new file mode 100644
index 000000000000..cdef37548e7b
--- /dev/null
+++ b/basebmp/inc/basebmp/metafunctions.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: metafunctions.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:42 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_METAFUNCTIONS_HXX
+#define INCLUDED_BASEBMP_METAFUNCTIONS_HXX
+
+namespace basebmp
+{
+
+// TODO(Q3): move to generic place (o3tl?)
+
+/// template meta function: add const qualifier, if given 2nd type has it
+template<typename A, typename B> struct clone_const
+{
+ typedef B type;
+};
+template<typename A, typename B> struct clone_const<const A,B>
+{
+ typedef const B type;
+};
+
+/// template meta function: remove const qualifier from plain type
+template <typename T> struct remove_const
+{
+ typedef T type;
+};
+template <typename T> struct remove_const<const T>
+{
+ typedef T type;
+};
+
+/// returns true, if given number is strictly less than 0
+template< typename T > inline bool is_negative( T x )
+{
+ return x < 0;
+}
+
+/// Overload for ints (branch-free)
+inline bool is_negative( int x )
+{
+ // force logic shift (result for signed shift right is undefined)
+ return static_cast<unsigned int>(x) >> (sizeof(int)*8-1);
+}
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_METAFUNCTIONS_HXX */
diff --git a/basebmp/inc/basebmp/packedpixeliterator.hxx b/basebmp/inc/basebmp/packedpixeliterator.hxx
new file mode 100644
index 000000000000..48330d5c27ad
--- /dev/null
+++ b/basebmp/inc/basebmp/packedpixeliterator.hxx
@@ -0,0 +1,676 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: packedpixeliterator.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:42 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX
+#define INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX
+
+#include "metafunctions.hxx"
+#include "stridedarrayiterator.hxx"
+
+#include <boost/static_assert.hpp>
+#include <vigra/metaprogramming.hxx>
+#include <vigra/diff2d.hxx>
+
+namespace basebmp
+{
+
+/// Get bitmask for data at given intra-word position, for given bit depth
+template< typename data_type, int bits_per_pixel, bool MsbFirst, typename difference_type > inline data_type get_mask( difference_type d )
+{
+ BOOST_STATIC_ASSERT(bits_per_pixel > 0);
+ BOOST_STATIC_ASSERT(sizeof(data_type)*8 % bits_per_pixel == 0);
+ BOOST_STATIC_ASSERT(sizeof(data_type)*8 / bits_per_pixel > 1);
+ BOOST_STATIC_ASSERT(vigra::TypeTraits<data_type>::isPOD::asBool);
+
+ const unsigned int nIntraWordPositions( sizeof(data_type)*8 / bits_per_pixel );
+
+ // create bits_per_pixel 1s shift to intra-word position
+ return ((~(~0 << bits_per_pixel)) << bits_per_pixel*(MsbFirst ?
+ (nIntraWordPositions-1 - (d % nIntraWordPositions)) :
+ (d % nIntraWordPositions)));
+}
+
+template< int num_intraword_positions, int bits_per_pixel, bool MsbFirst, typename difference_type > inline difference_type get_shift( difference_type remainder )
+{
+ return bits_per_pixel*(MsbFirst ?
+ (num_intraword_positions - 1 - remainder) :
+ remainder);
+}
+
+template< typename Datatype,
+ typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelColumnIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Datatype data_type;
+ typedef Valuetype value_type;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef typename remove_const<data_type>::type mask_type;
+ typedef data_type* pointer;
+ typedef StridedArrayIterator< data_type > MoveY;
+
+ enum {
+ /** The number of pixel within a single data_type value
+ */
+ num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+private:
+ MoveY y;
+ mask_type mask_;
+ difference_type shift_;
+
+ void inc()
+ {
+ ++y;
+ }
+
+ void dec()
+ {
+ --y;
+ }
+
+ bool equal( PackedPixelColumnIterator const & rhs ) const
+ {
+ return rhs.y == y;
+ }
+
+ bool less( PackedPixelColumnIterator const & rhs ) const
+ {
+ return y < rhs.y;
+ }
+
+public:
+ PackedPixelColumnIterator() :
+ y(0),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst, difference_type>(0) )
+ {}
+
+ PackedPixelColumnIterator( const MoveY& base, difference_type remainder ) :
+ y(base),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) ),
+ shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder) )
+ {}
+
+ PackedPixelColumnIterator& operator+=( difference_type d )
+ {
+ y += d;
+ return *this;
+ }
+
+ PackedPixelColumnIterator& operator-=( difference_type d )
+ {
+ y -= d;
+ return *this;
+ }
+
+ PackedPixelColumnIterator operator+( difference_type d )
+ {
+ PackedPixelColumnIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PackedPixelColumnIterator operator-( difference_type d )
+ {
+ PackedPixelColumnIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PackedPixelColumnIterator& operator++()
+ {
+ inc();
+ return *this;
+ }
+
+ PackedPixelColumnIterator& operator--()
+ {
+ dec();
+ return *this;
+ }
+
+ PackedPixelColumnIterator operator++(int)
+ {
+ PackedPixelColumnIterator res(*this);
+ inc();
+ return res;
+ }
+
+ PackedPixelColumnIterator operator--(int)
+ {
+ PackedPixelColumnIterator res(*this);
+ dec();
+ return res;
+ }
+
+ bool operator==(PackedPixelColumnIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PackedPixelColumnIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ bool operator>(PackedPixelColumnIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ difference_type operator-(PackedPixelColumnIterator const & rhs) const
+ {
+ return y - rhs.y;
+ }
+
+ value_type get() const
+ {
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return static_cast<unsigned int>(*y() & mask_) >> shift_;
+ }
+
+ value_type get(difference_type d) const
+ {
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return static_cast<unsigned int>(*y(d) & mask_) >> shift_;
+ }
+
+ void set( value_type v ) const
+ {
+ const value_type pixel_value( (v << shift_) & mask_ );
+ *y() = (*y() & ~mask_) | pixel_value;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ const value_type pixel_value( (v << shift_) & mask_ );
+ *y(d) = (*y(d) & ~mask_) | pixel_value;
+ }
+};
+
+template< typename Datatype,
+ typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelRowIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Datatype data_type;
+ typedef Valuetype value_type;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef typename remove_const<data_type>::type mask_type;
+ typedef data_type* pointer;
+
+ enum {
+ /** The number of pixel within a single data_type value
+ */
+ num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+private:
+ pointer data_;
+ mask_type mask_;
+ difference_type remainder_;
+
+ void update_mask()
+ {
+ mask_ = get_mask<data_type, bits_per_pixel, MsbFirst>(remainder_);
+ }
+
+ void inc()
+ {
+ const difference_type newValue( remainder_ + 1 );
+ const difference_type data_offset( newValue / num_intraword_positions );
+
+ data_ += data_offset;
+ remainder_ = newValue % num_intraword_positions;
+
+ const mask_type shifted_mask(
+ MsbFirst ?
+ // TODO(Q3): use traits to get unsigned type for data_type
+ // (if not already)
+ static_cast<unsigned int>(mask_) >> bits_per_pixel :
+ mask_ << bits_per_pixel );
+
+ // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
+ mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
+ bit_mask << bits_per_pixel*(num_intraword_positions-1) :
+ bit_mask);
+ }
+
+ void dec()
+ {
+ const difference_type newValue( remainder_ - 1 );
+ const bool isNegative( is_negative(newValue) );
+ const difference_type newRemainder( newValue % num_intraword_positions );
+
+ // calc data_ += newValue / num_intraword_positions;
+ // remainder_ = newRemainder;
+ // for newValue >= 0, and
+ // data_ += newValue / num_intraword_positions - 1;
+ // remainder_ = num_intraword_positions - newRemainder;
+ // (to force remainder_ to be positive).
+ // This is branch-free, if is_negative() is branch-free
+ const difference_type data_offset( newValue / num_intraword_positions - isNegative );
+ data_ += data_offset;
+ remainder_ = newRemainder + isNegative*num_intraword_positions;
+
+ const mask_type shifted_mask(
+ MsbFirst ?
+ mask_ << bits_per_pixel :
+ // TODO(Q3): use traits to get unsigned type for data_type
+ // (if not already)
+ static_cast<unsigned int>(mask_) >> bits_per_pixel );
+
+ // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
+ mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
+ bit_mask :
+ bit_mask << bits_per_pixel*(num_intraword_positions-1));
+ }
+
+ bool equal( PackedPixelRowIterator const & rhs ) const
+ {
+ return rhs.data_ == data_ && rhs.remainder_ == remainder_;
+ }
+
+ bool less( PackedPixelRowIterator const & rhs ) const
+ {
+ return data_ == rhs.data_ ?
+ (remainder_ < rhs.remainder_) :
+ (data_ < rhs.data_);
+ }
+
+public:
+ PackedPixelRowIterator() :
+ data_(0),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ remainder_(0)
+ {}
+
+ explicit PackedPixelRowIterator( pointer base, int x ) :
+ data_(base),
+ mask_(0),
+ remainder_(x % num_intraword_positions)
+ {
+ update_mask();
+ }
+
+ PackedPixelRowIterator& operator+=( difference_type d )
+ {
+ const difference_type newValue( remainder_ + d );
+
+ data_ += newValue / num_intraword_positions;
+ remainder_ = newValue % num_intraword_positions;
+ update_mask();
+
+ return *this;
+ }
+
+ PackedPixelRowIterator& operator-=( difference_type d )
+ {
+ const difference_type newValue( remainder_ - d );
+ const bool isNegative( is_negative(newValue) );
+ const difference_type newRemainder( newValue % num_intraword_positions );
+
+ // calc data_ += newValue / num_intraword_positions;
+ // remainder_ = newRemainder;
+ // for newValue >= 0, and
+ // data_ += newValue / num_intraword_positions - 1;
+ // remainder_ = num_intraword_positions - newRemainder;
+ // (to force remainder_ to be positive).
+ // This is branch-free, if is_negative() is branch-free
+ data_ += newValue / num_intraword_positions - isNegative;
+ remainder_ = newRemainder + isNegative*(num_intraword_positions - 2*newRemainder);
+ update_mask();
+
+ return *this;
+ }
+
+ PackedPixelRowIterator operator+( difference_type d )
+ {
+ PackedPixelRowIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PackedPixelRowIterator operator-( difference_type d )
+ {
+ PackedPixelRowIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PackedPixelRowIterator& operator++()
+ {
+ inc();
+ return *this;
+ }
+
+ PackedPixelRowIterator& operator--()
+ {
+ dec();
+ return *this;
+ }
+
+ PackedPixelRowIterator operator++(int)
+ {
+ PackedPixelRowIterator res(*this);
+ inc();
+ return res;
+ }
+
+ PackedPixelRowIterator operator--(int)
+ {
+ PackedPixelRowIterator res(*this);
+ dec();
+ return res;
+ }
+
+ bool operator==(PackedPixelRowIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PackedPixelRowIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PackedPixelRowIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PackedPixelRowIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ bool operator>(PackedPixelRowIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PackedPixelRowIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ difference_type operator-(PackedPixelRowIterator const & rhs) const
+ {
+ return (data_ - rhs.data_)*num_intraword_positions + (remainder_ - rhs.remainder_);
+ }
+
+ value_type get() const
+ {
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return static_cast<unsigned int>(*data_ & mask_) >>
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_);
+ }
+
+ value_type get(difference_type d) const
+ {
+ PackedPixelRowIterator tmp(*this);
+ tmp += d;
+ return tmp.get();
+ }
+
+ void set( value_type v ) const
+ {
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_))
+ & mask_ );
+ *data_ = (*data_ & ~mask_) | pixel_value;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ PackedPixelRowIterator tmp(*this);
+ tmp += d;
+ tmp.set(v);
+ }
+};
+
+template< typename Datatype,
+ typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Datatype data_type;
+ typedef Valuetype value_type;
+ typedef vigra::Diff2D difference_type;
+ typedef image_traverser_tag iterator_category;
+ typedef PackedPixelRowIterator<data_type,
+ value_type,
+ bits_per_pixel,
+ MsbFirst> row_iterator;
+ typedef PackedPixelColumnIterator<data_type,
+ value_type,
+ bits_per_pixel,
+ MsbFirst> column_iterator;
+
+ typedef data_type* pointer;
+ typedef int MoveX;
+ typedef StridedArrayIterator< data_type > MoveY;
+
+ enum {
+ /** The number of pixel within a single data_type value
+ */
+ num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+ // TODO(F2): direction of iteration (ImageIterator can be made to
+ // run backwards)
+
+private:
+ pointer current() const
+ {
+ return y() + (x / num_intraword_positions);
+ }
+
+ pointer current(int dx, int dy) const
+ {
+ return y(dy) + ((x+dx)/num_intraword_positions);
+ }
+
+ bool equal(PackedPixelIterator const & rhs) const
+ {
+ return (x == rhs.x) && (y == rhs.y);
+ }
+
+public:
+ PackedPixelIterator() :
+ x(0),
+ y(0)
+ {}
+
+ PackedPixelIterator(pointer base, int ystride) :
+ x(0),
+ y(ystride,base)
+ {}
+
+ bool operator==(PackedPixelIterator const & rhs) const
+ {
+ return equal(rhs);
+ }
+
+ bool operator!=(PackedPixelIterator const & rhs) const
+ {
+ return !equal(rhs);
+ }
+
+ difference_type operator-(PackedPixelIterator const & rhs) const
+ {
+ return difference_type(x - rhs.x, y - rhs.y);
+ }
+
+ MoveX x;
+ MoveY y;
+
+ PackedPixelIterator & operator+=(difference_type const & s)
+ {
+ x += s.x;
+ y += s.y;
+ return *this;
+ }
+
+ PackedPixelIterator & operator-=(difference_type const & s)
+ {
+ x -= s.x;
+ y -= s.y;
+ return *this;
+ }
+
+ PackedPixelIterator operator+(difference_type const & s) const
+ {
+ PackedPixelIterator ret(*this);
+ ret += s;
+ return ret;
+ }
+
+ PackedPixelIterator operator-(difference_type const & s) const
+ {
+ PackedPixelIterator ret(*this);
+ ret -= s;
+ return ret;
+ }
+
+ row_iterator rowIterator() const
+ {
+ return row_iterator(current(),x);
+ }
+
+ column_iterator columnIterator() const
+ {
+ return column_iterator(MoveY(y,
+ x / num_intraword_positions),
+ x % num_intraword_positions);
+ }
+
+ value_type get() const
+ {
+ const int remainder( x % num_intraword_positions );
+
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ value_type nTmp0( *current() );
+ unsigned int nTmp1(static_cast<unsigned int>(*current() &
+ get_mask<data_type, bits_per_pixel, MsbFirst>(remainder)));
+ unsigned int nTmp2( (static_cast<unsigned int>(*current() &
+ get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
+ >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder)));
+
+ return (static_cast<unsigned int>(*current() &
+ get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
+ >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
+ }
+
+ value_type get(difference_type const & d) const
+ {
+ const int remainder( x(d.x) % num_intraword_positions );
+
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return (static_cast<unsigned int>(*current(d.x,d.y) &
+ get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
+ >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
+ }
+
+ void set( value_type v ) const
+ {
+ const int remainder( x % num_intraword_positions );
+ const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
+ & mask );
+ pointer p = current();
+ *p = (*p & ~mask) | pixel_value;
+ }
+
+ void set( value_type v, difference_type const & d ) const
+ {
+ const int remainder( (x + d.x) % num_intraword_positions );
+ const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
+ & mask );
+ pointer p = current(d.x,d.y);
+ *p = (*p & ~mask) | pixel_value;
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX */
diff --git a/basebmp/inc/basebmp/paletteimageaccessor.hxx b/basebmp/inc/basebmp/paletteimageaccessor.hxx
new file mode 100644
index 000000000000..848ea59d7a50
--- /dev/null
+++ b/basebmp/inc/basebmp/paletteimageaccessor.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: paletteimageaccessor.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:42 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX
+#define INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX
+
+#include "metafunctions.hxx"
+
+#include <vigra/numerictraits.hxx>
+#include <vigra/mathutil.hxx>
+
+#include <algorithm>
+
+
+namespace basebmp
+{
+
+/** Access (possibly packed-pixel) data via palette indirection
+ */
+template< typename Valuetype, typename Datatype > class PaletteImageAccessor
+{
+public:
+ typedef Valuetype value_type;
+ typedef Datatype data_type;
+ typedef typename remove_const<data_type>::type count_type;
+
+
+private:
+ const value_type* palette;
+ count_type num_entries;
+
+ double norm( value_type const& rLHS,
+ value_type const& rRHS ) const
+ {
+ return (rRHS - rLHS).magnitude();
+ }
+
+ data_type find_best_match(value_type const& v) const
+ {
+ // TODO(P3): use table-based/octree approach here!
+ const value_type* best_entry;
+ const value_type* palette_end( palette+num_entries );
+ if( (best_entry=std::find( palette, palette_end, v)) != palette_end )
+ return best_entry-palette;
+
+ // TODO(F3): HACK. Need palette traits, and an error function
+ // here. We blatantly assume value_type is a normed linear
+ // space.
+ const value_type* curr_entry( palette );
+ best_entry = curr_entry;
+ while( curr_entry != palette_end )
+ {
+ if( norm(*curr_entry,*best_entry) > norm(*curr_entry,v) )
+ best_entry = curr_entry;
+
+ ++curr_entry;
+ }
+
+ return best_entry-palette;
+ }
+
+ value_type toCol( value_type const& rCol ) const
+ {
+ return rCol;
+ }
+
+public:
+ PaletteImageAccessor() :
+ palette(0),
+ num_entries(0)
+ {}
+
+ PaletteImageAccessor( const value_type* pPalette,
+ data_type entries ) :
+ palette(pPalette),
+ num_entries(entries)
+ {}
+
+ template< class Iterator >
+ value_type operator()(Iterator const& i) const { return toCol(palette[i.get()]); }
+ value_type operator()(data_type const* i) const { return toCol(palette[*i]); }
+
+ template< class Iterator, class Difference >
+ value_type operator()(Iterator const& i, Difference const& diff) const
+ {
+ return toCol(palette[i.get(diff)]);
+ }
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ i.set(
+ find_best_match(
+ vigra::detail::RequiresExplicitCast<value_type>::cast(value) ));
+ }
+
+ template< typename V, class Iterator, class Difference >
+ void set(V const& value, Iterator const& i, Difference const& diff) const
+ {
+ i.set(
+ find_best_match(
+ vigra::detail::RequiresExplicitCast<value_type>::cast(value)),
+ diff );
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX */
diff --git a/basebmp/inc/basebmp/pixeliterator.hxx b/basebmp/inc/basebmp/pixeliterator.hxx
new file mode 100644
index 000000000000..9f1f3c997ea2
--- /dev/null
+++ b/basebmp/inc/basebmp/pixeliterator.hxx
@@ -0,0 +1,362 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pixeliterator.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:43 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_PIXELITERATOR_HXX
+#define INCLUDED_BASEBMP_PIXELITERATOR_HXX
+
+#include "metafunctions.hxx"
+#include "stridedarrayiterator.hxx"
+
+#include <boost/static_assert.hpp>
+#include <vigra/metaprogramming.hxx>
+#include <vigra/diff2d.hxx>
+
+namespace basebmp
+{
+
+template< typename Valuetype > class PixelColumnIterator
+{
+public:
+ typedef Valuetype value_type;
+ typedef Valuetype& reference;
+ typedef Valuetype* pointer;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef StridedArrayIterator< value_type > MoveY;
+
+private:
+ MoveY y;
+
+ bool equal( PixelColumnIterator const & rhs ) const
+ {
+ return rhs.y == y;
+ }
+
+ bool less( PixelColumnIterator const & rhs ) const
+ {
+ return y < rhs.y;
+ }
+
+public:
+ PixelColumnIterator() :
+ y(0)
+ {}
+
+ explicit PixelColumnIterator( const MoveY& pos ) :
+ y(pos)
+ {}
+
+ PixelColumnIterator( const MoveY& pos, int x ) :
+ y(pos,x)
+ {}
+
+ PixelColumnIterator& operator+=( difference_type d )
+ {
+ y += d;
+ return *this;
+ }
+
+ PixelColumnIterator& operator-=( difference_type d )
+ {
+ y -= d;
+ return *this;
+ }
+
+ PixelColumnIterator operator+( difference_type d )
+ {
+ PixelColumnIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PixelColumnIterator operator-( difference_type d )
+ {
+ PixelColumnIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PixelColumnIterator& operator++()
+ {
+ ++y;
+ return *this;
+ }
+
+ PixelColumnIterator& operator--()
+ {
+ --y;
+ return *this;
+ }
+
+ PixelColumnIterator operator++(int)
+ {
+ PixelColumnIterator res(*this);
+ ++y;
+ return res;
+ }
+
+ PixelColumnIterator operator--(int)
+ {
+ PixelColumnIterator res(*this);
+ --y;
+ return res;
+ }
+
+ bool operator==(PixelColumnIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PixelColumnIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PixelColumnIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PixelColumnIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ bool operator>(PixelColumnIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PixelColumnIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ difference_type operator-(PixelColumnIterator const & rhs) const
+ {
+ return y - rhs.y;
+ }
+
+ value_type get() const
+ {
+ return *y();
+ }
+
+ value_type get(difference_type d) const
+ {
+ return *y(d);
+ }
+
+ void set( value_type v ) const
+ {
+ *y() = v;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ *y(d) = v;
+ }
+
+ reference operator*() const
+ {
+ return *y();
+ }
+
+ pointer operator->() const
+ {
+ return y();
+ }
+
+ reference operator[](difference_type d) const
+ {
+ return *y(d);
+ }
+
+ reference operator()(int dy) const
+ {
+ return *y(dy);
+ }
+};
+
+template< typename Valuetype > class PixelIterator
+{
+public:
+ typedef Valuetype value_type;
+ typedef Valuetype& reference;
+ typedef Valuetype* pointer;
+ typedef vigra::Diff2D difference_type;
+ typedef image_traverser_tag iterator_category;
+ typedef pointer row_iterator;
+ typedef PixelColumnIterator<value_type> column_iterator;
+
+ typedef int MoveX;
+ typedef StridedArrayIterator< value_type > MoveY;
+
+ // TODO(F2): direction of iteration (ImageIterator can be made to
+ // run backwards)
+
+private:
+ bool equal(PixelIterator const & rhs) const
+ {
+ return (x == rhs.x) && (y == rhs.y);
+ }
+
+ pointer current() const
+ {
+ return y() + x;
+ }
+
+ pointer current(int dx, int dy) const
+ {
+ return y(dy) + x+dy;
+ }
+
+public:
+ PixelIterator() :
+ x(0),
+ y(0)
+ {}
+
+ PixelIterator(pointer base, int ystride) :
+ x(0),
+ y(ystride,base)
+ {}
+
+ bool operator==(PixelIterator const & rhs) const
+ {
+ return equal(rhs);
+ }
+
+ bool operator!=(PixelIterator const & rhs) const
+ {
+ return !equal(rhs);
+ }
+
+ difference_type operator-(PixelIterator const & rhs) const
+ {
+ return difference_type(x - rhs.x, y - rhs.y);
+ }
+
+ MoveX x;
+ MoveY y;
+
+ PixelIterator & operator+=(difference_type const & s)
+ {
+ x += s.x;
+ y += s.y;
+ return *this;
+ }
+
+ PixelIterator & operator-=(difference_type const & s)
+ {
+ x -= s.x;
+ y -= s.y;
+ return *this;
+ }
+
+ PixelIterator operator+(difference_type const & s) const
+ {
+ PixelIterator ret(*this);
+ ret += s;
+ return ret;
+ }
+
+ PixelIterator operator-(difference_type const & s) const
+ {
+ PixelIterator ret(*this);
+ ret -= s;
+ return ret;
+ }
+
+ row_iterator rowIterator() const
+ {
+ return row_iterator(y()+x);
+ }
+
+ column_iterator columnIterator() const
+ {
+ return column_iterator(y,x);
+ }
+
+ value_type get() const
+ {
+ return *current();
+ }
+
+ value_type get(difference_type const & d) const
+ {
+ return *current(d.y, d.x);
+ }
+
+ void set( value_type v ) const
+ {
+ *current() = v;
+ }
+
+ void set( value_type v, difference_type const & d ) const
+ {
+ *current(d.y,d.x) = v;
+ }
+
+ reference operator*() const
+ {
+ return *current();
+ }
+
+ pointer operator->() const
+ {
+ return current();
+ }
+
+ reference operator[]( const vigra::Diff2D& d ) const
+ {
+ return *current(d.x,d.y);
+ }
+
+ reference operator()(int dx, int dy) const
+ {
+ return *current(dx,dy);
+ }
+
+ pointer operator[](int dy) const
+ {
+ return y(dy) + x;
+ }
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_PIXELITERATOR_HXX */
diff --git a/basebmp/inc/basebmp/scanlineformats.hxx b/basebmp/inc/basebmp/scanlineformats.hxx
new file mode 100644
index 000000000000..c0aef970c1a8
--- /dev/null
+++ b/basebmp/inc/basebmp/scanlineformats.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * $RCSfile: scanlineformats.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:43 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_SCANLINEFORMATS_HXX
+#define INCLUDED_BASEBMP_SCANLINEFORMATS_HXX
+
+/* Definition of Scanline formats */
+
+namespace basebmp { namespace Format
+{
+ static const sal_Int32 ONE_BIT_MSB_PAL = (sal_Int32)0x01;
+ static const sal_Int32 ONE_BIT_LSB_PAL = (sal_Int32)0x02;
+ static const sal_Int32 TWO_BIT_MSB_PAL = (sal_Int32)0x03;
+ static const sal_Int32 TWO_BIT_LSB_PAL = (sal_Int32)0x04;
+ static const sal_Int32 FOUR_BIT_MSB_PAL = (sal_Int32)0x05;
+ static const sal_Int32 FOUR_BIT_LSB_PAL = (sal_Int32)0x06;
+ static const sal_Int32 EIGHT_BIT_PAL = (sal_Int32)0x07;
+ static const sal_Int32 EIGHT_BIT_TC_MASK = (sal_Int32)0x0A;
+ static const sal_Int32 SIXTEEN_BIT_TC_MASK = (sal_Int32)0x0B;
+ static const sal_Int32 TWENTYFOUR_BIT_TC_MASK = (sal_Int32)0x0C;
+ static const sal_Int32 THIRTYTWO_BIT_TC_MASK = (sal_Int32)0x0D;
+} }
+
+#endif /* INCLUDED_BASEBMP_SCANLINEFORMATS_HXX */
diff --git a/basebmp/inc/basebmp/stridedarrayiterator.hxx b/basebmp/inc/basebmp/stridedarrayiterator.hxx
new file mode 100644
index 000000000000..bcff5a21c518
--- /dev/null
+++ b/basebmp/inc/basebmp/stridedarrayiterator.hxx
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: stridedarrayiterator.hxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:43 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BASEBMP_STRIDEDARRAYITERATOR_HXX
+#define INCLUDED_BASEBMP_STRIDEDARRAYITERATOR_HXX
+
+namespace basebmp
+{
+
+// changed semantics re. DirectionSelector<StridedArrayTag>: stride
+// now counts in <em>raw</em> bytes!
+template< typename T > class StridedArrayIterator
+{
+public:
+ typedef typename clone_const<T, unsigned char>::type internal_type;
+
+ StridedArrayIterator(int stride, T* ptr = 0) :
+ stride_(stride),
+ current_(reinterpret_cast<internal_type*>(ptr))
+ {}
+
+ /// Copy from other StridedArrayIterator, plus given offset
+ StridedArrayIterator( StridedArrayIterator const& rSrc,
+ int offset ) :
+ stride_(rSrc.stride_),
+ current_(reinterpret_cast<internal_type*>(
+ reinterpret_cast<T*>(rSrc.current_)+offset))
+ {}
+
+ void operator++() {current_ += stride_; }
+ void operator++(int) {current_ += stride_; }
+ void operator--() {current_ -= stride_; }
+ void operator--(int) {current_ -= stride_; }
+ void operator+=(int dy) {current_ += dy*stride_; }
+ void operator-=(int dy) {current_ -= dy*stride_; }
+
+ bool operator==(StridedArrayIterator const & rhs) const
+ { return (current_ == rhs.current_); }
+
+ bool operator!=(StridedArrayIterator const & rhs) const
+ { return (current_ != rhs.current_); }
+
+ bool operator<(StridedArrayIterator const & rhs) const
+ { return (current_ < rhs.current_); }
+
+ bool operator<=(StridedArrayIterator const & rhs) const
+ { return (current_ <= rhs.current_); }
+
+ bool operator>(StridedArrayIterator const & rhs) const
+ { return (current_ > rhs.current_); }
+
+ bool operator>=(StridedArrayIterator const & rhs) const
+ { return (current_ >= rhs.current_); }
+
+ int operator-(StridedArrayIterator const & rhs) const
+ { return (current_ - rhs.current_) / stride_; }
+
+ T* operator()() const
+ { return reinterpret_cast<T*>(current_); }
+
+ T* operator()(int d) const
+ { return reinterpret_cast<T*>(current_ + d*stride_); }
+
+ int stride_;
+ internal_type* current_;
+};
+
+} // namespace basebmp
+
+#endif /* INCLUDED_BASEBMP_STRIDEDARRAYITERATOR_HXX */
diff --git a/basebmp/prj/build.lst b/basebmp/prj/build.lst
new file mode 100644
index 000000000000..36813ae257d8
--- /dev/null
+++ b/basebmp/prj/build.lst
@@ -0,0 +1,4 @@
+bx basebmp : sal vigra basegfx boost NULL
+bx basebmp usr1 - all bx_mkout NULL
+bx basebmp\source nmake - all bx_source NULL
+bx basebmp\util nmake - all bx_util bx_source NULL
diff --git a/basebmp/prj/d.lst b/basebmp/prj/d.lst
new file mode 100644
index 000000000000..03cfbcd3fe25
--- /dev/null
+++ b/basebmp/prj/d.lst
@@ -0,0 +1,10 @@
+..\%__SRC%\lib\ibasebmp.lib %_DEST%\lib%_EXT%\ibasebmp.lib
+
+..\%__SRC%\bin\basebmp?????.dll %_DEST%\bin%_EXT%\basebmp?????.dll
+
+..\%__SRC%\lib\libbasebmp?????.* %_DEST%\lib%_EXT%\libbasebmp?????.*
+..\%__SRC%\lib\*.a %_DEST%\lib%_EXT%\*.a
+..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib
+
+mkdir: %_DEST%\inc%_EXT%\basebmp
+..\inc\basebmp\*.hxx %_DEST%\inc%_EXT%\basebmp\*.hxx
diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx
new file mode 100644
index 000000000000..3ee33010f2b2
--- /dev/null
+++ b/basebmp/source/bitmapdevice.cxx
@@ -0,0 +1,1023 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bitmapdevice.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:44 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "basebmp/bitmapdevice.hxx"
+#include "basebmp/packedpixeliterator.hxx"
+#include "basebmp/pixeliterator.hxx"
+#include "basebmp/paletteimageaccessor.hxx"
+#include "basebmp/color.hxx"
+#include "basebmp/accessor.hxx"
+#include "basebmp/accessoradapters.hxx"
+#include "basebmp/scanlineformats.hxx"
+#include "basebmp/linerenderer.hxx"
+
+#include <rtl/alloc.h>
+#include <rtl/memory.h>
+#include <osl/diagnose.h>
+
+#include <basegfx/tools/tools.hxx>
+#include <basegfx/range/b2irange.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygonclipper.hxx>
+#include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/vector/b2ivector.hxx>
+
+#include <vigra/basicimage.hxx>
+#include <vigra/imageiterator.hxx>
+
+
+namespace basebmp
+{
+
+namespace
+{
+ typedef PackedPixelIterator< sal_uInt8,
+ sal_uInt8,
+ 1,
+ true > MaskIterator;
+ typedef StandardAccessor< sal_uInt8 > MaskAccessor;
+
+ typedef vigra::ImageIterator< sal_uInt8 > AlphaMaskIterator;
+ typedef vigra::AccessorTraits< sal_uInt8 >::default_accessor AlphaMaskAccessor;
+
+
+ template< class DestIterator, class DestAccessor > class Renderer :
+ public basegfx::B2DPolyPolygonRasterConverter
+ {
+ private:
+ basegfx::B2IRange bounds_;
+ typename DestIterator::value_type fillColor_;
+ typename DestIterator::value_type clearColor_;
+ DestIterator begin_;
+ DestAccessor accessor_;
+
+ public:
+ Renderer(const basegfx::B2DPolyPolygon& rPolyPolyRaster,
+ typename DestIterator::value_type fillColor,
+ const basegfx::B2IRange& bounds,
+ DestIterator begin,
+ DestIterator end,
+ DestAccessor accessor ) :
+ B2DPolyPolygonRasterConverter(rPolyPolyRaster,
+ basegfx::B2DRange(bounds) ),
+ bounds_(bounds),
+ fillColor_( fillColor ),
+ begin_( begin ),
+ accessor_( accessor )
+ {
+ }
+
+ virtual void span(const double& rfXLeft,
+ const double& rfXRight,
+ sal_Int32 nY,
+ bool bOn )
+ {
+ if( !bOn ||
+ nY < bounds_.getMinY() ||
+ nY >= bounds_.getMaxY() ||
+ rfXLeft >= bounds_.getMaxX() ||
+ rfXRight < bounds_.getMinX() )
+ {
+ return;
+ }
+
+ // clip span to bitmap bounds
+ const sal_Int32 nStartX( std::max( bounds_.getMinX(),
+ std::min( bounds_.getMaxX()-1,
+ basegfx::fround( rfXLeft ))));
+ const sal_Int32 nEndX ( std::max( bounds_.getMinX(),
+ std::min( bounds_.getMaxX()-1,
+ basegfx::fround( rfXRight ))));
+
+ DestIterator currIter( begin_ + vigra::Diff2D(0,nY) );
+ typename DestIterator::row_iterator rowIter( currIter.rowIterator() + nStartX);
+ typename DestIterator::row_iterator rowEnd( currIter.rowIterator() + nEndX );
+
+ // TODO(P2): Provide specialized span fill methods on the
+ // iterator/accessor
+ while( rowIter != rowEnd )
+ accessor_.set(fillColor_, rowIter++);
+ }
+ };
+
+ template< class DestIterator, class DestAccessor >
+ std::auto_ptr< Renderer< DestIterator, DestAccessor > > makeRenderer(
+ const basegfx::B2DPolyPolygon& rPolyPolyRaster,
+ typename DestIterator::value_type fillColor,
+ const basegfx::B2IRange& outRange,
+ vigra::triple<DestIterator, DestIterator, DestAccessor> dest )
+ {
+ basegfx::B2IRange aBmpRange(0,0,
+ dest.second.x - dest.first.x,
+ dest.second.y - dest.first.y );
+ aBmpRange.intersect( outRange );
+
+ return std::auto_ptr< Renderer< DestIterator, DestAccessor > >(
+ new Renderer< DestIterator, DestAccessor >(rPolyPolyRaster,
+ fillColor,
+ aBmpRange,
+ dest.first,
+ dest.second,
+ dest.third));
+ }
+
+ template< class DestIterator, class DestAccessor > class BitmapRenderer : public BitmapDevice
+ {
+ public:
+ typedef BitmapRenderer<MaskIterator,
+ MaskAccessor> MaskBitmap;
+ typedef BitmapRenderer<AlphaMaskIterator,
+ AlphaMaskAccessor> AlphaMaskBitmap;
+ typedef typename xorAccessor<DestAccessor>::type XorAccessor;
+ typedef typename maskedAccessor<DestAccessor,
+ MaskAccessor,
+ DestIterator,
+ MaskIterator>::type MaskedAccessor;
+ typedef typename maskedAccessor<XorAccessor,
+ MaskAccessor,
+ DestIterator,
+ MaskIterator>::type MaskedXorAccessor;
+
+ DestIterator maBegin;
+ DestIterator maEnd;
+ DestAccessor maAccessor;
+ XorAccessor maXorAccessor;
+ MaskedAccessor maMaskedAccessor;
+ MaskedXorAccessor maMaskedXorAccessor;
+ int mnWidth;
+ int mnHeight;
+
+ BitmapRenderer( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat,
+ sal_Int32 nScanlineStride,
+ DestIterator begin,
+ DestIterator end,
+ DestAccessor accessor,
+ const RawMemorySharedPtr& rMem ) :
+ BitmapDevice( rSize, bTopDown, nScanlineFormat, nScanlineStride, rMem ),
+ maBegin( begin ),
+ maEnd( end ),
+ maAccessor( accessor ),
+ maXorAccessor( accessor ),
+ maMaskedAccessor( accessor ),
+ maMaskedXorAccessor( maXorAccessor ),
+ mnWidth( maEnd.x - maBegin.x ),
+ mnHeight( maEnd.y - maBegin.y )
+ {}
+
+ private:
+ boost::shared_ptr<BitmapRenderer> getCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
+ {
+ return boost::dynamic_pointer_cast< BitmapRenderer >( bmp );
+ }
+
+ virtual bool isCompatibleBitmap( const BitmapDeviceSharedPtr& bmp ) const
+ {
+ // TODO(P1): dynamic_cast usually called twice for
+ // compatible formats
+ return getCompatibleBitmap(bmp).get() != NULL;
+ }
+
+ boost::shared_ptr<MaskBitmap> getCompatibleMask( const BitmapDeviceSharedPtr& bmp ) const
+ {
+ return boost::dynamic_pointer_cast<MaskBitmap>( bmp );
+ }
+
+ virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const
+ {
+ // TODO(P1): dynamic_cast usually called twice for
+ // compatible formats
+ return getCompatibleMask( bmp ).get() != NULL;
+ }
+
+ boost::shared_ptr<AlphaMaskBitmap> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
+ {
+ return boost::dynamic_pointer_cast<AlphaMaskBitmap>( bmp );
+ }
+
+ virtual bool isCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const
+ {
+ // TODO(P1): dynamic_cast usually called twice for
+ // compatible formats
+ return getCompatibleAlphaMask( bmp ).get() != NULL;
+ }
+
+ virtual const Color* getPalette_i() const
+ {
+ // TODO(F3): Palette
+ return NULL;
+ }
+
+ virtual const sal_Int32 getPaletteEntryCount_i() const
+ {
+ // TODO(F3): Palette
+ return 0;
+ }
+
+ virtual void clear_i( Color fillColor )
+ {
+ DestIterator currIter( maBegin );
+ const DestIterator endIter( maBegin + vigra::Diff2D(0,mnHeight) );
+ while( currIter != endIter )
+ {
+ typename DestIterator::row_iterator rowIter( currIter.rowIterator() );
+ const typename DestIterator::row_iterator rowEnd( rowIter + mnWidth );
+
+ // TODO(P2): Provide specialized span fill methods on the
+ // iterator/accessor
+ while( rowIter != rowEnd )
+ maAccessor.set(fillColor, rowIter++);
+
+ currIter += vigra::Diff2D( 0,1 );
+ }
+ }
+
+ virtual void setPixel_i( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode )
+ {
+ const DestIterator pixel( maBegin +
+ vigra::Diff2D(rPt.getX(),
+ rPt.getY()) );
+ if( drawMode == DrawMode_XOR )
+ maXorAccessor.set( lineColor, pixel );
+ else
+ maAccessor.set( lineColor, pixel );
+ }
+
+ virtual void setPixel_i( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+ {
+ boost::shared_ptr<MaskBitmap> pMask( getCompatibleMask(rClip) );
+
+ const vigra::Diff2D offset(rPt.getX(),
+ rPt.getY());
+
+ const DestIterator pixel( maBegin + offset );
+ const MaskIterator maskPixel( pMask->maBegin + offset );
+
+ if( drawMode == DrawMode_XOR )
+ maMaskedXorAccessor.set( lineColor, pixel, maskPixel );
+ else
+ maMaskedAccessor.set( lineColor, pixel, maskPixel );
+ }
+
+ virtual Color getPixel_i(const basegfx::B2IPoint& rPt )
+ {
+ const DestIterator pixel( maBegin +
+ vigra::Diff2D(rPt.getX(),
+ rPt.getY()) );
+ return maAccessor(pixel);
+ }
+
+ virtual void drawLine_i(const basegfx::B2DPoint& rPt1,
+ const basegfx::B2DPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode )
+ {
+ renderLine( basegfx::fround(rPt1),
+ basegfx::fround(rPt2),
+ lineColor,
+ maBegin,
+ maEnd,
+ maAccessor );
+ }
+
+ virtual void drawLine_i(const basegfx::B2DPoint& rPt1,
+ const basegfx::B2DPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+ {
+ OSL_ENSURE( false, "drawLine_i(): Clipped output not yet implemented!" );
+ }
+
+ virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode )
+ {
+ const sal_uInt32 nVertices( rPoly.count() );
+ for( sal_uInt32 i=1; i<nVertices; ++i )
+ {
+ renderLine( basegfx::fround(rPoly.getB2DPoint(i-1)),
+ basegfx::fround(rPoly.getB2DPoint(i)),
+ lineColor,
+ maBegin,
+ maEnd,
+ maAccessor );
+ }
+
+ if( nVertices > 1 && rPoly.isClosed() )
+ renderLine( basegfx::fround(rPoly.getB2DPoint(nVertices-1)),
+ basegfx::fround(rPoly.getB2DPoint(0)),
+ lineColor,
+ maBegin,
+ maEnd,
+ maAccessor );
+ }
+
+ virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+ {
+ OSL_ENSURE( false, "drawPolygon_i(): clipped output not yet implemented!" );
+ }
+
+ virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const basegfx::B2IRange& rBounds )
+ {
+/*
+ if( drawMode == DrawMode_XOR )
+ makeRenderer( rPoly,
+ fillColor,
+ rBounds,
+ maBegin,
+ maEnd,
+ maXorAccessor )->rasterConvert(
+ basegfx::FillRule_NONZERO_WINDING_NUMBER );
+ else
+*/
+ makeRenderer( rPoly,
+ fillColor,
+ rBounds,
+ vigra::make_triple(
+ maBegin,
+ maEnd,
+ maAccessor) )->rasterConvert(
+ basegfx::FillRule_NONZERO_WINDING_NUMBER );
+ }
+
+ virtual void fillPolyPolygon_i(const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const basegfx::B2IRange& rBounds,
+ const BitmapDeviceSharedPtr& rClip )
+ {
+ OSL_ENSURE( false, "fillPolyPolygon_i(): Clipped output not yet implemented!" );
+/* Need uniform accessor for both plain and masked output. Combine
+ mask and bitmap iterator into proxy iterator, and pass that one
+ to the render method
+
+ if( drawMode == DrawMode_XOR )
+ makeRenderer( rPoly,
+ fillColor,
+ rBounds,
+ maBegin,
+ maEnd,
+ maMaskedXorAccessor )->rasterConvert(
+ basegfx::FillRule_NONZERO_WINDING_NUMBER );
+ else
+ makeRenderer( rPoly,
+ fillColor,
+ rBounds,
+ maBegin,
+ maEnd,
+ maMaskedAccessor )->rasterConvert(
+ basegfx::FillRule_NONZERO_WINDING_NUMBER );
+*/
+ }
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode )
+ {
+ OSL_ENSURE( false, "Method not yet implemented!" );
+ }
+
+ virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+ {
+ OSL_ENSURE( false, "Method not yet implemented!" );
+ }
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawMaskedColor_i(Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint )
+ {
+ OSL_ENSURE( false, "Method not yet implemented!" );
+ }
+
+ virtual void drawMaskedColor_i(Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint,
+ const BitmapDeviceSharedPtr& rClip )
+ {
+ OSL_ENSURE( false, "Method not yet implemented!" );
+ }
+
+ // must work with *this == rSrcBitmap!
+ virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode )
+ {
+ OSL_ENSURE( false, "Method not yet implemented!" );
+ }
+
+ virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const
+
+ BitmapDeviceSharedPtr& rClip )
+ {
+ OSL_ENSURE( false, "Method not yet implemented!" );
+ }
+ };
+} // namespace
+
+struct ImplBitmapDevice
+{
+ /// Bitmap memory plus deleter
+ RawMemorySharedPtr mpMem;
+
+ basegfx::B2IRange maBounds;
+ basegfx::B2DRange maFloatBounds;
+ sal_Int32 mnScanlineFormat;
+ sal_Int32 mnScanlineStride;
+};
+
+
+BitmapDevice::BitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat,
+ sal_Int32 nScanlineStride,
+ const RawMemorySharedPtr& rMem ) :
+ mpImpl( new ImplBitmapDevice )
+{
+ mpImpl->mpMem = rMem;
+ mpImpl->maBounds = basegfx::B2IRange( 0,0,rSize.getX(),rSize.getY() );
+ mpImpl->maFloatBounds = basegfx::B2DRange( 0,0,rSize.getX(),rSize.getY() );
+ mpImpl->mnScanlineFormat = nScanlineFormat;
+ mpImpl->mnScanlineStride = bTopDown ? nScanlineStride : -nScanlineStride;
+}
+
+BitmapDevice::~BitmapDevice()
+{
+ // outline, because of internal ImplBitmapDevice
+}
+
+basegfx::B2IVector BitmapDevice::getSize() const
+{
+ return basegfx::B2IVector( mpImpl->maBounds.getWidth(),
+ mpImpl->maBounds.getHeight() );
+}
+
+bool BitmapDevice::isTopDown() const
+{
+ return mpImpl->mnScanlineStride >= 0;
+}
+
+sal_Int32 BitmapDevice::getScanlineFormat() const
+{
+ return mpImpl->mnScanlineFormat;
+}
+
+sal_Int32 BitmapDevice::getScanlineStride() const
+{
+ return mpImpl->mnScanlineStride;
+}
+
+RawMemorySharedPtr BitmapDevice::getBuffer() const
+{
+ return mpImpl->mpMem;
+}
+
+const Color* BitmapDevice::getPalette() const
+{
+ return getPalette_i();
+}
+
+const sal_Int32 BitmapDevice::getPaletteEntryCount() const
+{
+ return getPaletteEntryCount_i();
+}
+
+void BitmapDevice::clear( Color fillColor )
+{
+ clear_i( fillColor );
+}
+
+void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode )
+{
+ if( mpImpl->maBounds.isInside(rPt) )
+ setPixel_i(rPt,lineColor,drawMode);
+}
+
+void BitmapDevice::setPixel( const basegfx::B2IPoint& rPt,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+{
+ if( mpImpl->maBounds.isInside(rPt) )
+ {
+ if( isCompatibleClipMask( rClip ) )
+ setPixel_i(rPt,lineColor,drawMode,rClip);
+ else
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+}
+
+Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt )
+{
+ if( mpImpl->maBounds.isInside(rPt) )
+ return getPixel_i(rPt);
+
+ return Color();
+}
+
+void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode )
+{
+ basegfx::B2DPoint aPt1( rPt1 );
+ basegfx::B2DPoint aPt2( rPt2 );
+
+ if( basegfx::tools::liangBarskyClip2D(aPt1,aPt2,mpImpl->maFloatBounds) )
+ drawLine_i( aPt1, aPt2,
+ lineColor,
+ drawMode );
+}
+
+void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1,
+ const basegfx::B2IPoint& rPt2,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+{
+#if 1
+ drawLine( rPt1, rPt2, lineColor, drawMode );
+#else
+ basegfx::B2DPoint aPt1( rPt1 );
+ basegfx::B2DPoint aPt2( rPt2 );
+
+ if( basegfx::tools::liangBarskyClip2D(aPt1,aPt2,mpImpl->maFloatBounds) )
+ {
+ if( isCompatibleClipMask( rClip ) )
+ drawLine_i( aPt1, aPt2,
+ lineColor,
+ drawMode,
+ rClip );
+ else
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+#endif
+}
+
+void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode )
+{
+ basegfx::B2DPolyPolygon aPoly(
+ basegfx::tools::clipPolygonOnRange( rPoly,
+ mpImpl->maFloatBounds,
+ true,
+ true ));
+ const sal_uInt32 numPolies( aPoly.count() );
+ for( sal_uInt32 i=0; i<numPolies; ++i )
+ if( aPoly.getB2DPolygon(i).count() )
+ drawPolygon_i( aPoly.getB2DPolygon(i), lineColor, drawMode );
+}
+
+void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly,
+ Color lineColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+{
+#if 1
+ drawPolygon( rPoly, lineColor, drawMode );
+#else
+ basegfx::B2DPolyPolygon aPoly(
+ basegfx::tools::clipPolygonOnRange( rPoly,
+ mpImpl->maFloatBounds,
+ true,
+ true ));
+ const sal_uInt32 numPolies( aPoly.count() );
+ for( sal_uInt32 i=0; i<numPolies; ++i )
+ if( aPoly.getB2DPolygon(i).count() )
+ if( isCompatibleClipMask( rClip ) )
+ drawPolygon_i( aPoly.getB2DPolygon(i), lineColor, drawMode, rClip );
+ else
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+#endif
+}
+
+void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode )
+{
+ fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds );
+}
+
+void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly,
+ Color fillColor,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+{
+#if 1
+ fillPolyPolygon( rPoly, fillColor, drawMode );
+#else
+ if( isCompatibleClipMask( rClip ) )
+ fillPolyPolygon_i( rPoly, fillColor, drawMode, mpImpl->maBounds, rClip );
+ else
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+#endif
+}
+
+
+namespace
+{
+ // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down
+ // to basegfx, and use here!
+ bool clipAreaImpl( ::basegfx::B2IRange* o_pDestArea,
+ ::basegfx::B2IRange& io_rSourceArea,
+ ::basegfx::B2IPoint& io_rDestPoint,
+ const ::basegfx::B2IRange& rSourceBounds,
+ const ::basegfx::B2IRange& rDestBounds )
+ {
+ const ::basegfx::B2IPoint aSourceTopLeft(
+ io_rSourceArea.getMinimum() );
+
+ ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
+
+ // clip source area (which must be inside rSourceBounds)
+ aLocalSourceArea.intersect( rSourceBounds );
+
+ if( aLocalSourceArea.isEmpty() )
+ return false;
+
+ // calc relative new source area points (relative to orig
+ // source area)
+ const ::basegfx::B2IVector aUpperLeftOffset(
+ aLocalSourceArea.getMinimum()-aSourceTopLeft );
+ const ::basegfx::B2IVector aLowerRightOffset(
+ aLocalSourceArea.getMaximum()-aSourceTopLeft );
+
+ ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
+ io_rDestPoint + aLowerRightOffset );
+
+ // clip dest area (which must be inside rDestBounds)
+ aLocalDestArea.intersect( rDestBounds );
+
+ if( aLocalDestArea.isEmpty() )
+ return false;
+
+ // calc relative new dest area points (relative to orig
+ // source area)
+ const ::basegfx::B2IVector aDestUpperLeftOffset(
+ aLocalDestArea.getMinimum()-io_rDestPoint );
+ const ::basegfx::B2IVector aDestLowerRightOffset(
+ aLocalDestArea.getMaximum()-io_rDestPoint );
+
+ io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
+ aSourceTopLeft + aDestLowerRightOffset );
+ io_rDestPoint = aLocalDestArea.getMinimum();
+
+ if( o_pDestArea )
+ *o_pDestArea = aLocalDestArea;
+
+ return true;
+ }
+}
+
+void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode )
+{
+ const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
+ const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
+
+ basegfx::B2IRange aSrcRange( rSrcRect );
+ basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() );
+ basegfx::B2IRange aDestRange;
+
+ // TODO(F2): Scaling/shrinking
+ if( clipAreaImpl( &aDestRange,
+ aSrcRange,
+ aDestPoint,
+ aSrcBounds,
+ mpImpl->maBounds ))
+ {
+ if( isCompatibleBitmap( rSrcBitmap ) )
+ drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode );
+ else
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+}
+
+void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+{
+ const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
+ const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
+
+ basegfx::B2IRange aSrcRange( rSrcRect );
+ basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() );
+ basegfx::B2IRange aDestRange;
+
+ // TODO(F2): Scaling/shrinking
+ if( clipAreaImpl( &aDestRange,
+ aSrcRange,
+ aDestPoint,
+ aSrcBounds,
+ mpImpl->maBounds ))
+ {
+ if( isCompatibleBitmap( rSrcBitmap ) &&
+ isCompatibleClipMask( rClip ) )
+ {
+ drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode, rClip );
+ }
+ else
+ {
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+ }
+}
+
+void BitmapDevice::drawMaskedColor( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint )
+{
+ const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
+ const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
+
+ basegfx::B2IRange aSrcRange( rSrcRect );
+ basegfx::B2IPoint aDestPoint( rDstPoint );
+
+ if( clipAreaImpl( NULL,
+ aSrcRange,
+ aDestPoint,
+ aSrcBounds,
+ mpImpl->maBounds ))
+ {
+ if( isCompatibleAlphaMask( rAlphaMask ) )
+ drawMaskedColor_i( rSrcColor, rAlphaMask, aSrcRange, aDestPoint );
+ else
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+}
+
+void BitmapDevice::drawMaskedColor( Color rSrcColor,
+ const BitmapDeviceSharedPtr& rAlphaMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IPoint& rDstPoint,
+ const BitmapDeviceSharedPtr& rClip )
+{
+ const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() );
+ const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
+
+ basegfx::B2IRange aSrcRange( rSrcRect );
+ basegfx::B2IPoint aDestPoint( rDstPoint );
+
+ if( clipAreaImpl( NULL,
+ aSrcRange,
+ aDestPoint,
+ aSrcBounds,
+ mpImpl->maBounds ))
+ {
+ if( isCompatibleAlphaMask( rAlphaMask ) &&
+ isCompatibleClipMask( rClip ) )
+ {
+ drawMaskedColor_i( rSrcColor, rAlphaMask, aSrcRange, aDestPoint, rClip );
+ }
+ else
+ {
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+ }
+}
+
+void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode )
+{
+ OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
+
+ const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
+ const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
+
+ basegfx::B2IRange aSrcRange( rSrcRect );
+ basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() );
+ basegfx::B2IRange aDestRange;
+
+ // TODO(F2): Scaling/shrinking
+ if( clipAreaImpl( &aDestRange,
+ aSrcRange,
+ aDestPoint,
+ aSrcBounds,
+ mpImpl->maBounds ))
+ {
+ if( isCompatibleBitmap( rSrcBitmap ) &&
+ isCompatibleClipMask( rMask ) )
+ {
+ drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode );
+ }
+ else
+ {
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+ }
+}
+
+void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap,
+ const BitmapDeviceSharedPtr& rMask,
+ const basegfx::B2IRange& rSrcRect,
+ const basegfx::B2IRange& rDstRect,
+ DrawMode drawMode,
+ const BitmapDeviceSharedPtr& rClip )
+{
+ OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() );
+
+ const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() );
+ const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() );
+
+ basegfx::B2IRange aSrcRange( rSrcRect );
+ basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() );
+ basegfx::B2IRange aDestRange;
+
+ // TODO(F2): Scaling/shrinking
+ if( clipAreaImpl( &aDestRange,
+ aSrcRange,
+ aDestPoint,
+ aSrcBounds,
+ mpImpl->maBounds ))
+ {
+ if( isCompatibleBitmap( rSrcBitmap ) &&
+ isCompatibleClipMask( rMask ) &&
+ isCompatibleClipMask( rClip ) )
+ {
+ drawMaskedBitmap_i( rSrcBitmap, rMask, aSrcRange, aDestRange, drawMode, rClip );
+ }
+ else
+ {
+ OSL_ENSURE( false, "Generic output not yet implemented!" );
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------------------
+
+typedef PaletteImageAccessor<Color,sal_uInt8> PaletteAccessor;
+typedef BitmapRenderer<MaskIterator,PaletteAccessor > OneBitMsbPaletteRenderer;
+typedef BitmapRenderer<AlphaMaskIterator,AlphaMaskAccessor> EightBitTrueColorRenderer;
+typedef PixelIterator<Color> ThirtyTwoBitPixelIterator;
+typedef BitmapRenderer<ThirtyTwoBitPixelIterator,
+ vigra::AccessorTraits<Color>::default_accessor> ThirtyTwoBitTrueColorRenderer;
+
+BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize,
+ bool bTopDown,
+ sal_Int32 nScanlineFormat )
+{
+ sal_Int32 nScanlineStride(0);
+
+ // HACK: 1bpp and 24bpp only, currently
+ if( nScanlineFormat == Format::ONE_BIT_MSB_PAL )
+ nScanlineStride = (rSize.getX() + 7) >> 3;
+ else if( nScanlineFormat == Format::EIGHT_BIT_TC_MASK )
+ nScanlineStride = rSize.getX();
+ else if( nScanlineFormat == Format::THIRTYTWO_BIT_TC_MASK )
+ nScanlineStride = 4*rSize.getX();
+
+ nScanlineStride *= bTopDown ? 1 : -1;
+
+ const std::size_t nMemSize(
+ (nScanlineStride < 0 ? -nScanlineStride : nScanlineStride)*rSize.getY() );
+
+ boost::shared_ptr< sal_uInt8 > pMem(
+ reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( nMemSize )),
+ &rtl_freeMemory );
+ sal_uInt8* pFirstScanline = nScanlineStride < 0 ?
+ pMem.get() + nMemSize : pMem.get();
+
+ rtl_zeroMemory(pMem.get(),nMemSize);
+
+ switch( nScanlineFormat )
+ {
+ case Format::ONE_BIT_MSB_PAL:
+ {
+ static Color bwPalette[] = { Color(0x00000000),
+ Color(0xFFFFFFFF) };
+
+ return BitmapDeviceSharedPtr(
+ new OneBitMsbPaletteRenderer(
+ rSize,
+ bTopDown,
+ nScanlineFormat,
+ nScanlineStride,
+ MaskIterator(pFirstScanline,
+ nScanlineStride),
+ MaskIterator(pFirstScanline,
+ nScanlineStride)
+ + vigra::Diff2D(rSize.getX(),
+ rSize.getY()),
+ PaletteAccessor( bwPalette,
+ sizeof(bwPalette)/sizeof(*bwPalette)),
+ pMem ));
+ }
+
+ case Format::EIGHT_BIT_TC_MASK:
+ {
+ return BitmapDeviceSharedPtr(
+ new EightBitTrueColorRenderer(
+ rSize,
+ bTopDown,
+ nScanlineFormat,
+ nScanlineStride,
+ AlphaMaskIterator(pFirstScanline,
+ nScanlineStride),
+ AlphaMaskIterator(pFirstScanline,
+ nScanlineStride)
+ + vigra::Diff2D(rSize.getX(),
+ rSize.getY()),
+ AlphaMaskAccessor(),
+ pMem ));
+ }
+
+ case Format::THIRTYTWO_BIT_TC_MASK:
+ {
+ return BitmapDeviceSharedPtr(
+ new ThirtyTwoBitTrueColorRenderer(
+ rSize,
+ bTopDown,
+ nScanlineFormat,
+ nScanlineStride,
+ ThirtyTwoBitPixelIterator(reinterpret_cast<Color*>(pFirstScanline),
+ nScanlineStride),
+ ThirtyTwoBitPixelIterator(reinterpret_cast<Color*>(pFirstScanline),
+ nScanlineStride)
+ + vigra::Diff2D(rSize.getX(),
+ rSize.getY()),
+ vigra::AccessorTraits<Color>::default_accessor(),
+ pMem ));
+ }
+
+ default:
+ // TODO(F3): other formats not yet implemented
+ return BitmapDeviceSharedPtr();
+ }
+}
+
+} // namespace basebmp
diff --git a/basebmp/source/debug.cxx b/basebmp/source/debug.cxx
new file mode 100644
index 000000000000..cb168a82db9f
--- /dev/null
+++ b/basebmp/source/debug.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * $RCSfile: debug.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:44 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/vector/b2ivector.hxx>
+
+#include <basebmp/scanlineformats.hxx>
+#include <basebmp/color.hxx>
+#include <basebmp/bitmapdevice.hxx>
+#include <basebmp/debug.hxx>
+
+#include <iomanip>
+
+namespace basebmp
+{
+ namespace
+ {
+ static const char* getFormatString( sal_Int32 nScanlineFormat )
+ {
+ switch( nScanlineFormat )
+ {
+ case Format::ONE_BIT_MSB_PAL:
+ return "ONE_BIT_MSB_PAL";
+ case Format::EIGHT_BIT_TC_MASK:
+ return "EIGHT_BIT_TC_MASK";
+ case Format::THIRTYTWO_BIT_TC_MASK:
+ return "THIRTYTWO_BIT_TC_MASK";
+ default:
+ return "<unknown>";
+ }
+ }
+ }
+
+ void debugDump( const BitmapDeviceSharedPtr& rDevice,
+ std::ostream& rOutputStream )
+ {
+ const basegfx::B2IVector aSize( rDevice->getSize() );
+ const bool bTopDown( rDevice->isTopDown() );
+ const sal_Int32 nScanlineFormat( rDevice->getScanlineFormat() );
+
+ rOutputStream
+ << "/* basebmp::BitmapDevice memory dump */" << std::endl
+ << "/* Width = " << aSize.getX() << " */" << std::endl
+ << "/* Height = " << aSize.getY() << " */" << std::endl
+ << "/* TopDown = " << bTopDown << " */" << std::endl
+ << "/* Format = " << getFormatString(nScanlineFormat) << " */" << std::endl
+ << std::endl;
+
+ rOutputStream << std::hex;
+ for( int y=0; y<aSize.getY(); ++y )
+ {
+ for( int x=0; x<aSize.getX(); ++x )
+ rOutputStream << std::setw(8) << (sal_uInt32)rDevice->getPixel( basegfx::B2IPoint(x,y) ) << " ";
+ rOutputStream << std::endl;
+ }
+ }
+}
diff --git a/basebmp/source/makefile.mk b/basebmp/source/makefile.mk
new file mode 100644
index 000000000000..827b53606b07
--- /dev/null
+++ b/basebmp/source/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: thb $ $Date: 2006-05-31 09:49:44 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..$/
+
+PRJNAME=basebmp
+TARGET=wrapper
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Common ----------------------------------------------------------
+
+SLOFILES = \
+ $(SLO)$/bitmapdevice.obj \
+ $(SLO)$/debug.obj
+
+# ==========================================================================
+
+.INCLUDE : target.mk
diff --git a/basebmp/test/basictest.cxx b/basebmp/test/basictest.cxx
new file mode 100644
index 000000000000..ef819c81ab6e
--- /dev/null
+++ b/basebmp/test/basictest.cxx
@@ -0,0 +1,133 @@
+// autogenerated file with codegen.pl
+
+#include <cppunit/simpleheader.hxx>
+
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+
+#include <basebmp/color.hxx>
+#include <basebmp/scanlineformats.hxx>
+#include <basebmp/bitmapdevice.hxx>
+
+using namespace ::basebmp;
+
+namespace
+{
+
+class BasicTest : public CppUnit::TestFixture
+{
+public:
+ void testConstruction()
+ {
+ const basegfx::B2ISize aSize(101,101);
+ basegfx::B2ISize aSize2(aSize);
+ BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize,
+ true,
+ Format::ONE_BIT_MSB_PAL ));
+ CPPUNIT_ASSERT_MESSAGE("right size",
+ pDevice->getSize() == aSize2 );
+ CPPUNIT_ASSERT_MESSAGE("Top down format",
+ pDevice->isTopDown() == true );
+ CPPUNIT_ASSERT_MESSAGE("Scanline format",
+ pDevice->getScanlineFormat() == Format::ONE_BIT_MSB_PAL );
+ CPPUNIT_ASSERT_MESSAGE("Scanline len",
+ pDevice->getScanlineStride() == (aSize2.getY() + 7)/8 );
+ }
+
+ void testPixelFuncs()
+ {
+ // 1bpp
+ const basegfx::B2ISize aSize(101,101);
+ BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize,
+ true,
+ Format::ONE_BIT_MSB_PAL ));
+
+ const basegfx::B2IPoint aPt(3,3);
+ const Color aCol(0xFFFFFFFF);
+ pDevice->setPixel( aPt, aCol, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #1",
+ pDevice->getPixel(aPt) == aCol);
+
+ const basegfx::B2IPoint aPt2(0,0);
+ const Color aCol2(0xFFFFFFFF);
+ pDevice->setPixel( aPt2, aCol2, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #2",
+ pDevice->getPixel(aPt2) == aCol2);
+
+ const basegfx::B2IPoint aPt3(aSize.getX()-1,aSize.getY()-1);
+ const Color aCol3(0x00000000);
+ pDevice->setPixel( aPt3, aCol3, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #3",
+ pDevice->getPixel(aPt3) == aCol3);
+
+ const basegfx::B2IPoint aPt4(-100000,-100000);
+ pDevice->setPixel( aPt4, aCol3, DrawMode_PAINT );
+ const basegfx::B2IPoint aPt5(100000,100000);
+ pDevice->setPixel( aPt5, aCol3, DrawMode_PAINT );
+
+ // 8bpp
+ {
+ pDevice = createBitmapDevice( aSize,
+ true,
+ Format::EIGHT_BIT_TC_MASK );
+
+ const Color aCol4(0x01);
+ pDevice->setPixel( aPt, aCol4, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #4",
+ pDevice->getPixel(aPt) == aCol4);
+
+ const Color aCol5(0x0F);
+ pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #5",
+ pDevice->getPixel(aPt2) == aCol5);
+
+ const Color aCol6(0xFF);
+ pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #6",
+ pDevice->getPixel(aPt3) == aCol6);
+ }
+
+ // 32bpp
+ {
+ pDevice = createBitmapDevice( aSize,
+ true,
+ Format::THIRTYTWO_BIT_TC_MASK );
+
+ const Color aCol4(0x01010101);
+ pDevice->setPixel( aPt, aCol4, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #7",
+ pDevice->getPixel(aPt) == aCol4);
+
+ const Color aCol5(0x0F0F0F0F);
+ pDevice->setPixel( aPt2, aCol5, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #8",
+ pDevice->getPixel(aPt2) == aCol5);
+
+ const Color aCol6(0xFFFFFFFF);
+ pDevice->setPixel( aPt3, aCol6, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #9",
+ pDevice->getPixel(aPt3) == aCol6);
+ }
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(BasicTest);
+ CPPUNIT_TEST(testConstruction);
+ CPPUNIT_TEST(testPixelFuncs);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+// -----------------------------------------------------------------------------
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicTest, "BasicTest");
+}
+
+
+// -----------------------------------------------------------------------------
+
+// this macro creates an empty function, which will called by the RegisterAllFunctions()
+// to let the user the possibility to also register some functions by hand.
+NOADDITIONAL;
+
diff --git a/basebmp/test/bmpdemo.cxx b/basebmp/test/bmpdemo.cxx
new file mode 100644
index 000000000000..29d5c143b4af
--- /dev/null
+++ b/basebmp/test/bmpdemo.cxx
@@ -0,0 +1,1278 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: bmpdemo.cxx,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: thb $ $Date: 2006-05-31 09:49:44 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#ifndef _USE_MATH_DEFINES
+#define _USE_MATH_DEFINES // needed by Visual C++ for math constants
+#endif
+#include <math.h>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/regpathhelper.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+
+#include <ucbhelper/contentbroker.hxx>
+#include <ucbhelper/configurationkeys.hxx>
+
+#include <vcl/window.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/msgbox.hxx>
+#include <vcl/unowrap.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/bmpacc.hxx>
+
+#include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+
+#include <basebmp/color.hxx>
+#include <basebmp/scanlineformats.hxx>
+#include <basebmp/bitmapdevice.hxx>
+
+#include <rtl/bootstrap.hxx>
+
+#include <vigra/metaprogramming.hxx>
+#include <vigra/static_assert.hxx>
+#include <vigra/resizeimage.hxx>
+#include <vigra/basicimageview.hxx>
+
+#include <boost/static_assert.hpp>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+
+
+namespace
+{
+
+/// template meta function: add const qualifier, if given 2nd type has it
+template<typename A, typename B> struct clone_const
+{
+ typedef B type;
+};
+template<typename A, typename B> struct clone_const<const A,B>
+{
+ typedef const B type;
+};
+
+template< class DestIterator, class DestAccessor > class Renderer :
+ public basegfx::B2DPolyPolygonRasterConverter
+{
+private:
+ typename DestIterator::value_type fillColor_;
+ typename DestIterator::value_type clearColor_;
+ DestIterator begin_;
+ DestAccessor accessor_;
+
+public:
+ Renderer(const basegfx::B2DPolyPolygon& rPolyPolyRaster,
+ typename DestIterator::value_type fillColor,
+ typename DestIterator::value_type clearColor,
+ DestIterator begin,
+ DestIterator end,
+ DestAccessor accessor ) :
+ B2DPolyPolygonRasterConverter(rPolyPolyRaster,
+ basegfx::B2DRange(0,0,
+ end.x - end.x,
+ begin.y - begin.y )),
+ fillColor_( fillColor ),
+ clearColor_( clearColor ),
+ begin_( begin ),
+ accessor_( accessor )
+ {
+ }
+
+ virtual void span(const double& rfXLeft,
+ const double& rfXRight,
+ sal_Int32 nY,
+ bool bOn )
+ {
+ DestIterator currIter( begin_ + vigra::Diff2D(0,nY) );
+ typename DestIterator::row_iterator rowIter( currIter.rowIterator() +
+ basegfx::fround(rfXLeft) );
+ typename DestIterator::row_iterator rowEnd( currIter.rowIterator() +
+ basegfx::fround(rfXRight) );
+ if( bOn )
+ while( rowIter != rowEnd )
+ {
+ accessor_.set(fillColor_, rowIter);
+ ++rowIter;
+ }
+ else
+ while( rowIter != rowEnd )
+ {
+ accessor_.set(accessor_(rowIter)*clearColor_, rowIter);
+ ++rowIter;
+ }
+ }
+};
+
+template< class DestIterator, class DestAccessor >
+ std::auto_ptr< Renderer< DestIterator, DestAccessor > > makeRenderer(
+ const basegfx::B2DPolyPolygon& rPolyPolyRaster,
+ typename DestIterator::value_type fillColor,
+ typename DestIterator::value_type clearColor,
+ vigra::triple<DestIterator, DestIterator, DestAccessor> dest )
+{
+ return std::auto_ptr< Renderer< DestIterator, DestAccessor > >(
+ new Renderer< DestIterator, DestAccessor >(rPolyPolyRaster,
+ fillColor,
+ clearColor,
+ dest.first,
+ dest.second,
+ dest.third));
+}
+
+
+// changed semantics re. DirectionSelector<StridedArrayTag>: stride
+// now counts in <em>raw</em> bytes!
+template< typename T > class StridedArrayIterator
+{
+public:
+ typedef typename clone_const<T, unsigned char>::type internal_type;
+
+ StridedArrayIterator(int stride, T* ptr = 0) :
+ stride_(stride),
+ current_(reinterpret_cast<internal_type*>(ptr))
+ {}
+
+ /// Copy from other StridedArrayIterator, plus given offset
+ StridedArrayIterator( StridedArrayIterator const& rSrc,
+ int offset ) :
+ stride_(rSrc.stride_),
+ current_(reinterpret_cast<internal_type*>(
+ reinterpret_cast<T*>(rSrc.current_)+offset))
+ {}
+
+ void operator++() {current_ += stride_; }
+ void operator++(int) {current_ += stride_; }
+ void operator--() {current_ -= stride_; }
+ void operator--(int) {current_ -= stride_; }
+ void operator+=(int dy) {current_ += dy*stride_; }
+ void operator-=(int dy) {current_ -= dy*stride_; }
+
+ bool operator==(StridedArrayIterator const & rhs) const
+ { return (current_ == rhs.current_); }
+
+ bool operator!=(StridedArrayIterator const & rhs) const
+ { return (current_ != rhs.current_); }
+
+ bool operator<(StridedArrayIterator const & rhs) const
+ { return (current_ < rhs.current_); }
+
+ bool operator<=(StridedArrayIterator const & rhs) const
+ { return (current_ <= rhs.current_); }
+
+ bool operator>(StridedArrayIterator const & rhs) const
+ { return (current_ > rhs.current_); }
+
+ bool operator>=(StridedArrayIterator const & rhs) const
+ { return (current_ >= rhs.current_); }
+
+ int operator-(StridedArrayIterator const & rhs) const
+ { return (current_ - rhs.current_) / stride_; }
+
+ T* operator()() const
+ { return reinterpret_cast<T*>(current_); }
+
+ T* operator()(int d) const
+ { return reinterpret_cast<T*>(current_ + d*stride_); }
+
+ int stride_;
+ internal_type* current_;
+};
+
+/// template meta function: remove const qualifier from plain type
+template <typename T> struct remove_const
+{
+ typedef T type;
+};
+template <typename T> struct remove_const<const T>
+{
+ typedef T type;
+};
+
+/// returns true, if given number is strictly less than 0
+template< typename T > inline bool is_negative( T x )
+{
+ return x < 0;
+}
+
+/// Overload for ints (branch-free)
+inline bool is_negative( int x )
+{
+ // force logic shift (result for signed shift right is undefined)
+ return static_cast<unsigned int>(x) >> (sizeof(int)*8-1);
+}
+
+/// Get bitmask for data at given intra-word position, for given bit depth
+template< typename data_type, int bits_per_pixel, bool MsbFirst, typename difference_type > inline data_type get_mask( difference_type d )
+{
+ BOOST_STATIC_ASSERT(bits_per_pixel > 0);
+ BOOST_STATIC_ASSERT(sizeof(data_type)*8 % bits_per_pixel == 0);
+ BOOST_STATIC_ASSERT(sizeof(data_type)*8 / bits_per_pixel > 1);
+ BOOST_STATIC_ASSERT(vigra::TypeTraits<data_type>::isPOD::asBool);
+
+ const unsigned int nIntraWordPositions( sizeof(data_type)*8 / bits_per_pixel );
+
+ // create bits_per_pixel 1s shift to intra-word position
+ return ((~(~0 << bits_per_pixel)) << bits_per_pixel*(MsbFirst ?
+ (nIntraWordPositions-1 - (d % nIntraWordPositions)) :
+ (d % nIntraWordPositions)));
+}
+
+template< int num_intraword_positions, int bits_per_pixel, bool MsbFirst, typename difference_type > inline difference_type get_shift( difference_type remainder )
+{
+ return bits_per_pixel*(MsbFirst ?
+ (num_intraword_positions - 1 - remainder) :
+ remainder);
+}
+
+template< typename Datatype,
+ typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelColumnIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Datatype data_type;
+ typedef Valuetype value_type;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef typename remove_const<data_type>::type mask_type;
+ typedef data_type* pointer;
+ typedef StridedArrayIterator< data_type > MoveY;
+
+ enum {
+ /** The number of pixel within a single data_type value
+ */
+ num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+private:
+ MoveY y;
+ mask_type mask_;
+ difference_type shift_;
+
+ void inc()
+ {
+ ++y;
+ }
+
+ void dec()
+ {
+ --y;
+ }
+
+ bool equal( PackedPixelColumnIterator const & rhs ) const
+ {
+ return rhs.y == y;
+ }
+
+ bool less( PackedPixelColumnIterator const & rhs ) const
+ {
+ return y < rhs.y;
+ }
+
+public:
+ PackedPixelColumnIterator() :
+ y(0),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst, difference_type>(0) )
+ {}
+
+ PackedPixelColumnIterator( const MoveY& base, difference_type remainder ) :
+ y(base),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) ),
+ shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder) )
+ {}
+
+ PackedPixelColumnIterator& operator+=( difference_type d )
+ {
+ y += d;
+ return *this;
+ }
+
+ PackedPixelColumnIterator& operator-=( difference_type d )
+ {
+ y -= d;
+ return *this;
+ }
+
+ PackedPixelColumnIterator operator+( difference_type d )
+ {
+ PackedPixelColumnIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PackedPixelColumnIterator operator-( difference_type d )
+ {
+ PackedPixelColumnIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PackedPixelColumnIterator& operator++()
+ {
+ inc();
+ return *this;
+ }
+
+ PackedPixelColumnIterator& operator--()
+ {
+ dec();
+ return *this;
+ }
+
+ PackedPixelColumnIterator operator++(int)
+ {
+ PackedPixelColumnIterator res(*this);
+ res.inc();
+ return res;
+ }
+
+ PackedPixelColumnIterator operator--(int)
+ {
+ PackedPixelColumnIterator res(*this);
+ res.dec();
+ return res;
+ }
+
+ bool operator==(PackedPixelColumnIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PackedPixelColumnIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ bool operator>(PackedPixelColumnIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PackedPixelColumnIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ difference_type operator-(PackedPixelColumnIterator const & rhs) const
+ {
+ return y - rhs.y;
+ }
+
+ value_type get() const
+ {
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return static_cast<unsigned int>(*y() & mask_) >> shift_;
+ }
+
+ value_type get(difference_type d) const
+ {
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return static_cast<unsigned int>(*y(d) & mask_) >> shift_;
+ }
+
+ void set( value_type v ) const
+ {
+ const value_type pixel_value( (v << shift_) & mask_ );
+ *y() = (*y() & ~mask_) | pixel_value;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ const value_type pixel_value( (v << shift_) & mask_ );
+ *y(d) = (*y(d) & ~mask_) | pixel_value;
+ }
+};
+
+template< typename Datatype,
+ typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelRowIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Datatype data_type;
+ typedef Valuetype value_type;
+ typedef int difference_type;
+ typedef image_traverser_tag iterator_category;
+
+ typedef typename remove_const<data_type>::type mask_type;
+ typedef data_type* pointer;
+
+ enum {
+ /** The number of pixel within a single data_type value
+ */
+ num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+private:
+ pointer data_;
+ mask_type mask_;
+ difference_type remainder_;
+
+ void update_mask()
+ {
+ mask_ = get_mask<data_type, bits_per_pixel, MsbFirst>(remainder_);
+ }
+
+ void inc()
+ {
+ const difference_type newValue( remainder_ + 1 );
+ const difference_type data_offset( newValue / num_intraword_positions );
+
+ data_ += data_offset;
+ remainder_ = newValue % num_intraword_positions;
+
+ const mask_type shifted_mask(
+ MsbFirst ?
+ // TODO(Q3): use traits to get unsigned type for data_type
+ // (if not already)
+ static_cast<unsigned int>(mask_) >> bits_per_pixel :
+ mask_ << bits_per_pixel );
+
+ // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
+ mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
+ bit_mask << bits_per_pixel*(num_intraword_positions-1) :
+ bit_mask);
+ }
+
+ void dec()
+ {
+ const difference_type newValue( remainder_ - 1 );
+ const bool isNegative( is_negative(newValue) );
+ const difference_type newRemainder( newValue % num_intraword_positions );
+
+ // calc data_ += newValue / num_intraword_positions;
+ // remainder_ = newRemainder;
+ // for newValue >= 0, and
+ // data_ += newValue / num_intraword_positions - 1;
+ // remainder_ = num_intraword_positions - newRemainder;
+ // (to force remainder_ to be positive).
+ // This is branch-free, if is_negative() is branch-free
+ const difference_type data_offset( newValue / num_intraword_positions - isNegative );
+ data_ += data_offset;
+ remainder_ = newRemainder + isNegative*num_intraword_positions;
+
+ const mask_type shifted_mask(
+ MsbFirst ?
+ mask_ << bits_per_pixel :
+ // TODO(Q3): use traits to get unsigned type for data_type
+ // (if not already)
+ static_cast<unsigned int>(mask_) >> bits_per_pixel );
+
+ // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
+ mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
+ bit_mask :
+ bit_mask << bits_per_pixel*(num_intraword_positions-1));
+ }
+
+ bool equal( PackedPixelRowIterator const & rhs ) const
+ {
+ return rhs.data_ == data_ && rhs.remainder_ == remainder_;
+ }
+
+ bool less( PackedPixelRowIterator const & rhs ) const
+ {
+ return data_ == rhs.data_ ?
+ (remainder_ < rhs.remainder_) :
+ (data_ < rhs.data_);
+ }
+
+public:
+ PackedPixelRowIterator() :
+ data_(0),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ remainder_(0)
+ {}
+
+ explicit PackedPixelRowIterator( pointer base ) :
+ data_(base),
+ mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
+ remainder_(0)
+ {}
+
+ PackedPixelRowIterator& operator+=( difference_type d )
+ {
+ const difference_type newValue( remainder_ + d );
+
+ data_ += newValue / num_intraword_positions;
+ remainder_ = newValue % num_intraword_positions;
+ update_mask();
+
+ return *this;
+ }
+
+ PackedPixelRowIterator& operator-=( difference_type d )
+ {
+ const difference_type newValue( remainder_ - d );
+ const bool isNegative( is_negative(newValue) );
+ const difference_type newRemainder( newValue % num_intraword_positions );
+
+ // calc data_ += newValue / num_intraword_positions;
+ // remainder_ = newRemainder;
+ // for newValue >= 0, and
+ // data_ += newValue / num_intraword_positions - 1;
+ // remainder_ = num_intraword_positions - newRemainder;
+ // (to force remainder_ to be positive).
+ // This is branch-free, if is_negative() is branch-free
+ data_ += newValue / num_intraword_positions - isNegative;
+ remainder_ = newRemainder + isNegative*(num_intraword_positions - 2*newRemainder);
+ update_mask();
+
+ return *this;
+ }
+
+ PackedPixelRowIterator operator+( difference_type d )
+ {
+ PackedPixelRowIterator res(*this);
+ res += d;
+ return res;
+ }
+
+ PackedPixelRowIterator operator-( difference_type d )
+ {
+ PackedPixelRowIterator res(*this);
+ res -= d;
+ return res;
+ }
+
+ PackedPixelRowIterator& operator++()
+ {
+ inc();
+ return *this;
+ }
+
+ PackedPixelRowIterator& operator--()
+ {
+ dec();
+ return *this;
+ }
+
+ PackedPixelRowIterator operator++(int)
+ {
+ PackedPixelRowIterator res(*this);
+ res.inc();
+ return res;
+ }
+
+ PackedPixelRowIterator operator--(int)
+ {
+ PackedPixelRowIterator res(*this);
+ res.dec();
+ return res;
+ }
+
+ bool operator==(PackedPixelRowIterator const & rhs) const
+ {
+ return equal( rhs );
+ }
+
+ bool operator!=(PackedPixelRowIterator const & rhs) const
+ {
+ return !equal( rhs );
+ }
+
+ bool operator<(PackedPixelRowIterator const & rhs) const
+ {
+ return less(rhs);
+ }
+
+ bool operator<=(PackedPixelRowIterator const & rhs) const
+ {
+ return !less(rhs);
+ }
+
+ bool operator>(PackedPixelRowIterator const & rhs) const
+ {
+ return rhs.less(*this);
+ }
+
+ bool operator>=(PackedPixelRowIterator const & rhs) const
+ {
+ return !rhs.less(*this);
+ }
+
+ difference_type operator-(PackedPixelRowIterator const & rhs) const
+ {
+ return (data_ - rhs.data_)*num_intraword_positions + (remainder_ - rhs.remainder_);
+ }
+
+ value_type get() const
+ {
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return static_cast<unsigned int>(*data_ & mask_) >>
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_);
+ }
+
+ value_type get(difference_type d) const
+ {
+ PackedPixelRowIterator tmp(*this);
+ tmp += d;
+ return tmp.get();
+ }
+
+ void set( value_type v ) const
+ {
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_))
+ & mask_ );
+ *data_ = (*data_ & ~mask_) | pixel_value;
+ }
+
+ void set( value_type v, difference_type d ) const
+ {
+ PackedPixelRowIterator tmp(*this);
+ tmp += d;
+ tmp.set(v);
+ }
+};
+
+template< typename Datatype,
+ typename Valuetype,
+ int bits_per_pixel,
+ bool MsbFirst > class PackedPixelIterator
+{
+public:
+ // no reference, no index_reference type here
+ typedef Datatype data_type;
+ typedef Valuetype value_type;
+ typedef vigra::Diff2D difference_type;
+ typedef image_traverser_tag iterator_category;
+ typedef PackedPixelRowIterator<data_type,
+ value_type,
+ bits_per_pixel,
+ MsbFirst> row_iterator;
+ typedef PackedPixelColumnIterator<data_type,
+ value_type,
+ bits_per_pixel,
+ MsbFirst> column_iterator;
+
+ typedef data_type* pointer;
+ typedef int MoveX;
+ typedef StridedArrayIterator< data_type > MoveY;
+
+ enum {
+ /** The number of pixel within a single data_type value
+ */
+ num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
+ /** Bit mask for one pixel (least significant bits)
+ */
+ bit_mask=~(~0 << bits_per_pixel)
+ };
+
+ // TODO(F2): direction of iteration (ImageIterator can be made to
+ // run backwards)
+
+private:
+ pointer current() const
+ {
+ return y() + (x / num_intraword_positions);
+ }
+
+ pointer current(int dx, int dy) const
+ {
+ return y(dy) + ((x+dx)/num_intraword_positions);
+ }
+
+ bool equal(PackedPixelIterator const & rhs) const
+ {
+ return (x == rhs.x) && (y == rhs.y);
+ }
+
+public:
+ PackedPixelIterator() :
+ x(0),
+ y(0)
+ {}
+
+ PackedPixelIterator(pointer base, int ystride) :
+ x(0),
+ y(ystride,base)
+ {}
+
+ bool operator==(PackedPixelIterator const & rhs) const
+ {
+ return equal(rhs);
+ }
+
+ bool operator!=(PackedPixelIterator const & rhs) const
+ {
+ return !equal(rhs);
+ }
+
+ difference_type operator-(PackedPixelIterator const & rhs) const
+ {
+ return difference_type(x - rhs.x, y - rhs.y);
+ }
+
+ MoveX x;
+ MoveY y;
+
+ PackedPixelIterator & operator+=(difference_type const & s)
+ {
+ x += s.x;
+ y += s.y;
+ return *this;
+ }
+
+ PackedPixelIterator & operator-=(difference_type const & s)
+ {
+ x -= s.x;
+ y -= s.y;
+ return *this;
+ }
+
+ PackedPixelIterator operator+(difference_type const & s) const
+ {
+ PackedPixelIterator ret(*this);
+ ret += s;
+ return ret;
+ }
+
+ PackedPixelIterator operator-(difference_type const & s) const
+ {
+ PackedPixelIterator ret(*this);
+ ret -= s;
+ return ret;
+ }
+
+ row_iterator rowIterator() const
+ {
+ return row_iterator(current());
+ }
+
+ column_iterator columnIterator() const
+ {
+ return column_iterator(MoveY(y,
+ x / num_intraword_positions),
+ x % num_intraword_positions);
+ }
+
+ value_type get() const
+ {
+ const int remainder( x() % num_intraword_positions );
+
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return (static_cast<unsigned int>(*current() &
+ get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
+ >> (MsbFirst ?
+ (num_intraword_positions - remainder) :
+ remainder));
+ }
+
+ value_type get(difference_type const & d) const
+ {
+ const int remainder( x(d.x) % num_intraword_positions );
+
+ // TODO(Q3): use traits to get unsigned type for data_type (if
+ // not already)
+ return (static_cast<unsigned int>(*current(d.x,d.y) &
+ get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
+ >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
+ }
+
+ void set( value_type v ) const
+ {
+ const int remainder( x() % num_intraword_positions );
+ const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
+ & mask );
+ pointer p = current();
+ *p = (*p & ~mask) | pixel_value;
+ }
+
+ void set( value_type v, difference_type const & d ) const
+ {
+ const int remainder( x(d.x) % num_intraword_positions );
+ const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
+ const value_type pixel_value(
+ (v <<
+ get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
+ & mask );
+ pointer p = current(d.x,d.y);
+ *p = (*p & ~mask) | pixel_value;
+ }
+};
+
+
+/** Access (possibly packed-pixel) data via palette indirection
+ */
+template< typename Valuetype, typename Datatype > class PaletteImageAccessor
+{
+ public:
+ typedef Valuetype value_type;
+ typedef Datatype data_type;
+ typedef typename remove_const<data_type>::type count_type;
+
+
+private:
+ const BitmapColor* palette;
+ count_type num_entries;
+
+ double norm( BitmapColor const& rLHS,
+ BitmapColor const& rRHS ) const
+ {
+ // convert RGBValue's linear space to a normed linear space
+ return sqrt(
+ vigra::sq(rLHS.GetRed()-rRHS.GetRed()) +
+ vigra::sq(rLHS.GetGreen()-rRHS.GetGreen()) +
+ vigra::sq(rLHS.GetBlue()-rRHS.GetBlue()) );
+ }
+
+ data_type find_best_match(value_type const& v) const
+ {
+ // TODO(F3): not generic!!!
+ const BitmapColor aTmpCol(v.red(),
+ v.green(),
+ v.blue());
+
+ // TODO(P3): use table-based/octree approach here!
+ const BitmapColor* best_entry;
+ const BitmapColor* palette_end( palette+num_entries );
+ if( (best_entry=std::find( palette, palette_end, aTmpCol)) != palette_end )
+ return best_entry-palette;
+
+ // TODO(F3): HACK. Need palette traits, and an error function
+ // here. We blatantly assume value_type is a normed linear
+ // space.
+ const BitmapColor* curr_entry( palette );
+ best_entry = curr_entry;
+ while( curr_entry != palette_end )
+ {
+ if( norm(*curr_entry,*best_entry) > norm(*curr_entry,aTmpCol) )
+ best_entry = curr_entry;
+
+ ++curr_entry;
+ }
+
+ return best_entry-palette;
+ }
+
+ value_type toCol( BitmapColor const& rCol ) const
+ {
+ return value_type(rCol.GetRed(),rCol.GetGreen(),rCol.GetBlue());
+ }
+
+public:
+ PaletteImageAccessor() :
+ palette(0),
+ num_entries(0)
+ {}
+
+ PaletteImageAccessor( const BitmapColor* pPalette,
+ data_type entries ) :
+ palette(pPalette),
+ num_entries(entries)
+ {}
+
+ template< class Iterator >
+ value_type operator()(Iterator const& i) const { return toCol(palette[i.get()]); }
+ value_type operator()(data_type const* i) const { return toCol(palette[*i]); }
+
+ template< class Iterator, class Difference >
+ value_type operator()(Iterator const& i, Difference const& diff) const
+ {
+ return toCol(palette[i.get(diff)]);
+ }
+
+ template< typename V, class Iterator >
+ void set(V const& value, Iterator const& i) const
+ {
+ i.set(
+ find_best_match(
+ vigra::detail::RequiresExplicitCast<value_type>::cast(value) ));
+ }
+
+ template< typename V, class Iterator, class Difference >
+ void set(V const& value, Iterator const& i, Difference const& diff) const
+ {
+ i.set(
+ find_best_match(
+ vigra::detail::RequiresExplicitCast<value_type>::cast(value)),
+ diff );
+ }
+};
+
+}
+
+
+class TestApp : public Application
+{
+public:
+ virtual void Main();
+ virtual USHORT Exception( USHORT nError );
+};
+
+class TestWindow : public Dialog
+{
+ public:
+ TestWindow() : Dialog( (Window *) NULL )
+ {
+ SetText( rtl::OUString::createFromAscii( "VIGRA test" ) );
+ SetSizePixel( Size( 1024, 500 ) );
+ EnablePaint( true );
+ Show();
+ }
+ virtual ~TestWindow() {}
+ virtual void MouseButtonUp( const MouseEvent& rMEvt )
+ {
+ //TODO: do something cool
+ EndDialog();
+ }
+ virtual void Paint( const Rectangle& rRect );
+};
+
+void TestWindow::Paint( const Rectangle& rRect )
+{
+ {
+ const basegfx::B2ISize aSize(11,11);
+ basebmp::BitmapDeviceSharedPtr pDevice( basebmp::createBitmapDevice( aSize,
+ true,
+ basebmp::Format::THIRTYTWO_BIT_TC_MASK ));
+
+ const basegfx::B2IPoint aPt1(1,1);
+ const basegfx::B2IPoint aPt2(1,9);
+ const basebmp::Color aCol(0);
+ pDevice->clear( aCol );
+ const basebmp::Color aCol2(0xFFFFFFFF);
+ pDevice->drawLine( aPt1, aPt2, aCol2, basebmp::DrawMode_PAINT );
+ }
+
+ enum{ srcBitDepth=1, dstBitDepth=4 };
+ typedef vigra::RGBValue< sal_uInt8 > RGBVal;
+
+ Bitmap aSourceBitmap( Size(100,100),
+ srcBitDepth );
+ DrawBitmap( Point(0,350), aSourceBitmap );
+
+ // Fill bitmap with rhombus
+ {
+ ScopedBitmapWriteAccess pWriteAccess( aSourceBitmap.AcquireWriteAccess(),
+ aSourceBitmap );
+ pWriteAccess->SetFillColor(0xFF0000);
+ Polygon aPoly(5);
+ aPoly[0] = Point(50,0);
+ aPoly[1] = Point(100,50);
+ aPoly[2] = Point(50,100);
+ aPoly[3] = Point(0,50);
+ aPoly[4] = Point(50,0);
+ pWriteAccess->FillPolygon(aPoly);
+ }
+
+ Bitmap aDestBitmap( Size(300,300),
+ dstBitDepth );
+
+ {
+ ScopedBitmapReadAccess pReadAccess( aSourceBitmap.AcquireReadAccess(),
+ aSourceBitmap );
+ ScopedBitmapWriteAccess pWriteAccess( aDestBitmap.AcquireWriteAccess(),
+ aDestBitmap );
+
+ const sal_Int32 nSrcWidth( pReadAccess->Width() );
+ const sal_Int32 nSrcHeight( pReadAccess->Height() );
+ const bool bSrcTopDown( pReadAccess->IsTopDown() );
+ const sal_uInt32 nSrcScanlineFormat( pReadAccess->GetScanlineFormat() );
+ const sal_uInt32 nSrcScanlineStride( pReadAccess->GetScanlineSize() );
+ const sal_uInt16 nSrcBitCount( pReadAccess->GetBitCount() );
+ const sal_uInt16 nSrcPaletteEntries( pReadAccess->GetPaletteEntryCount() );
+ const BitmapColor* pSrcPalette( &pReadAccess->GetPalette()[0] );
+ const BYTE* pSrcBuffer = pReadAccess->GetBuffer();
+
+ const sal_Int32 nDstWidth( pWriteAccess->Width() );
+ const sal_Int32 nDstHeight( pWriteAccess->Height() );
+ const bool bDstTopDown( pWriteAccess->IsTopDown() );
+ const sal_uInt32 nDstScanlineFormat( pWriteAccess->GetScanlineFormat() );
+ const sal_uInt32 nDstScanlineStride( pWriteAccess->GetScanlineSize() );
+ const sal_uInt16 nDstBitCount( pWriteAccess->GetBitCount() );
+ const sal_uInt16 nDstPaletteEntries( pWriteAccess->GetPaletteEntryCount() );
+ const BitmapColor* pDstPalette( &pWriteAccess->GetPalette()[0] );
+ BYTE* pDstBuffer = pWriteAccess->GetBuffer();
+
+ typedef PackedPixelIterator< const BYTE,
+ BYTE,
+ srcBitDepth,
+ true > SrcPixelIterator;
+ typedef PaletteImageAccessor< RGBVal, BYTE > SrcImageAccessor;
+
+ typedef PackedPixelIterator< BYTE,
+ BYTE,
+ dstBitDepth,
+ true > DstPixelIterator;
+ typedef PaletteImageAccessor< RGBVal, BYTE > DstImageAccessor;
+
+ const SrcPixelIterator aStartImage( pSrcBuffer,nSrcScanlineStride );
+ const SrcPixelIterator aEndImage( aStartImage + vigra::Diff2D(nSrcWidth,nSrcHeight) );
+
+ const DstPixelIterator aStartDstImage( pDstBuffer,nDstScanlineStride );
+ const DstPixelIterator aEndDstImage( aStartDstImage + vigra::Diff2D(nDstWidth,nDstHeight) );
+
+ vigra::resizeImageNoInterpolation(
+ //vigra::resizeImageLinearInterpolation(
+ vigra::make_triple(
+ aStartImage,
+ aEndImage,
+ SrcImageAccessor(
+ pSrcPalette,
+ nSrcPaletteEntries)),
+ vigra::make_triple(
+ aStartDstImage,
+ aEndDstImage,
+ DstImageAccessor(
+ pDstPalette,
+ nDstPaletteEntries)));
+ }
+
+ DrawBitmap( Point(), aDestBitmap );
+
+
+ Bitmap aDestBitmap2( Size(300,300),
+ dstBitDepth );
+
+ {
+ ScopedBitmapReadAccess pReadAccess( aSourceBitmap.AcquireReadAccess(),
+ aSourceBitmap );
+ ScopedBitmapWriteAccess pWriteAccess( aDestBitmap2.AcquireWriteAccess(),
+ aDestBitmap2 );
+
+ const sal_Int32 nSrcWidth( pReadAccess->Width() );
+ const sal_Int32 nSrcHeight( pReadAccess->Height() );
+ const bool bSrcTopDown( pReadAccess->IsTopDown() );
+ const sal_uInt32 nSrcScanlineFormat( pReadAccess->GetScanlineFormat() );
+ const sal_uInt32 nSrcScanlineStride( pReadAccess->GetScanlineSize() );
+ const sal_uInt16 nSrcBitCount( pReadAccess->GetBitCount() );
+ const sal_uInt16 nSrcPaletteEntries( pReadAccess->GetPaletteEntryCount() );
+ const BitmapColor* pSrcPalette( &pReadAccess->GetPalette()[0] );
+ const BYTE* pSrcBuffer = pReadAccess->GetBuffer();
+
+ const sal_Int32 nDstWidth( pWriteAccess->Width() );
+ const sal_Int32 nDstHeight( pWriteAccess->Height() );
+ const bool bDstTopDown( pWriteAccess->IsTopDown() );
+ const sal_uInt32 nDstScanlineFormat( pWriteAccess->GetScanlineFormat() );
+ const sal_uInt32 nDstScanlineStride( pWriteAccess->GetScanlineSize() );
+ const sal_uInt16 nDstBitCount( pWriteAccess->GetBitCount() );
+ const sal_uInt16 nDstPaletteEntries( pWriteAccess->GetPaletteEntryCount() );
+ const BitmapColor* pDstPalette( &pWriteAccess->GetPalette()[0] );
+ BYTE* pDstBuffer = pWriteAccess->GetBuffer();
+
+ typedef vigra::RGBValue< sal_uInt8 > RGBVal;
+ typedef PackedPixelIterator< const BYTE,
+ BYTE,
+ srcBitDepth,
+ true > SrcPixelIterator;
+ typedef PaletteImageAccessor< RGBVal,BYTE > SrcImageAccessor;
+
+ typedef PackedPixelIterator< BYTE,
+ BYTE,
+ dstBitDepth,
+ true > DstPixelIterator;
+ typedef PaletteImageAccessor< RGBVal,BYTE > DstImageAccessor;
+
+ const SrcPixelIterator aStartImage( pSrcBuffer,nSrcScanlineStride );
+ const SrcPixelIterator aEndImage( aStartImage + vigra::Diff2D(nSrcWidth,nSrcHeight) );
+
+ const DstPixelIterator aStartDstImage( pDstBuffer,nDstScanlineStride );
+ const DstPixelIterator aEndDstImage( aStartDstImage + vigra::Diff2D(nDstWidth,nDstHeight) );
+
+ vigra::resizeImageLinearInterpolation(
+ vigra::make_triple(
+ aStartImage,
+ aEndImage,
+ SrcImageAccessor(
+ pSrcPalette,
+ nSrcPaletteEntries)),
+ vigra::make_triple(
+ aStartDstImage,
+ aEndDstImage,
+ DstImageAccessor(
+ pDstPalette,
+ nDstPaletteEntries)));
+ }
+
+ DrawBitmap( Point(310,0), aDestBitmap2 );
+
+
+ Bitmap aDestBitmap3( Size(300,300),
+ 24 );
+
+ {
+ ScopedBitmapReadAccess pReadAccess( aSourceBitmap.AcquireReadAccess(),
+ aSourceBitmap );
+ ScopedBitmapWriteAccess pWriteAccess( aDestBitmap3.AcquireWriteAccess(),
+ aDestBitmap3 );
+
+ const sal_Int32 nSrcWidth( pReadAccess->Width() );
+ const sal_Int32 nSrcHeight( pReadAccess->Height() );
+ const bool bSrcTopDown( pReadAccess->IsTopDown() );
+ const sal_uInt32 nSrcScanlineFormat( pReadAccess->GetScanlineFormat() );
+ const sal_uInt32 nSrcScanlineStride( pReadAccess->GetScanlineSize() );
+ const sal_uInt16 nSrcBitCount( pReadAccess->GetBitCount() );
+ const sal_uInt16 nSrcPaletteEntries( pReadAccess->GetPaletteEntryCount() );
+ const BitmapColor* pSrcPalette( &pReadAccess->GetPalette()[0] );
+ const BYTE* pSrcBuffer = pReadAccess->GetBuffer();
+
+ const sal_Int32 nDstWidth( pWriteAccess->Width() );
+ const sal_Int32 nDstHeight( pWriteAccess->Height() );
+ const bool bDstTopDown( pWriteAccess->IsTopDown() );
+ const sal_uInt32 nDstScanlineFormat( pWriteAccess->GetScanlineFormat() );
+ const sal_uInt32 nDstScanlineStride( pWriteAccess->GetScanlineSize() );
+ const sal_uInt16 nDstBitCount( pWriteAccess->GetBitCount() );
+ BYTE* pDstBuffer = pWriteAccess->GetBuffer();
+
+ vigra::BasicImageView< RGBVal > aDestImage(
+ reinterpret_cast<RGBVal*>(pDstBuffer),
+ nDstWidth,
+ nDstHeight,
+ 0 /*nDstScanlineStride should be an integer multiple of 4*/ );
+
+ typedef PackedPixelIterator< const BYTE,
+ BYTE,
+ srcBitDepth,
+ true > SrcPixelIterator;
+ typedef PaletteImageAccessor< RGBVal,BYTE > SrcImageAccessor;
+
+ const SrcPixelIterator aStartImage( pSrcBuffer,nSrcScanlineStride );
+ const SrcPixelIterator aEndImage( aStartImage + vigra::Diff2D(nSrcWidth,nSrcHeight) );
+
+ // resize bitmap
+ vigra::resizeImageSplineInterpolation(
+ vigra::make_triple(
+ aStartImage,
+ aEndImage,
+ SrcImageAccessor(
+ pSrcPalette,
+ nSrcPaletteEntries)),
+ vigra::destImageRange(aDestImage));
+
+ // add ellipse to bitmap
+ basegfx::B2DPolygon aPoly(
+ basegfx::tools::createPolygonFromEllipse(
+ basegfx::B2DPoint(150,150),
+ 50, 80 ));
+ aPoly = basegfx::tools::adaptiveSubdivideByCount(aPoly);
+ makeRenderer( basegfx::B2DPolyPolygon( aPoly ),
+ RGBVal(0,0xFF,0),
+ RGBVal(0xFF,0xFF,0xFF),
+ vigra::destImageRange(aDestImage) )->rasterConvert(
+ basegfx::FillRule_NONZERO_WINDING_NUMBER );
+ }
+
+ DrawBitmap( Point(620,0), aDestBitmap3 );
+ DrawBitmap( Point(310,350), aSourceBitmap );
+}
+
+USHORT TestApp::Exception( USHORT nError )
+{
+ switch( nError & EXC_MAJORTYPE )
+ {
+ case EXC_RSCNOTLOADED:
+ Abort( String::CreateFromAscii( "Error: could not load language resources.\nPlease check your installation.\n" ) );
+ break;
+ }
+ return 0;
+}
+
+void TestApp::Main()
+{
+ //-------------------------------------------------
+ // create the global service-manager
+ //-------------------------------------------------
+ uno::Reference< lang::XMultiServiceFactory > xFactory;
+ try
+ {
+ uno::Reference< uno::XComponentContext > xCtx = ::cppu::defaultBootstrap_InitialComponentContext();
+ xFactory = uno::Reference< lang::XMultiServiceFactory >( xCtx->getServiceManager(),
+ uno::UNO_QUERY );
+ if( xFactory.is() )
+ ::comphelper::setProcessServiceFactory( xFactory );
+ }
+ catch( uno::Exception& )
+ {
+ }
+
+ if( !xFactory.is() )
+ {
+ OSL_TRACE( "Could not bootstrap UNO, installation must be in disorder. Exiting.\n" );
+ exit( 1 );
+ }
+
+ // Create UCB.
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL );
+ aArgs[ 1 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE );
+ ::ucb::ContentBroker::initialize( xFactory, aArgs );
+
+ TestWindow pWindow;
+ pWindow.Execute();
+
+ // clean up UCB
+ ::ucb::ContentBroker::deinitialize();
+}
+
+TestApp aDemoApp;
diff --git a/basebmp/test/export.map b/basebmp/test/export.map
new file mode 100644
index 000000000000..8cb6caacc51e
--- /dev/null
+++ b/basebmp/test/export.map
@@ -0,0 +1,42 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: export.map,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: thb $ $Date: 2006-05-31 09:49:44 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+UDK_3.1 {
+ global:
+ registerAllTestFunction;
+
+ local:
+ *;
+};
diff --git a/basebmp/test/filltest.cxx b/basebmp/test/filltest.cxx
new file mode 100644
index 000000000000..8a458cac573f
--- /dev/null
+++ b/basebmp/test/filltest.cxx
@@ -0,0 +1,113 @@
+// autogenerated file with codegen.pl
+
+#include <cppunit/simpleheader.hxx>
+
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+#include <basebmp/color.hxx>
+#include <basebmp/scanlineformats.hxx>
+#include <basebmp/bitmapdevice.hxx>
+#include <basebmp/debug.hxx>
+
+#include <iostream>
+#include <fstream>
+
+using namespace ::basebmp;
+
+namespace
+{
+/*
+ std::ofstream output("32bpp_test.dump");
+ debugDump( mpDevice32bpp, output );
+*/
+
+class FillTest : public CppUnit::TestFixture
+{
+private:
+ BitmapDeviceSharedPtr mpDevice1bpp;
+ BitmapDeviceSharedPtr mpDevice32bpp;
+
+ int countPixel( const BitmapDeviceSharedPtr& rDevice,
+ Color checkColor ) const
+ {
+ int count(0);
+ const basegfx::B2ISize& rSize( rDevice->getSize() );
+ for( sal_Int32 y=0; y<rSize.getY(); ++y )
+ for( sal_Int32 x=0; x<rSize.getX(); ++x )
+ if( rDevice->getPixel( basegfx::B2IPoint(x,y) ) == checkColor )
+ ++count;
+
+ return count;
+ }
+
+ void implTestRectFill(const BitmapDeviceSharedPtr& rDevice)
+ {
+ rDevice->clear(Color(0));
+
+ const basegfx::B2DRange aRect(1,1,10,10);
+ const basegfx::B2DPolygon aRectPoly(
+ basegfx::tools::createPolygonFromRect( aRect ));
+
+ const Color aCol(0xFFFFFFFF);
+ rDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aRectPoly),
+ aCol,
+ DrawMode_PAINT );
+ const basegfx::B2IPoint aPt1(1,1);
+ CPPUNIT_ASSERT_MESSAGE("first pixel set",
+ rDevice->getPixel(aPt1) == aCol);
+ const basegfx::B2IPoint aPt2(9,9);
+ CPPUNIT_ASSERT_MESSAGE("last pixel set",
+ rDevice->getPixel(aPt2) == aCol);
+ const basegfx::B2IPoint aPt3(0,0);
+ CPPUNIT_ASSERT_MESSAGE("topmost pixel not set",
+ rDevice->getPixel(aPt3) != aCol);
+ const basegfx::B2IPoint aPt4(10,10);
+ CPPUNIT_ASSERT_MESSAGE("bottommost pixel not set",
+ rDevice->getPixel(aPt4) != aCol);
+
+ CPPUNIT_ASSERT_MESSAGE("number of rendered pixel is not 81",
+ countPixel( rDevice, aCol ) == 81);
+ }
+
+public:
+ void setUp()
+ {
+ const basegfx::B2ISize aSize(11,11);
+ mpDevice1bpp = createBitmapDevice( aSize,
+ true,
+ Format::ONE_BIT_MSB_PAL );
+ mpDevice32bpp = createBitmapDevice( aSize,
+ true,
+ Format::THIRTYTWO_BIT_TC_MASK );
+ }
+
+ void testRectFill()
+ {
+ implTestRectFill( mpDevice1bpp );
+ implTestRectFill( mpDevice32bpp );
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(FillTest);
+ CPPUNIT_TEST(testRectFill);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+// -----------------------------------------------------------------------------
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FillTest, "FillTest");
+}
+
+
+// -----------------------------------------------------------------------------
+
+// this macro creates an empty function, which will called by the RegisterAllFunctions()
+// to let the user the possibility to also register some functions by hand.
+//NOADDITIONAL;
+
diff --git a/basebmp/test/linetest.cxx b/basebmp/test/linetest.cxx
new file mode 100644
index 000000000000..12e82cd0de3a
--- /dev/null
+++ b/basebmp/test/linetest.cxx
@@ -0,0 +1,178 @@
+// autogenerated file with codegen.pl
+
+#include <cppunit/simpleheader.hxx>
+
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+
+#include <basebmp/color.hxx>
+#include <basebmp/scanlineformats.hxx>
+#include <basebmp/bitmapdevice.hxx>
+#include <basebmp/debug.hxx>
+
+#include <iostream>
+#include <fstream>
+
+using namespace ::basebmp;
+
+namespace
+{
+/*
+ std::ofstream output("32bpp_test.dump");
+ debugDump( mpDevice32bpp, output );
+*/
+
+class LineTest : public CppUnit::TestFixture
+{
+private:
+ BitmapDeviceSharedPtr mpDevice1bpp;
+ BitmapDeviceSharedPtr mpDevice32bpp;
+
+ int countPixel( const BitmapDeviceSharedPtr& rDevice,
+ Color checkColor ) const
+ {
+ int count(0);
+ const basegfx::B2ISize& rSize( rDevice->getSize() );
+ for( sal_Int32 y=0; y<rSize.getY(); ++y )
+ for( sal_Int32 x=0; x<rSize.getX(); ++x )
+ if( rDevice->getPixel( basegfx::B2IPoint(x,y) ) == checkColor )
+ ++count;
+
+ return count;
+ }
+
+ void implTestBasicDiagonalLines(const BitmapDeviceSharedPtr& rDevice)
+ {
+ rDevice->clear(Color(0));
+
+ const basegfx::B2IPoint aPt1(1,1);
+ const basegfx::B2IPoint aPt2(9,9);
+ const Color aCol(0xFFFFFFFF);
+ rDevice->drawLine( aPt1, aPt2, aCol, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("first pixel set",
+ rDevice->getPixel(aPt1) == aCol);
+ CPPUNIT_ASSERT_MESSAGE("last pixel set",
+ rDevice->getPixel(aPt2) == aCol);
+ const basegfx::B2IPoint aPt3(0,0);
+ CPPUNIT_ASSERT_MESSAGE("topmost pixel not set",
+ rDevice->getPixel(aPt3) != aCol);
+ const basegfx::B2IPoint aPt4(10,10);
+ CPPUNIT_ASSERT_MESSAGE("bottommost pixel not set",
+ rDevice->getPixel(aPt4) != aCol);
+
+ CPPUNIT_ASSERT_MESSAGE("number of rendered pixel is not 9",
+ countPixel( rDevice, aCol ) == 9);
+
+ rDevice->drawLine( aPt2, aPt1, aCol, DrawMode_PAINT );
+
+ CPPUNIT_ASSERT_MESSAGE("number of rendered pixel after "
+ "reversed paint is not 9",
+ countPixel( rDevice, aCol ) == 9);
+ }
+
+ void implTestBasicVerticalLines(const BitmapDeviceSharedPtr& rDevice)
+ {
+ rDevice->clear(Color(0));
+
+ const basegfx::B2IPoint aPt1(1,1);
+ const basegfx::B2IPoint aPt2(1,9);
+ const Color aCol(0xFFFFFFFF);
+ rDevice->drawLine( aPt1, aPt2, aCol, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("first pixel set",
+ rDevice->getPixel(aPt1) == aCol);
+ CPPUNIT_ASSERT_MESSAGE("last pixel set",
+ rDevice->getPixel(aPt2) == aCol);
+ const basegfx::B2IPoint aPt3(0,0);
+ CPPUNIT_ASSERT_MESSAGE("topmost pixel not set",
+ rDevice->getPixel(aPt3) != aCol);
+ const basegfx::B2IPoint aPt4(0,10);
+ CPPUNIT_ASSERT_MESSAGE("bottommost pixel not set",
+ rDevice->getPixel(aPt4) != aCol);
+
+ CPPUNIT_ASSERT_MESSAGE("number of rendered pixel is not 9",
+ countPixel( rDevice, aCol ) == 9);
+ }
+
+ // test pixel rounding (should always tend towards start point of
+ // the line)
+ void implTestTieBreaking(const BitmapDeviceSharedPtr& rDevice)
+ {
+ rDevice->clear(Color(0));
+
+ const basegfx::B2IPoint aPt1(1,1);
+ const basegfx::B2IPoint aPt2(3,2);
+ const Color aCol(0xFFFFFFFF);
+ rDevice->drawLine( aPt1, aPt2, aCol, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("first pixel set",
+ rDevice->getPixel(aPt1) == aCol);
+ CPPUNIT_ASSERT_MESSAGE("second pixel set",
+ rDevice->getPixel(basegfx::B2IPoint(2,1)) == aCol);
+ CPPUNIT_ASSERT_MESSAGE("last pixel set",
+ rDevice->getPixel(aPt2) == aCol);
+ CPPUNIT_ASSERT_MESSAGE("number of rendered pixel after "
+ "reversed paint is not 3",
+ countPixel( rDevice, aCol ) == 3);
+
+ rDevice->drawLine( aPt2, aPt1, aCol, DrawMode_PAINT );
+ CPPUNIT_ASSERT_MESSAGE("alternate second pixel set",
+ rDevice->getPixel(basegfx::B2IPoint(2,2)) == aCol);
+
+ CPPUNIT_ASSERT_MESSAGE("number of rendered pixel after "
+ "reversed paint is not 4",
+ countPixel( rDevice, aCol ) == 4);
+ }
+
+public:
+ void setUp()
+ {
+ const basegfx::B2ISize aSize(11,11);
+ mpDevice1bpp = createBitmapDevice( aSize,
+ true,
+ Format::ONE_BIT_MSB_PAL );
+ mpDevice32bpp = createBitmapDevice( aSize,
+ true,
+ Format::THIRTYTWO_BIT_TC_MASK );
+ }
+
+ void testBasicDiagonalLines()
+ {
+ implTestBasicDiagonalLines( mpDevice1bpp );
+ implTestBasicDiagonalLines( mpDevice32bpp );
+ }
+
+ void testBasicVerticalLines()
+ {
+ implTestBasicVerticalLines( mpDevice1bpp );
+ //implTestBasicVerticalLines( mpDevice32bpp );
+ }
+
+ // test pixel rounding (should always tend towards start point of
+ // the line)
+ void testTieBreaking()
+ {
+ implTestTieBreaking( mpDevice1bpp );
+ implTestTieBreaking( mpDevice32bpp );
+ }
+
+ // Change the following lines only, if you add, remove or rename
+ // member functions of the current class,
+ // because these macros are need by auto register mechanism.
+
+ CPPUNIT_TEST_SUITE(LineTest);
+ CPPUNIT_TEST(testBasicDiagonalLines);
+ CPPUNIT_TEST(testBasicVerticalLines);
+ CPPUNIT_TEST(testTieBreaking);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+// -----------------------------------------------------------------------------
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(LineTest, "LineTest");
+}
+
+
+// -----------------------------------------------------------------------------
+
+// this macro creates an empty function, which will called by the RegisterAllFunctions()
+// to let the user the possibility to also register some functions by hand.
+//NOADDITIONAL;
+
diff --git a/basebmp/test/makefile.mk b/basebmp/test/makefile.mk
new file mode 100644
index 000000000000..e6fec62d9df1
--- /dev/null
+++ b/basebmp/test/makefile.mk
@@ -0,0 +1,110 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: thb $ $Date: 2006-05-31 09:49:45 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=basebmp
+TARGET=tests
+TARGETTYPE=GUI
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(debug)"!="" || "$(DEBUG)"!=""
+
+.IF "$(COM)"=="MSC"
+# disable inlining for MSVC
+CFLAGS += -Ob0
+.ENDIF
+
+.IF "$(COM)"=="GCC"
+# disable inlining for gcc
+CFLAGS += -fno-inline
+.ENDIF
+
+.ENDIF
+
+# --- Common ----------------------------------------------------------
+
+# BEGIN ----------------------------------------------------------------
+# auto generated Target:tests by codegen.pl
+SHL1OBJS= \
+ $(SLO)$/basictest.obj \
+ $(SLO)$/filltest.obj \
+ $(SLO)$/linetest.obj
+
+SHL1TARGET= tests
+SHL1STDLIBS= $(SALLIB) \
+ $(CPPUNITLIB) \
+ $(BASEGFXLIB) \
+ $(BASEBMPLIB)
+
+SHL1IMPLIB= i$(SHL1TARGET)
+
+DEF1NAME =$(SHL1TARGET)
+SHL1VERSIONMAP = export.map
+
+# END ------------------------------------------------------------------
+
+APP2TARGET= bmpdemo
+
+APP2OBJS= \
+ $(OBJ)$/bmpdemo.obj
+
+APP2STDLIBS=$(TOOLSLIB) \
+ $(COMPHELPERLIB) \
+ $(BASEGFXLIB) \
+ $(BASEBMPLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(SALLIB) \
+ $(VCLLIB)
+
+.IF "$(GUI)"!="UNX"
+APP2DEF= $(MISC)$/$(TARGET).def
+.ENDIF
+
+#------------------------------- All object files -------------------------------
+# do this here, so we get right dependencies
+SLOFILES=$(SHL1OBJS)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+.INCLUDE : _cppunit.mk
diff --git a/basebmp/util/basebmp.flt b/basebmp/util/basebmp.flt
new file mode 100644
index 000000000000..28a1dd1b65c6
--- /dev/null
+++ b/basebmp/util/basebmp.flt
@@ -0,0 +1,4 @@
+__CT
+Impl
+IMP
+internal \ No newline at end of file
diff --git a/basebmp/util/makefile.mk b/basebmp/util/makefile.mk
new file mode 100644
index 000000000000..8f30bf61694b
--- /dev/null
+++ b/basebmp/util/makefile.mk
@@ -0,0 +1,74 @@
+#*************************************************************************
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: thb $ $Date: 2006-05-31 09:49:45 $
+#
+# The Contents of this file are made available subject to
+# the terms of GNU Lesser General Public License Version 2.1.
+#
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2005 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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 for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=basebmp
+TARGET=basebmp
+
+# --- Settings ---------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Allgemein ---------------------------------------------------
+
+LIB1TARGET=$(SLB)$/basebmp.lib
+LIB1FILES=\
+ $(SLB)$/wrapper.lib
+
+SHL1TARGET= basebmp$(UPD)$(DLLPOSTFIX)
+SHL1IMPLIB= ibasebmp
+
+SHL1STDLIBS=\
+ $(SALLIB) \
+ $(BASEGFXLIB)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1LIBS= $(SLB)$/basebmp.lib
+
+DEF1NAME =$(SHL1TARGET)
+DEF1DEPN =$(MISC)$/$(SHL1TARGET).flt \
+ $(LIB1TARGET)
+
+DEF1DES =BaseBMP
+DEFLIB1NAME =basebmp
+
+# --- Targets -----------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(MISC)$/$(SHL1TARGET).flt : makefile.mk
+ @+$(TYPE) $(TARGET).flt > $@
+