From 6a4ea42a8fa08a8b1016b1481aea47d2f02705e8 Mon Sep 17 00:00:00 2001 From: Thorsten Behrens Date: Fri, 2 Jun 2006 07:36:15 +0000 Subject: [PATCH] #i65904# Made drawBitmap/drawMaskedColor functional; added raw access for palette images --- basebmp/inc/basebmp/accessor.hxx | 7 +- basebmp/inc/basebmp/accessoradapters.hxx | 22 +- basebmp/inc/basebmp/bitmapdevice.hxx | 73 ++- basebmp/inc/basebmp/clippedlinerenderer.hxx | 6 +- basebmp/inc/basebmp/packedpixeliterator.hxx | 102 ++-- basebmp/inc/basebmp/paletteimageaccessor.hxx | 34 +- basebmp/inc/basebmp/pixeliterator.hxx | 8 +- basebmp/inc/basebmp/scanlineformats.hxx | 24 +- basebmp/source/bitmapdevice.cxx | 469 +++++++++++++++---- basebmp/test/bmpdemo.cxx | 37 +- basebmp/test/filltest.cxx | 28 +- basebmp/test/linetest.cxx | 18 +- basebmp/test/makefile.mk | 9 +- 13 files changed, 583 insertions(+), 254 deletions(-) diff --git a/basebmp/inc/basebmp/accessor.hxx b/basebmp/inc/basebmp/accessor.hxx index c1cd068724f9..a21edd8280ec 100644 --- a/basebmp/inc/basebmp/accessor.hxx +++ b/basebmp/inc/basebmp/accessor.hxx @@ -4,9 +4,9 @@ * * $RCSfile: accessor.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:11 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:13 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,6 +36,8 @@ #ifndef INCLUDED_BASEBMP_ACCESSOR_HXX #define INCLUDED_BASEBMP_ACCESSOR_HXX +#include + namespace basebmp { @@ -43,7 +45,6 @@ template class StandardAccessor { public: typedef ValueType value_type; - typedef ValueType data_type; template< class Iterator > value_type operator()(Iterator const& i) const { return i.get(); } diff --git a/basebmp/inc/basebmp/accessoradapters.hxx b/basebmp/inc/basebmp/accessoradapters.hxx index 30d096005e8b..2c2d5d8f3753 100644 --- a/basebmp/inc/basebmp/accessoradapters.hxx +++ b/basebmp/inc/basebmp/accessoradapters.hxx @@ -4,9 +4,9 @@ * * $RCSfile: accessoradapters.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:11 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,9 +36,9 @@ #ifndef INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX #define INCLUDED_BASEBMP_ACCESSORADAPTERS_HXX -#include "metafunctions.hxx" -#include "packedpixeliterator.hxx" -#include "paletteimageaccessor.hxx" +#include +#include +#include namespace basebmp { @@ -230,16 +230,14 @@ template< class WrappedAccessor, class Iterator > struct maskedAccessor< WrappedAccessor, MaskAccessor, Iterator, - PackedPixelIterator< typename MaskAccessor::data_type, - typename MaskAccessor::value_type, + PackedPixelIterator< typename MaskAccessor::value_type, 1, true > > { typedef BinaryInputAccessorAdapter< WrappedAccessor, MaskAccessor, Iterator, - PackedPixelIterator< typename MaskAccessor::data_type, - typename MaskAccessor::value_type, + PackedPixelIterator< typename MaskAccessor::value_type, 1, true >, FastMaskFunctor< typename WrappedAccessor::value_type > > @@ -250,16 +248,14 @@ template< class WrappedAccessor, class Iterator > struct maskedAccessor< WrappedAccessor, MaskAccessor, Iterator, - PackedPixelIterator< typename MaskAccessor::data_type, - typename MaskAccessor::value_type, + PackedPixelIterator< typename MaskAccessor::value_type, 1, false > > { typedef BinaryInputAccessorAdapter< WrappedAccessor, MaskAccessor, Iterator, - PackedPixelIterator< typename MaskAccessor::data_type, - typename MaskAccessor::value_type, + PackedPixelIterator< typename MaskAccessor::value_type, 1, false >, FastMaskFunctor< typename WrappedAccessor::value_type > > diff --git a/basebmp/inc/basebmp/bitmapdevice.hxx b/basebmp/inc/basebmp/bitmapdevice.hxx index dac7588b642e..4e5d106ae3bb 100644 --- a/basebmp/inc/basebmp/bitmapdevice.hxx +++ b/basebmp/inc/basebmp/bitmapdevice.hxx @@ -2,9 +2,9 @@ * * $RCSfile: bitmapdevice.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:11 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -42,13 +42,14 @@ #include #endif #ifndef INCLUDED_BASEBMP_DRAWMODES_HXX -#include "drawmodes.hxx" +#include #endif #include #include +#include #include - +#include /* What to do first: @@ -79,19 +80,20 @@ 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; +typedef boost::shared_ptr< class BitmapDevice > BitmapDeviceSharedPtr; +typedef boost::shared_array< sal_uInt8 > RawMemorySharedArray; +typedef boost::shared_ptr< const std::vector > PaletteMemorySharedVector; struct ImplBitmapDevice; /** Definition of BitmapDevice interface - Use createBitmapDevice() factory method to create one instance. + Use the 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 + instances work best with 1 bit TC 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 @@ -121,17 +123,20 @@ public: /** Get pointer to frame buffer */ - RawMemorySharedPtr getBuffer() const; + RawMemorySharedArray 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; + The returned pointer is const on purpose, since the + BitmapDevice might internally cache lookup information. - /** Query number of palette entries + @return shared pointer to vector of Color entries. + */ + PaletteMemorySharedVector getPalette() const; + + /** Query number of palette entries. + + This is just a frontend for getPalette->size() */ const sal_Int32 getPaletteEntryCount() const; @@ -178,6 +183,14 @@ public: */ Color getPixel( const basegfx::B2IPoint& rPt ); + /** Get underlying pixel data value at given position + + This method returns the raw pixel data. In the case of + paletted bitmaps, this is the palette index, not the final + color value. + */ + sal_uInt32 getPixelData( const basegfx::B2IPoint& rPt ); + /** Draw a line @param rPt1 @@ -276,11 +289,12 @@ public: const BitmapDeviceSharedPtr& rClip ); protected: - BitmapDevice( const basegfx::B2IVector& rSize, - bool bTopDown, - sal_Int32 nScanlineFormat, - sal_Int32 nScanlineStride, - const RawMemorySharedPtr& rMem ); + BitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + sal_Int32 nScanlineStride, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ); virtual ~BitmapDevice(); @@ -289,9 +303,6 @@ private: 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, @@ -304,6 +315,8 @@ private: virtual Color getPixel_i( const basegfx::B2IPoint& rPt ) = 0; + virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) = 0; + virtual void drawLine_i( const basegfx::B2DPoint& rPt1, const basegfx::B2DPoint& rPt2, Color lineColor, @@ -376,6 +389,18 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, bool bTopDown, sal_Int32 nScanlineFormat ); +/** Factory method to create a BitmapDevice for given scanline format + from the given piece of raw memory + + Note: the provided memory must have sufficient size, to store the + image of the specified area and format. + */ +BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ); + } #endif /* INCLUDED_BASEBMP_BITMAPDEVICE_HXX */ diff --git a/basebmp/inc/basebmp/clippedlinerenderer.hxx b/basebmp/inc/basebmp/clippedlinerenderer.hxx index 69b46e1ef80c..0c484a08ad3f 100644 --- a/basebmp/inc/basebmp/clippedlinerenderer.hxx +++ b/basebmp/inc/basebmp/clippedlinerenderer.hxx @@ -4,9 +4,9 @@ * * $RCSfile: clippedlinerenderer.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:11 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,7 +36,9 @@ #ifndef INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX #define INCLUDED_BASEBMP_CLIPPEDLINERENDERER_HXX +#ifndef _BGFX_TOOLS_RECTCLIPTOOLS_HXX #include +#endif namespace basebmp { diff --git a/basebmp/inc/basebmp/packedpixeliterator.hxx b/basebmp/inc/basebmp/packedpixeliterator.hxx index bb758f90b27d..96833e1ef382 100644 --- a/basebmp/inc/basebmp/packedpixeliterator.hxx +++ b/basebmp/inc/basebmp/packedpixeliterator.hxx @@ -4,9 +4,9 @@ * * $RCSfile: packedpixeliterator.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:12 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,8 +36,8 @@ #ifndef INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX #define INCLUDED_BASEBMP_PACKEDPIXELITERATOR_HXX -#include "metafunctions.hxx" -#include "stridedarrayiterator.hxx" +#include +#include #include #include @@ -47,14 +47,14 @@ 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 ) +template< typename value_type, int bits_per_pixel, bool MsbFirst, typename difference_type > inline value_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::isPOD::asBool); + BOOST_STATIC_ASSERT(sizeof(value_type)*8 % bits_per_pixel == 0); + BOOST_STATIC_ASSERT(sizeof(value_type)*8 / bits_per_pixel > 1); + BOOST_STATIC_ASSERT(vigra::TypeTraits::isPOD::asBool); - const unsigned int nIntraWordPositions( sizeof(data_type)*8 / bits_per_pixel ); + const unsigned int nIntraWordPositions( sizeof(value_type)*8 / bits_per_pixel ); // create bits_per_pixel 1s shift to intra-word position return ((~(~0 << bits_per_pixel)) << bits_per_pixel*(MsbFirst ? @@ -69,26 +69,24 @@ template< int num_intraword_positions, int bits_per_pixel, bool MsbFirst, typena remainder); } -template< typename Datatype, - typename Valuetype, +template< 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::type mask_type; - typedef data_type* pointer; - typedef StridedArrayIterator< data_type > MoveY; + typedef typename remove_const::type mask_type; + typedef value_type* pointer; + typedef StridedArrayIterator< value_type > MoveY; enum { - /** The number of pixel within a single data_type value + /** The number of pixel within a single value_type value */ - num_intraword_positions=sizeof(data_type)*8/bits_per_pixel, + num_intraword_positions=sizeof(value_type)*8/bits_per_pixel, /** Bit mask for one pixel (least significant bits) */ bit_mask=~(~0 << bits_per_pixel) @@ -122,13 +120,13 @@ private: public: PackedPixelColumnIterator() : y(0), - mask_( get_mask(0) ), + mask_( get_mask(0) ), shift_( get_shift(0) ) {} PackedPixelColumnIterator( const MoveY& base, difference_type remainder ) : y(base), - mask_( get_mask(remainder) ), + mask_( get_mask(remainder) ), shift_( get_shift(remainder) ) {} @@ -221,14 +219,14 @@ public: value_type get() const { - // TODO(Q3): use traits to get unsigned type for data_type (if + // TODO(Q3): use traits to get unsigned type for value_type (if // not already) return static_cast(*y() & mask_) >> shift_; } value_type get(difference_type d) const { - // TODO(Q3): use traits to get unsigned type for data_type (if + // TODO(Q3): use traits to get unsigned type for value_type (if // not already) return static_cast(*y(d) & mask_) >> shift_; } @@ -246,25 +244,23 @@ public: } }; -template< typename Datatype, - typename Valuetype, +template< 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::type mask_type; - typedef data_type* pointer; + typedef typename remove_const::type mask_type; + typedef value_type* pointer; enum { - /** The number of pixel within a single data_type value + /** The number of pixel within a single value_type value */ - num_intraword_positions=sizeof(data_type)*8/bits_per_pixel, + num_intraword_positions=sizeof(value_type)*8/bits_per_pixel, /** Bit mask for one pixel (least significant bits) */ bit_mask=~(~0 << bits_per_pixel) @@ -277,7 +273,7 @@ private: void update_mask() { - mask_ = get_mask(remainder_); + mask_ = get_mask(remainder_); } void inc() @@ -290,7 +286,7 @@ private: const mask_type shifted_mask( MsbFirst ? - // TODO(Q3): use traits to get unsigned type for data_type + // TODO(Q3): use traits to get unsigned type for value_type // (if not already) static_cast(mask_) >> bits_per_pixel : mask_ << bits_per_pixel ); @@ -321,7 +317,7 @@ private: const mask_type shifted_mask( MsbFirst ? mask_ << bits_per_pixel : - // TODO(Q3): use traits to get unsigned type for data_type + // TODO(Q3): use traits to get unsigned type for value_type // (if not already) static_cast(mask_) >> bits_per_pixel ); @@ -346,7 +342,7 @@ private: public: PackedPixelRowIterator() : data_(0), - mask_( get_mask(0) ), + mask_( get_mask(0) ), remainder_(0) {} @@ -466,7 +462,7 @@ public: value_type get() const { - // TODO(Q3): use traits to get unsigned type for data_type (if + // TODO(Q3): use traits to get unsigned type for value_type (if // not already) return static_cast(*data_ & mask_) >> get_shift(remainder_); @@ -496,34 +492,36 @@ public: } }; -template< typename Datatype, - typename Valuetype, +/** 2D image iterator for packed pixel formats + + This iterator can be used for image formats that pack more than + one pixel into an machine data type (like one bit per pixel, eight + of which packed into one char) + */ +template< 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 row_iterator; - typedef PackedPixelColumnIterator column_iterator; - typedef data_type* pointer; + typedef value_type* pointer; typedef int MoveX; - typedef StridedArrayIterator< data_type > MoveY; + typedef StridedArrayIterator< value_type > MoveY; enum { - /** The number of pixel within a single data_type value + /** The number of pixel within a single value_type value */ - num_intraword_positions=sizeof(data_type)*8/bits_per_pixel, + num_intraword_positions=sizeof(value_type)*8/bits_per_pixel, /** Bit mask for one pixel (least significant bits) */ bit_mask=~(~0 << bits_per_pixel) @@ -621,17 +619,17 @@ public: { const int remainder( x % num_intraword_positions ); - // TODO(Q3): use traits to get unsigned type for data_type (if + // TODO(Q3): use traits to get unsigned type for value_type (if // not already) value_type nTmp0( *current() ); unsigned int nTmp1(static_cast(*current() & - get_mask(remainder))); + get_mask(remainder))); unsigned int nTmp2( (static_cast(*current() & - get_mask(remainder)) + get_mask(remainder)) >> get_shift(remainder))); return (static_cast(*current() & - get_mask(remainder)) + get_mask(remainder)) >> get_shift(remainder)); } @@ -639,17 +637,17 @@ public: { const int remainder( x(d.x) % num_intraword_positions ); - // TODO(Q3): use traits to get unsigned type for data_type (if + // TODO(Q3): use traits to get unsigned type for value_type (if // not already) return (static_cast(*current(d.x,d.y) & - get_mask(remainder)) + get_mask(remainder)) >> get_shift(remainder)); } void set( value_type v ) const { const int remainder( x % num_intraword_positions ); - const int mask( get_mask(remainder) ); + const int mask( get_mask(remainder) ); const value_type pixel_value( (v << get_shift(remainder)) @@ -661,7 +659,7 @@ public: void set( value_type v, difference_type const & d ) const { const int remainder( (x + d.x) % num_intraword_positions ); - const int mask( get_mask(remainder) ); + const int mask( get_mask(remainder) ); const value_type pixel_value( (v << get_shift(remainder)) diff --git a/basebmp/inc/basebmp/paletteimageaccessor.hxx b/basebmp/inc/basebmp/paletteimageaccessor.hxx index c70dc5606cd0..66d3ee6b30a6 100644 --- a/basebmp/inc/basebmp/paletteimageaccessor.hxx +++ b/basebmp/inc/basebmp/paletteimageaccessor.hxx @@ -4,9 +4,9 @@ * * $RCSfile: paletteimageaccessor.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:12 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,7 +36,8 @@ #ifndef INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX #define INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX -#include "metafunctions.hxx" +#include +#include #include #include @@ -103,9 +104,9 @@ public: {} PaletteImageAccessor( const value_type* pPalette, - data_type entries ) : + data_type numEntries ) : palette(pPalette), - num_entries(entries) + num_entries(numEntries) {} template< class Iterator > @@ -136,6 +137,29 @@ public: } }; + +/// Retrieve raw pixel data accessor for given Accessor type +template< class Accessor > struct rawAccessor +{ + // generic case: both accessors are the same + typedef Accessor type; +}; + +template< typename ValueType > struct RawAccessor : public StandardAccessor< ValueType > +{ + RawAccessor() {} + template< typename DataType > explicit RawAccessor( + const PaletteImageAccessor< ValueType, DataType >& a ) {} +}; + +// specialization for PaletteImageAccessor, to provide the +// corresponding StandardAccessor to the pixel index values +template< typename ValueType, typename DataType > +struct rawAccessor< PaletteImageAccessor< ValueType, DataType > > +{ + typedef RawAccessor< ValueType > type; +}; + } // namespace basebmp #endif /* INCLUDED_BASEBMP_PALETTEIMAGEACCESSOR_HXX */ diff --git a/basebmp/inc/basebmp/pixeliterator.hxx b/basebmp/inc/basebmp/pixeliterator.hxx index b90dc05d4d03..c3b2bf01ec03 100644 --- a/basebmp/inc/basebmp/pixeliterator.hxx +++ b/basebmp/inc/basebmp/pixeliterator.hxx @@ -4,9 +4,9 @@ * * $RCSfile: pixeliterator.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:12 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -36,8 +36,8 @@ #ifndef INCLUDED_BASEBMP_PIXELITERATOR_HXX #define INCLUDED_BASEBMP_PIXELITERATOR_HXX -#include "metafunctions.hxx" -#include "stridedarrayiterator.hxx" +#include +#include #include #include diff --git a/basebmp/inc/basebmp/scanlineformats.hxx b/basebmp/inc/basebmp/scanlineformats.hxx index 70c5f5007020..db7befdedc2d 100644 --- a/basebmp/inc/basebmp/scanlineformats.hxx +++ b/basebmp/inc/basebmp/scanlineformats.hxx @@ -2,9 +2,9 @@ * * $RCSfile: scanlineformats.hxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:12 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -62,17 +62,23 @@ #ifndef INCLUDED_BASEBMP_SCANLINEFORMATS_HXX #define INCLUDED_BASEBMP_SCANLINEFORMATS_HXX +#ifndef _SAL_TYPES_H_ +#include +#endif + /* 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 ONE_BIT_MSB_TC_MASK = (sal_Int32)0x01; + static const sal_Int32 ONE_BIT_LSB_TC_MASK = (sal_Int32)0x02; + static const sal_Int32 ONE_BIT_MSB_PAL = (sal_Int32)0x03; + static const sal_Int32 ONE_BIT_LSB_PAL = (sal_Int32)0x04; + static const sal_Int32 TWO_BIT_MSB_PAL = (sal_Int32)0x05; + static const sal_Int32 TWO_BIT_LSB_PAL = (sal_Int32)0x06; + static const sal_Int32 FOUR_BIT_MSB_PAL = (sal_Int32)0x07; + static const sal_Int32 FOUR_BIT_LSB_PAL = (sal_Int32)0x08; + static const sal_Int32 EIGHT_BIT_PAL = (sal_Int32)0x09; 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; diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx index 78a772541e3d..598ed9dd6a7c 100644 --- a/basebmp/source/bitmapdevice.cxx +++ b/basebmp/source/bitmapdevice.cxx @@ -4,9 +4,9 @@ * * $RCSfile: bitmapdevice.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:12 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -42,6 +42,7 @@ #include "basebmp/accessoradapters.hxx" #include "basebmp/scanlineformats.hxx" #include "basebmp/linerenderer.hxx" +#include "basebmp/copyimage.hxx" #include #include @@ -53,12 +54,14 @@ #include #include #include +#include #include #include #include #include #include +#include namespace basebmp @@ -67,7 +70,6 @@ namespace basebmp namespace { typedef PackedPixelIterator< sal_uInt8, - sal_uInt8, 1, true > MaskIterator; typedef StandardAccessor< sal_uInt8 > MaskAccessor; @@ -163,6 +165,7 @@ namespace MaskAccessor> MaskBitmap; typedef BitmapRenderer AlphaMaskBitmap; + typedef typename rawAccessor::type RawAccessor; typedef typename xorAccessor::type XorAccessor; typedef typename maskedAccessor::type MaskedXorAccessor; + typedef DestIterator dest_iterator; + typedef DestAccessor dest_accessor; + DestIterator maBegin; DestIterator maEnd; DestAccessor maAccessor; + RawAccessor maRawAccessor; 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 ), + BitmapRenderer( const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + sal_Int32 nScanlineStride, + DestIterator begin, + DestIterator end, + DestAccessor accessor, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ) : + BitmapDevice( rSize, bTopDown, nScanlineFormat, nScanlineStride, rMem, rPalette ), maBegin( begin ), maEnd( end ), maAccessor( accessor ), + maRawAccessor( accessor ), maXorAccessor( accessor ), maMaskedAccessor( accessor ), maMaskedXorAccessor( maXorAccessor ), @@ -238,18 +247,6 @@ namespace 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 ); @@ -264,7 +261,7 @@ namespace while( rowIter != rowEnd ) maAccessor.set(fillColor, rowIter++); - currIter += vigra::Diff2D( 0,1 ); + ++currIter.y; } } @@ -308,6 +305,14 @@ namespace return maAccessor(pixel); } + virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) + { + const DestIterator pixel( maBegin + + vigra::Diff2D(rPt.getX(), + rPt.getY()) ); + return maRawAccessor(pixel); + } + virtual void drawLine_i(const basegfx::B2DPoint& rPt1, const basegfx::B2DPoint& rPt2, Color lineColor, @@ -367,6 +372,9 @@ namespace DrawMode drawMode, const basegfx::B2IRange& rBounds ) { + basegfx::B2DPolyPolygon aPoly( rPoly ); + if( rPoly.areControlVectorsUsed() ) + aPoly = basegfx::tools::adaptiveSubdivideByCount( rPoly ); /* if( drawMode == DrawMode_XOR ) makeRenderer( rPoly, @@ -378,7 +386,7 @@ namespace basegfx::FillRule_NONZERO_WINDING_NUMBER ); else */ - makeRenderer( rPoly, + makeRenderer( aPoly, fillColor, rBounds, vigra::make_triple( @@ -418,13 +426,29 @@ namespace */ } - // 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!" ); + boost::shared_ptr pSrcBmp( getCompatibleBitmap(rSrcBitmap) ); + OSL_ASSERT( pSrcBmp ); + + // since resizeImageNoInterpolation() internally copyies + // to a temporary buffer, also works with *this == rSrcBitmap + vigra::resizeImageNoInterpolation( + vigra::make_triple( + pSrcBmp->maBegin + vigra::Diff2D(rSrcRect.getMinX(), + rSrcRect.getMinY()), + pSrcBmp->maBegin + vigra::Diff2D(rSrcRect.getMaxX(), + rSrcRect.getMaxY()), + pSrcBmp->maAccessor), + vigra::make_triple( + maBegin + vigra::Diff2D(rDstRect.getMinX(), + rDstRect.getMinY()), + maBegin + vigra::Diff2D(rDstRect.getMaxX(), + rDstRect.getMaxY()), + maAccessor)); } virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap, @@ -436,13 +460,22 @@ namespace 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!" ); + boost::shared_ptr pAlpha( getCompatibleAlphaMask(rAlphaMask) ); + OSL_ASSERT( pAlpha ); + + copyImage( pAlpha->maBegin + vigra::Diff2D(rSrcRect.getMinX(), + rSrcRect.getMinY()), + pAlpha->maBegin + vigra::Diff2D(rSrcRect.getMaxX(), + rSrcRect.getMaxY()), + pAlpha->maAccessor, + maBegin + vigra::Diff2D(rDstPoint.getX(), + rDstPoint.getY()), + maAccessor ); } virtual void drawMaskedColor_i(Color rSrcColor, @@ -481,23 +514,27 @@ namespace struct ImplBitmapDevice { /// Bitmap memory plus deleter - RawMemorySharedPtr mpMem; + RawMemorySharedArray mpMem; + /// Palette memory plus deleter (might be NULL) + PaletteMemorySharedVector mpPalette; - basegfx::B2IRange maBounds; - basegfx::B2DRange maFloatBounds; - sal_Int32 mnScanlineFormat; - sal_Int32 mnScanlineStride; + 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 ) : +BitmapDevice::BitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + sal_Int32 nScanlineStride, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ) : mpImpl( new ImplBitmapDevice ) { mpImpl->mpMem = rMem; + mpImpl->mpPalette = rPalette; mpImpl->maBounds = basegfx::B2IRange( 0,0,rSize.getX(),rSize.getY() ); mpImpl->maFloatBounds = basegfx::B2DRange( 0,0,rSize.getX(),rSize.getY() ); mpImpl->mnScanlineFormat = nScanlineFormat; @@ -530,19 +567,19 @@ sal_Int32 BitmapDevice::getScanlineStride() const return mpImpl->mnScanlineStride; } -RawMemorySharedPtr BitmapDevice::getBuffer() const +RawMemorySharedArray BitmapDevice::getBuffer() const { return mpImpl->mpMem; } -const Color* BitmapDevice::getPalette() const +PaletteMemorySharedVector BitmapDevice::getPalette() const { - return getPalette_i(); + return mpImpl->mpPalette; } const sal_Int32 BitmapDevice::getPaletteEntryCount() const { - return getPaletteEntryCount_i(); + return mpImpl->mpPalette ? mpImpl->mpPalette->size() : 0; } void BitmapDevice::clear( Color fillColor ) @@ -580,6 +617,14 @@ Color BitmapDevice::getPixel( const basegfx::B2IPoint& rPt ) return Color(); } +sal_uInt32 BitmapDevice::getPixelData( const basegfx::B2IPoint& rPt ) +{ + if( mpImpl->maBounds.isInside(rPt) ) + return getPixelData_i(rPt); + + return Color(); +} + void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1, const basegfx::B2IPoint& rPt2, Color lineColor, @@ -682,10 +727,26 @@ void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly, namespace { + void assertImagePoint( const basegfx::B2IPoint& rPt, + const basegfx::B2IRange& rPermittedRange ) + { + OSL_ASSERT( rPermittedRange.isInside(rPt) ); + } + + void assertImageRange( const basegfx::B2IRange& rRange, + const basegfx::B2IRange& rPermittedRange ) + { +#if OSL_DEBUG_LEVEL > 0 + basegfx::B2IRange aRange( rRange ); + aRange.intersect( rPermittedRange ); + + OSL_ASSERT( aRange == rRange ); +#endif + } + // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down // to basegfx, and use here! - bool clipAreaImpl( ::basegfx::B2IRange* o_pDestArea, - ::basegfx::B2IRange& io_rSourceArea, + bool clipAreaImpl( ::basegfx::B2IRange& io_rSourceArea, ::basegfx::B2IPoint& io_rDestPoint, const ::basegfx::B2IRange& rSourceBounds, const ::basegfx::B2IRange& rDestBounds ) @@ -728,8 +789,71 @@ namespace aSourceTopLeft + aDestLowerRightOffset ); io_rDestPoint = aLocalDestArea.getMinimum(); - if( o_pDestArea ) - *o_pDestArea = aLocalDestArea; + return true; + } + + // TODO(Q3): Move canvas/canvastools.hxx clipBlit() down + // to basegfx, and use here! + bool clipAreaImpl( ::basegfx::B2IRange& io_rDestArea, + ::basegfx::B2IRange& io_rSourceArea, + const ::basegfx::B2IRange& rDestBounds, + const ::basegfx::B2IRange& rSourceBounds ) + { + // extract inherent scale + const double nScaleX( io_rDestArea.getWidth() / (double)io_rSourceArea.getWidth() ); + const double nScaleY( io_rDestArea.getHeight() / (double)io_rSourceArea.getHeight() ); + + // extract range origins + const basegfx::B2IPoint aDestTopLeft( + io_rDestArea.getMinimum() ); + 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( basegfx::fround(aDestTopLeft.getX() + nScaleX*aUpperLeftOffset.getX()), + basegfx::fround(aDestTopLeft.getY() + nScaleY*aUpperLeftOffset.getY()), + basegfx::fround(aDestTopLeft.getX() + nScaleX*aLowerRightOffset.getX()), + basegfx::fround(aDestTopLeft.getY() + nScaleY*aLowerRightOffset.getY()) ); + + // 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()-aDestTopLeft ); + const ::basegfx::B2IVector aDestLowerRightOffset( + aLocalDestArea.getMaximum()-aDestTopLeft ); + + io_rSourceArea = ::basegfx::B2IRange( basegfx::fround(aSourceTopLeft.getX() + aDestUpperLeftOffset.getX()/nScaleX), + basegfx::fround(aSourceTopLeft.getY() + aDestUpperLeftOffset.getY()/nScaleY), + basegfx::fround(aSourceTopLeft.getX() + aDestLowerRightOffset.getX()/nScaleX), + basegfx::fround(aSourceTopLeft.getY() + aDestLowerRightOffset.getY()/nScaleY) ); + io_rDestArea = aLocalDestArea; + + // final source area clip (chopping round-offs) + io_rSourceArea.intersect( rSourceBounds ); + + if( io_rSourceArea.isEmpty() ) + return false; + return true; } @@ -741,19 +865,21 @@ void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, DrawMode drawMode ) { const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); - const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); + const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX()+1,rSrcSize.getY()+1 ); + const basegfx::B2IVector& rDstSize( getSize() ); + const basegfx::B2IRange aDstBounds( 0,0,rDstSize.getX()+1,rDstSize.getY()+1 ); basegfx::B2IRange aSrcRange( rSrcRect ); - basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() ); - basegfx::B2IRange aDestRange; + basegfx::B2IRange aDestRange( rDstRect ); - // TODO(F2): Scaling/shrinking - if( clipAreaImpl( &aDestRange, + if( clipAreaImpl( aDestRange, aSrcRange, - aDestPoint, - aSrcBounds, - mpImpl->maBounds )) + aDstBounds, + aSrcBounds )) { + assertImageRange(aDestRange,aDstBounds); + assertImageRange(aSrcRange,aSrcBounds); + if( isCompatibleBitmap( rSrcBitmap ) ) drawBitmap_i( rSrcBitmap, aSrcRange, aDestRange, drawMode ); else @@ -768,19 +894,21 @@ void BitmapDevice::drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, const BitmapDeviceSharedPtr& rClip ) { const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); - const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); + const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX()+1,rSrcSize.getY()+1 ); + const basegfx::B2IVector& rDstSize( getSize() ); + const basegfx::B2IRange aDstBounds( 0,0,rDstSize.getX()+1,rDstSize.getY()+1 ); basegfx::B2IRange aSrcRange( rSrcRect ); - basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() ); - basegfx::B2IRange aDestRange; + basegfx::B2IRange aDestRange( rDstRect ); - // TODO(F2): Scaling/shrinking - if( clipAreaImpl( &aDestRange, + if( clipAreaImpl( aDestRange, aSrcRange, - aDestPoint, - aSrcBounds, - mpImpl->maBounds )) + aDstBounds, + aSrcBounds )) { + assertImageRange(aDestRange,aDstBounds); + assertImageRange(aSrcRange,aSrcBounds); + if( isCompatibleBitmap( rSrcBitmap ) && isCompatibleClipMask( rClip ) ) { @@ -799,17 +927,21 @@ void BitmapDevice::drawMaskedColor( Color rSrcColor, const basegfx::B2IPoint& rDstPoint ) { const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() ); - const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); + const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX()+1,rSrcSize.getY()+1 ); + const basegfx::B2IVector& rDstSize( getSize() ); + const basegfx::B2IRange aDstBounds( 0,0,rDstSize.getX()+1,rDstSize.getY()+1 ); basegfx::B2IRange aSrcRange( rSrcRect ); basegfx::B2IPoint aDestPoint( rDstPoint ); - if( clipAreaImpl( NULL, - aSrcRange, + if( clipAreaImpl( aSrcRange, aDestPoint, aSrcBounds, - mpImpl->maBounds )) + aDstBounds )) { + assertImagePoint(aDestPoint,aDstBounds); + assertImageRange(aSrcRange,aSrcBounds); + if( isCompatibleAlphaMask( rAlphaMask ) ) drawMaskedColor_i( rSrcColor, rAlphaMask, aSrcRange, aDestPoint ); else @@ -824,17 +956,21 @@ void BitmapDevice::drawMaskedColor( Color rSrcColor, const BitmapDeviceSharedPtr& rClip ) { const basegfx::B2IVector& rSrcSize( rAlphaMask->getSize() ); - const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); + const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX()+1,rSrcSize.getY()+1 ); + const basegfx::B2IVector& rDstSize( getSize() ); + const basegfx::B2IRange aDstBounds( 0,0,rDstSize.getX()+1,rDstSize.getY()+1 ); basegfx::B2IRange aSrcRange( rSrcRect ); basegfx::B2IPoint aDestPoint( rDstPoint ); - if( clipAreaImpl( NULL, - aSrcRange, + if( clipAreaImpl( aSrcRange, aDestPoint, aSrcBounds, - mpImpl->maBounds )) + aDstBounds )) { + assertImagePoint(aDestPoint,aDstBounds); + assertImageRange(aSrcRange,aSrcBounds); + if( isCompatibleAlphaMask( rAlphaMask ) && isCompatibleClipMask( rClip ) ) { @@ -856,19 +992,21 @@ void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() ); const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); - const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); + const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX()+1,rSrcSize.getY()+1 ); + const basegfx::B2IVector& rDstSize( getSize() ); + const basegfx::B2IRange aDstBounds( 0,0,rDstSize.getX()+1,rDstSize.getY()+1 ); basegfx::B2IRange aSrcRange( rSrcRect ); - basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() ); - basegfx::B2IRange aDestRange; + basegfx::B2IRange aDestRange( rDstRect ); - // TODO(F2): Scaling/shrinking - if( clipAreaImpl( &aDestRange, + if( clipAreaImpl( aDestRange, aSrcRange, - aDestPoint, - aSrcBounds, - mpImpl->maBounds )) + aDstBounds, + aSrcBounds )) { + assertImageRange(aDestRange,aDstBounds); + assertImageRange(aSrcRange,aSrcBounds); + if( isCompatibleBitmap( rSrcBitmap ) && isCompatibleClipMask( rMask ) ) { @@ -891,19 +1029,21 @@ void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, OSL_ASSERT( rMask->getSize() == rSrcBitmap->getSize() ); const basegfx::B2IVector& rSrcSize( rSrcBitmap->getSize() ); - const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX(),rSrcSize.getY() ); + const basegfx::B2IRange aSrcBounds( 0,0,rSrcSize.getX()+1,rSrcSize.getY()+1 ); + const basegfx::B2IVector& rDstSize( getSize() ); + const basegfx::B2IRange aDstBounds( 0,0,rDstSize.getX()+1,rDstSize.getY()+1 ); basegfx::B2IRange aSrcRange( rSrcRect ); - basegfx::B2IPoint aDestPoint( rDstRect.getMinimum() ); - basegfx::B2IRange aDestRange; + basegfx::B2IRange aDestRange( rDstRect ); - // TODO(F2): Scaling/shrinking - if( clipAreaImpl( &aDestRange, + if( clipAreaImpl( aDestRange, aSrcRange, - aDestPoint, - aSrcBounds, - mpImpl->maBounds )) + aDstBounds, + aSrcBounds )) { + assertImageRange(aDestRange,aDstBounds); + assertImageRange(aSrcRange,aSrcBounds); + if( isCompatibleBitmap( rSrcBitmap ) && isCompatibleClipMask( rMask ) && isCompatibleClipMask( rClip ) ) @@ -921,6 +1061,7 @@ void BitmapDevice::drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, //---------------------------------------------------------------------------------- typedef PaletteImageAccessor PaletteAccessor; +typedef BitmapRenderer OneBitMsbMaskRenderer; typedef BitmapRenderer OneBitMsbPaletteRenderer; typedef BitmapRenderer EightBitTrueColorRenderer; typedef PixelIterator ThirtyTwoBitPixelIterator; @@ -933,7 +1074,7 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, { sal_Int32 nScanlineStride(0); - // HACK: 1bpp and 24bpp only, currently + // HACK: 1bpp and 32bpp only, currently if( nScanlineFormat == Format::ONE_BIT_MSB_PAL ) nScanlineStride = (rSize.getX() + 7) >> 3; else if( nScanlineFormat == Format::EIGHT_BIT_TC_MASK ) @@ -946,7 +1087,7 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, const std::size_t nMemSize( (nScanlineStride < 0 ? -nScanlineStride : nScanlineStride)*rSize.getY() ); - boost::shared_ptr< sal_uInt8 > pMem( + boost::shared_array< sal_uInt8 > pMem( reinterpret_cast(rtl_allocateMemory( nMemSize )), &rtl_freeMemory ); sal_uInt8* pFirstScanline = nScanlineStride < 0 ? @@ -954,12 +1095,34 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, rtl_zeroMemory(pMem.get(),nMemSize); + PaletteMemorySharedVector pPal; + switch( nScanlineFormat ) { + case Format::ONE_BIT_MSB_TC_MASK: + { + return BitmapDeviceSharedPtr( + new OneBitMsbMaskRenderer( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + MaskIterator(pFirstScanline, + nScanlineStride), + MaskIterator(pFirstScanline, + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + MaskAccessor(), + pMem, + pPal )); + } + case Format::ONE_BIT_MSB_PAL: { - static Color bwPalette[] = { Color(0x00000000), - Color(0xFFFFFFFF) }; + boost::shared_ptr< std::vector > pPal( new std::vector(2) ); + pPal->at(0) = Color(0x00000000); + pPal->at(1) = Color(0xFFFFFFFF); return BitmapDeviceSharedPtr( new OneBitMsbPaletteRenderer( @@ -973,9 +1136,10 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, nScanlineStride) + vigra::Diff2D(rSize.getX(), rSize.getY()), - PaletteAccessor( bwPalette, - sizeof(bwPalette)/sizeof(*bwPalette)), - pMem )); + PaletteAccessor( &pPal->at(0), + pPal->size() ), + pMem, + pPal )); } case Format::EIGHT_BIT_TC_MASK: @@ -993,7 +1157,8 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + vigra::Diff2D(rSize.getX(), rSize.getY()), AlphaMaskAccessor(), - pMem )); + pMem, + pPal )); } case Format::THIRTYTWO_BIT_TC_MASK: @@ -1011,7 +1176,117 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + vigra::Diff2D(rSize.getX(), rSize.getY()), vigra::AccessorTraits::default_accessor(), - pMem )); + pMem, + pPal )); + } + + default: + // TODO(F3): other formats not yet implemented + return BitmapDeviceSharedPtr(); + } +} + +BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + sal_Int32 nScanlineFormat, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ) +{ + sal_Int32 nScanlineStride(0); + + // HACK: 1bpp and 32bpp 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() ); + + sal_uInt8* pFirstScanline = nScanlineStride < 0 ? + rMem.get() + nMemSize : rMem.get(); + + switch( nScanlineFormat ) + { + case Format::ONE_BIT_MSB_TC_MASK: + { + return BitmapDeviceSharedPtr( + new OneBitMsbMaskRenderer( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + MaskIterator(pFirstScanline, + nScanlineStride), + MaskIterator(pFirstScanline, + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + MaskAccessor(), + rMem, + rPalette )); + } + + case Format::ONE_BIT_MSB_PAL: + { + return BitmapDeviceSharedPtr( + new OneBitMsbPaletteRenderer( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + MaskIterator(pFirstScanline, + nScanlineStride), + MaskIterator(pFirstScanline, + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + PaletteAccessor( &rPalette->at(0), + rPalette->size() ), + rMem, + rPalette )); + } + + 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(), + rMem, + rPalette)); + } + + case Format::THIRTYTWO_BIT_TC_MASK: + { + return BitmapDeviceSharedPtr( + new ThirtyTwoBitTrueColorRenderer( + rSize, + bTopDown, + nScanlineFormat, + nScanlineStride, + ThirtyTwoBitPixelIterator(reinterpret_cast(pFirstScanline), + nScanlineStride), + ThirtyTwoBitPixelIterator(reinterpret_cast(pFirstScanline), + nScanlineStride) + + vigra::Diff2D(rSize.getX(), + rSize.getY()), + vigra::AccessorTraits::default_accessor(), + rMem, + rPalette )); } default: diff --git a/basebmp/test/bmpdemo.cxx b/basebmp/test/bmpdemo.cxx index 82fadf8d0b18..b1312a597df1 100644 --- a/basebmp/test/bmpdemo.cxx +++ b/basebmp/test/bmpdemo.cxx @@ -4,9 +4,9 @@ * * $RCSfile: bmpdemo.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:13 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -56,10 +56,13 @@ #include #include +#include +#include #include #include #include #include +#include #include #include @@ -992,17 +995,33 @@ class TestWindow : public Dialog void TestWindow::Paint( const Rectangle& rRect ) { { - const basegfx::B2ISize aSize(11,11); + const basegfx::B2ISize aSize(10,10); + basebmp::BitmapDeviceSharedPtr pBmp( basebmp::createBitmapDevice( aSize, + true, + basebmp::Format::THIRTYTWO_BIT_TC_MASK )); basebmp::BitmapDeviceSharedPtr pDevice( basebmp::createBitmapDevice( aSize, true, basebmp::Format::THIRTYTWO_BIT_TC_MASK )); + ::rtl::OUString aSvg = ::rtl::OUString::createFromAscii( + "m 0 0h5v10h5v-5h-10z" ); - 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 ); + basegfx::B2DPolyPolygon aPoly; + basegfx::tools::importFromSvgD( aPoly, aSvg ); + const basebmp::Color aCol(0xFFFFFFFF); + pBmp->clear(basebmp::Color(0)); + pBmp->fillPolyPolygon( + aPoly, + aCol, + basebmp::DrawMode_PAINT ); + + const basegfx::B2IRange aSourceRect(0,0,11,11); + const basegfx::B2IRange aDestLeftTop(0,0,5,5); + pDevice->clear(basebmp::Color(0)); + pDevice->drawBitmap( + pBmp, + aSourceRect, + aDestLeftTop, + basebmp::DrawMode_PAINT ); } enum{ srcBitDepth=1, dstBitDepth=4 }; diff --git a/basebmp/test/filltest.cxx b/basebmp/test/filltest.cxx index f3025c55e7bb..fcaa08058df7 100644 --- a/basebmp/test/filltest.cxx +++ b/basebmp/test/filltest.cxx @@ -4,9 +4,9 @@ * * $RCSfile: filltest.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:13 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:15 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -47,6 +47,7 @@ #include #include #include +#include "tools.hxx" #include #include @@ -66,19 +67,6 @@ 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; ygetPixel( basegfx::B2IPoint(x,y) ) == checkColor ) - ++count; - - return count; - } - void implTestRectFill(const BitmapDeviceSharedPtr& rDevice) { rDevice->clear(Color(0)); @@ -170,9 +158,6 @@ private: const basegfx::B2IPoint aPt4(5,10); CPPUNIT_ASSERT_MESSAGE("bottom-middle pixel set", rDevice->getPixel(aPt4) == aCol); - - std::ofstream output("32bpp_test.dump"); - debugDump( rDevice, output ); } void implTestClipping(const BitmapDeviceSharedPtr& rDevice) @@ -247,6 +232,12 @@ public: implTestClipping( mpDevice32bpp ); } + void testCornerCases() + { + implTestCornerCases( mpDevice1bpp ); + implTestCornerCases( 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. @@ -254,6 +245,7 @@ public: CPPUNIT_TEST_SUITE(FillTest); CPPUNIT_TEST(testRectFill); CPPUNIT_TEST(testClipping); + CPPUNIT_TEST(testCornerCases); CPPUNIT_TEST_SUITE_END(); }; diff --git a/basebmp/test/linetest.cxx b/basebmp/test/linetest.cxx index 2a0d4dfa7594..3f4515ebfd72 100644 --- a/basebmp/test/linetest.cxx +++ b/basebmp/test/linetest.cxx @@ -4,9 +4,9 @@ * * $RCSfile: linetest.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: thb $ $Date: 2006-05-31 10:12:13 $ + * last change: $Author: thb $ $Date: 2006-06-02 08:36:15 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -44,6 +44,7 @@ #include #include #include +#include "tools.hxx" #include #include @@ -63,19 +64,6 @@ 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; ygetPixel( basegfx::B2IPoint(x,y) ) == checkColor ) - ++count; - - return count; - } - void implTestBasicDiagonalLines(const BitmapDeviceSharedPtr& rDevice) { rDevice->clear(Color(0)); diff --git a/basebmp/test/makefile.mk b/basebmp/test/makefile.mk index 31518e01ed3a..1ad61ffd7ede 100644 --- a/basebmp/test/makefile.mk +++ b/basebmp/test/makefile.mk @@ -4,9 +4,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.2 $ +# $Revision: 1.3 $ # -# last change: $Author: thb $ $Date: 2006-05-31 10:12:13 $ +# last change: $Author: thb $ $Date: 2006-06-02 08:36:15 $ # # The Contents of this file are made available subject to # the terms of GNU Lesser General Public License Version 2.1. @@ -65,8 +65,11 @@ CFLAGS += -fno-inline # auto generated Target:tests by codegen.pl SHL1OBJS= \ $(SLO)$/basictest.obj \ + $(SLO)$/bmptest.obj \ $(SLO)$/filltest.obj \ - $(SLO)$/linetest.obj + $(SLO)$/linetest.obj \ + $(SLO)$/masktest.obj \ + $(SLO)$/tools.obj SHL1TARGET= tests SHL1STDLIBS= $(SALLIB) \