1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
31 #include <vcl/glyphcache.hxx>
34 //------------------------------------------------------------------------
36 RawBitmap::RawBitmap()
37 : mpBits(0), mnAllocated(0)
40 //------------------------------------------------------------------------
42 RawBitmap::~RawBitmap()
49 //------------------------------------------------------------------------
51 // used by 90 and 270 degree rotations on 8 bit deep bitmaps
52 static void ImplRotate8_90( unsigned char* p1
, const unsigned char* p2
,
53 int xmax
, int ymax
, int dx
, int dy
, int nPad
)
55 for( int y
= ymax
; --y
>= 0; p2
+= dy
)
57 for( int x
= xmax
; --x
>= 0; p2
+= dx
)
59 for( int i
= nPad
; --i
>= 0; )
64 //------------------------------------------------------------------------
66 // used by inplace 180 degree rotation on 8 bit deep bitmaps
67 static void ImplRotate8_180( unsigned char* p1
, int xmax
, int ymax
, int nPad
)
69 unsigned char* p2
= p1
+ ymax
* (xmax
+ nPad
);
70 for( int y
= ymax
/2; --y
>= 0; )
73 for( int x
= xmax
; --x
>= 0; )
75 unsigned char cTmp
= *(--p2
);
82 // reverse middle line
86 unsigned char cTmp
= *(--p2
);
92 //------------------------------------------------------------------------
94 // used by 90 or 270 degree rotations on 1 bit deep bitmaps
95 static void ImplRotate1_90( unsigned char* p1
, const unsigned char* p2
,
96 int xmax
, int ymax
, int dx
, int nShift
, int nDeltaShift
, int nPad
)
98 for( int y
= ymax
; --y
>= 0; )
101 const unsigned char* p20
= p2
;
102 for( int x
= xmax
; --x
>= 0; p2
+= dx
)
104 // build bitwise and store when byte finished
105 nTemp
+= nTemp
+ ((*p2
>> nShift
) & 1);
106 if( nTemp
>= 0x100U
)
108 *(p1
++) = (unsigned char)nTemp
;
114 // store left aligned remainder if needed
117 for(; nTemp
< 0x100U
; nTemp
+= nTemp
) ;
118 *(p1
++) = (unsigned char)nTemp
;
120 // pad scanline with zeroes
121 for( int i
= nPad
; --i
>= 0;)
124 // increase/decrease shift, but keep bound inside 0 to 7
125 nShift
+= nDeltaShift
;
126 if( nShift
!= (nShift
& 7) )
132 //------------------------------------------------------------------------
134 // used by 180 degrees rotations on 1 bit deep bitmaps
135 static void ImplRotate1_180( unsigned char* p1
, const unsigned char* p2
,
136 int xmax
, int ymax
, int nPad
)
139 for( int y
= ymax
; --y
>= 0; )
144 unsigned nInp
= (0x100 + *p2
) >> (-xmax
& 7);
145 for( int x
= xmax
; --x
>= 0; )
147 // build bitwise and store when byte finished
148 nTemp
+= nTemp
+ (nInp
& 1);
151 *(p1
++) = (unsigned char)nTemp
;
154 // update input byte if needed (and available)
155 if( (nInp
>>= 1) <= 1 && ((y
!= 0) || (x
!= 0)) )
156 nInp
= 0x100 + *(--p2
);
159 // store left aligned remainder if needed
162 for(; nTemp
< 0x100; nTemp
+= nTemp
) ;
163 *(p1
++) = (unsigned char)nTemp
;
165 // scanline pad is already clean
170 //------------------------------------------------------------------------
172 bool RawBitmap::Rotate( int nAngle
)
174 ULONG nNewScanlineSize
= 0;
175 ULONG nNewHeight
= 0;
178 // do inplace rotation or prepare double buffered rotation
181 case 0: // nothing to do
184 default: // non rectangular angles not allowed
186 case 1800: // rotate by 180 degrees
187 mnXOffset
= -(mnXOffset
+ mnWidth
);
188 mnYOffset
= -(mnYOffset
+ mnHeight
);
189 if( mnBitCount
== 8 )
191 ImplRotate8_180( mpBits
, mnWidth
, mnHeight
, mnScanlineSize
-mnWidth
);
195 nNewHeight
= mnHeight
;
196 nNewScanlineSize
= mnScanlineSize
;
198 case +900: // left by 90 degrees
200 case 2700: // right by 90 degrees
201 nNewWidth
= mnHeight
;
202 nNewHeight
= mnWidth
;
204 nNewScanlineSize
= (nNewWidth
+ 7) / 8;
206 nNewScanlineSize
= (nNewWidth
+ 3) & -4;
210 unsigned int nBufSize
= nNewHeight
* nNewScanlineSize
;
211 unsigned char* pBuf
= new unsigned char[ nBufSize
];
215 memset( pBuf
, 0, nBufSize
);
218 // dispatch non-inplace rotations
221 case 1800: // rotate by 180 degrees
222 // we know we only need to deal with 1 bit depth
223 ImplRotate1_180( pBuf
, mpBits
+ mnHeight
* mnScanlineSize
,
224 mnWidth
, mnHeight
, mnScanlineSize
- (mnWidth
+ 7) / 8 );
226 case +900: // rotate left by 90 degrees
228 mnXOffset
= mnYOffset
;
229 mnYOffset
= -nNewHeight
- i
;
230 if( mnBitCount
== 8 )
231 ImplRotate8_90( pBuf
, mpBits
+ mnWidth
- 1,
232 nNewWidth
, nNewHeight
, +mnScanlineSize
, -1-mnHeight
*mnScanlineSize
,
233 nNewScanlineSize
- nNewWidth
);
235 ImplRotate1_90( pBuf
, mpBits
+ (mnWidth
- 1) / 8,
236 nNewWidth
, nNewHeight
, +mnScanlineSize
,
237 (-mnWidth
& 7), +1, nNewScanlineSize
- (nNewWidth
+ 7) / 8 );
239 case 2700: // rotate right by 90 degrees
242 mnXOffset
= -(nNewWidth
+ mnYOffset
);
244 if( mnBitCount
== 8 )
245 ImplRotate8_90( pBuf
, mpBits
+ mnScanlineSize
* (mnHeight
-1),
246 nNewWidth
, nNewHeight
, -mnScanlineSize
, +1+mnHeight
*mnScanlineSize
,
247 nNewScanlineSize
- nNewWidth
);
249 ImplRotate1_90( pBuf
, mpBits
+ mnScanlineSize
* (mnHeight
-1),
250 nNewWidth
, nNewHeight
, -mnScanlineSize
,
251 +7, -1, nNewScanlineSize
- (nNewWidth
+ 7) / 8 );
256 mnHeight
= nNewHeight
;
257 mnScanlineSize
= nNewScanlineSize
;
259 if( nBufSize
< mnAllocated
)
261 memcpy( mpBits
, pBuf
, nBufSize
);
268 mnAllocated
= nBufSize
;
274 //------------------------------------------------------------------------