Update ooo320-m1
[ooovba.git] / goodies / source / filter.vcl / icgm / bitmap.cxx
blob6d58c15b193d600309c2b2fd5fef0ac78ebbafdb
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: bitmap.cxx,v $
10 * $Revision: 1.6 $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include "main.hxx"
36 // ---------------------------------------------------------------
38 CGMBitmap::CGMBitmap( CGM& rCGM ) :
39 mpCGM ( &rCGM ),
40 pCGMBitmapDescriptor ( new CGMBitmapDescriptor )
42 ImplGetBitmap( *pCGMBitmapDescriptor );
45 // ---------------------------------------------------------------
47 CGMBitmap::~CGMBitmap()
49 delete pCGMBitmapDescriptor;
52 // ---------------------------------------------------------------
54 void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc )
56 rDesc.mbStatus = sal_True;
57 long nx, ny, nxC, nxCount, nyCount;
59 if ( ImplGetDimensions( rDesc ) && rDesc.mpBuf )
61 if ( ( rDesc.mpBitmap = new Bitmap( Size( rDesc.mnX, rDesc.mnY ), (sal_uInt16)rDesc.mnDstBitsPerPixel ) ) != NULL )
63 if ( ( rDesc.mpAcc = rDesc.mpBitmap->AcquireWriteAccess() ) != NULL )
66 // the picture may either be read from left to right or right to left, from top to bottom ...
68 nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing
69 nyCount = rDesc.mnY + 1;
71 switch ( rDesc.mnDstBitsPerPixel )
73 case 1 :
75 if ( rDesc.mnLocalColorPrecision == 1 )
76 ImplSetCurrentPalette( rDesc );
77 else
79 rDesc.mpAcc->SetPaletteEntryCount( 2 );
80 rDesc.mpAcc->SetPaletteColor( 0, BMCOL( mpCGM->pElement->nBackGroundColor ) );
81 rDesc.mpAcc->SetPaletteColor( 1,
82 ( mpCGM->pElement->nAspectSourceFlags & ASF_FILLINTERIORSTYLE )
83 ? BMCOL( mpCGM->pElement->pFillBundle->GetColor() )
84 : BMCOL( mpCGM->pElement->aFillBundle.GetColor() ) ) ;
86 for ( ny = 0; --nyCount ; ny++, rDesc.mpBuf += rDesc.mnScanSize )
88 nxC = nxCount;
89 for ( nx = 0; --nxC; nx++ )
90 { // this is not fast, but a one bit/pixel format is rarely used
91 rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( (*( rDesc.mpBuf + ( nx >> 3 ) ) >> ( ( nx & 7 ) ^ 7 ) ) ) & 1 );
95 break;
97 case 2 :
99 ImplSetCurrentPalette( rDesc );
100 for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
102 nxC = nxCount;
103 for ( nx = 0; --nxC; nx++ )
104 { // this is not fast, but a two bits/pixel format is rarely used
105 rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( (*( rDesc.mpBuf + ( nx >> 2 ) ) >> ( ( ( nx & 3 ) ^ 3 ) << 1 ) ) ) & 3 );
109 break;
111 case 4 :
113 ImplSetCurrentPalette( rDesc );
114 for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
116 nxC = nxCount;
117 sal_Int8 nDat;
118 sal_uInt8* pTemp = rDesc.mpBuf;
119 for ( nx = 0; --nxC; nx++ )
121 nDat = *pTemp++;
122 rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( nDat >> 4 ) );
123 if ( --nxC )
125 nx ++;
126 rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( nDat & 15 ) );
128 else
129 break;
133 break;
135 case 8 :
137 ImplSetCurrentPalette( rDesc );
138 for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
140 sal_uInt8* pTemp = rDesc.mpBuf;
141 nxC = nxCount;
142 for ( nx = 0; --nxC; nx++ )
144 rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( *pTemp++ ) );
148 break;
150 case 24 :
153 BitmapColor aBitmapColor;
154 for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
156 sal_uInt8* pTemp = rDesc.mpBuf;
157 nxC = nxCount;
158 for ( nx = 0; --nxC; nx++ )
160 aBitmapColor.SetRed( (sal_Int8)*pTemp++ );
161 aBitmapColor.SetGreen( (sal_Int8)*pTemp++ );
162 aBitmapColor.SetBlue( (sal_Int8)*pTemp++ );
163 rDesc.mpAcc->SetPixel( ny, nx, aBitmapColor );
168 break;
170 double nX = rDesc.mnR.X - rDesc.mnQ.X;
171 double nY = rDesc.mnR.Y - rDesc.mnQ.Y;
173 rDesc.mndy = sqrt( nX * nX + nY * nY );
175 nX = rDesc.mnR.X - rDesc.mnP.X;
176 nY = rDesc.mnR.Y - rDesc.mnP.Y;
178 rDesc.mndx = sqrt( nX * nX + nY * nY );
180 nX = rDesc.mnR.X - rDesc.mnP.X;
181 nY = rDesc.mnR.Y - rDesc.mnP.Y;
183 rDesc.mnOrientation = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
184 if ( nY > 0 )
185 rDesc.mnOrientation = 360 - rDesc.mnOrientation;
187 nX = rDesc.mnQ.X - rDesc.mnR.X;
188 nY = rDesc.mnQ.Y - rDesc.mnR.Y;
190 double fAngle = 0.01745329251994 * ( 360 - rDesc.mnOrientation );
191 double fSin = sin(fAngle);
192 double fCos = cos(fAngle);
193 nX = fCos * nX + fSin * nY;
194 nY = -( fSin * nX - fCos * nY );
196 fAngle = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
197 if ( nY > 0 )
198 fAngle = 360 - fAngle;
200 if ( fAngle > 180 ) // wird das bild nach oben oder unten aufgebaut ?
202 rDesc.mnOrigin = rDesc.mnP;
204 else
206 rDesc.mbVMirror = sal_True;
207 rDesc.mnOrigin = rDesc.mnP;
208 rDesc.mnOrigin.X += rDesc.mnQ.X - rDesc.mnR.X;
209 rDesc.mnOrigin.Y += rDesc.mnQ.Y - rDesc.mnR.Y;
212 else
213 rDesc.mbStatus = sal_False;
215 else
216 rDesc.mbStatus = sal_False;
218 else
219 rDesc.mbStatus = sal_False;
221 if ( rDesc.mpAcc )
223 rDesc.mpBitmap->ReleaseAccess( rDesc.mpAcc );
224 rDesc.mpAcc = NULL;
226 if ( rDesc.mbStatus == sal_False )
228 if ( rDesc.mpBitmap )
230 delete rDesc.mpBitmap;
231 rDesc.mpBitmap = NULL;
236 // ---------------------------------------------------------------
238 void CGMBitmap::ImplSetCurrentPalette( CGMBitmapDescriptor& rDesc )
240 sal_uInt16 nColors = sal::static_int_cast< sal_uInt16 >(
241 1 << rDesc.mnDstBitsPerPixel);
242 rDesc.mpAcc->SetPaletteEntryCount( nColors );
243 for ( sal_uInt16 i = 0; i < nColors; i++ )
245 rDesc.mpAcc->SetPaletteColor( i, BMCOL( mpCGM->pElement->aLatestColorTable[ i ] ) );
249 // ---------------------------------------------------------------
251 sal_Bool CGMBitmap::ImplGetDimensions( CGMBitmapDescriptor& rDesc )
253 mpCGM->ImplGetPoint( rDesc.mnP ); // parallelogram p < - > r
254 mpCGM->ImplGetPoint( rDesc.mnQ ); // |
255 mpCGM->ImplGetPoint( rDesc.mnR ); // q
256 sal_uInt32 nPrecision = mpCGM->pElement->nIntegerPrecision;
257 rDesc.mnX = mpCGM->ImplGetUI( nPrecision );
258 rDesc.mnY = mpCGM->ImplGetUI( nPrecision );
259 rDesc.mnLocalColorPrecision = mpCGM->ImplGetI( nPrecision );
260 rDesc.mnScanSize = 0;
261 switch( rDesc.mnLocalColorPrecision )
263 case 0x80000001 : // monochrome ( bit = 0->backgroundcolor )
264 case 0 : // bit = 1->fillcolor
265 rDesc.mnDstBitsPerPixel = 1;
266 break;
267 case 1 : // 2 color indexed ( monochrome )
268 case -1 :
269 rDesc.mnDstBitsPerPixel = 1;
270 break;
271 case 2 : // 4 color indexed
272 case -2 :
273 rDesc.mnDstBitsPerPixel = 2;
274 break;
275 case 4 : // 16 color indexed
276 case -4 :
277 rDesc.mnDstBitsPerPixel = 4;
278 break;
279 case 8 : // 256 color indexed
280 case -8 :
281 rDesc.mnDstBitsPerPixel = 8;
282 rDesc.mnScanSize = rDesc.mnX;
283 break;
284 case 16 : // NS
285 case -16 :
286 rDesc.mbStatus = sal_False;
287 break;
288 case 24 : // 24 bit directColor ( 8 bits each component )
289 case -24 :
290 rDesc.mnDstBitsPerPixel = 24;
291 break;
292 case 32 : // NS
293 case -32 :
294 rDesc.mbStatus = sal_False;
295 break;
298 // mnCompressionMode == 0 : CCOMP_RUNLENGTH
299 // == 1 : CCOMP_PACKED ( no compression. each row starts on a 4 byte boundary )
300 if ( ( rDesc.mnCompressionMode = mpCGM->ImplGetUI16() ) != 1 )
301 rDesc.mbStatus = sal_False;
303 if ( ( rDesc.mnX || rDesc.mnY ) == 0 )
304 rDesc.mbStatus = sal_False;
306 sal_uInt32 nHeaderSize = 2 + 3 * nPrecision + 3 * mpCGM->ImplGetPointSize();
307 rDesc.mnScanSize = ( ( rDesc.mnX * rDesc.mnDstBitsPerPixel + 7 ) >> 3 );
309 sal_uInt32 nScanSize;
310 nScanSize = rDesc.mnScanSize;
311 if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // try a scansize without dw alignment
313 nScanSize = ( rDesc.mnScanSize + 1 ) & ~1;
314 if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // then we'll try word alignment
316 nScanSize = ( rDesc.mnScanSize + 3 ) & ~3;
317 if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // and last we'll try dword alignment
319 nScanSize = ( rDesc.mnScanSize + 1 ) & ~1; // and LAST BUT NOT LEAST we'll try word alignment without aligning the last line
320 if ( ( nScanSize * ( rDesc.mnY - 1 ) + rDesc.mnScanSize + nHeaderSize ) != mpCGM->mnElementSize )
322 nScanSize = ( rDesc.mnScanSize + 3 ) & ~3;
323 if ( ( nScanSize * ( rDesc.mnY - 1 ) + rDesc.mnScanSize + nHeaderSize ) != mpCGM->mnElementSize )
325 mpCGM->mnParaSize = 0; // this format is corrupt
326 rDesc.mbStatus = sal_False;
332 rDesc.mnScanSize = nScanSize;
333 if ( rDesc.mbStatus )
335 rDesc.mpBuf = mpCGM->mpSource + mpCGM->mnParaSize; // mpBuf now points to the first scanline
336 mpCGM->mnParaSize += rDesc.mnScanSize * rDesc.mnY;
338 return rDesc.mbStatus;
341 // ---------------------------------------------------------------
343 void CGMBitmap::ImplInsert( CGMBitmapDescriptor& rSource, CGMBitmapDescriptor& rDest )
345 if ( ( rSource.mnR.Y == rDest.mnQ.Y ) && ( rSource.mnR.X == rDest.mnQ.X ) )
346 { // Insert on Bottom
347 if ( mpCGM->mnVDCYmul == -1 )
348 rDest.mnOrigin = rSource.mnOrigin; // neuer origin
349 rDest.mpBitmap->Expand( 0, rSource.mnY );
350 rDest.mpBitmap->CopyPixel( Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
351 Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap );
352 FloatPoint aFloatPoint;
353 aFloatPoint.X = rSource.mnQ.X - rSource.mnR.X;
354 aFloatPoint.Y = rSource.mnQ.Y - rSource.mnR.Y;
355 rDest.mnQ.X += aFloatPoint.X;
356 rDest.mnQ.Y += aFloatPoint.Y;
357 rDest.mnP = rSource.mnP;
358 rDest.mnR = rSource.mnR;
360 else
361 { // Insert on Top
362 if ( mpCGM->mnVDCYmul == 1 )
363 rDest.mnOrigin = rSource.mnOrigin; // neuer origin
364 rDest.mpBitmap->Expand( 0, rSource.mnY );
365 rDest.mpBitmap->CopyPixel( Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
366 Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap );
367 rDest.mnP = rSource.mnP;
368 rDest.mnR = rSource.mnR;
370 rDest.mnY += rSource.mnY;
371 rDest.mndy += rSource.mndy;
374 // ---------------------------------------------------------------
376 CGMBitmap* CGMBitmap::GetNext()
378 if ( pCGMBitmapDescriptor->mpBitmap && pCGMBitmapDescriptor->mbStatus )
380 CGMBitmap* pCGMTempBitmap = new CGMBitmap( *mpCGM );
381 if ( pCGMTempBitmap )
383 if ( ( (long)pCGMTempBitmap->pCGMBitmapDescriptor->mnOrientation == (long)pCGMBitmapDescriptor->mnOrientation ) &&
384 ( ( ( pCGMTempBitmap->pCGMBitmapDescriptor->mnR.X == pCGMBitmapDescriptor->mnQ.X ) &&
385 ( pCGMTempBitmap->pCGMBitmapDescriptor->mnR.Y == pCGMBitmapDescriptor->mnQ.Y ) ) ||
386 ( ( pCGMTempBitmap->pCGMBitmapDescriptor->mnQ.X == pCGMBitmapDescriptor->mnR.X ) &&
387 ( pCGMTempBitmap->pCGMBitmapDescriptor->mnQ.Y == pCGMBitmapDescriptor->mnR.Y ) ) ) )
389 ImplInsert( *(pCGMTempBitmap->pCGMBitmapDescriptor), *(pCGMBitmapDescriptor) );
390 delete pCGMTempBitmap;
391 return NULL;
393 else // we'll replace the pointers and return the old one
395 CGMBitmapDescriptor* pTempBD = pCGMBitmapDescriptor;
396 pCGMBitmapDescriptor = pCGMTempBitmap->pCGMBitmapDescriptor;
397 pCGMTempBitmap->pCGMBitmapDescriptor = pTempBD;
398 return pCGMTempBitmap;
401 return NULL;
403 else
404 return NULL;
407 // ---------------------------------------------------------------
409 CGMBitmapDescriptor* CGMBitmap::GetBitmap()
411 return pCGMBitmapDescriptor;