merge the formfield patch from ooo-build
[ooovba.git] / basebmp / test / bmpdemo.cxx
blob63919b3317841eb22e1e82edb6ce23d3c479bc9c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bmpdemo.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #ifndef _USE_MATH_DEFINES
32 #define _USE_MATH_DEFINES // needed by Visual C++ for math constants
33 #endif
34 #include <math.h>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/regpathhelper.hxx>
38 #include <cppuhelper/servicefactory.hxx>
39 #include <cppuhelper/bootstrap.hxx>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 #include <com/sun/star/lang/XInitialization.hpp>
42 #include <com/sun/star/registry/XSimpleRegistry.hpp>
44 #include <ucbhelper/contentbroker.hxx>
45 #include <ucbhelper/configurationkeys.hxx>
47 #include <vcl/window.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/msgbox.hxx>
50 #include <vcl/unowrap.hxx>
51 #include <vcl/bitmap.hxx>
52 #include <vcl/bmpacc.hxx>
54 #include <basegfx/polygon/b2dlinegeometry.hxx>
55 #include <basegfx/polygon/b2dpolypolygon.hxx>
56 #include <basegfx/polygon/b2dpolypolygontools.hxx>
57 #include <basegfx/polygon/b2dpolypolygonrasterconverter.hxx>
58 #include <basegfx/polygon/b2dpolygontools.hxx>
59 #include <basegfx/polygon/b2dpolygon.hxx>
60 #include <basegfx/numeric/ftools.hxx>
61 #include <basegfx/range/b2irange.hxx>
62 #include <basegfx/vector/b2isize.hxx>
63 #include <basegfx/point/b2ipoint.hxx>
65 #include <basebmp/color.hxx>
66 #include <basebmp/scanlineformats.hxx>
67 #include <basebmp/bitmapdevice.hxx>
68 #include <basebmp/debug.hxx>
70 #include <rtl/bootstrap.hxx>
72 #include <vigra/metaprogramming.hxx>
73 #include <vigra/static_assert.hxx>
74 #include <vigra/basicimageview.hxx>
76 #include <boost/static_assert.hpp>
77 #include <algorithm>
78 #include <iostream>
79 #include <fstream>
81 using namespace ::com::sun::star;
84 namespace
87 /// template meta function: add const qualifier, if given 2nd type has it
88 template<typename A, typename B> struct clone_const
90 typedef B type;
92 template<typename A, typename B> struct clone_const<const A,B>
94 typedef const B type;
97 template< class DestIterator, class DestAccessor > class Renderer :
98 public basegfx::B2DPolyPolygonRasterConverter
100 private:
101 typename DestIterator::value_type fillColor_;
102 typename DestIterator::value_type clearColor_;
103 DestIterator begin_;
104 DestAccessor accessor_;
106 public:
107 Renderer(const basegfx::B2DPolyPolygon& rPolyPolyRaster,
108 typename DestIterator::value_type fillColor,
109 typename DestIterator::value_type clearColor,
110 DestIterator begin,
111 DestIterator end,
112 DestAccessor accessor ) :
113 B2DPolyPolygonRasterConverter(rPolyPolyRaster,
114 basegfx::B2DRange(0,0,
115 end.x - end.x,
116 begin.y - begin.y )),
117 fillColor_( fillColor ),
118 clearColor_( clearColor ),
119 begin_( begin ),
120 accessor_( accessor )
124 virtual void span(const double& rfXLeft,
125 const double& rfXRight,
126 sal_Int32 nY,
127 bool bOn )
129 DestIterator currIter( begin_ + vigra::Diff2D(0,nY) );
130 typename DestIterator::row_iterator rowIter( currIter.rowIterator() +
131 basegfx::fround(rfXLeft) );
132 typename DestIterator::row_iterator rowEnd( currIter.rowIterator() +
133 basegfx::fround(rfXRight) );
134 if( bOn )
135 while( rowIter != rowEnd )
137 accessor_.set(fillColor_, rowIter);
138 ++rowIter;
140 else
141 while( rowIter != rowEnd )
143 accessor_.set(accessor_(rowIter)*clearColor_, rowIter);
144 ++rowIter;
149 template< class DestIterator, class DestAccessor >
150 std::auto_ptr< Renderer< DestIterator, DestAccessor > > makeRenderer(
151 const basegfx::B2DPolyPolygon& rPolyPolyRaster,
152 typename DestIterator::value_type fillColor,
153 typename DestIterator::value_type clearColor,
154 vigra::triple<DestIterator, DestIterator, DestAccessor> dest )
156 return std::auto_ptr< Renderer< DestIterator, DestAccessor > >(
157 new Renderer< DestIterator, DestAccessor >(rPolyPolyRaster,
158 fillColor,
159 clearColor,
160 dest.first,
161 dest.second,
162 dest.third));
166 // changed semantics re. DirectionSelector<StridedArrayTag>: stride
167 // now counts in <em>raw</em> bytes!
168 template< typename T > class StridedArrayIterator
170 public:
171 typedef typename clone_const<T, unsigned char>::type internal_type;
173 StridedArrayIterator(int stride, T* ptr = 0) :
174 stride_(stride),
175 current_(reinterpret_cast<internal_type*>(ptr))
178 /// Copy from other StridedArrayIterator, plus given offset
179 StridedArrayIterator( StridedArrayIterator const& rSrc,
180 int offset ) :
181 stride_(rSrc.stride_),
182 current_(reinterpret_cast<internal_type*>(
183 reinterpret_cast<T*>(rSrc.current_)+offset))
186 void operator++() {current_ += stride_; }
187 void operator++(int) {current_ += stride_; }
188 void operator--() {current_ -= stride_; }
189 void operator--(int) {current_ -= stride_; }
190 void operator+=(int dy) {current_ += dy*stride_; }
191 void operator-=(int dy) {current_ -= dy*stride_; }
193 bool operator==(StridedArrayIterator const & rhs) const
194 { return (current_ == rhs.current_); }
196 bool operator!=(StridedArrayIterator const & rhs) const
197 { return (current_ != rhs.current_); }
199 bool operator<(StridedArrayIterator const & rhs) const
200 { return (current_ < rhs.current_); }
202 bool operator<=(StridedArrayIterator const & rhs) const
203 { return (current_ <= rhs.current_); }
205 bool operator>(StridedArrayIterator const & rhs) const
206 { return (current_ > rhs.current_); }
208 bool operator>=(StridedArrayIterator const & rhs) const
209 { return (current_ >= rhs.current_); }
211 int operator-(StridedArrayIterator const & rhs) const
212 { return (current_ - rhs.current_) / stride_; }
214 T* operator()() const
215 { return reinterpret_cast<T*>(current_); }
217 T* operator()(int d) const
218 { return reinterpret_cast<T*>(current_ + d*stride_); }
220 int stride_;
221 internal_type* current_;
224 /// template meta function: remove const qualifier from plain type
225 template <typename T> struct remove_const
227 typedef T type;
229 template <typename T> struct remove_const<const T>
231 typedef T type;
234 /// returns true, if given number is strictly less than 0
235 template< typename T > inline bool is_negative( T x )
237 return x < 0;
240 /// Overload for ints (branch-free)
241 inline bool is_negative( int x )
243 // force logic shift (result for signed shift right is undefined)
244 return static_cast<unsigned int>(x) >> (sizeof(int)*8-1);
247 /// Get bitmask for data at given intra-word position, for given bit depth
248 template< typename data_type, int bits_per_pixel, bool MsbFirst, typename difference_type > inline data_type get_mask( difference_type d )
250 BOOST_STATIC_ASSERT(bits_per_pixel > 0);
251 BOOST_STATIC_ASSERT(sizeof(data_type)*8 % bits_per_pixel == 0);
252 BOOST_STATIC_ASSERT(sizeof(data_type)*8 / bits_per_pixel > 1);
253 BOOST_STATIC_ASSERT(vigra::TypeTraits<data_type>::isPOD::asBool);
255 const unsigned int nIntraWordPositions( sizeof(data_type)*8 / bits_per_pixel );
257 // create bits_per_pixel 1s shift to intra-word position
258 return ((~(~0 << bits_per_pixel)) << bits_per_pixel*(MsbFirst ?
259 (nIntraWordPositions-1 - (d % nIntraWordPositions)) :
260 (d % nIntraWordPositions)));
263 template< int num_intraword_positions, int bits_per_pixel, bool MsbFirst, typename difference_type > inline difference_type get_shift( difference_type remainder )
265 return bits_per_pixel*(MsbFirst ?
266 (num_intraword_positions - 1 - remainder) :
267 remainder);
270 template< typename Datatype,
271 typename Valuetype,
272 int bits_per_pixel,
273 bool MsbFirst > class PackedPixelColumnIterator
275 public:
276 // no reference, no index_reference type here
277 typedef Datatype data_type;
278 typedef Valuetype value_type;
279 typedef int difference_type;
280 typedef image_traverser_tag iterator_category;
282 typedef typename remove_const<data_type>::type mask_type;
283 typedef data_type* pointer;
284 typedef StridedArrayIterator< data_type > MoveY;
286 enum {
287 /** The number of pixel within a single data_type value
289 num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
290 /** Bit mask for one pixel (least significant bits)
292 bit_mask=~(~0 << bits_per_pixel)
295 private:
296 MoveY y;
297 mask_type mask_;
298 difference_type shift_;
300 void inc()
302 ++y;
305 void dec()
307 --y;
310 bool equal( PackedPixelColumnIterator const & rhs ) const
312 return rhs.y == y;
315 bool less( PackedPixelColumnIterator const & rhs ) const
317 return y < rhs.y;
320 public:
321 PackedPixelColumnIterator() :
322 y(0),
323 mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
324 shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst, difference_type>(0) )
327 PackedPixelColumnIterator( const MoveY& base, difference_type remainder ) :
328 y(base),
329 mask_( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) ),
330 shift_( get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder) )
333 PackedPixelColumnIterator& operator+=( difference_type d )
335 y += d;
336 return *this;
339 PackedPixelColumnIterator& operator-=( difference_type d )
341 y -= d;
342 return *this;
345 PackedPixelColumnIterator operator+( difference_type d )
347 PackedPixelColumnIterator res(*this);
348 res += d;
349 return res;
352 PackedPixelColumnIterator operator-( difference_type d )
354 PackedPixelColumnIterator res(*this);
355 res -= d;
356 return res;
359 PackedPixelColumnIterator& operator++()
361 inc();
362 return *this;
365 PackedPixelColumnIterator& operator--()
367 dec();
368 return *this;
371 PackedPixelColumnIterator operator++(int)
373 PackedPixelColumnIterator res(*this);
374 res.inc();
375 return res;
378 PackedPixelColumnIterator operator--(int)
380 PackedPixelColumnIterator res(*this);
381 res.dec();
382 return res;
385 bool operator==(PackedPixelColumnIterator const & rhs) const
387 return equal( rhs );
390 bool operator!=(PackedPixelColumnIterator const & rhs) const
392 return !equal( rhs );
395 bool operator<(PackedPixelColumnIterator const & rhs) const
397 return less(rhs);
400 bool operator<=(PackedPixelColumnIterator const & rhs) const
402 return !less(rhs);
405 bool operator>(PackedPixelColumnIterator const & rhs) const
407 return rhs.less(*this);
410 bool operator>=(PackedPixelColumnIterator const & rhs) const
412 return !rhs.less(*this);
415 difference_type operator-(PackedPixelColumnIterator const & rhs) const
417 return y - rhs.y;
420 value_type get() const
422 // TODO(Q3): use traits to get unsigned type for data_type (if
423 // not already)
424 return static_cast<unsigned int>(*y() & mask_) >> shift_;
427 value_type get(difference_type d) const
429 // TODO(Q3): use traits to get unsigned type for data_type (if
430 // not already)
431 return static_cast<unsigned int>(*y(d) & mask_) >> shift_;
434 void set( value_type v ) const
436 const value_type pixel_value( (v << shift_) & mask_ );
437 *y() = (*y() & ~mask_) | pixel_value;
440 void set( value_type v, difference_type d ) const
442 const value_type pixel_value( (v << shift_) & mask_ );
443 *y(d) = (*y(d) & ~mask_) | pixel_value;
447 template< typename Datatype,
448 typename Valuetype,
449 int bits_per_pixel,
450 bool MsbFirst > class PackedPixelRowIterator
452 public:
453 // no reference, no index_reference type here
454 typedef Datatype data_type;
455 typedef Valuetype value_type;
456 typedef int difference_type;
457 typedef image_traverser_tag iterator_category;
459 typedef typename remove_const<data_type>::type mask_type;
460 typedef data_type* pointer;
462 enum {
463 /** The number of pixel within a single data_type value
465 num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
466 /** Bit mask for one pixel (least significant bits)
468 bit_mask=~(~0 << bits_per_pixel)
471 private:
472 pointer data_;
473 mask_type mask_;
474 difference_type remainder_;
476 void update_mask()
478 mask_ = get_mask<data_type, bits_per_pixel, MsbFirst>(remainder_);
481 void inc()
483 const difference_type newValue( remainder_ + 1 );
484 const difference_type data_offset( newValue / num_intraword_positions );
486 data_ += data_offset;
487 remainder_ = newValue % num_intraword_positions;
489 const mask_type shifted_mask(
490 MsbFirst ?
491 // TODO(Q3): use traits to get unsigned type for data_type
492 // (if not already)
493 static_cast<unsigned int>(mask_) >> bits_per_pixel :
494 mask_ << bits_per_pixel );
496 // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
497 mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
498 bit_mask << bits_per_pixel*(num_intraword_positions-1) :
499 bit_mask);
502 void dec()
504 const difference_type newValue( remainder_ - 1 );
505 const bool isNegative( is_negative(newValue) );
506 const difference_type newRemainder( newValue % num_intraword_positions );
508 // calc data_ += newValue / num_intraword_positions;
509 // remainder_ = newRemainder;
510 // for newValue >= 0, and
511 // data_ += newValue / num_intraword_positions - 1;
512 // remainder_ = num_intraword_positions - newRemainder;
513 // (to force remainder_ to be positive).
514 // This is branch-free, if is_negative() is branch-free
515 const difference_type data_offset( newValue / num_intraword_positions - isNegative );
516 data_ += data_offset;
517 remainder_ = newRemainder + isNegative*num_intraword_positions;
519 const mask_type shifted_mask(
520 MsbFirst ?
521 mask_ << bits_per_pixel :
522 // TODO(Q3): use traits to get unsigned type for data_type
523 // (if not already)
524 static_cast<unsigned int>(mask_) >> bits_per_pixel );
526 // data_offset is 0 for shifted mask, and 1 for wrapped-around mask
527 mask_ = (1-data_offset)*shifted_mask + data_offset*(MsbFirst ?
528 bit_mask :
529 bit_mask << bits_per_pixel*(num_intraword_positions-1));
532 bool equal( PackedPixelRowIterator const & rhs ) const
534 return rhs.data_ == data_ && rhs.remainder_ == remainder_;
537 bool less( PackedPixelRowIterator const & rhs ) const
539 return data_ == rhs.data_ ?
540 (remainder_ < rhs.remainder_) :
541 (data_ < rhs.data_);
544 public:
545 PackedPixelRowIterator() :
546 data_(0),
547 mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
548 remainder_(0)
551 explicit PackedPixelRowIterator( pointer base ) :
552 data_(base),
553 mask_( get_mask<data_type, bits_per_pixel, MsbFirst, difference_type>(0) ),
554 remainder_(0)
557 PackedPixelRowIterator& operator+=( difference_type d )
559 const difference_type newValue( remainder_ + d );
561 data_ += newValue / num_intraword_positions;
562 remainder_ = newValue % num_intraword_positions;
563 update_mask();
565 return *this;
568 PackedPixelRowIterator& operator-=( difference_type d )
570 const difference_type newValue( remainder_ - d );
571 const bool isNegative( is_negative(newValue) );
572 const difference_type newRemainder( newValue % num_intraword_positions );
574 // calc data_ += newValue / num_intraword_positions;
575 // remainder_ = newRemainder;
576 // for newValue >= 0, and
577 // data_ += newValue / num_intraword_positions - 1;
578 // remainder_ = num_intraword_positions - newRemainder;
579 // (to force remainder_ to be positive).
580 // This is branch-free, if is_negative() is branch-free
581 data_ += newValue / num_intraword_positions - isNegative;
582 remainder_ = newRemainder + isNegative*(num_intraword_positions - 2*newRemainder);
583 update_mask();
585 return *this;
588 PackedPixelRowIterator operator+( difference_type d )
590 PackedPixelRowIterator res(*this);
591 res += d;
592 return res;
595 PackedPixelRowIterator operator-( difference_type d )
597 PackedPixelRowIterator res(*this);
598 res -= d;
599 return res;
602 PackedPixelRowIterator& operator++()
604 inc();
605 return *this;
608 PackedPixelRowIterator& operator--()
610 dec();
611 return *this;
614 PackedPixelRowIterator operator++(int)
616 PackedPixelRowIterator res(*this);
617 res.inc();
618 return res;
621 PackedPixelRowIterator operator--(int)
623 PackedPixelRowIterator res(*this);
624 res.dec();
625 return res;
628 bool operator==(PackedPixelRowIterator const & rhs) const
630 return equal( rhs );
633 bool operator!=(PackedPixelRowIterator const & rhs) const
635 return !equal( rhs );
638 bool operator<(PackedPixelRowIterator const & rhs) const
640 return less(rhs);
643 bool operator<=(PackedPixelRowIterator const & rhs) const
645 return !less(rhs);
648 bool operator>(PackedPixelRowIterator const & rhs) const
650 return rhs.less(*this);
653 bool operator>=(PackedPixelRowIterator const & rhs) const
655 return !rhs.less(*this);
658 difference_type operator-(PackedPixelRowIterator const & rhs) const
660 return (data_ - rhs.data_)*num_intraword_positions + (remainder_ - rhs.remainder_);
663 value_type get() const
665 // TODO(Q3): use traits to get unsigned type for data_type (if
666 // not already)
667 return static_cast<unsigned int>(*data_ & mask_) >>
668 get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_);
671 value_type get(difference_type d) const
673 PackedPixelRowIterator tmp(*this);
674 tmp += d;
675 return tmp.get();
678 void set( value_type v ) const
680 const value_type pixel_value(
681 (v <<
682 get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder_))
683 & mask_ );
684 *data_ = (*data_ & ~mask_) | pixel_value;
687 void set( value_type v, difference_type d ) const
689 PackedPixelRowIterator tmp(*this);
690 tmp += d;
691 tmp.set(v);
695 template< typename Datatype,
696 typename Valuetype,
697 int bits_per_pixel,
698 bool MsbFirst > class PackedPixelIterator
700 public:
701 // no reference, no index_reference type here
702 typedef Datatype data_type;
703 typedef Valuetype value_type;
704 typedef vigra::Diff2D difference_type;
705 typedef image_traverser_tag iterator_category;
706 typedef PackedPixelRowIterator<data_type,
707 value_type,
708 bits_per_pixel,
709 MsbFirst> row_iterator;
710 typedef PackedPixelColumnIterator<data_type,
711 value_type,
712 bits_per_pixel,
713 MsbFirst> column_iterator;
715 typedef data_type* pointer;
716 typedef int MoveX;
717 typedef StridedArrayIterator< data_type > MoveY;
719 enum {
720 /** The number of pixel within a single data_type value
722 num_intraword_positions=sizeof(data_type)*8/bits_per_pixel,
723 /** Bit mask for one pixel (least significant bits)
725 bit_mask=~(~0 << bits_per_pixel)
728 // TODO(F2): direction of iteration (ImageIterator can be made to
729 // run backwards)
731 private:
732 pointer current() const
734 return y() + (x / num_intraword_positions);
737 pointer current(int dx, int dy) const
739 return y(dy) + ((x+dx)/num_intraword_positions);
742 bool equal(PackedPixelIterator const & rhs) const
744 return (x == rhs.x) && (y == rhs.y);
747 public:
748 PackedPixelIterator() :
749 x(0),
750 y(0)
753 PackedPixelIterator(pointer base, int ystride) :
754 x(0),
755 y(ystride,base)
758 bool operator==(PackedPixelIterator const & rhs) const
760 return equal(rhs);
763 bool operator!=(PackedPixelIterator const & rhs) const
765 return !equal(rhs);
768 difference_type operator-(PackedPixelIterator const & rhs) const
770 return difference_type(x - rhs.x, y - rhs.y);
773 MoveX x;
774 MoveY y;
776 PackedPixelIterator & operator+=(difference_type const & s)
778 x += s.x;
779 y += s.y;
780 return *this;
783 PackedPixelIterator & operator-=(difference_type const & s)
785 x -= s.x;
786 y -= s.y;
787 return *this;
790 PackedPixelIterator operator+(difference_type const & s) const
792 PackedPixelIterator ret(*this);
793 ret += s;
794 return ret;
797 PackedPixelIterator operator-(difference_type const & s) const
799 PackedPixelIterator ret(*this);
800 ret -= s;
801 return ret;
804 row_iterator rowIterator() const
806 return row_iterator(current());
809 column_iterator columnIterator() const
811 return column_iterator(MoveY(y,
812 x / num_intraword_positions),
813 x % num_intraword_positions);
816 value_type get() const
818 const int remainder( x() % num_intraword_positions );
820 // TODO(Q3): use traits to get unsigned type for data_type (if
821 // not already)
822 return (static_cast<unsigned int>(*current() &
823 get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
824 >> (MsbFirst ?
825 (num_intraword_positions - remainder) :
826 remainder));
829 value_type get(difference_type const & d) const
831 const int remainder( x(d.x) % num_intraword_positions );
833 // TODO(Q3): use traits to get unsigned type for data_type (if
834 // not already)
835 return (static_cast<unsigned int>(*current(d.x,d.y) &
836 get_mask<data_type, bits_per_pixel, MsbFirst>(remainder))
837 >> get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder));
840 void set( value_type v ) const
842 const int remainder( x() % num_intraword_positions );
843 const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
844 const value_type pixel_value(
845 (v <<
846 get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
847 & mask );
848 pointer p = current();
849 *p = (*p & ~mask) | pixel_value;
852 void set( value_type v, difference_type const & d ) const
854 const int remainder( x(d.x) % num_intraword_positions );
855 const int mask( get_mask<data_type, bits_per_pixel, MsbFirst>(remainder) );
856 const value_type pixel_value(
857 (v <<
858 get_shift<num_intraword_positions, bits_per_pixel, MsbFirst>(remainder))
859 & mask );
860 pointer p = current(d.x,d.y);
861 *p = (*p & ~mask) | pixel_value;
866 /** Access (possibly packed-pixel) data via palette indirection
868 template< typename Valuetype, typename Datatype > class PaletteImageAccessor
870 public:
871 typedef Valuetype value_type;
872 typedef Datatype data_type;
873 typedef typename remove_const<data_type>::type count_type;
876 private:
877 const BitmapColor* palette;
878 count_type num_entries;
880 double norm( BitmapColor const& rLHS,
881 BitmapColor const& rRHS ) const
883 // convert RGBValue's linear space to a normed linear space
884 return sqrt(
885 vigra::sq(rLHS.GetRed()-rRHS.GetRed()) +
886 vigra::sq(rLHS.GetGreen()-rRHS.GetGreen()) +
887 vigra::sq(rLHS.GetBlue()-rRHS.GetBlue()) );
890 data_type find_best_match(value_type const& v) const
892 // TODO(F3): not generic!!!
893 const BitmapColor aTmpCol(v.red(),
894 v.green(),
895 v.blue());
897 // TODO(P3): use table-based/octree approach here!
898 const BitmapColor* best_entry;
899 const BitmapColor* palette_end( palette+num_entries );
900 if( (best_entry=std::find( palette, palette_end, aTmpCol)) != palette_end )
901 return best_entry-palette;
903 // TODO(F3): HACK. Need palette traits, and an error function
904 // here. We blatantly assume value_type is a normed linear
905 // space.
906 const BitmapColor* curr_entry( palette );
907 best_entry = curr_entry;
908 while( curr_entry != palette_end )
910 if( norm(*curr_entry,*best_entry) > norm(*curr_entry,aTmpCol) )
911 best_entry = curr_entry;
913 ++curr_entry;
916 return best_entry-palette;
919 value_type toCol( BitmapColor const& rCol ) const
921 return value_type(rCol.GetRed(),rCol.GetGreen(),rCol.GetBlue());
924 public:
925 PaletteImageAccessor() :
926 palette(0),
927 num_entries(0)
930 PaletteImageAccessor( const BitmapColor* pPalette,
931 data_type entries ) :
932 palette(pPalette),
933 num_entries(entries)
936 template< class Iterator >
937 value_type operator()(Iterator const& i) const { return toCol(palette[i.get()]); }
938 value_type operator()(data_type const* i) const { return toCol(palette[*i]); }
940 template< class Iterator, class Difference >
941 value_type operator()(Iterator const& i, Difference const& diff) const
943 return toCol(palette[i.get(diff)]);
946 template< typename V, class Iterator >
947 void set(V const& value, Iterator const& i) const
949 i.set(
950 find_best_match(
951 vigra::detail::RequiresExplicitCast<value_type>::cast(value) ));
954 template< typename V, class Iterator, class Difference >
955 void set(V const& value, Iterator const& i, Difference const& diff) const
957 i.set(
958 find_best_match(
959 vigra::detail::RequiresExplicitCast<value_type>::cast(value)),
960 diff );
967 class TestApp : public Application
969 public:
970 virtual void Main();
971 virtual USHORT Exception( USHORT nError );
974 class TestWindow : public Dialog
976 public:
977 TestWindow() : Dialog( (Window *) NULL )
979 SetText( rtl::OUString::createFromAscii( "VIGRA test" ) );
980 SetSizePixel( Size( 1024, 1024 ) );
981 EnablePaint( true );
982 Show();
984 virtual ~TestWindow() {}
985 virtual void MouseButtonUp( const MouseEvent& /*rMEvt*/ )
987 //TODO: do something cool
988 EndDialog();
990 virtual void Paint( const Rectangle& rRect );
994 static basegfx::B2IPoint project( const basegfx::B2IPoint& rPoint )
996 const double angle_x = M_PI / 6.0;
997 const double angle_z = M_PI / 6.0;
999 // transform planar coordinates to 3d
1000 double x = rPoint.getX();
1001 double y = rPoint.getY();
1002 //double z = 0;
1004 // rotate around X axis
1005 double x1 = x;
1006 double y1 = y * cos( angle_x );
1007 double z1 = y * sin( angle_x );
1009 // rotate around Z axis
1010 double x2 = x1 * cos( angle_z ) + y1 * sin( angle_z );
1011 //double y2 = y1 * cos( angle_z ) - x1 * sin( angle_z );
1012 double z2 = z1;
1014 //return basegfx::B2IPoint( (sal_Int32)3*x2, (sal_Int32)3*z2 );
1015 return basegfx::B2IPoint( (sal_Int32)(6*x2), (sal_Int32)(6*z2) );
1018 static basebmp::Color approachColor( const basebmp::Color& rFrom, const basebmp::Color& rTo )
1020 basebmp::Color aColor;
1021 UINT8 nDiff;
1022 // approach red
1023 if( rFrom.getRed() < rTo.getRed() )
1025 nDiff = rTo.getRed() - rFrom.getRed();
1026 aColor.setRed( rFrom.getRed() + ( nDiff < 10 ? nDiff : 10 ) );
1028 else if( rFrom.getRed() > rTo.getRed() )
1030 nDiff = rFrom.getRed() - rTo.getRed();
1031 aColor.setRed( rFrom.getRed() - ( nDiff < 10 ? nDiff : 10 ) );
1033 else
1034 aColor.setRed( rFrom.getRed() );
1036 // approach Green
1037 if( rFrom.getGreen() < rTo.getGreen() )
1039 nDiff = rTo.getGreen() - rFrom.getGreen();
1040 aColor.setGreen( rFrom.getGreen() + ( nDiff < 10 ? nDiff : 10 ) );
1042 else if( rFrom.getGreen() > rTo.getGreen() )
1044 nDiff = rFrom.getGreen() - rTo.getGreen();
1045 aColor.setGreen( rFrom.getGreen() - ( nDiff < 10 ? nDiff : 10 ) );
1047 else
1048 aColor.setGreen( rFrom.getGreen() );
1050 // approach blue
1051 if( rFrom.getBlue() < rTo.getBlue() )
1053 nDiff = rTo.getBlue() - rFrom.getBlue();
1054 aColor.setBlue( rFrom.getBlue() + ( nDiff < 10 ? nDiff : 10 ) );
1056 else if( rFrom.getBlue() > rTo.getBlue() )
1058 nDiff = rFrom.getBlue() - rTo.getBlue();
1059 aColor.setBlue( rFrom.getBlue() - ( nDiff < 10 ? nDiff : 10 ) );
1061 else
1062 aColor.setBlue( rFrom.getBlue() );
1064 return aColor;
1067 #define DELTA 5.0
1071 void TestWindow::Paint( const Rectangle& /*rRect*/ )
1073 basegfx::B2ISize aTestSize(1000,1000);
1074 basebmp::BitmapDeviceSharedPtr pDevice( basebmp::createBitmapDevice( aTestSize,
1075 false,
1076 basebmp::Format::THIRTYTWO_BIT_TC_MASK ));
1079 ::rtl::OUString aSvg;
1080 basegfx::B2DPolyPolygon aPoly;
1082 basegfx::tools::importFromSvgD( aPoly,
1083 ::rtl::OUString::createFromAscii(
1084 "m0 0 h7 v7 h-7 z" ) );
1085 basegfx::tools::importFromSvgD( aPoly,
1086 ::rtl::OUString::createFromAscii(
1087 "m2 2 h3 v3 h-3 z" ) );
1089 pDevice->fillPolyPolygon(
1090 aPoly,
1091 basebmp::Color(0xFFFFFFFF),
1092 basebmp::DrawMode_PAINT );
1095 #if 0
1097 basebmp::BitmapDeviceSharedPtr pMask( basebmp::createBitmapDevice( aTestSize,
1098 false,
1099 basebmp::Format::ONE_BIT_MSB_GREY ));
1101 const basegfx::B2IPoint aPt111(10,10);
1102 const basegfx::B2IPoint aPt222(0,10);
1103 const basebmp::Color aCol333(0xFFFFFFFF);
1104 pMask->drawLine( aPt111, aPt222, aCol333, basebmp::DrawMode_PAINT );
1107 ::rtl::OUString aSvg = ::rtl::OUString::createFromAscii(
1108 "m 0 0 h5 l5 5 v5 h-5 l-5-5 z" );
1109 basegfx::B2DPolyPolygon aPoly;
1110 basegfx::tools::importFromSvgD( aPoly, aSvg );
1111 pMask->clear(basebmp::Color(0xFFFFFFFF));
1112 pMask->drawPolygon(
1113 aPoly.getB2DPolygon(0),
1114 basebmp::Color(0),
1115 basebmp::DrawMode_PAINT );
1117 basebmp::BitmapDeviceSharedPtr pSubsetDevice =
1118 basebmp::subsetBitmapDevice( pDevice,
1119 basegfx::B2IRange(3,3,7,7) );
1121 const basegfx::B2IPoint aPt1(0,0);
1122 const basegfx::B2IPoint aPt2(1,9);
1123 const basebmp::Color aCol(0xFFFFFFFF);
1124 pDevice->drawLine( aPt1, aPt2, aCol, basebmp::DrawMode_PAINT, pMask );
1128 const basebmp::Color aCol(0xFFFFFFFF);
1129 basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect(
1130 basegfx::B2DRange( 0,0,1001,1001 ));
1131 pDevice->drawPolygon( aRect, aCol, basebmp::DrawMode_PAINT );
1133 const basegfx::B2IPoint aPt1(0,0);
1134 const basegfx::B2IPoint aPt2(0,800);
1135 pDevice->drawLine( aPt1, aPt2, aCol, basebmp::DrawMode_PAINT );
1137 const basegfx::B2IPoint aPt3(0,1001);
1138 pDevice->drawLine( aPt1, aPt3, aCol, basebmp::DrawMode_PAINT );
1140 #endif
1143 pDevice->clear(basebmp::Color(0));
1145 basegfx::B2IPoint aCenter( aTestSize.getX()/2,
1146 aTestSize.getY()/2 );
1147 //basegfx::B2IPoint aP1( aTestSize.getX()/48, 0), aP2( aTestSize.getX()/40, 0 ), aPoint;
1148 //basegfx::B2IPoint aP1( aTestSize.getX()/7, 0), aP2( aTestSize.getX()/6, 0 ), aPoint;
1149 //basegfx::B2IPoint aP1( aTestSize.getX()/5, 0), aP2( aTestSize.getX()/4, 0 ), aPoint;
1150 basegfx::B2IPoint aP1( aTestSize.getX()/12, 0), aP2( aTestSize.getX()/11, 0 ), aPoint;
1152 double sind = sin( DELTA*M_PI/180.0 );
1153 double cosd = cos( DELTA*M_PI/180.0 );
1154 double factor = 1 + (DELTA/1000.0);
1155 int n=0;
1156 basebmp::Color aLineColor( 0, 0, 0 );
1157 basebmp::Color aApproachColor( 0, 0, 200 );
1158 while ( aP2.getX() < aCenter.getX() && n++ < 680 )
1160 aLineColor = approachColor( aLineColor, aApproachColor );
1162 // switch aproach color
1163 if( aApproachColor == aLineColor )
1165 if( aApproachColor.getRed() )
1166 aApproachColor = basebmp::Color( 0, 0, 200 );
1167 else if( aApproachColor.getGreen() )
1168 aApproachColor = basebmp::Color( 200, 0, 0 );
1169 else
1170 aApproachColor = basebmp::Color( 0, 200, 0 );
1173 basegfx::B2DPolygon aPoly;
1174 aPoly.append( basegfx::B2DPoint(project( aP1 ) + aCenter) );
1175 aPoly.append( basegfx::B2DPoint(project( aP2 ) + aCenter) );
1176 pDevice->fillPolyPolygon(
1177 basegfx::tools::createAreaGeometryForPolygon(
1178 aPoly,
1179 // std::max(1,n/30),
1180 // std::max(1,n/60),
1181 std::max(1,n/30),
1182 basegfx::tools::B2DLINEJOIN_NONE),
1183 aLineColor,
1184 basebmp::DrawMode_PAINT);
1186 aPoint.setX( (int)((((double)aP1.getX())*cosd - ((double)aP1.getY())*sind)*factor) );
1187 aPoint.setY( (int)((((double)aP1.getY())*cosd + ((double)aP1.getX())*sind)*factor) );
1188 aP1 = aPoint;
1189 aPoint.setX( (int)((((double)aP2.getX())*cosd - ((double)aP2.getY())*sind)*factor) );
1190 aPoint.setY( (int)((((double)aP2.getY())*cosd + ((double)aP2.getX())*sind)*factor) );
1191 aP2 = aPoint;
1195 Bitmap aBitmap( Size(aTestSize.getX(),
1196 aTestSize.getY()), 24 );
1198 // Fill bitmap with generated content
1200 ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(),
1201 aBitmap );
1202 for( int y=0; y<aTestSize.getY(); ++y )
1203 for( int x=0; x<aTestSize.getX(); ++x )
1204 pWriteAccess->SetPixel(y,x,
1205 Color(pDevice->getPixelData(basegfx::B2IPoint(x,y))) );
1208 DrawBitmap( Point(), aBitmap );
1211 USHORT TestApp::Exception( USHORT nError )
1213 switch( nError & EXC_MAJORTYPE )
1215 case EXC_RSCNOTLOADED:
1216 Abort( String::CreateFromAscii( "Error: could not load language resources.\nPlease check your installation.\n" ) );
1217 break;
1219 return 0;
1222 void TestApp::Main()
1224 //-------------------------------------------------
1225 // create the global service-manager
1226 //-------------------------------------------------
1227 uno::Reference< lang::XMultiServiceFactory > xFactory;
1230 uno::Reference< uno::XComponentContext > xCtx = ::cppu::defaultBootstrap_InitialComponentContext();
1231 xFactory = uno::Reference< lang::XMultiServiceFactory >( xCtx->getServiceManager(),
1232 uno::UNO_QUERY );
1233 if( xFactory.is() )
1234 ::comphelper::setProcessServiceFactory( xFactory );
1236 catch( uno::Exception& )
1240 if( !xFactory.is() )
1242 OSL_TRACE( "Could not bootstrap UNO, installation must be in disorder. Exiting.\n" );
1243 exit( 1 );
1246 // Create UCB.
1247 uno::Sequence< uno::Any > aArgs( 2 );
1248 aArgs[ 0 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL );
1249 aArgs[ 1 ] <<= rtl::OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE );
1250 ::ucb::ContentBroker::initialize( xFactory, aArgs );
1252 TestWindow pWindow;
1253 pWindow.Execute();
1255 // clean up UCB
1256 ::ucb::ContentBroker::deinitialize();
1259 TestApp aDemoApp;