xref: /aoo41x/main/vcl/source/glyphs/gcach_rbmp.cxx (revision 79aad27f)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9f62ea84SAndrew Rist  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9f62ea84SAndrew Rist  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19*9f62ea84SAndrew Rist  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <glyphcache.hxx>
28cdf0e10cSrcweir #include <string.h>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir //------------------------------------------------------------------------
31cdf0e10cSrcweir 
RawBitmap()32cdf0e10cSrcweir RawBitmap::RawBitmap()
33cdf0e10cSrcweir : mpBits(0), mnAllocated(0)
34cdf0e10cSrcweir {}
35cdf0e10cSrcweir 
36cdf0e10cSrcweir //------------------------------------------------------------------------
37cdf0e10cSrcweir 
~RawBitmap()38cdf0e10cSrcweir RawBitmap::~RawBitmap()
39cdf0e10cSrcweir {
40cdf0e10cSrcweir     delete[] mpBits;
41cdf0e10cSrcweir     mpBits = 0;
42cdf0e10cSrcweir     mnAllocated = 0;
43cdf0e10cSrcweir }
44cdf0e10cSrcweir 
45cdf0e10cSrcweir //------------------------------------------------------------------------
46cdf0e10cSrcweir 
47cdf0e10cSrcweir // used by 90 and 270 degree rotations on 8 bit deep bitmaps
ImplRotate8_90(unsigned char * p1,const unsigned char * p2,int xmax,int ymax,int dx,int dy,int nPad)48cdf0e10cSrcweir static void ImplRotate8_90( unsigned char* p1, const unsigned char* p2,
49cdf0e10cSrcweir     int xmax, int ymax, int dx, int dy, int nPad )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     for( int y = ymax; --y >= 0; p2 += dy )
52cdf0e10cSrcweir     {
53cdf0e10cSrcweir         for( int x = xmax; --x >= 0; p2 += dx )
54cdf0e10cSrcweir             *(p1++) = *p2;
55cdf0e10cSrcweir         for( int i = nPad; --i >= 0; )
56cdf0e10cSrcweir             *(p1++) = 0;
57cdf0e10cSrcweir     }
58cdf0e10cSrcweir }
59cdf0e10cSrcweir 
60cdf0e10cSrcweir //------------------------------------------------------------------------
61cdf0e10cSrcweir 
62cdf0e10cSrcweir // used by inplace 180 degree rotation on 8 bit deep bitmaps
ImplRotate8_180(unsigned char * p1,int xmax,int ymax,int nPad)63cdf0e10cSrcweir static void ImplRotate8_180( unsigned char* p1, int xmax, int ymax, int nPad )
64cdf0e10cSrcweir {
65cdf0e10cSrcweir     unsigned char* p2 = p1 + ymax * (xmax + nPad);
66cdf0e10cSrcweir     for( int y = ymax/2; --y >= 0; )
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir         p2 -= nPad;
69cdf0e10cSrcweir         for( int x = xmax; --x >= 0; )
70cdf0e10cSrcweir         {
71cdf0e10cSrcweir             unsigned char cTmp = *(--p2);
72cdf0e10cSrcweir             *p2 = *p1;
73cdf0e10cSrcweir             *(p1++) = cTmp;
74cdf0e10cSrcweir         }
75cdf0e10cSrcweir         p1 += nPad;
76cdf0e10cSrcweir     }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     // reverse middle line
79cdf0e10cSrcweir     p2 -= nPad;
80cdf0e10cSrcweir     while( p1 < p2 )
81cdf0e10cSrcweir     {
82cdf0e10cSrcweir         unsigned char cTmp = *(--p2);
83cdf0e10cSrcweir         *p2 = *p1;
84cdf0e10cSrcweir         *(p1++) = cTmp;
85cdf0e10cSrcweir     }
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir //------------------------------------------------------------------------
89cdf0e10cSrcweir 
90cdf0e10cSrcweir // used by 90 or 270 degree rotations on 1 bit deep bitmaps
ImplRotate1_90(unsigned char * p1,const unsigned char * p2,int xmax,int ymax,int dx,int nShift,int nDeltaShift,int nPad)91cdf0e10cSrcweir static void ImplRotate1_90( unsigned char* p1, const unsigned char* p2,
92cdf0e10cSrcweir     int xmax, int ymax, int dx, int nShift, int nDeltaShift, int nPad )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir     for( int y = ymax; --y >= 0; )
95cdf0e10cSrcweir     {
96cdf0e10cSrcweir         unsigned nTemp = 1;
97cdf0e10cSrcweir         const unsigned char* p20 = p2;
98cdf0e10cSrcweir         for( int x = xmax; --x >= 0; p2 += dx )
99cdf0e10cSrcweir         {
100cdf0e10cSrcweir             // build bitwise and store when byte finished
101cdf0e10cSrcweir            nTemp += nTemp + ((*p2 >> nShift) & 1);
102cdf0e10cSrcweir             if( nTemp >= 0x100U )
103cdf0e10cSrcweir             {
104cdf0e10cSrcweir                 *(p1++) = (unsigned char)nTemp;
105cdf0e10cSrcweir                 nTemp = 1;
106cdf0e10cSrcweir             }
107cdf0e10cSrcweir         }
108cdf0e10cSrcweir         p2 = p20;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir         // store left aligned remainder if needed
111cdf0e10cSrcweir         if( nTemp > 1 )
112cdf0e10cSrcweir         {
113cdf0e10cSrcweir             for(; nTemp < 0x100U; nTemp += nTemp ) ;
114cdf0e10cSrcweir             *(p1++) = (unsigned char)nTemp;
115cdf0e10cSrcweir         }
116cdf0e10cSrcweir         // pad scanline with zeroes
117cdf0e10cSrcweir         for( int i = nPad; --i >= 0;)
118cdf0e10cSrcweir             *(p1++) = 0;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir         // increase/decrease shift, but keep bound inside 0 to 7
121cdf0e10cSrcweir         nShift += nDeltaShift;
122cdf0e10cSrcweir         if( nShift != (nShift & 7) )
123cdf0e10cSrcweir             p2 -= nDeltaShift;
124cdf0e10cSrcweir         nShift &= 7;
125cdf0e10cSrcweir     }
126cdf0e10cSrcweir }
127cdf0e10cSrcweir 
128cdf0e10cSrcweir //------------------------------------------------------------------------
129cdf0e10cSrcweir 
130cdf0e10cSrcweir // used by 180 degrees rotations on 1 bit deep bitmaps
ImplRotate1_180(unsigned char * p1,const unsigned char * p2,int xmax,int ymax,int nPad)131cdf0e10cSrcweir static void ImplRotate1_180( unsigned char* p1, const unsigned char* p2,
132cdf0e10cSrcweir     int xmax, int ymax, int nPad )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     --p2;
135cdf0e10cSrcweir     for( int y = ymax; --y >= 0; )
136cdf0e10cSrcweir     {
137cdf0e10cSrcweir         p2 -= nPad;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir         unsigned nTemp = 1;
140cdf0e10cSrcweir         unsigned nInp = (0x100 + *p2) >> (-xmax & 7);
141cdf0e10cSrcweir         for( int x = xmax; --x >= 0; )
142cdf0e10cSrcweir         {
143cdf0e10cSrcweir             // build bitwise and store when byte finished
144cdf0e10cSrcweir             nTemp += nTemp + (nInp & 1);
145cdf0e10cSrcweir             if( nTemp >= 0x100 )
146cdf0e10cSrcweir             {
147cdf0e10cSrcweir                 *(p1++) = (unsigned char)nTemp;
148cdf0e10cSrcweir                 nTemp = 1;
149cdf0e10cSrcweir             }
150cdf0e10cSrcweir             // update input byte if needed (and available)
151cdf0e10cSrcweir             if( (nInp >>= 1) <= 1 && ((y != 0) || (x != 0)) )
152cdf0e10cSrcweir                 nInp = 0x100 + *(--p2);
153cdf0e10cSrcweir         }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir         // store left aligned remainder if needed
156cdf0e10cSrcweir         if( nTemp > 1 )
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             for(; nTemp < 0x100; nTemp += nTemp ) ;
159cdf0e10cSrcweir             *(p1++) = (unsigned char)nTemp;
160cdf0e10cSrcweir         }
161cdf0e10cSrcweir         // scanline pad is already clean
162cdf0e10cSrcweir         p1 += nPad;
163cdf0e10cSrcweir     }
164cdf0e10cSrcweir }
165cdf0e10cSrcweir 
166cdf0e10cSrcweir //------------------------------------------------------------------------
167cdf0e10cSrcweir 
Rotate(int nAngle)168cdf0e10cSrcweir bool RawBitmap::Rotate( int nAngle )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir     sal_uLong nNewScanlineSize = 0;
171cdf0e10cSrcweir     sal_uLong nNewHeight = 0;
172cdf0e10cSrcweir     sal_uLong nNewWidth = 0;
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     // do inplace rotation or prepare double buffered rotation
175cdf0e10cSrcweir     switch( nAngle )
176cdf0e10cSrcweir     {
177cdf0e10cSrcweir         case 0:     // nothing to do
178cdf0e10cSrcweir         case 3600:
179cdf0e10cSrcweir             return true;
180cdf0e10cSrcweir         default:    // non rectangular angles not allowed
181cdf0e10cSrcweir             return false;
182cdf0e10cSrcweir         case 1800:  // rotate by 180 degrees
183cdf0e10cSrcweir             mnXOffset = -(mnXOffset + mnWidth);
184cdf0e10cSrcweir             mnYOffset = -(mnYOffset + mnHeight);
185cdf0e10cSrcweir             if( mnBitCount == 8 )
186cdf0e10cSrcweir             {
187cdf0e10cSrcweir                 ImplRotate8_180( mpBits, mnWidth, mnHeight, mnScanlineSize-mnWidth );
188cdf0e10cSrcweir                 return true;
189cdf0e10cSrcweir             }
190cdf0e10cSrcweir             nNewWidth        = mnWidth;
191cdf0e10cSrcweir             nNewHeight       = mnHeight;
192cdf0e10cSrcweir             nNewScanlineSize = mnScanlineSize;
193cdf0e10cSrcweir             break;
194cdf0e10cSrcweir         case +900:  // left by 90 degrees
195cdf0e10cSrcweir         case -900:
196cdf0e10cSrcweir         case 2700:  // right by 90 degrees
197cdf0e10cSrcweir             nNewWidth        = mnHeight;
198cdf0e10cSrcweir             nNewHeight       = mnWidth;
199cdf0e10cSrcweir             if( mnBitCount==1 )
200cdf0e10cSrcweir                 nNewScanlineSize = (nNewWidth + 7) / 8;
201cdf0e10cSrcweir             else
202cdf0e10cSrcweir                 nNewScanlineSize = (nNewWidth + 3) & -4;
203cdf0e10cSrcweir             break;
204cdf0e10cSrcweir     }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     unsigned int nBufSize = nNewHeight * nNewScanlineSize;
207cdf0e10cSrcweir     unsigned char* pBuf = new unsigned char[ nBufSize ];
208cdf0e10cSrcweir     if( !pBuf )
209cdf0e10cSrcweir         return false;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     memset( pBuf, 0, nBufSize );
212cdf0e10cSrcweir     int i;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     // dispatch non-inplace rotations
215cdf0e10cSrcweir     switch( nAngle )
216cdf0e10cSrcweir     {
217cdf0e10cSrcweir         case 1800:  // rotate by 180 degrees
218cdf0e10cSrcweir             // we know we only need to deal with 1 bit depth
219cdf0e10cSrcweir             ImplRotate1_180( pBuf, mpBits + mnHeight * mnScanlineSize,
220cdf0e10cSrcweir                 mnWidth, mnHeight, mnScanlineSize - (mnWidth + 7) / 8 );
221cdf0e10cSrcweir             break;
222cdf0e10cSrcweir         case +900:  // rotate left by 90 degrees
223cdf0e10cSrcweir             i = mnXOffset;
224cdf0e10cSrcweir             mnXOffset = mnYOffset;
225cdf0e10cSrcweir             mnYOffset = -nNewHeight - i;
226cdf0e10cSrcweir             if( mnBitCount == 8 )
227cdf0e10cSrcweir                 ImplRotate8_90( pBuf, mpBits + mnWidth - 1,
228cdf0e10cSrcweir                     nNewWidth, nNewHeight, +mnScanlineSize, -1-mnHeight*mnScanlineSize,
229cdf0e10cSrcweir                     nNewScanlineSize - nNewWidth );
230cdf0e10cSrcweir             else
231cdf0e10cSrcweir                 ImplRotate1_90( pBuf, mpBits + (mnWidth - 1) / 8,
232cdf0e10cSrcweir                     nNewWidth, nNewHeight, +mnScanlineSize,
233cdf0e10cSrcweir                     (-mnWidth & 7), +1, nNewScanlineSize - (nNewWidth + 7) / 8 );
234cdf0e10cSrcweir             break;
235cdf0e10cSrcweir         case 2700:  // rotate right by 90 degrees
236cdf0e10cSrcweir         case -900:
237cdf0e10cSrcweir             i = mnXOffset;
238cdf0e10cSrcweir             mnXOffset = -(nNewWidth + mnYOffset);
239cdf0e10cSrcweir             mnYOffset = i;
240cdf0e10cSrcweir             if( mnBitCount == 8 )
241cdf0e10cSrcweir                 ImplRotate8_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
242cdf0e10cSrcweir                     nNewWidth, nNewHeight, -mnScanlineSize, +1+mnHeight*mnScanlineSize,
243cdf0e10cSrcweir                     nNewScanlineSize - nNewWidth );
244cdf0e10cSrcweir             else
245cdf0e10cSrcweir                 ImplRotate1_90( pBuf, mpBits + mnScanlineSize * (mnHeight-1),
246cdf0e10cSrcweir                     nNewWidth, nNewHeight, -mnScanlineSize,
247cdf0e10cSrcweir                     +7, -1, nNewScanlineSize - (nNewWidth + 7) / 8 );
248cdf0e10cSrcweir             break;
249cdf0e10cSrcweir     }
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     mnWidth        = nNewWidth;
252cdf0e10cSrcweir     mnHeight       = nNewHeight;
253cdf0e10cSrcweir     mnScanlineSize = nNewScanlineSize;
254cdf0e10cSrcweir 
255cdf0e10cSrcweir     if( nBufSize < mnAllocated )
256cdf0e10cSrcweir     {
257cdf0e10cSrcweir         memcpy( mpBits, pBuf, nBufSize );
258cdf0e10cSrcweir         delete[] pBuf;
259cdf0e10cSrcweir     }
260cdf0e10cSrcweir     else
261cdf0e10cSrcweir     {
262cdf0e10cSrcweir         delete[] mpBits;
263cdf0e10cSrcweir         mpBits = pBuf;
264cdf0e10cSrcweir         mnAllocated = nBufSize;
265cdf0e10cSrcweir     }
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     return true;
268cdf0e10cSrcweir }
269cdf0e10cSrcweir 
270cdf0e10cSrcweir //------------------------------------------------------------------------
271