xref: /aoo41x/main/basebmp/test/bmpdemo.cxx (revision 69de5a4c)
1*69de5a4cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*69de5a4cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*69de5a4cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*69de5a4cSAndrew Rist  * distributed with this work for additional information
6*69de5a4cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*69de5a4cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*69de5a4cSAndrew Rist  * "License"); you may not use this file except in compliance
9*69de5a4cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*69de5a4cSAndrew Rist  *
11*69de5a4cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*69de5a4cSAndrew Rist  *
13*69de5a4cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*69de5a4cSAndrew Rist  * software distributed under the License is distributed on an
15*69de5a4cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*69de5a4cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*69de5a4cSAndrew Rist  * specific language governing permissions and limitations
18*69de5a4cSAndrew Rist  * under the License.
19*69de5a4cSAndrew Rist  *
20*69de5a4cSAndrew Rist  *************************************************************/
21*69de5a4cSAndrew Rist 
22*69de5a4cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #ifndef  _USE_MATH_DEFINES
25cdf0e10cSrcweir #define  _USE_MATH_DEFINES  // needed by Visual C++ for math constants
26cdf0e10cSrcweir #endif
27cdf0e10cSrcweir #include <math.h>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
30cdf0e10cSrcweir #include <comphelper/regpathhelper.hxx>
31cdf0e10cSrcweir #include <cppuhelper/servicefactory.hxx>
32cdf0e10cSrcweir #include <cppuhelper/bootstrap.hxx>
33cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
35cdf0e10cSrcweir #include <com/sun/star/registry/XSimpleRegistry.hpp>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <ucbhelper/contentbroker.hxx>
38cdf0e10cSrcweir #include <ucbhelper/configurationkeys.hxx>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <vcl/window.hxx>
41cdf0e10cSrcweir #include <vcl/svapp.hxx>
42cdf0e10cSrcweir #include <vcl/msgbox.hxx>
43cdf0e10cSrcweir #include <vcl/unowrap.hxx>
44cdf0e10cSrcweir #include <vcl/bitmap.hxx>
45cdf0e10cSrcweir #include <vcl/bmpacc.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include <basegfx/polygon/b2dlinegeometry.hxx>
48cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
49cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
50cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx>
51cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
52cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
53cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
54cdf0e10cSrcweir #include <basegfx/range/b2irange.hxx>
55cdf0e10cSrcweir #include <basegfx/vector/b2isize.hxx>
56cdf0e10cSrcweir #include <basegfx/point/b2ipoint.hxx>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir #include <basebmp/color.hxx>
59cdf0e10cSrcweir #include <basebmp/scanlineformats.hxx>
60cdf0e10cSrcweir #include <basebmp/bitmapdevice.hxx>
61cdf0e10cSrcweir #include <basebmp/debug.hxx>
62cdf0e10cSrcweir 
63cdf0e10cSrcweir #include <rtl/bootstrap.hxx>
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #include <vigra/metaprogramming.hxx>
66cdf0e10cSrcweir #include <vigra/static_assert.hxx>
67cdf0e10cSrcweir #include <vigra/basicimageview.hxx>
68cdf0e10cSrcweir 
69cdf0e10cSrcweir #include <boost/static_assert.hpp>
70cdf0e10cSrcweir #include <algorithm>
71cdf0e10cSrcweir #include <iostream>
72cdf0e10cSrcweir #include <fstream>
73cdf0e10cSrcweir 
74cdf0e10cSrcweir using namespace ::com::sun::star;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir namespace
78cdf0e10cSrcweir {
79cdf0e10cSrcweir 
80cdf0e10cSrcweir /// template meta function: add const qualifier, if given 2nd type has it
81cdf0e10cSrcweir template<typename A, typename B> struct clone_const
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     typedef B type;
84cdf0e10cSrcweir };
85cdf0e10cSrcweir template<typename A, typename B> struct clone_const<const A,B>
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     typedef const B type;
88cdf0e10cSrcweir };
89cdf0e10cSrcweir 
90cdf0e10cSrcweir template< class DestIterator, class DestAccessor > class Renderer :
91cdf0e10cSrcweir         public basegfx::B2DPolyPolygonRasterConverter
92cdf0e10cSrcweir {
93cdf0e10cSrcweir private:
94cdf0e10cSrcweir     typename DestIterator::value_type fillColor_;
95cdf0e10cSrcweir     typename DestIterator::value_type clearColor_;
96cdf0e10cSrcweir     DestIterator                      begin_;
97cdf0e10cSrcweir     DestAccessor                      accessor_;
98cdf0e10cSrcweir 
99cdf0e10cSrcweir public:
Renderer(const basegfx::B2DPolyPolygon & rPolyPolyRaster,typename DestIterator::value_type fillColor,typename DestIterator::value_type clearColor,DestIterator begin,DestIterator end,DestAccessor accessor)100cdf0e10cSrcweir     Renderer(const basegfx::B2DPolyPolygon&     rPolyPolyRaster,
101cdf0e10cSrcweir              typename DestIterator::value_type  fillColor,
102cdf0e10cSrcweir              typename DestIterator::value_type  clearColor,
103cdf0e10cSrcweir              DestIterator                       begin,
104cdf0e10cSrcweir              DestIterator                       end,
105cdf0e10cSrcweir              DestAccessor                       accessor ) :
106cdf0e10cSrcweir         B2DPolyPolygonRasterConverter(rPolyPolyRaster,
107cdf0e10cSrcweir                                       basegfx::B2DRange(0,0,
108cdf0e10cSrcweir                                                         end.x - end.x,
109cdf0e10cSrcweir                                                         begin.y - begin.y )),
110cdf0e10cSrcweir         fillColor_( fillColor ),
111cdf0e10cSrcweir         clearColor_( clearColor ),
112cdf0e10cSrcweir         begin_( begin ),
113cdf0e10cSrcweir         accessor_( accessor )
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir 
span(const double & rfXLeft,const double & rfXRight,sal_Int32 nY,bool bOn)117cdf0e10cSrcweir     virtual void span(const double& rfXLeft,
118cdf0e10cSrcweir                       const double& rfXRight,
119cdf0e10cSrcweir                       sal_Int32 	nY,
120cdf0e10cSrcweir                       bool 			bOn )
121cdf0e10cSrcweir     {
122cdf0e10cSrcweir         DestIterator currIter( begin_ + vigra::Diff2D(0,nY) );
123cdf0e10cSrcweir         typename DestIterator::row_iterator rowIter( currIter.rowIterator() +
124cdf0e10cSrcweir                                                      basegfx::fround(rfXLeft) );
125cdf0e10cSrcweir         typename DestIterator::row_iterator rowEnd( currIter.rowIterator() +
126cdf0e10cSrcweir                                                     basegfx::fround(rfXRight) );
127cdf0e10cSrcweir         if( bOn )
128cdf0e10cSrcweir             while( rowIter != rowEnd )
129cdf0e10cSrcweir             {
130cdf0e10cSrcweir                 accessor_.set(fillColor_, rowIter);
131cdf0e10cSrcweir                 ++rowIter;
132cdf0e10cSrcweir             }
133cdf0e10cSrcweir         else
134cdf0e10cSrcweir             while( rowIter != rowEnd )
135cdf0e10cSrcweir             {
136cdf0e10cSrcweir                 accessor_.set(accessor_(rowIter)*clearColor_, rowIter);
137cdf0e10cSrcweir                 ++rowIter;
138cdf0e10cSrcweir             }
139cdf0e10cSrcweir     }
140cdf0e10cSrcweir };
141cdf0e10cSrcweir 
142cdf0e10cSrcweir template< class DestIterator, class DestAccessor >
makeRenderer(const basegfx::B2DPolyPolygon & rPolyPolyRaster,typename DestIterator::value_type fillColor,typename DestIterator::value_type clearColor,vigra::triple<DestIterator,DestIterator,DestAccessor> dest)143cdf0e10cSrcweir     std::auto_ptr< Renderer< DestIterator, DestAccessor > > makeRenderer(
144cdf0e10cSrcweir         const basegfx::B2DPolyPolygon&                          rPolyPolyRaster,
145cdf0e10cSrcweir         typename DestIterator::value_type                       fillColor,
146cdf0e10cSrcweir         typename DestIterator::value_type                       clearColor,
147cdf0e10cSrcweir         vigra::triple<DestIterator, DestIterator, DestAccessor> dest )
148cdf0e10cSrcweir {
149cdf0e10cSrcweir     return std::auto_ptr< Renderer< DestIterator, DestAccessor > >(
150cdf0e10cSrcweir         new Renderer< DestIterator, DestAccessor >(rPolyPolyRaster,
151cdf0e10cSrcweir                                                    fillColor,
152cdf0e10cSrcweir                                                    clearColor,
153cdf0e10cSrcweir                                                    dest.first,
154cdf0e10cSrcweir                                                    dest.second,
155cdf0e10cSrcweir                                                    dest.third));
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir 
159cdf0e10cSrcweir // changed semantics re. DirectionSelector<StridedArrayTag>: stride
160cdf0e10cSrcweir // now counts in <em>raw</em> bytes!
161cdf0e10cSrcweir template< typename T > class StridedArrayIterator
162cdf0e10cSrcweir {
163cdf0e10cSrcweir public:
164cdf0e10cSrcweir     typedef typename clone_const<T, unsigned char>::type  internal_type;
165cdf0e10cSrcweir 
StridedArrayIterator(int stride,T * ptr=0)166cdf0e10cSrcweir     StridedArrayIterator(int stride, T* ptr = 0) :
167cdf0e10cSrcweir         stride_(stride),
168cdf0e10cSrcweir         current_(reinterpret_cast<internal_type*>(ptr))
169cdf0e10cSrcweir     {}
170cdf0e10cSrcweir 
171cdf0e10cSrcweir     /// Copy from other StridedArrayIterator, plus given offset
StridedArrayIterator(StridedArrayIterator const & rSrc,int offset)172cdf0e10cSrcweir     StridedArrayIterator( StridedArrayIterator const& rSrc,
173cdf0e10cSrcweir                           int                         offset ) :
174cdf0e10cSrcweir         stride_(rSrc.stride_),
175cdf0e10cSrcweir         current_(reinterpret_cast<internal_type*>(
176cdf0e10cSrcweir                      reinterpret_cast<T*>(rSrc.current_)+offset))
177cdf0e10cSrcweir     {}
178cdf0e10cSrcweir 
operator ++()179cdf0e10cSrcweir     void operator++() {current_ += stride_; }
operator ++(int)180cdf0e10cSrcweir     void operator++(int) {current_ += stride_; }
operator --()181cdf0e10cSrcweir     void operator--() {current_ -= stride_; }
operator --(int)182cdf0e10cSrcweir     void operator--(int) {current_ -= stride_; }
operator +=(int dy)183cdf0e10cSrcweir     void operator+=(int dy) {current_ += dy*stride_; }
operator -=(int dy)184cdf0e10cSrcweir     void operator-=(int dy) {current_ -= dy*stride_; }
185cdf0e10cSrcweir 
operator ==(StridedArrayIterator const & rhs) const186cdf0e10cSrcweir     bool operator==(StridedArrayIterator const & rhs) const
187cdf0e10cSrcweir     { return (current_ == rhs.current_); }
188cdf0e10cSrcweir 
operator !=(StridedArrayIterator const & rhs) const189cdf0e10cSrcweir     bool operator!=(StridedArrayIterator const & rhs) const
190cdf0e10cSrcweir     { return (current_ != rhs.current_); }
191cdf0e10cSrcweir 
operator <(StridedArrayIterator const & rhs) const192cdf0e10cSrcweir     bool operator<(StridedArrayIterator const & rhs) const
193cdf0e10cSrcweir     { return (current_ < rhs.current_); }
194cdf0e10cSrcweir 
operator <=(StridedArrayIterator const & rhs) const195cdf0e10cSrcweir     bool operator<=(StridedArrayIterator const & rhs) const
196cdf0e10cSrcweir     { return (current_ <= rhs.current_); }
197cdf0e10cSrcweir 
operator >(StridedArrayIterator const & rhs) const198cdf0e10cSrcweir     bool operator>(StridedArrayIterator const & rhs) const
199cdf0e10cSrcweir     { return (current_ > rhs.current_); }
200cdf0e10cSrcweir 
operator >=(StridedArrayIterator const & rhs) const201cdf0e10cSrcweir     bool operator>=(StridedArrayIterator const & rhs) const
202cdf0e10cSrcweir     { return (current_ >= rhs.current_); }
203cdf0e10cSrcweir 
operator -(StridedArrayIterator const & rhs) const204cdf0e10cSrcweir     int operator-(StridedArrayIterator const & rhs) const
205cdf0e10cSrcweir     { return (current_ - rhs.current_) / stride_; }
206cdf0e10cSrcweir 
operator ()() const207cdf0e10cSrcweir     T* operator()() const
208cdf0e10cSrcweir     { return reinterpret_cast<T*>(current_); }
209cdf0e10cSrcweir 
operator ()(int d) const210cdf0e10cSrcweir     T* operator()(int d) const
211cdf0e10cSrcweir     { return reinterpret_cast<T*>(current_ + d*stride_); }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     int            stride_;
214cdf0e10cSrcweir     internal_type* current_;
215cdf0e10cSrcweir };
216cdf0e10cSrcweir 
217cdf0e10cSrcweir /// template meta function: remove const qualifier from plain type
218cdf0e10cSrcweir template <typename T> struct remove_const
219cdf0e10cSrcweir {
220cdf0e10cSrcweir     typedef T type;
221cdf0e10cSrcweir };
222cdf0e10cSrcweir template <typename T> struct remove_const<const T>
223cdf0e10cSrcweir {
224cdf0e10cSrcweir     typedef T type;
225cdf0e10cSrcweir };
226cdf0e10cSrcweir 
227cdf0e10cSrcweir /// returns true, if given number is strictly less than 0
is_negative(T x)228cdf0e10cSrcweir template< typename T > inline bool is_negative( T x )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir     return x < 0;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir /// Overload for ints (branch-free)
is_negative(int x)234cdf0e10cSrcweir inline bool is_negative( int x )
235cdf0e10cSrcweir {
236cdf0e10cSrcweir     // force logic shift (result for signed shift right is undefined)
237cdf0e10cSrcweir     return static_cast<unsigned int>(x) >> (sizeof(int)*8-1);
238cdf0e10cSrcweir }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir /// Get bitmask for data at given intra-word position, for given bit depth
get_mask(difference_type d)241cdf0e10cSrcweir template< typename data_type, int bits_per_pixel, bool MsbFirst, typename difference_type > inline data_type get_mask( difference_type d )
242cdf0e10cSrcweir {
243cdf0e10cSrcweir     BOOST_STATIC_ASSERT(bits_per_pixel > 0);
244cdf0e10cSrcweir     BOOST_STATIC_ASSERT(sizeof(data_type)*8 % bits_per_pixel == 0);
245cdf0e10cSrcweir     BOOST_STATIC_ASSERT(sizeof(data_type)*8 / bits_per_pixel > 1);
246cdf0e10cSrcweir     BOOST_STATIC_ASSERT(vigra::TypeTraits<data_type>::isPOD::asBool);
247cdf0e10cSrcweir 
248cdf0e10cSrcweir     const unsigned int nIntraWordPositions( sizeof(data_type)*8 / bits_per_pixel );
249cdf0e10cSrcweir 
250cdf0e10cSrcweir     //      create bits_per_pixel 1s      shift to intra-word position
251cdf0e10cSrcweir     return ((~(~0 << bits_per_pixel)) << bits_per_pixel*(MsbFirst ?
252cdf0e10cSrcweir                                                          (nIntraWordPositions-1 - (d % nIntraWordPositions)) :
253cdf0e10cSrcweir                                                          (d % nIntraWordPositions)));
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
get_shift(difference_type remainder)256cdf0e10cSrcweir template< int num_intraword_positions, int bits_per_pixel, bool MsbFirst, typename difference_type > inline difference_type get_shift( difference_type remainder )
257cdf0e10cSrcweir {
258cdf0e10cSrcweir     return bits_per_pixel*(MsbFirst ?
259cdf0e10cSrcweir                            (num_intraword_positions - 1 - remainder) :
260cdf0e10cSrcweir                            remainder);
261cdf0e10cSrcweir }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir template< typename Datatype,
264cdf0e10cSrcweir           typename Valuetype,
265cdf0e10cSrcweir           int      bits_per_pixel,
266cdf0e10cSrcweir           bool     MsbFirst > class PackedPixelColumnIterator
267cdf0e10cSrcweir {
268cdf0e10cSrcweir public:
269cdf0e10cSrcweir     // no reference, no index_reference type here
270cdf0e10cSrcweir     typedef Datatype                                    data_type;
271cdf0e10cSrcweir     typedef Valuetype                                   value_type;
272cdf0e10cSrcweir     typedef int                                         difference_type;
273cdf0e10cSrcweir     typedef image_traverser_tag                         iterator_category;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     typedef typename remove_const<data_type>::type      mask_type;
276cdf0e10cSrcweir     typedef data_type*                                  pointer;
277cdf0e10cSrcweir     typedef StridedArrayIterator< data_type >           MoveY;
278cdf0e10cSrcweir 
279cdf0e10cSrcweir     enum {
280cdf0e10cSrcweir         /** The number of pixel within a single data_type value
281cdf0e10cSrcweir          */
282cdf0e10cSrcweir         num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
283cdf0e10cSrcweir         /** Bit mask for one pixel (least significant bits)
284cdf0e10cSrcweir          */
285cdf0e10cSrcweir         bit_mask=~(~0 << bits_per_pixel)
286cdf0e10cSrcweir     };
287cdf0e10cSrcweir 
288cdf0e10cSrcweir private:
289cdf0e10cSrcweir     MoveY           y;
290cdf0e10cSrcweir     mask_type       mask_;
291cdf0e10cSrcweir     difference_type shift_;
292cdf0e10cSrcweir 
inc()293cdf0e10cSrcweir     void inc()
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir         ++y;
296cdf0e10cSrcweir     }
297cdf0e10cSrcweir 
dec()298cdf0e10cSrcweir     void dec()
299cdf0e10cSrcweir     {
300cdf0e10cSrcweir         --y;
301cdf0e10cSrcweir     }
302cdf0e10cSrcweir 
equal(PackedPixelColumnIterator const & rhs) const303cdf0e10cSrcweir     bool equal( PackedPixelColumnIterator const & rhs ) const
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         return rhs.y == y;
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir 
less(PackedPixelColumnIterator const & rhs) const308cdf0e10cSrcweir     bool less( PackedPixelColumnIterator const & rhs ) const
309cdf0e10cSrcweir     {
310cdf0e10cSrcweir         return y < rhs.y;
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir public:
PackedPixelColumnIterator()314cdf0e10cSrcweir     PackedPixelColumnIterator() :
315cdf0e10cSrcweir         y(0),
316cdf0e10cSrcweir         mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
317cdf0e10cSrcweir         shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst, difference_type>(0) )
318cdf0e10cSrcweir     {}
319cdf0e10cSrcweir 
PackedPixelColumnIterator(const MoveY & base,difference_type remainder)320cdf0e10cSrcweir     PackedPixelColumnIterator( const MoveY& base, difference_type remainder ) :
321cdf0e10cSrcweir         y(base),
322cdf0e10cSrcweir         mask_( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) ),
323cdf0e10cSrcweir         shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder) )
324cdf0e10cSrcweir     {}
325cdf0e10cSrcweir 
operator +=(difference_type d)326cdf0e10cSrcweir     PackedPixelColumnIterator& operator+=( difference_type d )
327cdf0e10cSrcweir     {
328cdf0e10cSrcweir         y += d;
329cdf0e10cSrcweir         return *this;
330cdf0e10cSrcweir     }
331cdf0e10cSrcweir 
operator -=(difference_type d)332cdf0e10cSrcweir     PackedPixelColumnIterator& operator-=( difference_type d )
333cdf0e10cSrcweir     {
334cdf0e10cSrcweir         y -= d;
335cdf0e10cSrcweir         return *this;
336cdf0e10cSrcweir     }
337cdf0e10cSrcweir 
operator +(difference_type d)338cdf0e10cSrcweir     PackedPixelColumnIterator operator+( difference_type d )
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir         PackedPixelColumnIterator res(*this);
341cdf0e10cSrcweir         res += d;
342cdf0e10cSrcweir         return res;
343cdf0e10cSrcweir     }
344cdf0e10cSrcweir 
operator -(difference_type d)345cdf0e10cSrcweir     PackedPixelColumnIterator operator-( difference_type d )
346cdf0e10cSrcweir     {
347cdf0e10cSrcweir         PackedPixelColumnIterator res(*this);
348cdf0e10cSrcweir         res -= d;
349cdf0e10cSrcweir         return res;
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir 
operator ++()352cdf0e10cSrcweir     PackedPixelColumnIterator& operator++()
353cdf0e10cSrcweir     {
354cdf0e10cSrcweir         inc();
355cdf0e10cSrcweir         return *this;
356cdf0e10cSrcweir     }
357cdf0e10cSrcweir 
operator --()358cdf0e10cSrcweir     PackedPixelColumnIterator& operator--()
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         dec();
361cdf0e10cSrcweir         return *this;
362cdf0e10cSrcweir     }
363cdf0e10cSrcweir 
operator ++(int)364cdf0e10cSrcweir     PackedPixelColumnIterator operator++(int)
365cdf0e10cSrcweir     {
366cdf0e10cSrcweir         PackedPixelColumnIterator res(*this);
367cdf0e10cSrcweir         res.inc();
368cdf0e10cSrcweir         return res;
369cdf0e10cSrcweir     }
370cdf0e10cSrcweir 
operator --(int)371cdf0e10cSrcweir     PackedPixelColumnIterator operator--(int)
372cdf0e10cSrcweir     {
373cdf0e10cSrcweir         PackedPixelColumnIterator res(*this);
374cdf0e10cSrcweir         res.dec();
375cdf0e10cSrcweir         return res;
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir 
operator ==(PackedPixelColumnIterator const & rhs) const378cdf0e10cSrcweir     bool operator==(PackedPixelColumnIterator const & rhs) const
379cdf0e10cSrcweir     {
380cdf0e10cSrcweir         return equal( rhs );
381cdf0e10cSrcweir     }
382cdf0e10cSrcweir 
operator !=(PackedPixelColumnIterator const & rhs) const383cdf0e10cSrcweir     bool operator!=(PackedPixelColumnIterator const & rhs) const
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir         return !equal( rhs );
386cdf0e10cSrcweir     }
387cdf0e10cSrcweir 
operator <(PackedPixelColumnIterator const & rhs) const388cdf0e10cSrcweir     bool operator<(PackedPixelColumnIterator const & rhs) const
389cdf0e10cSrcweir     {
390cdf0e10cSrcweir         return less(rhs);
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir 
operator <=(PackedPixelColumnIterator const & rhs) const393cdf0e10cSrcweir     bool operator<=(PackedPixelColumnIterator const & rhs) const
394cdf0e10cSrcweir     {
395cdf0e10cSrcweir         return !less(rhs);
396cdf0e10cSrcweir     }
397cdf0e10cSrcweir 
operator >(PackedPixelColumnIterator const & rhs) const398cdf0e10cSrcweir     bool operator>(PackedPixelColumnIterator const & rhs) const
399cdf0e10cSrcweir     {
400cdf0e10cSrcweir         return rhs.less(*this);
401cdf0e10cSrcweir     }
402cdf0e10cSrcweir 
operator >=(PackedPixelColumnIterator const & rhs) const403cdf0e10cSrcweir     bool operator>=(PackedPixelColumnIterator const & rhs) const
404cdf0e10cSrcweir     {
405cdf0e10cSrcweir         return !rhs.less(*this);
406cdf0e10cSrcweir     }
407cdf0e10cSrcweir 
operator -(PackedPixelColumnIterator const & rhs) const408cdf0e10cSrcweir     difference_type operator-(PackedPixelColumnIterator const & rhs) const
409cdf0e10cSrcweir     {
410cdf0e10cSrcweir         return y - rhs.y;
411cdf0e10cSrcweir     }
412cdf0e10cSrcweir 
get() const413cdf0e10cSrcweir     value_type get() const
414cdf0e10cSrcweir     {
415cdf0e10cSrcweir         // TODO(Q3): use traits to get unsigned type for data_type (if
416cdf0e10cSrcweir         // not already)
417cdf0e10cSrcweir         return static_cast<unsigned int>(*y() & mask_) >> shift_;
418cdf0e10cSrcweir     }
419cdf0e10cSrcweir 
get(difference_type d) const420cdf0e10cSrcweir     value_type get(difference_type d) const
421cdf0e10cSrcweir     {
422cdf0e10cSrcweir         // TODO(Q3): use traits to get unsigned type for data_type (if
423cdf0e10cSrcweir         // not already)
424cdf0e10cSrcweir         return static_cast<unsigned int>(*y(d) & mask_) >> shift_;
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir 
set(value_type v) const427cdf0e10cSrcweir     void set( value_type v ) const
428cdf0e10cSrcweir     {
429cdf0e10cSrcweir         const value_type pixel_value( (v << shift_) & mask_ );
430cdf0e10cSrcweir         *y() = (*y() & ~mask_) | pixel_value;
431cdf0e10cSrcweir     }
432cdf0e10cSrcweir 
set(value_type v,difference_type d) const433cdf0e10cSrcweir     void set( value_type v, difference_type d ) const
434cdf0e10cSrcweir     {
435cdf0e10cSrcweir         const value_type pixel_value( (v << shift_) & mask_ );
436cdf0e10cSrcweir         *y(d) = (*y(d) & ~mask_) | pixel_value;
437cdf0e10cSrcweir     }
438cdf0e10cSrcweir };
439cdf0e10cSrcweir 
440cdf0e10cSrcweir template< typename Datatype,
441cdf0e10cSrcweir           typename Valuetype,
442cdf0e10cSrcweir           int      bits_per_pixel,
443cdf0e10cSrcweir           bool     MsbFirst > class PackedPixelRowIterator
444cdf0e10cSrcweir {
445cdf0e10cSrcweir public:
446cdf0e10cSrcweir     // no reference, no index_reference type here
447cdf0e10cSrcweir     typedef Datatype                                    data_type;
448cdf0e10cSrcweir     typedef Valuetype                                   value_type;
449cdf0e10cSrcweir     typedef int                                         difference_type;
450cdf0e10cSrcweir     typedef image_traverser_tag                         iterator_category;
451cdf0e10cSrcweir 
452cdf0e10cSrcweir     typedef typename remove_const<data_type>::type      mask_type;
453cdf0e10cSrcweir     typedef data_type*                                  pointer;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir     enum {
456cdf0e10cSrcweir         /** The number of pixel within a single data_type value
457cdf0e10cSrcweir          */
458cdf0e10cSrcweir         num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
459cdf0e10cSrcweir         /** Bit mask for one pixel (least significant bits)
460cdf0e10cSrcweir          */
461cdf0e10cSrcweir         bit_mask=~(~0 << bits_per_pixel)
462cdf0e10cSrcweir     };
463cdf0e10cSrcweir 
464cdf0e10cSrcweir private:
465cdf0e10cSrcweir     pointer         data_;
466cdf0e10cSrcweir     mask_type       mask_;
467cdf0e10cSrcweir     difference_type remainder_;
468cdf0e10cSrcweir 
update_mask()469cdf0e10cSrcweir     void update_mask()
470cdf0e10cSrcweir     {
471cdf0e10cSrcweir         mask_ = get_mask<data_type, bits_per_pixel, MsbFirst>(remainder_);
472cdf0e10cSrcweir     }
473cdf0e10cSrcweir 
inc()474cdf0e10cSrcweir     void inc()
475cdf0e10cSrcweir     {
476cdf0e10cSrcweir         const difference_type newValue( remainder_ + 1 );
477cdf0e10cSrcweir         const difference_type data_offset( newValue / num_intraword_positions );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir         data_ += data_offset;
480cdf0e10cSrcweir         remainder_ = newValue % num_intraword_positions;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir         const mask_type shifted_mask(
483cdf0e10cSrcweir             MsbFirst ?
484cdf0e10cSrcweir             // TODO(Q3): use traits to get unsigned type for data_type
485cdf0e10cSrcweir             // (if not already)
486cdf0e10cSrcweir             static_cast<unsigned int>(mask_) >> bits_per_pixel :
487cdf0e10cSrcweir             mask_ << bits_per_pixel );
488cdf0e10cSrcweir 
489cdf0e10cSrcweir         // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
490cdf0e10cSrcweir         mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
491cdf0e10cSrcweir                                                             bit_mask << bits_per_pixel*(num_intraword_positions-1) :
492cdf0e10cSrcweir                                                             bit_mask);
493cdf0e10cSrcweir     }
494cdf0e10cSrcweir 
dec()495cdf0e10cSrcweir     void dec()
496cdf0e10cSrcweir     {
497cdf0e10cSrcweir         const difference_type newValue( remainder_ - 1 );
498cdf0e10cSrcweir         const bool            isNegative( is_negative(newValue) );
499cdf0e10cSrcweir         const difference_type newRemainder( newValue % num_intraword_positions );
500cdf0e10cSrcweir 
501cdf0e10cSrcweir         // calc  data_ += newValue / num_intraword_positions;
502cdf0e10cSrcweir         //       remainder_ = newRemainder;
503cdf0e10cSrcweir         // for newValue >= 0, and
504cdf0e10cSrcweir         //       data_ += newValue / num_intraword_positions - 1;
505cdf0e10cSrcweir         //       remainder_ = num_intraword_positions - newRemainder;
506cdf0e10cSrcweir         // (to force remainder_ to be positive).
507cdf0e10cSrcweir         // This is branch-free, if is_negative() is branch-free
508cdf0e10cSrcweir         const difference_type data_offset( newValue / num_intraword_positions - isNegative );
509cdf0e10cSrcweir         data_     += data_offset;
510cdf0e10cSrcweir         remainder_ = newRemainder + isNegative*num_intraword_positions;
511cdf0e10cSrcweir 
512cdf0e10cSrcweir         const mask_type shifted_mask(
513cdf0e10cSrcweir             MsbFirst ?
514cdf0e10cSrcweir             mask_ << bits_per_pixel :
515cdf0e10cSrcweir             // TODO(Q3): use traits to get unsigned type for data_type
516cdf0e10cSrcweir             // (if not already)
517cdf0e10cSrcweir             static_cast<unsigned int>(mask_) >> bits_per_pixel );
518cdf0e10cSrcweir 
519cdf0e10cSrcweir         // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
520cdf0e10cSrcweir         mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
521cdf0e10cSrcweir                                                             bit_mask :
522cdf0e10cSrcweir                                                             bit_mask << bits_per_pixel*(num_intraword_positions-1));
523cdf0e10cSrcweir     }
524cdf0e10cSrcweir 
equal(PackedPixelRowIterator const & rhs) const525cdf0e10cSrcweir     bool equal( PackedPixelRowIterator const & rhs ) const
526cdf0e10cSrcweir     {
527cdf0e10cSrcweir         return rhs.data_ == data_ && rhs.remainder_ == remainder_;
528cdf0e10cSrcweir     }
529cdf0e10cSrcweir 
less(PackedPixelRowIterator const & rhs) const530cdf0e10cSrcweir     bool less( PackedPixelRowIterator const & rhs ) const
531cdf0e10cSrcweir     {
532cdf0e10cSrcweir         return data_ == rhs.data_ ?
533cdf0e10cSrcweir             (remainder_ < rhs.remainder_) :
534cdf0e10cSrcweir             (data_ < rhs.data_);
535cdf0e10cSrcweir     }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir public:
PackedPixelRowIterator()538cdf0e10cSrcweir     PackedPixelRowIterator() :
539cdf0e10cSrcweir         data_(0),
540cdf0e10cSrcweir         mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
541cdf0e10cSrcweir         remainder_(0)
542cdf0e10cSrcweir     {}
543cdf0e10cSrcweir 
PackedPixelRowIterator(pointer base)544cdf0e10cSrcweir     explicit PackedPixelRowIterator( pointer base ) :
545cdf0e10cSrcweir         data_(base),
546cdf0e10cSrcweir         mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
547cdf0e10cSrcweir         remainder_(0)
548cdf0e10cSrcweir     {}
549cdf0e10cSrcweir 
operator +=(difference_type d)550cdf0e10cSrcweir     PackedPixelRowIterator& operator+=( difference_type d )
551cdf0e10cSrcweir     {
552cdf0e10cSrcweir         const difference_type newValue( remainder_ + d );
553cdf0e10cSrcweir 
554cdf0e10cSrcweir         data_ += newValue / num_intraword_positions;
555cdf0e10cSrcweir         remainder_ = newValue % num_intraword_positions;
556cdf0e10cSrcweir         update_mask();
557cdf0e10cSrcweir 
558cdf0e10cSrcweir         return *this;
559cdf0e10cSrcweir     }
560cdf0e10cSrcweir 
operator -=(difference_type d)561cdf0e10cSrcweir     PackedPixelRowIterator& operator-=( difference_type d )
562cdf0e10cSrcweir     {
563cdf0e10cSrcweir         const difference_type newValue( remainder_ - d );
564cdf0e10cSrcweir         const bool            isNegative( is_negative(newValue) );
565cdf0e10cSrcweir         const difference_type newRemainder( newValue % num_intraword_positions );
566cdf0e10cSrcweir 
567cdf0e10cSrcweir         // calc  data_ += newValue / num_intraword_positions;
568cdf0e10cSrcweir         //       remainder_ = newRemainder;
569cdf0e10cSrcweir         // for newValue >= 0, and
570cdf0e10cSrcweir         //       data_ += newValue / num_intraword_positions - 1;
571cdf0e10cSrcweir         //       remainder_ = num_intraword_positions - newRemainder;
572cdf0e10cSrcweir         // (to force remainder_ to be positive).
573cdf0e10cSrcweir         // This is branch-free, if is_negative() is branch-free
574cdf0e10cSrcweir         data_     += newValue / num_intraword_positions - isNegative;
575cdf0e10cSrcweir         remainder_ = newRemainder + isNegative*(num_intraword_positions - 2*newRemainder);
576cdf0e10cSrcweir         update_mask();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir         return *this;
579cdf0e10cSrcweir     }
580cdf0e10cSrcweir 
operator +(difference_type d)581cdf0e10cSrcweir     PackedPixelRowIterator operator+( difference_type d )
582cdf0e10cSrcweir     {
583cdf0e10cSrcweir         PackedPixelRowIterator res(*this);
584cdf0e10cSrcweir         res += d;
585cdf0e10cSrcweir         return res;
586cdf0e10cSrcweir     }
587cdf0e10cSrcweir 
operator -(difference_type d)588cdf0e10cSrcweir     PackedPixelRowIterator operator-( difference_type d )
589cdf0e10cSrcweir     {
590cdf0e10cSrcweir         PackedPixelRowIterator res(*this);
591cdf0e10cSrcweir         res -= d;
592cdf0e10cSrcweir         return res;
593cdf0e10cSrcweir     }
594cdf0e10cSrcweir 
operator ++()595cdf0e10cSrcweir     PackedPixelRowIterator& operator++()
596cdf0e10cSrcweir     {
597cdf0e10cSrcweir         inc();
598cdf0e10cSrcweir         return *this;
599cdf0e10cSrcweir     }
600cdf0e10cSrcweir 
operator --()601cdf0e10cSrcweir     PackedPixelRowIterator& operator--()
602cdf0e10cSrcweir     {
603cdf0e10cSrcweir         dec();
604cdf0e10cSrcweir         return *this;
605cdf0e10cSrcweir     }
606cdf0e10cSrcweir 
operator ++(int)607cdf0e10cSrcweir     PackedPixelRowIterator operator++(int)
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         PackedPixelRowIterator res(*this);
610cdf0e10cSrcweir         res.inc();
611cdf0e10cSrcweir         return res;
612cdf0e10cSrcweir     }
613cdf0e10cSrcweir 
operator --(int)614cdf0e10cSrcweir     PackedPixelRowIterator operator--(int)
615cdf0e10cSrcweir     {
616cdf0e10cSrcweir         PackedPixelRowIterator res(*this);
617cdf0e10cSrcweir         res.dec();
618cdf0e10cSrcweir         return res;
619cdf0e10cSrcweir     }
620cdf0e10cSrcweir 
operator ==(PackedPixelRowIterator const & rhs) const621cdf0e10cSrcweir     bool operator==(PackedPixelRowIterator const & rhs) const
622cdf0e10cSrcweir     {
623cdf0e10cSrcweir         return equal( rhs );
624cdf0e10cSrcweir     }
625cdf0e10cSrcweir 
operator !=(PackedPixelRowIterator const & rhs) const626cdf0e10cSrcweir     bool operator!=(PackedPixelRowIterator const & rhs) const
627cdf0e10cSrcweir     {
628cdf0e10cSrcweir         return !equal( rhs );
629cdf0e10cSrcweir     }
630cdf0e10cSrcweir 
operator <(PackedPixelRowIterator const & rhs) const631cdf0e10cSrcweir     bool operator<(PackedPixelRowIterator const & rhs) const
632cdf0e10cSrcweir     {
633cdf0e10cSrcweir         return less(rhs);
634cdf0e10cSrcweir     }
635cdf0e10cSrcweir 
operator <=(PackedPixelRowIterator const & rhs) const636cdf0e10cSrcweir     bool operator<=(PackedPixelRowIterator const & rhs) const
637cdf0e10cSrcweir     {
638cdf0e10cSrcweir         return !less(rhs);
639cdf0e10cSrcweir     }
640cdf0e10cSrcweir 
operator >(PackedPixelRowIterator const & rhs) const641cdf0e10cSrcweir     bool operator>(PackedPixelRowIterator const & rhs) const
642cdf0e10cSrcweir     {
643cdf0e10cSrcweir         return rhs.less(*this);
644cdf0e10cSrcweir     }
645cdf0e10cSrcweir 
operator >=(PackedPixelRowIterator const & rhs) const646cdf0e10cSrcweir     bool operator>=(PackedPixelRowIterator const & rhs) const
647cdf0e10cSrcweir     {
648cdf0e10cSrcweir         return !rhs.less(*this);
649cdf0e10cSrcweir     }
650cdf0e10cSrcweir 
operator -(PackedPixelRowIterator const & rhs) const651cdf0e10cSrcweir     difference_type operator-(PackedPixelRowIterator const & rhs) const
652cdf0e10cSrcweir     {
653cdf0e10cSrcweir         return (data_ - rhs.data_)*num_intraword_positions + (remainder_ - rhs.remainder_);
654cdf0e10cSrcweir     }
655cdf0e10cSrcweir 
get() const656cdf0e10cSrcweir     value_type get() const
657cdf0e10cSrcweir     {
658cdf0e10cSrcweir         // TODO(Q3): use traits to get unsigned type for data_type (if
659cdf0e10cSrcweir         // not already)
660cdf0e10cSrcweir         return static_cast<unsigned int>(*data_ & mask_) >>
661cdf0e10cSrcweir             get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_);
662cdf0e10cSrcweir     }
663cdf0e10cSrcweir 
get(difference_type d) const664cdf0e10cSrcweir     value_type get(difference_type d) const
665cdf0e10cSrcweir     {
666cdf0e10cSrcweir         PackedPixelRowIterator tmp(*this);
667cdf0e10cSrcweir         tmp += d;
668cdf0e10cSrcweir         return tmp.get();
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir 
set(value_type v) const671cdf0e10cSrcweir     void set( value_type v ) const
672cdf0e10cSrcweir     {
673cdf0e10cSrcweir         const value_type pixel_value(
674cdf0e10cSrcweir             (v <<
675cdf0e10cSrcweir              get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_))
676cdf0e10cSrcweir             & mask_ );
677cdf0e10cSrcweir         *data_ = (*data_ & ~mask_) | pixel_value;
678cdf0e10cSrcweir     }
679cdf0e10cSrcweir 
set(value_type v,difference_type d) const680cdf0e10cSrcweir     void set( value_type v, difference_type d ) const
681cdf0e10cSrcweir     {
682cdf0e10cSrcweir         PackedPixelRowIterator tmp(*this);
683cdf0e10cSrcweir         tmp += d;
684cdf0e10cSrcweir         tmp.set(v);
685cdf0e10cSrcweir     }
686cdf0e10cSrcweir };
687cdf0e10cSrcweir 
688cdf0e10cSrcweir template< typename Datatype,
689cdf0e10cSrcweir           typename Valuetype,
690cdf0e10cSrcweir           int      bits_per_pixel,
691cdf0e10cSrcweir           bool     MsbFirst > class PackedPixelIterator
692cdf0e10cSrcweir {
693cdf0e10cSrcweir public:
694cdf0e10cSrcweir     // no reference, no index_reference type here
695cdf0e10cSrcweir     typedef Datatype                                    data_type;
696cdf0e10cSrcweir     typedef Valuetype                                   value_type;
697cdf0e10cSrcweir     typedef vigra::Diff2D                               difference_type;
698cdf0e10cSrcweir     typedef image_traverser_tag                         iterator_category;
699cdf0e10cSrcweir     typedef PackedPixelRowIterator<data_type,
700cdf0e10cSrcweir                                    value_type,
701cdf0e10cSrcweir                                    bits_per_pixel,
702cdf0e10cSrcweir                                    MsbFirst>            row_iterator;
703cdf0e10cSrcweir     typedef PackedPixelColumnIterator<data_type,
704cdf0e10cSrcweir                                       value_type,
705cdf0e10cSrcweir                                       bits_per_pixel,
706cdf0e10cSrcweir                                       MsbFirst>         column_iterator;
707cdf0e10cSrcweir 
708cdf0e10cSrcweir     typedef data_type*                                  pointer;
709cdf0e10cSrcweir     typedef int                                         MoveX;
710cdf0e10cSrcweir     typedef StridedArrayIterator< data_type >           MoveY;
711cdf0e10cSrcweir 
712cdf0e10cSrcweir     enum {
713cdf0e10cSrcweir         /** The number of pixel within a single data_type value
714cdf0e10cSrcweir          */
715cdf0e10cSrcweir         num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
716cdf0e10cSrcweir         /** Bit mask for one pixel (least significant bits)
717cdf0e10cSrcweir          */
718cdf0e10cSrcweir         bit_mask=~(~0 << bits_per_pixel)
719cdf0e10cSrcweir     };
720cdf0e10cSrcweir 
721cdf0e10cSrcweir     // TODO(F2): direction of iteration (ImageIterator can be made to
722cdf0e10cSrcweir     // run backwards)
723cdf0e10cSrcweir 
724cdf0e10cSrcweir private:
current() const725cdf0e10cSrcweir     pointer current() const
726cdf0e10cSrcweir     {
727cdf0e10cSrcweir         return y() + (x / num_intraword_positions);
728cdf0e10cSrcweir     }
729cdf0e10cSrcweir 
current(int dx,int dy) const730cdf0e10cSrcweir     pointer current(int dx, int dy) const
731cdf0e10cSrcweir     {
732cdf0e10cSrcweir         return y(dy) + ((x+dx)/num_intraword_positions);
733cdf0e10cSrcweir     }
734cdf0e10cSrcweir 
equal(PackedPixelIterator const & rhs) const735cdf0e10cSrcweir     bool equal(PackedPixelIterator const & rhs) const
736cdf0e10cSrcweir     {
737cdf0e10cSrcweir         return (x == rhs.x) && (y == rhs.y);
738cdf0e10cSrcweir     }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir public:
PackedPixelIterator()741cdf0e10cSrcweir     PackedPixelIterator() :
742cdf0e10cSrcweir         x(0),
743cdf0e10cSrcweir         y(0)
744cdf0e10cSrcweir     {}
745cdf0e10cSrcweir 
PackedPixelIterator(pointer base,int ystride)746cdf0e10cSrcweir     PackedPixelIterator(pointer base, int ystride) :
747cdf0e10cSrcweir         x(0),
748cdf0e10cSrcweir         y(ystride,base)
749cdf0e10cSrcweir     {}
750cdf0e10cSrcweir 
operator ==(PackedPixelIterator const & rhs) const751cdf0e10cSrcweir     bool operator==(PackedPixelIterator const & rhs) const
752cdf0e10cSrcweir     {
753cdf0e10cSrcweir         return equal(rhs);
754cdf0e10cSrcweir     }
755cdf0e10cSrcweir 
operator !=(PackedPixelIterator const & rhs) const756cdf0e10cSrcweir     bool operator!=(PackedPixelIterator const & rhs) const
757cdf0e10cSrcweir     {
758cdf0e10cSrcweir         return !equal(rhs);
759cdf0e10cSrcweir     }
760cdf0e10cSrcweir 
operator -(PackedPixelIterator const & rhs) const761cdf0e10cSrcweir     difference_type operator-(PackedPixelIterator const & rhs) const
762cdf0e10cSrcweir     {
763cdf0e10cSrcweir         return difference_type(x - rhs.x, y - rhs.y);
764cdf0e10cSrcweir     }
765cdf0e10cSrcweir 
766cdf0e10cSrcweir     MoveX x;
767cdf0e10cSrcweir     MoveY y;
768cdf0e10cSrcweir 
operator +=(difference_type const & s)769cdf0e10cSrcweir     PackedPixelIterator & operator+=(difference_type const & s)
770cdf0e10cSrcweir     {
771cdf0e10cSrcweir         x += s.x;
772cdf0e10cSrcweir         y += s.y;
773cdf0e10cSrcweir         return *this;
774cdf0e10cSrcweir     }
775cdf0e10cSrcweir 
operator -=(difference_type const & s)776cdf0e10cSrcweir     PackedPixelIterator & operator-=(difference_type const & s)
777cdf0e10cSrcweir     {
778cdf0e10cSrcweir         x -= s.x;
779cdf0e10cSrcweir         y -= s.y;
780cdf0e10cSrcweir         return *this;
781cdf0e10cSrcweir     }
782cdf0e10cSrcweir 
operator +(difference_type const & s) const783cdf0e10cSrcweir     PackedPixelIterator operator+(difference_type const & s) const
784cdf0e10cSrcweir     {
785cdf0e10cSrcweir         PackedPixelIterator ret(*this);
786cdf0e10cSrcweir         ret += s;
787cdf0e10cSrcweir         return ret;
788cdf0e10cSrcweir     }
789cdf0e10cSrcweir 
operator -(difference_type const & s) const790cdf0e10cSrcweir     PackedPixelIterator operator-(difference_type const & s) const
791cdf0e10cSrcweir     {
792cdf0e10cSrcweir         PackedPixelIterator ret(*this);
793cdf0e10cSrcweir         ret -= s;
794cdf0e10cSrcweir         return ret;
795cdf0e10cSrcweir     }
796cdf0e10cSrcweir 
rowIterator() const797cdf0e10cSrcweir     row_iterator rowIterator() const
798cdf0e10cSrcweir     {
799cdf0e10cSrcweir         return row_iterator(current());
800cdf0e10cSrcweir     }
801cdf0e10cSrcweir 
columnIterator() const802cdf0e10cSrcweir     column_iterator columnIterator() const
803cdf0e10cSrcweir     {
804cdf0e10cSrcweir         return column_iterator(MoveY(y,
805cdf0e10cSrcweir                                      x / num_intraword_positions),
806cdf0e10cSrcweir                                x % num_intraword_positions);
807cdf0e10cSrcweir     }
808cdf0e10cSrcweir 
get() const809cdf0e10cSrcweir     value_type get() const
810cdf0e10cSrcweir     {
811cdf0e10cSrcweir         const int remainder( x() % num_intraword_positions );
812cdf0e10cSrcweir 
813cdf0e10cSrcweir         // TODO(Q3): use traits to get unsigned type for data_type (if
814cdf0e10cSrcweir         // not already)
815cdf0e10cSrcweir         return (static_cast<unsigned int>(*current() &
816cdf0e10cSrcweir                                           get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
817cdf0e10cSrcweir                 >> (MsbFirst ?
818cdf0e10cSrcweir                     (num_intraword_positions - remainder) :
819cdf0e10cSrcweir                     remainder));
820cdf0e10cSrcweir     }
821cdf0e10cSrcweir 
get(difference_type const & d) const822cdf0e10cSrcweir     value_type get(difference_type const & d) const
823cdf0e10cSrcweir     {
824cdf0e10cSrcweir         const int remainder( x(d.x) % num_intraword_positions );
825cdf0e10cSrcweir 
826cdf0e10cSrcweir         // TODO(Q3): use traits to get unsigned type for data_type (if
827cdf0e10cSrcweir         // not already)
828cdf0e10cSrcweir         return (static_cast<unsigned int>(*current(d.x,d.y) &
829cdf0e10cSrcweir                                           get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
830cdf0e10cSrcweir                 >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
831cdf0e10cSrcweir     }
832cdf0e10cSrcweir 
set(value_type v) const833cdf0e10cSrcweir     void set( value_type v ) const
834cdf0e10cSrcweir     {
835cdf0e10cSrcweir         const int remainder( x() % num_intraword_positions );
836cdf0e10cSrcweir         const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
837cdf0e10cSrcweir         const value_type pixel_value(
838cdf0e10cSrcweir             (v <<
839cdf0e10cSrcweir              get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
840cdf0e10cSrcweir             & mask );
841cdf0e10cSrcweir         pointer p = current();
842cdf0e10cSrcweir         *p = (*p & ~mask) | pixel_value;
843cdf0e10cSrcweir     }
844cdf0e10cSrcweir 
set(value_type v,difference_type const & d) const845cdf0e10cSrcweir     void set( value_type v, difference_type const & d ) const
846cdf0e10cSrcweir     {
847cdf0e10cSrcweir         const int remainder( x(d.x) % num_intraword_positions );
848cdf0e10cSrcweir         const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
849cdf0e10cSrcweir         const value_type pixel_value(
850cdf0e10cSrcweir             (v <<
851cdf0e10cSrcweir              get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
852cdf0e10cSrcweir              & mask );
853cdf0e10cSrcweir         pointer p = current(d.x,d.y);
854cdf0e10cSrcweir         *p = (*p & ~mask) | pixel_value;
855cdf0e10cSrcweir     }
856cdf0e10cSrcweir };
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 
859cdf0e10cSrcweir /** Access (possibly packed-pixel) data via palette indirection
860cdf0e10cSrcweir  */
861cdf0e10cSrcweir template< typename Valuetype, typename Datatype > class PaletteImageAccessor
862cdf0e10cSrcweir {
863cdf0e10cSrcweir   public:
864cdf0e10cSrcweir     typedef Valuetype                                   value_type;
865cdf0e10cSrcweir     typedef Datatype                                    data_type;
866cdf0e10cSrcweir     typedef typename remove_const<data_type>::type      count_type;
867cdf0e10cSrcweir 
868cdf0e10cSrcweir 
869cdf0e10cSrcweir private:
870cdf0e10cSrcweir     const BitmapColor* palette;
871cdf0e10cSrcweir     count_type         num_entries;
872cdf0e10cSrcweir 
norm(BitmapColor const & rLHS,BitmapColor const & rRHS) const873cdf0e10cSrcweir     double norm( BitmapColor const& rLHS,
874cdf0e10cSrcweir                  BitmapColor const& rRHS ) const
875cdf0e10cSrcweir     {
876cdf0e10cSrcweir         // convert RGBValue's linear space to a normed linear space
877cdf0e10cSrcweir         return sqrt(
878cdf0e10cSrcweir             vigra::sq(rLHS.GetRed()-rRHS.GetRed()) +
879cdf0e10cSrcweir             vigra::sq(rLHS.GetGreen()-rRHS.GetGreen()) +
880cdf0e10cSrcweir             vigra::sq(rLHS.GetBlue()-rRHS.GetBlue()) );
881cdf0e10cSrcweir     }
882cdf0e10cSrcweir 
find_best_match(value_type const & v) const883cdf0e10cSrcweir     data_type find_best_match(value_type const& v) const
884cdf0e10cSrcweir     {
885cdf0e10cSrcweir         // TODO(F3): not generic!!!
886cdf0e10cSrcweir         const BitmapColor aTmpCol(v.red(),
887cdf0e10cSrcweir                                   v.green(),
888cdf0e10cSrcweir                                   v.blue());
889cdf0e10cSrcweir 
890cdf0e10cSrcweir         // TODO(P3): use table-based/octree approach here!
891cdf0e10cSrcweir         const BitmapColor* best_entry;
892cdf0e10cSrcweir         const BitmapColor* palette_end( palette+num_entries );
893cdf0e10cSrcweir         if( (best_entry=std::find( palette, palette_end, aTmpCol)) != palette_end )
894cdf0e10cSrcweir             return best_entry-palette;
895cdf0e10cSrcweir 
896cdf0e10cSrcweir         // TODO(F3): HACK. Need palette traits, and an error function
897cdf0e10cSrcweir         // here. We blatantly assume value_type is a normed linear
898cdf0e10cSrcweir         // space.
899cdf0e10cSrcweir         const BitmapColor* curr_entry( palette );
900cdf0e10cSrcweir         best_entry = curr_entry;
901cdf0e10cSrcweir         while( curr_entry != palette_end )
902cdf0e10cSrcweir         {
903cdf0e10cSrcweir             if( norm(*curr_entry,*best_entry) > norm(*curr_entry,aTmpCol) )
904cdf0e10cSrcweir                 best_entry = curr_entry;
905cdf0e10cSrcweir 
906cdf0e10cSrcweir             ++curr_entry;
907cdf0e10cSrcweir         }
908cdf0e10cSrcweir 
909cdf0e10cSrcweir         return best_entry-palette;
910cdf0e10cSrcweir     }
911cdf0e10cSrcweir 
toCol(BitmapColor const & rCol) const912cdf0e10cSrcweir     value_type toCol( BitmapColor const& rCol ) const
913cdf0e10cSrcweir     {
914cdf0e10cSrcweir         return value_type(rCol.GetRed(),rCol.GetGreen(),rCol.GetBlue());
915cdf0e10cSrcweir     }
916cdf0e10cSrcweir 
917cdf0e10cSrcweir public:
PaletteImageAccessor()918cdf0e10cSrcweir     PaletteImageAccessor() :
919cdf0e10cSrcweir         palette(0),
920cdf0e10cSrcweir         num_entries(0)
921cdf0e10cSrcweir     {}
922cdf0e10cSrcweir 
PaletteImageAccessor(const BitmapColor * pPalette,data_type entries)923cdf0e10cSrcweir     PaletteImageAccessor( const BitmapColor* pPalette,
924cdf0e10cSrcweir                           data_type          entries ) :
925cdf0e10cSrcweir         palette(pPalette),
926cdf0e10cSrcweir         num_entries(entries)
927cdf0e10cSrcweir     {}
928cdf0e10cSrcweir 
929cdf0e10cSrcweir     template< class Iterator >
operator ()(Iterator const & i) const930cdf0e10cSrcweir     value_type operator()(Iterator const& i) const { return toCol(palette[i.get()]); }
operator ()(data_type const * i) const931cdf0e10cSrcweir     value_type operator()(data_type const* i) const { return toCol(palette[*i]); }
932cdf0e10cSrcweir 
933cdf0e10cSrcweir     template< class Iterator, class Difference >
operator ()(Iterator const & i,Difference const & diff) const934cdf0e10cSrcweir     value_type operator()(Iterator const& i, Difference const& diff) const
935cdf0e10cSrcweir     {
936cdf0e10cSrcweir         return toCol(palette[i.get(diff)]);
937cdf0e10cSrcweir     }
938cdf0e10cSrcweir 
939cdf0e10cSrcweir     template< typename V, class Iterator >
set(V const & value,Iterator const & i) const940cdf0e10cSrcweir     void set(V const& value, Iterator const& i) const
941cdf0e10cSrcweir     {
942cdf0e10cSrcweir         i.set(
943cdf0e10cSrcweir             find_best_match(
944cdf0e10cSrcweir                 vigra::detail::RequiresExplicitCast<value_type>::cast(value) ));
945cdf0e10cSrcweir     }
946cdf0e10cSrcweir 
947cdf0e10cSrcweir     template< typename V, class Iterator, class Difference >
set(V const & value,Iterator const & i,Difference const & diff) const948cdf0e10cSrcweir     void set(V const& value, Iterator const& i, Difference const& diff) const
949cdf0e10cSrcweir     {
950cdf0e10cSrcweir         i.set(
951cdf0e10cSrcweir             find_best_match(
952cdf0e10cSrcweir                 vigra::detail::RequiresExplicitCast<value_type>::cast(value)),
953cdf0e10cSrcweir             diff );
954cdf0e10cSrcweir     }
955cdf0e10cSrcweir };
956cdf0e10cSrcweir 
957cdf0e10cSrcweir }
958cdf0e10cSrcweir 
959cdf0e10cSrcweir 
960cdf0e10cSrcweir class TestApp : public Application
961cdf0e10cSrcweir {
962cdf0e10cSrcweir public:
963cdf0e10cSrcweir 	virtual void Main();
964cdf0e10cSrcweir 	virtual USHORT	Exception( USHORT nError );
965cdf0e10cSrcweir };
966cdf0e10cSrcweir 
967cdf0e10cSrcweir class TestWindow : public Dialog
968cdf0e10cSrcweir {
969cdf0e10cSrcweir 	public:
TestWindow()970cdf0e10cSrcweir 		TestWindow() : Dialog( (Window *) NULL )
971cdf0e10cSrcweir 		{
972cdf0e10cSrcweir 			SetText( rtl::OUString::createFromAscii( "VIGRA test" ) );
973cdf0e10cSrcweir 			SetSizePixel( Size( 1024, 1024 ) );
974cdf0e10cSrcweir 			EnablePaint( true );
975cdf0e10cSrcweir 			Show();
976cdf0e10cSrcweir 		}
~TestWindow()977cdf0e10cSrcweir 		virtual ~TestWindow() {}
MouseButtonUp(const MouseEvent &)978cdf0e10cSrcweir         virtual void MouseButtonUp( const MouseEvent& /*rMEvt*/ )
979cdf0e10cSrcweir 		{
980cdf0e10cSrcweir 			//TODO: do something cool
981cdf0e10cSrcweir             EndDialog();
982cdf0e10cSrcweir         }
983cdf0e10cSrcweir 		virtual void Paint( const Rectangle& rRect );
984cdf0e10cSrcweir };
985cdf0e10cSrcweir 
986cdf0e10cSrcweir 
project(const basegfx::B2IPoint & rPoint)987cdf0e10cSrcweir static basegfx::B2IPoint project( const basegfx::B2IPoint& rPoint )
988cdf0e10cSrcweir {
989cdf0e10cSrcweir 	const double angle_x = M_PI / 6.0;
990cdf0e10cSrcweir 	const double angle_z = M_PI / 6.0;
991cdf0e10cSrcweir 
992cdf0e10cSrcweir 	// transform planar coordinates to 3d
993cdf0e10cSrcweir 	double x = rPoint.getX();
994cdf0e10cSrcweir 	double y = rPoint.getY();
995cdf0e10cSrcweir 	//double z = 0;
996cdf0e10cSrcweir 
997cdf0e10cSrcweir 	// rotate around X axis
998cdf0e10cSrcweir 	double x1 = x;
999cdf0e10cSrcweir 	double y1 = y * cos( angle_x );
1000cdf0e10cSrcweir 	double z1 = y * sin( angle_x );
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir 	// rotate around Z axis
1003cdf0e10cSrcweir 	double x2 = x1 * cos( angle_z ) + y1 * sin( angle_z );
1004cdf0e10cSrcweir 	//double y2 = y1 * cos( angle_z ) - x1 * sin( angle_z );
1005cdf0e10cSrcweir 	double z2 = z1;
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir 	//return basegfx::B2IPoint( (sal_Int32)3*x2, (sal_Int32)3*z2 );
1008cdf0e10cSrcweir 	return basegfx::B2IPoint( (sal_Int32)(6*x2), (sal_Int32)(6*z2) );
1009cdf0e10cSrcweir }
1010cdf0e10cSrcweir 
approachColor(const basebmp::Color & rFrom,const basebmp::Color & rTo)1011cdf0e10cSrcweir static basebmp::Color approachColor( const basebmp::Color& rFrom, const basebmp::Color& rTo )
1012cdf0e10cSrcweir {
1013cdf0e10cSrcweir 	basebmp::Color aColor;
1014cdf0e10cSrcweir 	UINT8 nDiff;
1015cdf0e10cSrcweir 	// approach red
1016cdf0e10cSrcweir 	if( rFrom.getRed() < rTo.getRed() )
1017cdf0e10cSrcweir 	{
1018cdf0e10cSrcweir 		nDiff = rTo.getRed() - rFrom.getRed();
1019cdf0e10cSrcweir 		aColor.setRed( rFrom.getRed() + ( nDiff < 10 ? nDiff : 10 ) );
1020cdf0e10cSrcweir 	}
1021cdf0e10cSrcweir 	else if( rFrom.getRed() > rTo.getRed() )
1022cdf0e10cSrcweir 	{
1023cdf0e10cSrcweir 		nDiff = rFrom.getRed() - rTo.getRed();
1024cdf0e10cSrcweir 		aColor.setRed( rFrom.getRed() - ( nDiff < 10 ? nDiff : 10 ) );
1025cdf0e10cSrcweir 	}
1026cdf0e10cSrcweir 	else
1027cdf0e10cSrcweir 		aColor.setRed( rFrom.getRed() );
1028cdf0e10cSrcweir 
1029cdf0e10cSrcweir 	// approach Green
1030cdf0e10cSrcweir 	if( rFrom.getGreen() < rTo.getGreen() )
1031cdf0e10cSrcweir 	{
1032cdf0e10cSrcweir 		nDiff = rTo.getGreen() - rFrom.getGreen();
1033cdf0e10cSrcweir 		aColor.setGreen( rFrom.getGreen() + ( nDiff < 10 ? nDiff : 10 ) );
1034cdf0e10cSrcweir 	}
1035cdf0e10cSrcweir 	else if( rFrom.getGreen() > rTo.getGreen() )
1036cdf0e10cSrcweir 	{
1037cdf0e10cSrcweir 		nDiff = rFrom.getGreen() - rTo.getGreen();
1038cdf0e10cSrcweir 		aColor.setGreen( rFrom.getGreen() - ( nDiff < 10 ? nDiff : 10 ) );
1039cdf0e10cSrcweir 	}
1040cdf0e10cSrcweir 	else
1041cdf0e10cSrcweir 		aColor.setGreen( rFrom.getGreen() );
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir 	// approach blue
1044cdf0e10cSrcweir 	if( rFrom.getBlue() < rTo.getBlue() )
1045cdf0e10cSrcweir 	{
1046cdf0e10cSrcweir 		nDiff = rTo.getBlue() - rFrom.getBlue();
1047cdf0e10cSrcweir 		aColor.setBlue( rFrom.getBlue() + ( nDiff < 10 ? nDiff : 10 ) );
1048cdf0e10cSrcweir 	}
1049cdf0e10cSrcweir 	else if( rFrom.getBlue() > rTo.getBlue() )
1050cdf0e10cSrcweir 	{
1051cdf0e10cSrcweir 		nDiff = rFrom.getBlue() - rTo.getBlue();
1052cdf0e10cSrcweir 		aColor.setBlue( rFrom.getBlue() - ( nDiff < 10 ? nDiff : 10 ) );
1053cdf0e10cSrcweir 	}
1054cdf0e10cSrcweir 	else
1055cdf0e10cSrcweir 		aColor.setBlue( rFrom.getBlue() );
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir 	return aColor;
1058cdf0e10cSrcweir }
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir #define DELTA 5.0
1061cdf0e10cSrcweir 
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 
Paint(const Rectangle &)1064cdf0e10cSrcweir void TestWindow::Paint( const Rectangle& /*rRect*/ )
1065cdf0e10cSrcweir {
1066cdf0e10cSrcweir     basegfx::B2ISize aTestSize(1000,1000);
1067cdf0e10cSrcweir     basebmp::BitmapDeviceSharedPtr pDevice( basebmp::createBitmapDevice( aTestSize,
1068cdf0e10cSrcweir                                                                          false,
1069cdf0e10cSrcweir                                                                          basebmp::Format::THIRTYTWO_BIT_TC_MASK ));
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir     {
1072cdf0e10cSrcweir         ::rtl::OUString aSvg;
1073cdf0e10cSrcweir         basegfx::B2DPolyPolygon aPoly;
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir         basegfx::tools::importFromSvgD( aPoly,
1076cdf0e10cSrcweir                                         ::rtl::OUString::createFromAscii(
1077cdf0e10cSrcweir                                             "m0 0 h7 v7 h-7 z" ) );
1078cdf0e10cSrcweir         basegfx::tools::importFromSvgD( aPoly,
1079cdf0e10cSrcweir                                         ::rtl::OUString::createFromAscii(
1080cdf0e10cSrcweir                                             "m2 2 h3 v3 h-3 z" ) );
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir         pDevice->fillPolyPolygon(
1083cdf0e10cSrcweir             aPoly,
1084cdf0e10cSrcweir             basebmp::Color(0xFFFFFFFF),
1085cdf0e10cSrcweir             basebmp::DrawMode_PAINT );
1086cdf0e10cSrcweir     }
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir #if 0
1089cdf0e10cSrcweir     {
1090cdf0e10cSrcweir         basebmp::BitmapDeviceSharedPtr pMask( basebmp::createBitmapDevice( aTestSize,
1091cdf0e10cSrcweir                                                                            false,
1092cdf0e10cSrcweir                                                                            basebmp::Format::ONE_BIT_MSB_GREY ));
1093cdf0e10cSrcweir 
1094cdf0e10cSrcweir         const basegfx::B2IPoint aPt111(10,10);
1095cdf0e10cSrcweir         const basegfx::B2IPoint aPt222(0,10);
1096cdf0e10cSrcweir         const basebmp::Color aCol333(0xFFFFFFFF);
1097cdf0e10cSrcweir         pMask->drawLine( aPt111, aPt222, aCol333, basebmp::DrawMode_PAINT );
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir 
1100cdf0e10cSrcweir         ::rtl::OUString aSvg = ::rtl::OUString::createFromAscii(
1101cdf0e10cSrcweir             "m 0 0 h5 l5 5 v5 h-5 l-5-5 z" );
1102cdf0e10cSrcweir         basegfx::B2DPolyPolygon aPoly;
1103cdf0e10cSrcweir         basegfx::tools::importFromSvgD( aPoly, aSvg );
1104cdf0e10cSrcweir         pMask->clear(basebmp::Color(0xFFFFFFFF));
1105cdf0e10cSrcweir         pMask->drawPolygon(
1106cdf0e10cSrcweir             aPoly.getB2DPolygon(0),
1107cdf0e10cSrcweir             basebmp::Color(0),
1108cdf0e10cSrcweir             basebmp::DrawMode_PAINT );
1109cdf0e10cSrcweir 
1110cdf0e10cSrcweir         basebmp::BitmapDeviceSharedPtr pSubsetDevice =
1111cdf0e10cSrcweir             basebmp::subsetBitmapDevice( pDevice,
1112cdf0e10cSrcweir                                          basegfx::B2IRange(3,3,7,7) );
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir         const basegfx::B2IPoint aPt1(0,0);
1115cdf0e10cSrcweir         const basegfx::B2IPoint aPt2(1,9);
1116cdf0e10cSrcweir         const basebmp::Color aCol(0xFFFFFFFF);
1117cdf0e10cSrcweir         pDevice->drawLine( aPt1, aPt2, aCol, basebmp::DrawMode_PAINT, pMask );
1118cdf0e10cSrcweir     }
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir     {
1121cdf0e10cSrcweir         const basebmp::Color aCol(0xFFFFFFFF);
1122cdf0e10cSrcweir         basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect(
1123cdf0e10cSrcweir             basegfx::B2DRange( 0,0,1001,1001 ));
1124cdf0e10cSrcweir         pDevice->drawPolygon( aRect, aCol, basebmp::DrawMode_PAINT );
1125cdf0e10cSrcweir 
1126cdf0e10cSrcweir         const basegfx::B2IPoint aPt1(0,0);
1127cdf0e10cSrcweir         const basegfx::B2IPoint aPt2(0,800);
1128cdf0e10cSrcweir         pDevice->drawLine( aPt1, aPt2, aCol, basebmp::DrawMode_PAINT );
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir         const basegfx::B2IPoint aPt3(0,1001);
1131cdf0e10cSrcweir         pDevice->drawLine( aPt1, aPt3, aCol, basebmp::DrawMode_PAINT );
1132cdf0e10cSrcweir     }
1133cdf0e10cSrcweir #endif
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir     {
1136cdf0e10cSrcweir         pDevice->clear(basebmp::Color(0));
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir         basegfx::B2IPoint aCenter( aTestSize.getX()/2,
1139cdf0e10cSrcweir                                    aTestSize.getY()/2 );
1140cdf0e10cSrcweir         //basegfx::B2IPoint aP1( aTestSize.getX()/48, 0), aP2( aTestSize.getX()/40, 0 ), aPoint;
1141cdf0e10cSrcweir         //basegfx::B2IPoint aP1( aTestSize.getX()/7, 0), aP2( aTestSize.getX()/6, 0 ), aPoint;
1142cdf0e10cSrcweir         //basegfx::B2IPoint aP1( aTestSize.getX()/5, 0), aP2( aTestSize.getX()/4, 0 ), aPoint;
1143cdf0e10cSrcweir         basegfx::B2IPoint aP1( aTestSize.getX()/12, 0), aP2( aTestSize.getX()/11, 0 ), aPoint;
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir         double sind = sin( DELTA*M_PI/180.0 );
1146cdf0e10cSrcweir         double cosd = cos( DELTA*M_PI/180.0 );
1147cdf0e10cSrcweir         double factor = 1 + (DELTA/1000.0);
1148cdf0e10cSrcweir         int n=0;
1149cdf0e10cSrcweir         basebmp::Color aLineColor( 0, 0, 0 );
1150cdf0e10cSrcweir         basebmp::Color aApproachColor( 0, 0, 200 );
1151cdf0e10cSrcweir         while ( aP2.getX() < aCenter.getX() && n++ < 680 )
1152cdf0e10cSrcweir         {
1153cdf0e10cSrcweir             aLineColor = approachColor( aLineColor, aApproachColor );
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir             // switch aproach color
1156cdf0e10cSrcweir             if( aApproachColor == aLineColor )
1157cdf0e10cSrcweir             {
1158cdf0e10cSrcweir                 if( aApproachColor.getRed() )
1159cdf0e10cSrcweir                     aApproachColor = basebmp::Color( 0, 0, 200 );
1160cdf0e10cSrcweir                 else if( aApproachColor.getGreen() )
1161cdf0e10cSrcweir                     aApproachColor = basebmp::Color( 200, 0, 0 );
1162cdf0e10cSrcweir                 else
1163cdf0e10cSrcweir                     aApproachColor = basebmp::Color( 0, 200, 0 );
1164cdf0e10cSrcweir             }
1165cdf0e10cSrcweir 
1166cdf0e10cSrcweir             basegfx::B2DPolygon aPoly;
1167cdf0e10cSrcweir             aPoly.append( basegfx::B2DPoint(project( aP1 ) + aCenter) );
1168cdf0e10cSrcweir             aPoly.append( basegfx::B2DPoint(project( aP2 ) + aCenter) );
1169cdf0e10cSrcweir             pDevice->fillPolyPolygon(
1170cdf0e10cSrcweir                 basegfx::tools::createAreaGeometryForPolygon(
1171cdf0e10cSrcweir                     aPoly,
1172cdf0e10cSrcweir //                    std::max(1,n/30),
1173cdf0e10cSrcweir //                    std::max(1,n/60),
1174cdf0e10cSrcweir                     std::max(1,n/30),
1175cdf0e10cSrcweir                     basegfx::tools::B2DLINEJOIN_NONE),
1176cdf0e10cSrcweir                 aLineColor,
1177cdf0e10cSrcweir                 basebmp::DrawMode_PAINT);
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir             aPoint.setX( (int)((((double)aP1.getX())*cosd - ((double)aP1.getY())*sind)*factor) );
1180cdf0e10cSrcweir             aPoint.setY( (int)((((double)aP1.getY())*cosd + ((double)aP1.getX())*sind)*factor) );
1181cdf0e10cSrcweir             aP1 = aPoint;
1182cdf0e10cSrcweir             aPoint.setX( (int)((((double)aP2.getX())*cosd - ((double)aP2.getY())*sind)*factor) );
1183cdf0e10cSrcweir             aPoint.setY( (int)((((double)aP2.getY())*cosd + ((double)aP2.getX())*sind)*factor) );
1184cdf0e10cSrcweir             aP2 = aPoint;
1185cdf0e10cSrcweir         }
1186cdf0e10cSrcweir     }
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir     Bitmap aBitmap( Size(aTestSize.getX(),
1189cdf0e10cSrcweir                          aTestSize.getY()), 24 );
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir     // Fill bitmap with generated content
1192cdf0e10cSrcweir     {
1193cdf0e10cSrcweir         ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(),
1194cdf0e10cSrcweir                                               aBitmap );
1195cdf0e10cSrcweir         for( int y=0; y<aTestSize.getY(); ++y )
1196cdf0e10cSrcweir             for( int x=0; x<aTestSize.getX(); ++x )
1197cdf0e10cSrcweir                 pWriteAccess->SetPixel(y,x,
1198cdf0e10cSrcweir                                        Color(pDevice->getPixelData(basegfx::B2IPoint(x,y))) );
1199cdf0e10cSrcweir     }
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir     DrawBitmap( Point(), aBitmap );
1202cdf0e10cSrcweir }
1203cdf0e10cSrcweir 
Exception(USHORT nError)1204cdf0e10cSrcweir USHORT TestApp::Exception( USHORT nError )
1205cdf0e10cSrcweir {
1206cdf0e10cSrcweir 	switch( nError & EXC_MAJORTYPE )
1207cdf0e10cSrcweir 	{
1208cdf0e10cSrcweir 		case EXC_RSCNOTLOADED:
1209cdf0e10cSrcweir 			Abort( String::CreateFromAscii( "Error: could not load language resources.\nPlease check your installation.\n" ) );
1210cdf0e10cSrcweir 			break;
1211cdf0e10cSrcweir 	}
1212cdf0e10cSrcweir 	return 0;
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir 
Main()1215cdf0e10cSrcweir void TestApp::Main()
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir 	//-------------------------------------------------
1218cdf0e10cSrcweir 	// create the global service-manager
1219cdf0e10cSrcweir 	//-------------------------------------------------
1220cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xFactory;
1221cdf0e10cSrcweir     try
1222cdf0e10cSrcweir     {
1223cdf0e10cSrcweir         uno::Reference< uno::XComponentContext > xCtx = ::cppu::defaultBootstrap_InitialComponentContext();
1224cdf0e10cSrcweir         xFactory = uno::Reference< lang::XMultiServiceFactory >(  xCtx->getServiceManager(),
1225cdf0e10cSrcweir                                                                   uno::UNO_QUERY );
1226cdf0e10cSrcweir         if( xFactory.is() )
1227cdf0e10cSrcweir             ::comphelper::setProcessServiceFactory( xFactory );
1228cdf0e10cSrcweir     }
1229cdf0e10cSrcweir     catch( uno::Exception& )
1230cdf0e10cSrcweir     {
1231cdf0e10cSrcweir     }
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir     if( !xFactory.is() )
1234cdf0e10cSrcweir     {
1235cdf0e10cSrcweir         OSL_TRACE( "Could not bootstrap UNO, installation must be in disorder. Exiting.\n" );
1236cdf0e10cSrcweir         exit( 1 );
1237cdf0e10cSrcweir     }
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir     // Create UCB.
1240cdf0e10cSrcweir     uno::Sequence< uno::Any > aArgs( 2 );
1241cdf0e10cSrcweir 	aArgs[ 0 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL );
1242cdf0e10cSrcweir 	aArgs[ 1 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE );
1243cdf0e10cSrcweir     ::ucb::ContentBroker::initialize( xFactory, aArgs );
1244cdf0e10cSrcweir 
1245cdf0e10cSrcweir 	TestWindow pWindow;
1246cdf0e10cSrcweir 	pWindow.Execute();
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir     // clean up UCB
1249cdf0e10cSrcweir 	::ucb::ContentBroker::deinitialize();
1250cdf0e10cSrcweir }
1251cdf0e10cSrcweir 
1252cdf0e10cSrcweir TestApp aDemoApp;
1253