Update ooo320-m1
[ooovba.git] / vcl / source / glyphs / gcach_rbmp.cxx
blob07e437cc44d9f2bc11ab79e90dc1dbcb6a18fb10
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 * 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>
32 #include <string.h>
34 //------------------------------------------------------------------------
36 RawBitmap::RawBitmap()
37 : mpBits(0), mnAllocated(0)
40 //------------------------------------------------------------------------
42 RawBitmap::~RawBitmap()
44 delete[] mpBits;
45 mpBits = 0;
46 mnAllocated = 0;
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 )
58 *(p1++) = *p2;
59 for( int i = nPad; --i >= 0; )
60 *(p1++) = 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; )
72 p2 -= nPad;
73 for( int x = xmax; --x >= 0; )
75 unsigned char cTmp = *(--p2);
76 *p2 = *p1;
77 *(p1++) = cTmp;
79 p1 += nPad;
82 // reverse middle line
83 p2 -= nPad;
84 while( p1 < p2 )
86 unsigned char cTmp = *(--p2);
87 *p2 = *p1;
88 *(p1++) = cTmp;
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; )
100 unsigned nTemp = 1;
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;
109 nTemp = 1;
112 p2 = p20;
114 // store left aligned remainder if needed
115 if( nTemp > 1 )
117 for(; nTemp < 0x100U; nTemp += nTemp ) ;
118 *(p1++) = (unsigned char)nTemp;
120 // pad scanline with zeroes
121 for( int i = nPad; --i >= 0;)
122 *(p1++) = 0;
124 // increase/decrease shift, but keep bound inside 0 to 7
125 nShift += nDeltaShift;
126 if( nShift != (nShift & 7) )
127 p2 -= nDeltaShift;
128 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 )
138 --p2;
139 for( int y = ymax; --y >= 0; )
141 p2 -= nPad;
143 unsigned nTemp = 1;
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);
149 if( nTemp >= 0x100 )
151 *(p1++) = (unsigned char)nTemp;
152 nTemp = 1;
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
160 if( nTemp > 1 )
162 for(; nTemp < 0x100; nTemp += nTemp ) ;
163 *(p1++) = (unsigned char)nTemp;
165 // scanline pad is already clean
166 p1 += nPad;
170 //------------------------------------------------------------------------
172 bool RawBitmap::Rotate( int nAngle )
174 ULONG nNewScanlineSize = 0;
175 ULONG nNewHeight = 0;
176 ULONG nNewWidth = 0;
178 // do inplace rotation or prepare double buffered rotation
179 switch( nAngle )
181 case 0: // nothing to do
182 case 3600:
183 return true;
184 default: // non rectangular angles not allowed
185 return false;
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 );
192 return true;
194 nNewWidth = mnWidth;
195 nNewHeight = mnHeight;
196 nNewScanlineSize = mnScanlineSize;
197 break;
198 case +900: // left by 90 degrees
199 case -900:
200 case 2700: // right by 90 degrees
201 nNewWidth = mnHeight;
202 nNewHeight = mnWidth;
203 if( mnBitCount==1 )
204 nNewScanlineSize = (nNewWidth + 7) / 8;
205 else
206 nNewScanlineSize = (nNewWidth + 3) & -4;
207 break;
210 unsigned int nBufSize = nNewHeight * nNewScanlineSize;
211 unsigned char* pBuf = new unsigned char[ nBufSize ];
212 if( !pBuf )
213 return false;
215 memset( pBuf, 0, nBufSize );
216 int i;
218 // dispatch non-inplace rotations
219 switch( nAngle )
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 );
225 break;
226 case +900: // rotate left by 90 degrees
227 i = mnXOffset;
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 );
234 else
235 ImplRotate1_90( pBuf, mpBits + (mnWidth - 1) / 8,
236 nNewWidth, nNewHeight, +mnScanlineSize,
237 (-mnWidth & 7), +1, nNewScanlineSize - (nNewWidth + 7) / 8 );
238 break;
239 case 2700: // rotate right by 90 degrees
240 case -900:
241 i = mnXOffset;
242 mnXOffset = -(nNewWidth + mnYOffset);
243 mnYOffset = i;
244 if( mnBitCount == 8 )
245 ImplRotate8_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
246 nNewWidth, nNewHeight, -mnScanlineSize, +1+mnHeight*mnScanlineSize,
247 nNewScanlineSize - nNewWidth );
248 else
249 ImplRotate1_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
250 nNewWidth, nNewHeight, -mnScanlineSize,
251 +7, -1, nNewScanlineSize - (nNewWidth + 7) / 8 );
252 break;
255 mnWidth = nNewWidth;
256 mnHeight = nNewHeight;
257 mnScanlineSize = nNewScanlineSize;
259 if( nBufSize < mnAllocated )
261 memcpy( mpBits, pBuf, nBufSize );
262 delete[] pBuf;
264 else
266 delete[] mpBits;
267 mpBits = pBuf;
268 mnAllocated = nBufSize;
271 return true;
274 //------------------------------------------------------------------------