diff options
author | Thorsten Behrens <thb@openoffice.org> | 2006-06-28 15:50:20 +0000 |
---|---|---|
committer | Thorsten Behrens <thb@openoffice.org> | 2006-06-28 15:50:20 +0000 |
commit | 0535516a2f4f08b15ad9a8007f12f9a57d4fbbb1 (patch) | |
tree | 5d366d47572bc783da6daf1a4aaaef4c7a7c904b | |
parent | b40eed0e55f88aae77acbffd9b9b667c42547ea4 (diff) |
#i65904# Added more docs; made clip masks for all cases (except masked bitmap); removed hardcoded unsigned int in favor of a metafunction; added tests for clips; fixed Color channel modification methods
-rw-r--r-- | basebmp/inc/basebmp/accessoradapters.hxx | 72 | ||||
-rw-r--r-- | basebmp/inc/basebmp/bitmapdevice.hxx | 332 | ||||
-rw-r--r-- | basebmp/inc/basebmp/clippedlinerenderer.hxx | 101 | ||||
-rw-r--r-- | basebmp/inc/basebmp/color.hxx | 10 | ||||
-rw-r--r-- | basebmp/inc/basebmp/drawmodes.hxx | 17 | ||||
-rw-r--r-- | basebmp/inc/basebmp/linerenderer.hxx | 5 | ||||
-rw-r--r-- | basebmp/inc/basebmp/metafunctions.hxx | 33 | ||||
-rw-r--r-- | basebmp/inc/basebmp/packedpixeliterator.hxx | 43 | ||||
-rw-r--r-- | basebmp/inc/basebmp/paletteimageaccessor.hxx | 7 | ||||
-rw-r--r-- | basebmp/source/bitmapdevice.cxx | 227 | ||||
-rw-r--r-- | basebmp/test/basictest.cxx | 47 | ||||
-rw-r--r-- | basebmp/test/bmpdemo.cxx | 324 | ||||
-rw-r--r-- | basebmp/test/cliptest.cxx | 274 |
13 files changed, 974 insertions, 518 deletions
diff --git a/basebmp/inc/basebmp/accessoradapters.hxx b/basebmp/inc/basebmp/accessoradapters.hxx index 84aab23ae833..83e390319e8e 100644 --- a/basebmp/inc/basebmp/accessoradapters.hxx +++ b/basebmp/inc/basebmp/accessoradapters.hxx @@ -4,9 +4,9 @@ * * $RCSfile: accessoradapters.hxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: thb $ $Date: 2006-06-09 04:21:00 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:18 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -263,54 +263,78 @@ template< typename ValueType, typename AlphaType > struct blendFunctorSelector : Used to blend an alpha mask 'through' a fixed color value into the destination. + + The getter functors return a constant value (usually the zero of + the value type, this preserves the original destination content + when blitting through a mask) - there really isn't no sensible + default behaviour for these methods. */ template< class WrappedAccessor, - typename AlphaType > class ConstantColorBlendAccessorAdapter + typename AlphaType > class ConstantColorBlendSetterAccessorAdapter { public: typedef AlphaType alpha_type; - typedef typename WrappedAccessor::value_type value_type; + typedef AlphaType value_type; + typedef typename WrappedAccessor::value_type color_type; private: - typename blendFunctorSelector< value_type, alpha_type >::type maFunctor; + typename blendFunctorSelector< color_type, alpha_type >::type maFunctor; WrappedAccessor maWrappee; - value_type maBlendColor; + color_type maBlendColor; + value_type maGetterValue; - // TODO(Q3): Merge with + // TODO(Q2): Merge with // BinarySetterFunctionAccessorAdapter. Problem there: how to // generate the functor, needs construction with accessor and // fixed color public: - ConstantColorBlendAccessorAdapter() : + ConstantColorBlendSetterAccessorAdapter() : maFunctor(), maWrappee(), - maBlendColor() + maBlendColor(), + maGetterValue() + {} + + explicit ConstantColorBlendSetterAccessorAdapter( WrappedAccessor acc ) : + maFunctor(), + maWrappee(acc), + maBlendColor(), + maGetterValue() {} - explicit ConstantColorBlendAccessorAdapter( WrappedAccessor acc ) : + ConstantColorBlendSetterAccessorAdapter( WrappedAccessor acc, + color_type col ) : maFunctor(), maWrappee(acc), - maBlendColor() + maBlendColor(col), + maGetterValue() {} - ConstantColorBlendAccessorAdapter( WrappedAccessor acc, - value_type col ) : + ConstantColorBlendSetterAccessorAdapter( WrappedAccessor acc, + color_type col, + value_type val ) : maFunctor(), maWrappee(acc), - maBlendColor(col) + maBlendColor(col), + maGetterValue(val) {} - void setColor( value_type col ) { maBlendColor=col; } + void setColor( color_type col ) { maBlendColor=col; } + color_type getColor() { return maBlendColor; } + void setGetterValue( value_type val ) { maGetterValue=val; } + value_type getGetterValue() { return maGetterValue; } - template< typename IteratorType > value_type operator()(IteratorType const& i) const + /// @return constant value, regardless of iterator content + template< typename IteratorType > value_type operator()(IteratorType const& ) const { - return maWrappee(i); + return maGetterValue; } + /// @return constant value, regardless of iterator content template< typename IteratorType, class Difference > - value_type operator()(IteratorType const& i, Difference const& diff) const + value_type operator()(IteratorType const& , Difference const& ) const { - return maWrappee(i,diff); + return maGetterValue; } template< typename V, typename IteratorType > @@ -379,11 +403,11 @@ template< typename T, typename M > struct IntegerInputMaskFunctor */ T operator()( T v, M m ) const { - // TODO(Q3): use traits to get unsigned type for T (if - // not already) + typedef typename make_unsigned<T>::type unsigned_T; // mask will be 0, iff m == 0, and 1 otherwise - const T mask( static_cast<unsigned int>(m | -m) >> (sizeof(unsigned int)*8 - 1) ); + const unsigned_T mask( + unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) ); return v*mask; } }; @@ -417,8 +441,10 @@ template< typename T, typename M > struct IntegerOutputMaskFunctor */ T operator()( T v1, M m, T v2 ) const { + typedef typename make_unsigned<T>::type unsigned_T; + // mask will be 0, iff m == 0, and 1 otherwise - const T mask( static_cast<unsigned int>(m | -m) >> (sizeof(unsigned int)*8 - 1) ); + const T mask( unsigned_cast<T>(m | -m) >> (sizeof(unsigned_T)*8 - 1) ); return v1*(M)(1-mask) + v2*mask; } }; diff --git a/basebmp/inc/basebmp/bitmapdevice.hxx b/basebmp/inc/basebmp/bitmapdevice.hxx index 7c8aa84ccef6..080f2a475e49 100644 --- a/basebmp/inc/basebmp/bitmapdevice.hxx +++ b/basebmp/inc/basebmp/bitmapdevice.hxx @@ -2,9 +2,9 @@ * * $RCSfile: bitmapdevice.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: thb $ $Date: 2006-06-08 00:01:47 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:18 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -51,20 +51,6 @@ #include <boost/noncopyable.hpp> #include <vector> -/* 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; @@ -88,13 +74,15 @@ struct ImplBitmapDevice; /** Definition of BitmapDevice interface - Use the createBitmapDevice() factory method to create one instance. + Use the createBitmapDevice() factory method to create instances. Implementation note: the clip mask and bitmap parameter instances of BitmapDevice that are passed to individual BitmapDevice - instances work best with 1 bit TC MSB masks for the clip and a + instances work best with 1 bit gray masks for the clip and a format matching that of the target BitmapDevice for the other - parameters. Everything else is accepted, but potentially slow. + parameters. The alpha mask passed to the drawMaskedColor() methods + works best when given as an eight bit gray bitmap. Everything else + is accepted, but potentially slow. */ class BitmapDevice : private boost::noncopyable { @@ -106,7 +94,9 @@ public: /** 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 + scanline, and false if it starts with the last one. The latter + is e.g. the typical scan line ordering for the Windows BMP + format. */ bool isTopDown() const; @@ -117,18 +107,24 @@ public: /** 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. + isTopDown()==false, this offset will be negative. */ sal_Int32 getScanlineStride() const; /** Get pointer to frame buffer + + @return a shared ptr to the bitmap buffer memory. As this is a + shared ptr, you can freely store and use the pointer, even + after this object has been deleted. */ RawMemorySharedArray getBuffer() const; /** Get pointer to palette The returned pointer is const on purpose, since the - BitmapDevice might internally cache lookup information. + BitmapDevice might internally cache lookup information. Don't + modify the returned data, unless you want to enter the realm + of completely undefined behaviour. @return shared pointer to vector of Color entries. */ @@ -141,6 +137,9 @@ public: const sal_Int32 getPaletteEntryCount() const; /** Clear whole device with given color + + This method works like a fill with the given color value, + resulting in a bitmap uniformly colored in fillColor. */ void clear( Color fillColor ); @@ -172,7 +171,7 @@ public: @param rClip Clip mask to use. If the clip mask is 0 at the given pixel - position, no change will happen. + position, no change will take place. */ void setPixel( const basegfx::B2IPoint& rPt, Color pixelColor, @@ -198,8 +197,8 @@ public: @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 + (with the actual pixel positions 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 @@ -220,8 +219,8 @@ public: @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 + (with the actual pixel positions 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 @@ -232,55 +231,314 @@ public: @param rClip Clip mask to use. Pixel where the corresponding clip mask - pixel is 0 will not be touched. + pixel is 0 will not be modified. */ - void drawLine( const basegfx::B2IPoint& rPt1, + void drawLine( const basegfx::B2IPoint& rPt1, const basegfx::B2IPoint& rPt2, Color lineColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ); + /** Draw a polygon + + @param rPoly + Polygon to draw. Depending on the value returned by rPoly's + isClosed() method, the resulting line polygon will be drawn + closed or not. + + @param lineColor + Color value to draw the polygon with + + @param drawMode + Draw mode to use when changing pixel values + */ void drawPolygon( const basegfx::B2DPolygon& rPoly, Color lineColor, DrawMode drawMode ); + + /** Draw a polygon + + @param rPoly + Polygon to draw. Depending on the value returned by rPoly's + isClosed() method, the resulting line polygon will be drawn + closed or not. + + @param lineColor + Color value to draw the polygon with + + @param drawMode + Draw mode to use when changing pixel values + + @param rClip + Clip mask to use. Pixel where the corresponding clip mask + pixel is 0 will not be modified. + */ void drawPolygon( const basegfx::B2DPolygon& rPoly, Color lineColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ); + /** Fill a poly-polygon + + @param rPoly + Poly-polygon to fill. Regardless of the value returned by + rPoly's isClosed() method, the resulting filled poly-polygon + is always considered closed. As usual, when filling a shape, + the rightmost and bottommost pixel are not filled, compared to + the drawPolygon() method. For example, the rectangle + (0,0),(1,1) will have four pixel set, when drawn via + drawPolygon(), and only one pixel, when filled via + fillPolyPolygon(). + + @param fillColor + Color value to fill the poly-polygon with + + @param drawMode + Draw mode to use when changing pixel values + */ void fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly, Color fillColor, DrawMode drawMode ); + + /** Fill a poly-polygon + + @param rPoly + Poly-polygon to fill. Regardless of the value returned by + rPoly's isClosed() method, the resulting filled poly-polygon + is always considered closed. As usual, when filling a shape, + the rightmost and bottommost pixel are not filled, compared to + the drawPolygon() method. For example, the rectangle + (0,0),(1,1) will have four pixel set, when drawn via + drawPolygon(), and only one pixel, when filled via + fillPolyPolygon(). + + @param fillColor + Color value to fill the poly-polygon with + + @param drawMode + Draw mode to use when changing pixel values + + @param rClip + Clip mask to use. Pixel where the corresponding clip mask + pixel is 0 will not be modified. + */ void fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly, Color fillColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ); + /** Draw another bitmap into this device + + @param rSrcBitmap + Bitmap to render into this one. It is permitted that source + and destination bitmap are the same. + + @param rSrcRect + Rectangle within the source bitmap to take the pixel from. + + @param rDstRect + Rectangle in the destination bitmap to put the pixel + into. Source and destination rectangle are permitted to have + differing sizes; this method will scale the source pixel + accordingly. Please note that both source and destination + rectangle are interpreted excluding the rightmost pixel column + and the bottommost pixel row, this is much like polygon + filling. As a result, filling a given rectangle with + fillPolyPolygon(), and using the same rectangle as the + destination rectangle of this method, will affect exactly the + same set of pixel. + + @param drawMode + Draw mode to use when changing pixel values + */ void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, const basegfx::B2IRange& rSrcRect, const basegfx::B2IRange& rDstRect, DrawMode drawMode ); + + /** Draw another bitmap into this device + + @param rSrcBitmap + Bitmap to render into this one. It is permitted that source + and destination bitmap are the same. + + @param rSrcRect + Rectangle within the source bitmap to take the pixel from. + + @param rDstRect + Rectangle in the destination bitmap to put the pixel + into. Source and destination rectangle are permitted to have + differing sizes; this method will scale the source pixel + accordingly. Please note that both source and destination + rectangle are interpreted excluding the rightmost pixel column + and the bottommost pixel row, this is much like polygon + filling. As a result, filling a given rectangle with + fillPolyPolygon(), and using the same rectangle as the + destination rectangle of this method, will affect exactly the + same set of pixel. + + @param drawMode + Draw mode to use when changing pixel values + + @param rClip + Clip mask to use. Pixel where the corresponding clip mask + pixel is 0 will not be modified. + */ void drawBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, const basegfx::B2IRange& rSrcRect, const basegfx::B2IRange& rDstRect, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ); - void drawMaskedColor( Color rSrcColor, + /** Draw a color with an alpha-modulation bitmap into this device + + This method takes a fixed color value, and an alpha mask. For + each pixel in the alpha mask, the given color value is blended + with the corresponding alpha value against the content of this + object. + + @param aSrcColor + Color value to use for blending + + @param rAlphaMask + Alpha mask to use for blending. It is permitted that alpha + mask and this bitmap are the same object. + + @param rSrcRect + Rectangle within the alpha mask to take the pixel from. + Please note that the destination rectangle is interpreted + excluding the rightmost pixel column and the bottommost pixel + row, this is much like polygon filling. As a result, filling a + given rectangle with fillPolyPolygon(), and using the same + rectangle as the source rectangle of this method, will affect + exactly the same set of pixel. + + @param rDstPoint + Destination point, where to start placing the pixel from the + source rectangle + */ + void drawMaskedColor( Color aSrcColor, const BitmapDeviceSharedPtr& rAlphaMask, const basegfx::B2IRange& rSrcRect, const basegfx::B2IPoint& rDstPoint ); - void drawMaskedColor( Color rSrcColor, + + /** Draw a color with an alpha-modulation bitmap into this device + + This method takes a fixed color value, and an alpha mask. For + each pixel in the alpha mask, the given color value is blended + with the corresponding alpha value against the content of this + object. + + @param aSrcColor + Color value to use for blending + + @param rAlphaMask + Alpha mask to use for blending. It is permitted that alpha + mask and this bitmap are the same object. + + @param rSrcRect + Rectangle within the alpha mask to take the pixel from. + Please note that the destination rectangle is interpreted + excluding the rightmost pixel column and the bottommost pixel + row, this is much like polygon filling. As a result, filling a + given rectangle with fillPolyPolygon(), and using the same + rectangle as the source rectangle of this method, will affect + exactly the same set of pixel. + + @param rDstPoint + Destination point, where to start placing the pixel from the + source rectangle + + @param rClip + Clip mask to use. Pixel where the corresponding clip mask + pixel is 0 will not be modified. + */ + void drawMaskedColor( Color aSrcColor, const BitmapDeviceSharedPtr& rAlphaMask, const basegfx::B2IRange& rSrcRect, const basegfx::B2IPoint& rDstPoint, const BitmapDeviceSharedPtr& rClip ); + /** Draw another bitmap through a mask into this device + + This method renders a source bitmap into this device, much + like the drawBitmap() method. The only difference is the + additional mask parameter, which operates much like an + additional clip mask: pixel with value zero in this mask + result in destination pixel not being modified. + + @param rSrcBitmap + Bitmap to render into this one. It is permitted that source + and destination bitmap are the same. + + @param rMask + Bitmap to use as a mask. Pixel with value zero in this mask + will result in destination pixel not being affected by the + blit operation. + + @param rSrcRect + Rectangle within the source bitmap to take the pixel from. + + @param rDstRect + Rectangle in the destination bitmap to put the pixel + into. Source and destination rectangle are permitted to have + differing sizes; this method will scale the source pixel + accordingly. Please note that both source and destination + rectangle are interpreted excluding the rightmost pixel column + and the bottommost pixel row, this is much like polygon + filling. As a result, filling a given rectangle with + fillPolyPolygon(), and using the same rectangle as the + destination rectangle of this method, will affect exactly the + same set of pixel. + + @param drawMode + Draw mode to use when changing pixel values + */ void drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, const BitmapDeviceSharedPtr& rMask, const basegfx::B2IRange& rSrcRect, const basegfx::B2IRange& rDstRect, DrawMode drawMode ); + + /** Draw another bitmap through a mask into this device + + This method renders a source bitmap into this device, much + like the drawBitmap() method. The only difference is the + additional mask parameter, which operates much like an + additional clip mask: pixel with value zero in this mask + result in destination pixel not being modified. + + @param rSrcBitmap + Bitmap to render into this one. It is permitted that source + and destination bitmap are the same. + + @param rMask + Bitmap to use as a mask. Pixel with value zero in this mask + will result in destination pixel not being affected by the + blit operation. + + @param rSrcRect + Rectangle within the source bitmap to take the pixel from. + + @param rDstRect + Rectangle in the destination bitmap to put the pixel + into. Source and destination rectangle are permitted to have + differing sizes; this method will scale the source pixel + accordingly. Please note that both source and destination + rectangle are interpreted excluding the rightmost pixel column + and the bottommost pixel row, this is much like polygon + filling. As a result, filling a given rectangle with + fillPolyPolygon(), and using the same rectangle as the + destination rectangle of this method, will affect exactly the + same set of pixel. + + @param drawMode + Draw mode to use when changing pixel values + + @param rClip + Clip mask to use. Pixel where the corresponding clip mask + pixel is 0 will not be modified. + */ void drawMaskedBitmap( const BitmapDeviceSharedPtr& rSrcBitmap, const BitmapDeviceSharedPtr& rMask, const basegfx::B2IRange& rSrcRect, @@ -317,20 +575,24 @@ private: virtual sal_uInt32 getPixelData_i( const basegfx::B2IPoint& rPt ) = 0; - virtual void drawLine_i( const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + virtual void drawLine_i( const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode ) = 0; - virtual void drawLine_i( const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + virtual void drawLine_i( const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ) = 0; virtual void drawPolygon_i( const basegfx::B2DPolygon& rPoly, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode ) = 0; virtual void drawPolygon_i( const basegfx::B2DPolygon& rPoly, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ) = 0; diff --git a/basebmp/inc/basebmp/clippedlinerenderer.hxx b/basebmp/inc/basebmp/clippedlinerenderer.hxx index 0c484a08ad3f..c48fc7ef2df6 100644 --- a/basebmp/inc/basebmp/clippedlinerenderer.hxx +++ b/basebmp/inc/basebmp/clippedlinerenderer.hxx @@ -4,9 +4,9 @@ * * $RCSfile: clippedlinerenderer.hxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: thb $ $Date: 2006-06-02 08:36:14 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -39,6 +39,12 @@ #ifndef _BGFX_TOOLS_RECTCLIPTOOLS_HXX #include <basegfx/tools/rectcliptools.hxx> #endif +#ifndef _BGFX_POINT_B2IPOINT_HXX +#include <basegfx/point/b2ipoint.hxx> +#endif +#ifndef _BGFX_RANGE_B2IRANGE_HXX +#include <basegfx/range/b2irange.hxx> +#endif namespace basebmp { @@ -107,13 +113,13 @@ inline bool prepareClip( sal_Int32 a1, { o_bs = b1 + cb; if( o_bs > bMax ) - return; + return false; } else { o_bs = b1 - cb; if( o_bs < bMin ) - return; + return false; } io_rem += ca - 2*da*cb; @@ -125,13 +131,13 @@ inline bool prepareClip( sal_Int32 a1, { o_as = a1 + ca; if( o_as > aMax ) - return; + return false; } else { o_as = a1 - ca; if( o_as < aMin ) - return; + return false; } io_rem += 2*db*ca - cb; @@ -207,7 +213,6 @@ void renderClippedLine( basegfx::B2IPoint aPt1, const basegfx::B2IRange& rClipRect, typename Accessor::value_type color, Iterator begin, - Iterator end, Accessor acc, bool bRoundTowardsPt2=false ) { @@ -272,43 +277,65 @@ void renderClippedLine( basegfx::B2IPoint aPt1, rClipRect.getMinY(), basegfx::tools::RectClipFlags::TOP, rClipRect.getMaxY(), basegfx::tools::RectClipFlags::BOTTOM, bRoundTowardsPt2 )); - const sal_Int32 diff = 2*(ady - adx); + + Iterator currIter( begin + vigra::Diff2D(0,ys) ); + typename Iterator::row_iterator rowIter( currIter.rowIterator() + xs ); + + adx *= 2; + ady *= 2; + if( bUseAlternateBresenham ) { while(true) { - plot(xs,ys); + acc.set(color, rowIter); if( rem >= 0 ) { if( --n < 0 ) break; - rem += diff; + ys += sy; + xs += sx; + rem -= adx; + + currIter.y += sy; + rowIter = currIter.rowIterator() + xs; } else - rem += 2*ady; + { + xs += sx; + rowIter += sx; + } - xs += sx; + rem += ady; } } else { while(true) { - plot(xs,ys); + acc.set(color, rowIter); if( --n < 0 ) break; + if( rem >= 0 ) { - rem += diff; ys += sy; + xs += sx; + rem -= adx; + + currIter.y += sy; + rowIter = currIter.rowIterator() + xs; } else - rem += 2*ady; + { + xs += sx; + rowIter += sx; + } - xs += sx; + rem += ady; } } } @@ -319,49 +346,71 @@ void renderClippedLine( basegfx::B2IPoint aPt1, const bool bUseAlternateBresenham( prepareClip(y1, y2, x1, ady, adx, ys, xs, sy, sx, - rem, clipCode1, clipCount1, clipCode1, clipCount2, + rem, n, 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); + + Iterator currIter( begin + vigra::Diff2D(xs,0) ); + typename Iterator::column_iterator colIter( currIter.columnIterator() + ys ); + + adx *= 2; + ady *= 2; + if( bUseAlternateBresenham ) { while(true) { - plot(xy,ys); + acc.set(color, colIter); if( rem >= 0 ) { if( --n < 0 ) break; - rem += diff; + xs += sx; + ys += sy; + rem -= ady; + + currIter.x += sx; + colIter = currIter.columnIterator() + ys; } else - rem += 2*adx; + { + ys += sy; + colIter += sy; + } - ys += sy; + rem += adx; } } else { while(true) { - plot(xs,ys); + acc.set(color, colIter); if( --n < 0 ) break; + if( rem >= 0 ) { - rem += diff; xs += sx; + ys += sy; + rem -= ady; + + currIter.x += sx; + colIter = currIter.columnIterator() + ys; } else - rem += 2*adx; + { + ys += sy; + colIter += sy; + } - ys += sy; + rem += adx; } } } diff --git a/basebmp/inc/basebmp/color.hxx b/basebmp/inc/basebmp/color.hxx index eadceaddc33c..6984780e7587 100644 --- a/basebmp/inc/basebmp/color.hxx +++ b/basebmp/inc/basebmp/color.hxx @@ -4,9 +4,9 @@ * * $RCSfile: color.hxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: hdu $ $Date: 2006-06-13 13:06:26 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -58,9 +58,9 @@ public: mnColor( ((sal_uInt32)nRed << 16) | ((sal_uInt32)nGreen << 8) | nBlue ) {} - void setRed( sal_uInt8 nRed ) { mnColor |= (sal_uInt32)nRed << 16; mnColor &= ~((sal_uInt32)nRed << 16); } - void setGreen( sal_uInt8 nGreen ) { mnColor |= (sal_uInt32)nGreen << 8; mnColor &= ~((sal_uInt32)nGreen << 8); } - void setBlue( sal_uInt8 nBlue ) { mnColor |= nBlue; mnColor &= ~(sal_uInt32)nBlue; } + void setRed( sal_uInt8 nRed ) { mnColor &= ~0x00FF0000UL; mnColor |= (sal_uInt32)nRed << 16; } + void setGreen( sal_uInt8 nGreen ) { mnColor &= ~0x0000FF00UL; mnColor |= (sal_uInt32)nGreen << 8; } + void setBlue( sal_uInt8 nBlue ) { mnColor &= ~0x000000FFUL; mnColor |= nBlue; } void setGray( sal_uInt8 nGrayVal ) { mnColor = (sal_uInt32)nGrayVal << 16 | (sal_uInt32)nGrayVal << 8 | nGrayVal; } diff --git a/basebmp/inc/basebmp/drawmodes.hxx b/basebmp/inc/basebmp/drawmodes.hxx index 2eb1fa6ff9e5..6dc5d13b8e98 100644 --- a/basebmp/inc/basebmp/drawmodes.hxx +++ b/basebmp/inc/basebmp/drawmodes.hxx @@ -2,9 +2,9 @@ * * $RCSfile: drawmodes.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-28 16:50:19 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -68,7 +68,20 @@ namespace basebmp { enum DrawMode { + /** Default draw mode, which simply renders pixel in the + requested color + */ DrawMode_PAINT, + + /** XOR draw mode, which XORs each existing pixel value with + the new color. + + The result of this XOR operation strongly depends on the + underlying pixel format, as it is defined by the bitwise + XOR of the (potentially palette-looked-up) color value and + the existing pixel content (being it true color or a + palette index). + */ DrawMode_XOR }; } diff --git a/basebmp/inc/basebmp/linerenderer.hxx b/basebmp/inc/basebmp/linerenderer.hxx index 87898e50142e..9e06d0c33bb6 100644 --- a/basebmp/inc/basebmp/linerenderer.hxx +++ b/basebmp/inc/basebmp/linerenderer.hxx @@ -4,9 +4,9 @@ * * $RCSfile: linerenderer.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-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -81,7 +81,6 @@ void renderLine( const basegfx::B2IPoint& rPt1, const basegfx::B2IPoint& rPt2, typename Accessor::value_type color, Iterator begin, - Iterator end, Accessor acc, bool bRoundTowardsPt2=false ) { diff --git a/basebmp/inc/basebmp/metafunctions.hxx b/basebmp/inc/basebmp/metafunctions.hxx index 7a3ff8fd62a2..0f15a5346795 100644 --- a/basebmp/inc/basebmp/metafunctions.hxx +++ b/basebmp/inc/basebmp/metafunctions.hxx @@ -4,9 +4,9 @@ * * $RCSfile: metafunctions.hxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: thb $ $Date: 2006-06-09 04:21:01 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -64,6 +64,35 @@ template <typename T> struct remove_const<const T> typedef T type; }; +/** template meta function: ensure that given integer type is unsigned + + If given integer type is already unsigned, return as-is - + otherwise, convert to unsigned type of same or greater range. + */ +template< typename T > struct make_unsigned; + +#define BASEBMP_MAKE_UNSIGNED(T,U) \ + template<> struct make_unsigned<T> { \ + typedef U type; \ + }; + +BASEBMP_MAKE_UNSIGNED(signed char,unsigned char) +BASEBMP_MAKE_UNSIGNED(unsigned char,unsigned char) +BASEBMP_MAKE_UNSIGNED(short,unsigned short) +BASEBMP_MAKE_UNSIGNED(unsigned short,unsigned short) +BASEBMP_MAKE_UNSIGNED(int,unsigned int) +BASEBMP_MAKE_UNSIGNED(unsigned int,unsigned int) +BASEBMP_MAKE_UNSIGNED(long,unsigned long) +BASEBMP_MAKE_UNSIGNED(unsigned long,unsigned long) + +#undef BASEBMP_MAKE_UNSIGNED + +/// cast integer to unsigned type of similar size +template< typename T > inline typename make_unsigned<T>::type unsigned_cast( T value ) +{ + return static_cast< typename make_unsigned<T>::type >(value); +} + /// returns true, if given number is strictly less than 0 template< typename T > inline bool is_negative( T x ) { diff --git a/basebmp/inc/basebmp/packedpixeliterator.hxx b/basebmp/inc/basebmp/packedpixeliterator.hxx index ba2b3dbd22af..c9824b6ed1c0 100644 --- a/basebmp/inc/basebmp/packedpixeliterator.hxx +++ b/basebmp/inc/basebmp/packedpixeliterator.hxx @@ -4,9 +4,9 @@ * * $RCSfile: packedpixeliterator.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: thb $ $Date: 2006-06-07 14:27:35 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -220,16 +220,12 @@ public: value_type get() const { - // TODO(Q3): use traits to get unsigned type for value_type (if - // not already) - return static_cast<unsigned int>(*y() & mask_) >> shift_; + return unsigned_cast<value_type>(*y() & mask_) >> shift_; } value_type get(difference_type d) const { - // TODO(Q3): use traits to get unsigned type for value_type (if - // not already) - return static_cast<unsigned int>(*y(d) & mask_) >> shift_; + return unsigned_cast<value_type>(*y(d) & mask_) >> shift_; } void set( value_type v ) const @@ -287,9 +283,7 @@ private: const mask_type shifted_mask( MsbFirst ? - // TODO(Q3): use traits to get unsigned type for value_type - // (if not already) - static_cast<unsigned int>(mask_) >> bits_per_pixel : + unsigned_cast<mask_type>(mask_) >> bits_per_pixel : mask_ << bits_per_pixel ); // data_offset is 0 for shifted mask, and 1 for wrapped-around mask @@ -318,9 +312,7 @@ private: const mask_type shifted_mask( MsbFirst ? mask_ << bits_per_pixel : - // TODO(Q3): use traits to get unsigned type for value_type - // (if not already) - static_cast<unsigned int>(mask_) >> bits_per_pixel ); + unsigned_cast<mask_type>(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 ? @@ -463,10 +455,10 @@ public: value_type get() const { - // TODO(Q3): use traits to get unsigned type for value_type (if - // not already) - return static_cast<unsigned int>(*data_ & mask_) >> - get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_); + return unsigned_cast<value_type>(*data_ & mask_) >> + get_shift<num_intraword_positions, + bits_per_pixel, + MsbFirst>(remainder_); } value_type get(difference_type d) const @@ -620,16 +612,7 @@ public: { const int remainder( x % num_intraword_positions ); - // TODO(Q3): use traits to get unsigned type for value_type (if - // not already) - value_type nTmp0( *current() ); - unsigned int nTmp1(static_cast<unsigned int>(*current() & - get_mask<value_type, bits_per_pixel, MsbFirst>(remainder))); - unsigned int nTmp2( (static_cast<unsigned int>(*current() & - get_mask<value_type, bits_per_pixel, MsbFirst>(remainder)) - >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))); - - return (static_cast<unsigned int>(*current() & + return (unsigned_cast<value_type>(*current() & get_mask<value_type, bits_per_pixel, MsbFirst>(remainder)) >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder)); } @@ -638,9 +621,7 @@ public: { const int remainder( x(d.x) % num_intraword_positions ); - // TODO(Q3): use traits to get unsigned type for value_type (if - // not already) - return (static_cast<unsigned int>(*current(d.x,d.y) & + return (unsigned_cast<value_type>(*current(d.x,d.y) & get_mask<value_type, bits_per_pixel, MsbFirst>(remainder)) >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder)); } diff --git a/basebmp/inc/basebmp/paletteimageaccessor.hxx b/basebmp/inc/basebmp/paletteimageaccessor.hxx index 20098242554c..ccc97c25b1fa 100644 --- a/basebmp/inc/basebmp/paletteimageaccessor.hxx +++ b/basebmp/inc/basebmp/paletteimageaccessor.hxx @@ -4,9 +4,9 @@ * * $RCSfile: paletteimageaccessor.hxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: thb $ $Date: 2006-06-07 14:27:35 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -152,8 +152,9 @@ template< class Accessor > struct rawAccessor template< typename DataType > struct RawAccessor : public StandardAccessor< DataType > { RawAccessor() {} + // converting constructor, which in fact discards argument template< typename ValueType > explicit RawAccessor( - const PaletteImageAccessor< ValueType, DataType >& a ) {} + const PaletteImageAccessor< ValueType, DataType >& ) {} }; // specialization for PaletteImageAccessor, to provide the diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx index e49405d1bfc3..2e85066bfd97 100644 --- a/basebmp/source/bitmapdevice.cxx +++ b/basebmp/source/bitmapdevice.cxx @@ -4,9 +4,9 @@ * * $RCSfile: bitmapdevice.cxx,v $ * - * $Revision: 1.12 $ + * $Revision: 1.13 $ * - * last change: $Author: thb $ $Date: 2006-06-09 04:21:01 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -41,7 +41,7 @@ #include "basebmp/accessor.hxx" #include "basebmp/accessoradapters.hxx" #include "basebmp/scanlineformats.hxx" -#include "basebmp/linerenderer.hxx" +#include "basebmp/clippedlinerenderer.hxx" #include "basebmp/compositeiterator.hxx" #include <rtl/alloc.h> @@ -105,6 +105,12 @@ namespace Color operator()( DataType c ) { return Color(c,c,c); } }; + /// type-safe conversion from Color to packed int32 + struct UInt32FromColor + { + sal_uInt32 operator()( const Color& c ) { return c.toInt32(); } + }; + /// Get converter from color to given data type template< typename DataType > struct fromColorConverter; template<> struct fromColorConverter< sal_uInt8 > @@ -127,6 +133,16 @@ namespace typedef std::identity<Color> type; }; + /// Get converter from given data type to sal_uInt32 + template< typename DataType > struct toUInt32Converter + { + typedef std::identity<DataType> type; + }; + template<> struct toUInt32Converter< Color > + { + typedef UInt32FromColor type; + }; + // Polygon scanline conversion //------------------------------------------------------------------------ @@ -146,7 +162,6 @@ namespace typename DestAccessor::value_type fillColor, const basegfx::B2IRange& bounds, DestIterator begin, - DestIterator end, DestAccessor accessor ) : B2DPolyPolygonRasterConverter(rPolyPolyRaster, basegfx::B2DRange(bounds) ), @@ -207,7 +222,6 @@ namespace fillColor, aBmpRange, dest.first, - dest.second, dest.third)); } @@ -229,6 +243,8 @@ namespace typedef typename toColorConverter< typename DestAccessor::value_type>::type ToColorFunctor; typedef typename rawAccessor<DestAccessor>::type RawAccessor; + typedef typename toUInt32Converter< + typename RawAccessor::value_type>::type ToUInt32Functor; typedef typename xorAccessor<DestAccessor>::type XorAccessor; typedef typename xorAccessor<RawAccessor>::type RawXorAccessor; typedef typename maskedAccessor<DestAccessor, @@ -243,7 +259,7 @@ namespace MaskAccessor, DestIterator, MaskIterator>::type MaskedXorAccessor; - typedef ConstantColorBlendAccessorAdapter< + typedef ConstantColorBlendSetterAccessorAdapter< DestAccessor, typename AlphaMaskAccessor::value_type> ColorBlendAccessor; typedef typename maskedAccessor<ColorBlendAccessor, @@ -265,6 +281,7 @@ namespace ColorLookupFunctor maColorLookup; FromColorFunctor maFromColorConverter; ToColorFunctor maToColorConverter; + ToUInt32Functor maToUInt32Converter; DestAccessor maAccessor; RawAccessor maRawAccessor; XorAccessor maXorAccessor; @@ -292,6 +309,7 @@ namespace maColorLookup(), maFromColorConverter(), maToColorConverter(), + maToUInt32Converter(), maAccessor( accessor ), maRawAccessor( accessor ), maXorAccessor( accessor ), @@ -319,16 +337,24 @@ namespace return getCompatibleBitmap(bmp).get() != NULL; } - boost::shared_ptr<MaskBitmap> getCompatibleMask( const BitmapDeviceSharedPtr& bmp ) const + boost::shared_ptr<MaskBitmap> getCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const { - return boost::dynamic_pointer_cast<MaskBitmap>( bmp ); + boost::shared_ptr<MaskBitmap> pMask( boost::dynamic_pointer_cast<MaskBitmap>( bmp )); + + if( !pMask ) + return pMask; + + if( pMask->getSize() != getSize() ) + pMask.reset(); + + return pMask; } virtual bool isCompatibleClipMask( const BitmapDeviceSharedPtr& bmp ) const { // TODO(P1): dynamic_cast usually called twice for // compatible formats - return getCompatibleMask( bmp ).get() != NULL; + return boost::dynamic_pointer_cast<MaskBitmap>( bmp ).get() != NULL; } boost::shared_ptr<AlphaMaskBitmap> getCompatibleAlphaMask( const BitmapDeviceSharedPtr& bmp ) const @@ -387,7 +413,7 @@ namespace DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ) { - boost::shared_ptr<MaskBitmap> pMask( getCompatibleMask(rClip) ); + boost::shared_ptr<MaskBitmap> pMask( getCompatibleClipMask(rClip) ); OSL_ASSERT( pMask ); const vigra::Diff2D offset(rPt.getX(), @@ -420,34 +446,35 @@ namespace const DestIterator pixel( maBegin + vigra::Diff2D(rPt.getX(), rPt.getY()) ); - // xxx TODO - return 0; // return maRawAccessor(pixel); + return maToUInt32Converter(maRawAccessor(pixel)); } template< typename Range, typename Col, typename RawAccessor > - void implRenderLine2( const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + void implRenderLine2( const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Col col, const Range& range, const RawAccessor& rawAcc ) { - renderLine( basegfx::fround(rPt1), - basegfx::fround(rPt2), - col, - range.first, - range.second, - rawAcc ); + renderClippedLine( rPt1, + rPt2, + rBounds, + col, + range.first, + rawAcc ); } template< typename Range, typename Accessor, typename RawAccessor > - void implRenderLine( const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + void implRenderLine( const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Color col, const Range& range, const Accessor& acc, const RawAccessor& rawAcc ) { - implRenderLine2( rPt1,rPt2, + implRenderLine2( rPt1,rPt2,rBounds, maColorLookup( acc, maFromColorConverter( col)), @@ -456,8 +483,9 @@ namespace } template< typename Range, typename RawAccessor, typename XorAccessor > - void implDrawLine( const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + void implDrawLine( const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Color col, const Range& range, const RawAccessor& rawAcc, @@ -465,19 +493,20 @@ namespace DrawMode drawMode ) { if( drawMode == DrawMode_XOR ) - implRenderLine( rPt1, rPt2, col, + implRenderLine( rPt1, rPt2, rBounds, col, range, maAccessor, xorAcc ); else - implRenderLine( rPt1, rPt2, col, + implRenderLine( rPt1, rPt2, rBounds, col, range, maAccessor, rawAcc ); } - virtual void drawLine_i(const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + virtual void drawLine_i(const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode ) { - implDrawLine(rPt1,rPt2,lineColor, + implDrawLine(rPt1,rPt2,rBounds,lineColor, std::make_pair(maBegin,maEnd), maRawAccessor,maRawXorAccessor,drawMode); } @@ -485,7 +514,7 @@ namespace vigra::pair<composite_iterator_type,composite_iterator_type> getMaskedRange( const BitmapDeviceSharedPtr& rClip ) const { - boost::shared_ptr<MaskBitmap> pMask( getCompatibleMask(rClip) ); + boost::shared_ptr<MaskBitmap> pMask( getCompatibleClipMask(rClip) ); OSL_ASSERT( pMask ); return std::make_pair( @@ -497,19 +526,21 @@ namespace pMask->maEnd )); } - virtual void drawLine_i(const basegfx::B2DPoint& rPt1, - const basegfx::B2DPoint& rPt2, + virtual void drawLine_i(const basegfx::B2IPoint& rPt1, + const basegfx::B2IPoint& rPt2, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ) { - implDrawLine(rPt1,rPt2,lineColor, + implDrawLine(rPt1,rPt2,rBounds,lineColor, getMaskedRange(rClip), maRawMaskedAccessor,maRawMaskedXorAccessor,drawMode); } template< typename Range, typename RawAccessor > void implDrawPolygon( const basegfx::B2DPolygon& rPoly, + const basegfx::B2IRange& rBounds, Color col, const Range& range, const RawAccessor& acc ) @@ -524,47 +555,51 @@ namespace col))); const sal_uInt32 nVertices( aPoly.count() ); for( sal_uInt32 i=1; i<nVertices; ++i ) - implRenderLine2( aPoly.getB2DPoint(i-1), - aPoly.getB2DPoint(i), + implRenderLine2( basegfx::fround(aPoly.getB2DPoint(i-1)), + basegfx::fround(aPoly.getB2DPoint(i)), + rBounds, colorIndex, range, acc ); if( nVertices > 1 && aPoly.isClosed() ) - implRenderLine2( aPoly.getB2DPoint(nVertices-1), - aPoly.getB2DPoint(0), + implRenderLine2( basegfx::fround(aPoly.getB2DPoint(nVertices-1)), + basegfx::fround(aPoly.getB2DPoint(0)), + rBounds, colorIndex, range, acc ); } virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode ) { if( drawMode == DrawMode_XOR ) - implDrawPolygon( rPoly, lineColor, + implDrawPolygon( rPoly, rBounds, lineColor, std::make_pair(maBegin, maEnd), maRawXorAccessor ); else - implDrawPolygon( rPoly, lineColor, + implDrawPolygon( rPoly, rBounds, lineColor, std::make_pair(maBegin, maEnd), maRawAccessor ); } virtual void drawPolygon_i(const basegfx::B2DPolygon& rPoly, + const basegfx::B2IRange& rBounds, Color lineColor, DrawMode drawMode, const BitmapDeviceSharedPtr& rClip ) { if( drawMode == DrawMode_XOR ) - implDrawPolygon( rPoly, lineColor, + implDrawPolygon( rPoly, rBounds, lineColor, getMaskedRange(rClip), maRawMaskedXorAccessor ); else - implDrawPolygon( rPoly, lineColor, + implDrawPolygon( rPoly, rBounds, lineColor, getMaskedRange(rClip), maRawMaskedAccessor ); } @@ -700,11 +735,8 @@ namespace pAlpha->maAccessor, maBegin + vigra::Diff2D(rDstPoint.getX(), rDstPoint.getY()), - ConstantColorBlendAccessorAdapter< - DestAccessor, - typename AlphaMaskAccessor::value_type>( - maAccessor, - maFromColorConverter(aSrcColor)) ); + ColorBlendAccessor( maAccessor, + maFromColorConverter(aSrcColor)) ); } virtual void drawMaskedColor_i(Color aSrcColor, @@ -713,7 +745,6 @@ namespace const basegfx::B2IPoint& rDstPoint, const BitmapDeviceSharedPtr& rClip ) { -#if 0 boost::shared_ptr<AlphaMaskBitmap> pAlpha( getCompatibleAlphaMask(rAlphaMask) ); OSL_ASSERT( pAlpha ); @@ -729,22 +760,25 @@ namespace aRange.first + vigra::Diff2D(rDstPoint.getX(), rDstPoint.getY()), maMaskedColorBlendAccessor ); -#else - drawMaskedColor_i(aSrcColor, - rAlphaMask, - rSrcRect, - rDstPoint ); -#endif } - // 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!" ); + // TODO(F3): This is a hack, at best. The mask must be the + // size of the source bitmap, and accordingly + // translated. Let alone interpolated. + if( drawMode == DrawMode_XOR ) + implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect, + getMaskedRange(rMask), + maRawMaskedXorAccessor); + else + implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect, + getMaskedRange(rMask), + maRawMaskedAccessor); } virtual void drawMaskedBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap, @@ -752,9 +786,16 @@ namespace const basegfx::B2IRange& rSrcRect, const basegfx::B2IRange& rDstRect, DrawMode drawMode, - const BitmapDeviceSharedPtr& rClip ) + const BitmapDeviceSharedPtr& rClip ) { - OSL_ENSURE( false, "Method not yet implemented!" ); + // TODO(F3): Clipped drawMaskedBitmap_i() not yet implemented + (void)rClip; + drawMaskedBitmap_i( rSrcBitmap, + rMask, + rSrcRect, + rDstRect, + drawMode ); + OSL_ENSURE( false, "Method not yet implemented, falling back to unclipped version!" ); } }; } // namespace @@ -884,15 +925,11 @@ void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1, 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 ); - } + drawLine_i( rPt1, + rPt2, + mpImpl->maBounds, + lineColor, + drawMode ); } void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1, @@ -907,34 +944,26 @@ void BitmapDevice::drawLine( const basegfx::B2IPoint& rPt1, return; } - 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!" ); - } + if( isCompatibleClipMask( rClip ) ) + drawLine_i( rPt1, + rPt2, + mpImpl->maBounds, + lineColor, + drawMode, + rClip ); + else + OSL_ENSURE( false, "Generic output not yet implemented!" ); } 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 ); + const sal_uInt32 numVertices( rPoly.count() ); + if( numVertices ) + drawPolygon_i( rPoly, + mpImpl->maBounds, + lineColor, drawMode ); } void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly, @@ -948,18 +977,14 @@ void BitmapDevice::drawPolygon( const basegfx::B2DPolygon& rPoly, return; } - 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!" ); + const sal_uInt32 numVertices( rPoly.count() ); + if( numVertices ) + if( isCompatibleClipMask( rClip ) ) + drawPolygon_i( rPoly, + mpImpl->maBounds, + lineColor, drawMode, rClip ); + else + OSL_ENSURE( false, "Generic output not yet implemented!" ); } void BitmapDevice::fillPolyPolygon( const basegfx::B2DPolyPolygon& rPoly, diff --git a/basebmp/test/basictest.cxx b/basebmp/test/basictest.cxx index 8e33561303f6..893fdae489d9 100644 --- a/basebmp/test/basictest.cxx +++ b/basebmp/test/basictest.cxx @@ -4,9 +4,9 @@ * * $RCSfile: basictest.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: thb $ $Date: 2006-06-07 14:27:36 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -61,6 +61,44 @@ namespace class BasicTest : public CppUnit::TestFixture { public: + void colorTest() + { + Color aTestColor; + + aTestColor = Color(0xDEADBEEF); + CPPUNIT_ASSERT_MESSAGE("unary constructor", + aTestColor.toInt32() == 0xDEADBEEF ); + + aTestColor = Color( 0x10, 0x20, 0xFF ); + CPPUNIT_ASSERT_MESSAGE("ternary constructor", + aTestColor.toInt32() == 0x001020FF ); + + aTestColor.setRed( 0x0F ); + CPPUNIT_ASSERT_MESSAGE("setRed()", + aTestColor.toInt32() == 0x00F20FF ); + + aTestColor.setGreen( 0x0F ); + CPPUNIT_ASSERT_MESSAGE("setGreen()", + aTestColor.toInt32() == 0x00F0FFF ); + + aTestColor.setBlue( 0x10 ); + CPPUNIT_ASSERT_MESSAGE("setBlue()", + aTestColor.toInt32() == 0x00F0F10 ); + + aTestColor.setGray( 0x13 ); + CPPUNIT_ASSERT_MESSAGE("setGray()", + aTestColor.toInt32() == 0x00131313 ); + + aTestColor = Color( 0x10, 0x20, 0xFF ); + CPPUNIT_ASSERT_MESSAGE("getRed()", + aTestColor.getRed() == 0x10 ); + CPPUNIT_ASSERT_MESSAGE("getGreen()", + aTestColor.getGreen() == 0x20 ); + CPPUNIT_ASSERT_MESSAGE("getBlue()", + aTestColor.getBlue() == 0xFF ); + + } + void testConstruction() { const basegfx::B2ISize aSize(101,101); @@ -117,10 +155,6 @@ public: const Color aCol4(0x010101); pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); - - std::ofstream output("32bpp_test.dump"); - debugDump( pDevice, output ); - CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #4", pDevice->getPixel(aPt) == aCol4); @@ -163,6 +197,7 @@ public: // because these macros are need by auto register mechanism. CPPUNIT_TEST_SUITE(BasicTest); + CPPUNIT_TEST(colorTest); CPPUNIT_TEST(testConstruction); CPPUNIT_TEST(testPixelFuncs); CPPUNIT_TEST_SUITE_END(); diff --git a/basebmp/test/bmpdemo.cxx b/basebmp/test/bmpdemo.cxx index 3e43ce8ce2d1..1a0b3d4512c4 100644 --- a/basebmp/test/bmpdemo.cxx +++ b/basebmp/test/bmpdemo.cxx @@ -4,9 +4,9 @@ * * $RCSfile: bmpdemo.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: thb $ $Date: 2006-06-09 04:21:01 $ + * last change: $Author: thb $ $Date: 2006-06-28 16:50:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -983,7 +983,7 @@ class TestWindow : public Dialog TestWindow() : Dialog( (Window *) NULL ) { SetText( rtl::OUString::createFromAscii( "VIGRA test" ) ); - SetSizePixel( Size( 1024, 500 ) ); + SetSizePixel( Size( 1024, 1024 ) ); EnablePaint( true ); Show(); } @@ -1017,7 +1017,8 @@ static basegfx::B2IPoint project( const basegfx::B2IPoint& rPoint ) //double y2 = y1 * cos( angle_z ) - x1 * sin( angle_z ); double z2 = z1; - return basegfx::B2IPoint( (sal_Int32)x2, (sal_Int32)z2 ); + //return basegfx::B2IPoint( (sal_Int32)3*x2, (sal_Int32)3*z2 ); + return basegfx::B2IPoint( (sal_Int32)6*x2, (sal_Int32)6*z2 ); } static basebmp::Color approachColor( const basebmp::Color& rFrom, const basebmp::Color& rTo ) @@ -1075,16 +1076,27 @@ static basebmp::Color approachColor( const basebmp::Color& rFrom, const basebmp: void TestWindow::Paint( const Rectangle& rRect ) { + basegfx::B2ISize aTestSize(1000,1000); + basebmp::BitmapDeviceSharedPtr pDevice( basebmp::createBitmapDevice( aTestSize, + true, + basebmp::Format::THIRTYTWO_BIT_TC_MASK )); + + { + const basegfx::B2IPoint aPt1(0,0); + const basegfx::B2IPoint aPt2(1,9); + const basebmp::Color aCol(0xFFFFFFFF); + pDevice->drawLine( aPt1, aPt2, aCol, basebmp::DrawMode_PAINT ); + } + { - basegfx::B2ISize aTestSize(500,500); - basebmp::BitmapDeviceSharedPtr pDevice2( basebmp::createBitmapDevice( aTestSize, - true, - basebmp::Format::THIRTYTWO_BIT_TC_MASK )); - pDevice2->clear(basebmp::Color(0)); + pDevice->clear(basebmp::Color(0)); basegfx::B2IPoint aCenter( aTestSize.getX()/2, aTestSize.getY()/2 ); - basegfx::B2IPoint aP1( aTestSize.getX()/48, 0), aP2( aTestSize.getX()/40, 0 ), aPoint; + //basegfx::B2IPoint aP1( aTestSize.getX()/48, 0), aP2( aTestSize.getX()/40, 0 ), aPoint; + //basegfx::B2IPoint aP1( aTestSize.getX()/7, 0), aP2( aTestSize.getX()/6, 0 ), aPoint; + //basegfx::B2IPoint aP1( aTestSize.getX()/5, 0), aP2( aTestSize.getX()/4, 0 ), aPoint; + basegfx::B2IPoint aP1( aTestSize.getX()/12, 0), aP2( aTestSize.getX()/11, 0 ), aPoint; double sind = sin( DELTA*M_PI/180.0 ); double cosd = cos( DELTA*M_PI/180.0 ); @@ -1110,14 +1122,12 @@ void TestWindow::Paint( const Rectangle& rRect ) basegfx::B2DPolygon aPoly; aPoly.append( basegfx::B2DPoint(project( aP1 ) + aCenter) ); aPoly.append( basegfx::B2DPoint(project( aP2 ) + aCenter) ); - pDevice2->drawPolygon( - aPoly, - basebmp::Color(0xFFFFFFFF), - basebmp::DrawMode_PAINT); - pDevice2->fillPolyPolygon( + pDevice->fillPolyPolygon( basegfx::tools::createAreaGeometryForPolygon( aPoly, - n/3, +// std::max(1,n/30), +// std::max(1,n/60), + std::max(1,n/30), basegfx::tools::B2DLINEJOIN_NONE), aLineColor, basebmp::DrawMode_PAINT); @@ -1131,271 +1141,23 @@ void TestWindow::Paint( const Rectangle& rRect ) } std::ofstream output4("svptest.dump"); - debugDump( pDevice2, output4 ); - - const basegfx::B2ISize aSize(10,10); - basebmp::BitmapDeviceSharedPtr pDevice( basebmp::createBitmapDevice( aSize, - true, - basebmp::Format::THIRTYTWO_BIT_TC_MASK )); - basebmp::BitmapDeviceSharedPtr pMask( basebmp::createBitmapDevice( aSize, - true, - basebmp::Format::ONE_BIT_MSB_GRAY )); - ::rtl::OUString aSvg = ::rtl::OUString::createFromAscii( - "m 0 0 h5 l5 5 v5 h-5 l-5-5 z" ); - basegfx::B2DPolyPolygon aPoly; - basegfx::tools::importFromSvgD( aPoly, aSvg ); - pMask->clear(basebmp::Color(0xFFFFFFFF)); - pMask->drawPolygon( - aPoly.getB2DPolygon(0), - basebmp::Color(0), - basebmp::DrawMode_PAINT ); - - basebmp::BitmapDeviceSharedPtr pBmp( basebmp::cloneBitmapDevice( - basegfx::B2IVector(3,3), - pDevice )); - basebmp::Color aCol1(0); - basebmp::Color aCol2(0xFFFFFFFF); - pBmp->clear(aCol1); - pBmp->setPixel(basegfx::B2IPoint(0,0),aCol2,basebmp::DrawMode_PAINT); - pBmp->setPixel(basegfx::B2IPoint(1,1),aCol2,basebmp::DrawMode_PAINT); - pBmp->setPixel(basegfx::B2IPoint(2,2),aCol2,basebmp::DrawMode_PAINT); - - pDevice->clear(aCol1); - pDevice->drawBitmap(pBmp, - basegfx::B2IRange(0,0,3,3), - basegfx::B2IRange(2,2,7,7), -// basegfx::B2IRange(-1,-1,5,5), - basebmp::DrawMode_PAINT, - pMask); - - std::ofstream output("32bpp_test.dump"); - debugDump( pDevice, output ); - std::ofstream output2("32bpp_bmp.dump"); - debugDump( pBmp, output2 ); - std::ofstream output3("clipmask.dump"); - debugDump( pMask, output3 ); - } - - 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 ); + debugDump( pDevice, output4 ); + } + + Bitmap aBitmap( Size(aTestSize.getX(), + aTestSize.getY()), 24 ); + + // Fill bitmap with generated content + { + ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(), + aBitmap ); + for( int y=0; y<aTestSize.getY(); ++y ) + for( int x=0; x<aTestSize.getX(); ++x ) + pWriteAccess->SetPixel(y,x, + Color(pDevice->getPixelData(basegfx::B2IPoint(x,y))) ); + } + + DrawBitmap( Point(), aBitmap ); } USHORT TestApp::Exception( USHORT nError ) diff --git a/basebmp/test/cliptest.cxx b/basebmp/test/cliptest.cxx new file mode 100644 index 000000000000..bf6dbc3d7376 --- /dev/null +++ b/basebmp/test/cliptest.cxx @@ -0,0 +1,274 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: cliptest.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: thb $ $Date: 2006-06-28 16:50:20 $ + * + * 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 + * + ************************************************************************/ + +// autogenerated file with codegen.pl + +#include <cppunit/simpleheader.hxx> + +#include <basegfx/vector/b2isize.hxx> +#include <basegfx/point/b2ipoint.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2irange.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> + +#include <basebmp/color.hxx> +#include <basebmp/scanlineformats.hxx> +#include <basebmp/bitmapdevice.hxx> +#include <basebmp/debug.hxx> +#include "tools.hxx" + +#include <iostream> +#include <fstream> + +using namespace ::basebmp; + +namespace +{ +/* + std::ofstream output("32bpp_test.dump"); + debugDump( mpDevice32bpp, output ); +*/ + +class ClipTest : public CppUnit::TestFixture +{ +private: + BitmapDeviceSharedPtr mpClipMask; + BitmapDeviceSharedPtr mpDevice1bpp; + BitmapDeviceSharedPtr mpDevice32bpp; + + void implTestPixelClip(const BitmapDeviceSharedPtr& rDevice) + { + const Color aBgCol(0); + rDevice->clear(aBgCol); + + const basegfx::B2IPoint aPt(0,0); + const Color aCol(0xFFFFFFFF); + rDevice->setPixel( aPt, aCol, DrawMode_PAINT, mpClipMask ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel clip #1", + rDevice->getPixel(aPt) == aBgCol); + + const basegfx::B2IPoint aPt2(10,10); + rDevice->setPixel( aPt2, aCol, DrawMode_PAINT, mpClipMask ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel clip #2", + rDevice->getPixel(aPt2) == aBgCol); + + const basegfx::B2IPoint aPt1(10,0); + rDevice->setPixel( aPt1, aCol, DrawMode_PAINT, mpClipMask ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel clip #3", + rDevice->getPixel(aPt1) != aBgCol); + + const basegfx::B2IPoint aPt3(0,10); + rDevice->setPixel( aPt3, aCol, DrawMode_PAINT, mpClipMask ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel clip #4", + rDevice->getPixel(aPt3) != aBgCol); + } + + void implTestLineClip(const BitmapDeviceSharedPtr& rDevice) + { + const Color aBgCol(0); + rDevice->clear(aBgCol); + + const basegfx::B2IPoint aPt1(0,0); + const basegfx::B2IPoint aPt2(1,9); + const Color aCol(0xFFFFFFFF); + rDevice->drawLine( aPt1, aPt2, aCol, DrawMode_PAINT, mpClipMask ); + + std::ofstream output("32bpp_test.dump"); + debugDump( mpDevice32bpp, output ); + + const basegfx::B2IPoint aPt3(1,5); + CPPUNIT_ASSERT_MESSAGE("get line pixel", + rDevice->getPixel(aPt3) != aBgCol); + CPPUNIT_ASSERT_MESSAGE("number of rendered line pixel is not 4", + countPixel( rDevice, + rDevice->getPixel(aPt3) ) == 4); + } + + void implTestFillClip(const BitmapDeviceSharedPtr& rDevice) + { + rDevice->clear(Color(0)); + + const basegfx::B2DRange aAllOver(-10,-10,20,20); + const Color aCol(0xFFFFFFFF); + rDevice->fillPolyPolygon( basegfx::B2DPolyPolygon( + basegfx::tools::createPolygonFromRect(aAllOver)), + aCol, + DrawMode_PAINT, + mpClipMask ); + const basegfx::B2IPoint aPt(0,10); + CPPUNIT_ASSERT_MESSAGE("number of clipped pixel is not 28", + countPixel( rDevice, rDevice->getPixel(aPt) ) == 121-28); + } + + void implTestBmpClip(const BitmapDeviceSharedPtr& rDevice) + { + BitmapDeviceSharedPtr pBmp( cloneBitmapDevice( + basegfx::B2IVector(3,3), + rDevice )); + Color aCol1(0); + Color aCol2(0xFFFFFFFF); + pBmp->clear(aCol1); + pBmp->setPixel(basegfx::B2IPoint(0,0),aCol2,DrawMode_PAINT); + pBmp->setPixel(basegfx::B2IPoint(1,1),aCol2,DrawMode_PAINT); + pBmp->setPixel(basegfx::B2IPoint(2,2),aCol2,basebmp::DrawMode_PAINT); + + rDevice->clear(aCol1); + rDevice->drawBitmap(pBmp, + basegfx::B2IRange(0,0,3,3), + basegfx::B2IRange(-1,-1,4,4), + DrawMode_PAINT, + mpClipMask); + + const basegfx::B2IPoint aPt(1,1); + CPPUNIT_ASSERT_MESSAGE("number of clipped pixel is not 5", + countPixel( rDevice, + rDevice->getPixel(aPt) ) == 5); + } + + void implTestMaskColorClip(const BitmapDeviceSharedPtr& rDevice) + { + BitmapDeviceSharedPtr pBmp( createBitmapDevice( rDevice->getSize(), + true, + Format::EIGHT_BIT_GRAY )); + + ::rtl::OUString aSvg = ::rtl::OUString::createFromAscii( + "m 0 0h5v10h5v-5h-10z" ); + + basegfx::B2DPolyPolygon aPoly; + basegfx::tools::importFromSvgD( aPoly, aSvg ); + const basebmp::Color aCol(0xFF); + pBmp->clear( basebmp::Color(0) ); + pBmp->fillPolyPolygon( + aPoly, + aCol, + basebmp::DrawMode_PAINT ); + + const basegfx::B2IRange aSourceRect(0,0,10,10); + const basegfx::B2IPoint aDestLeftTop(0,0); + const Color aCol2(0xF0F0F0F0); + rDevice->drawMaskedColor( + aCol2, + pBmp, + aSourceRect, + aDestLeftTop, + mpClipMask ); + const basegfx::B2IPoint aPt(1,1); + CPPUNIT_ASSERT_MESSAGE("number of rendered pixel is not 41", + countPixel( rDevice, rDevice->getPixel(aPt) ) == 41); + + } + +public: + void setUp() + { + const basegfx::B2ISize aSize(11,11); + mpClipMask = createBitmapDevice( aSize, + true, + Format::ONE_BIT_MSB_GRAY ); + mpDevice1bpp = createBitmapDevice( aSize, + true, + Format::ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, + Format::THIRTYTWO_BIT_TC_MASK ); + + ::rtl::OUString aSvg = ::rtl::OUString::createFromAscii( + "m 0 0 h5 l5 5 v5 h-5 l-5-5 z" ); + basegfx::B2DPolyPolygon aPoly; + basegfx::tools::importFromSvgD( aPoly, aSvg ); + mpClipMask->clear(Color(0xFFFFFFFF)); + mpClipMask->drawPolygon( + aPoly.getB2DPolygon(0), + Color(0), + DrawMode_PAINT ); + } + + void testPixelClip() + { + implTestPixelClip( mpDevice1bpp ); + implTestPixelClip( mpDevice32bpp ); + } + + void testLineClip() + { + implTestLineClip( mpDevice1bpp ); + implTestLineClip( mpDevice32bpp ); + } + + void testFillClip() + { + implTestFillClip( mpDevice1bpp ); + implTestFillClip( mpDevice32bpp ); + } + + void testBmpClip() + { + implTestBmpClip( mpDevice1bpp ); + implTestBmpClip( mpDevice32bpp ); + } + + void testMaskColorClip() + { + implTestMaskColorClip( mpDevice1bpp ); + implTestMaskColorClip( 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(ClipTest); + CPPUNIT_TEST(testPixelClip); + CPPUNIT_TEST(testLineClip); + CPPUNIT_TEST(testFillClip); + CPPUNIT_TEST(testBmpClip); + CPPUNIT_TEST(testMaskColorClip); + CPPUNIT_TEST_SUITE_END(); +}; + +// ----------------------------------------------------------------------------- +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ClipTest, "ClipTest"); +} + + +// ----------------------------------------------------------------------------- + +// 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; + |