Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "main.hxx"
31 : :
32 : : // ---------------------------------------------------------------
33 : :
34 : 0 : CGMBitmap::CGMBitmap( CGM& rCGM ) :
35 : : mpCGM ( &rCGM ),
36 : 0 : pCGMBitmapDescriptor ( new CGMBitmapDescriptor )
37 : : {
38 : 0 : ImplGetBitmap( *pCGMBitmapDescriptor );
39 : 0 : };
40 : :
41 : : // ---------------------------------------------------------------
42 : :
43 : 0 : CGMBitmap::~CGMBitmap()
44 : : {
45 : 0 : delete pCGMBitmapDescriptor;
46 : 0 : }
47 : :
48 : : // ---------------------------------------------------------------
49 : :
50 : 0 : void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc )
51 : : {
52 : 0 : rDesc.mbStatus = sal_True;
53 : :
54 : 0 : if ( ImplGetDimensions( rDesc ) && rDesc.mpBuf )
55 : : {
56 : 0 : if ( ( rDesc.mpBitmap = new Bitmap( Size( rDesc.mnX, rDesc.mnY ), (sal_uInt16)rDesc.mnDstBitsPerPixel ) ) != NULL )
57 : : {
58 : 0 : if ( ( rDesc.mpAcc = rDesc.mpBitmap->AcquireWriteAccess() ) != NULL )
59 : : {
60 : :
61 : : // the picture may either be read from left to right or right to left, from top to bottom ...
62 : :
63 : 0 : long nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing
64 : 0 : long nyCount = rDesc.mnY + 1;
65 : : long nx, ny, nxC;
66 : :
67 : 0 : switch ( rDesc.mnDstBitsPerPixel )
68 : : {
69 : : case 1 :
70 : : {
71 : 0 : if ( rDesc.mnLocalColorPrecision == 1 )
72 : 0 : ImplSetCurrentPalette( rDesc );
73 : : else
74 : : {
75 : 0 : rDesc.mpAcc->SetPaletteEntryCount( 2 );
76 : 0 : rDesc.mpAcc->SetPaletteColor( 0, BMCOL( mpCGM->pElement->nBackGroundColor ) );
77 : : rDesc.mpAcc->SetPaletteColor( 1,
78 : : ( mpCGM->pElement->nAspectSourceFlags & ASF_FILLINTERIORSTYLE )
79 : 0 : ? BMCOL( mpCGM->pElement->pFillBundle->GetColor() )
80 : 0 : : BMCOL( mpCGM->pElement->aFillBundle.GetColor() ) ) ;
81 : : }
82 : 0 : for ( ny = 0; --nyCount ; ny++, rDesc.mpBuf += rDesc.mnScanSize )
83 : : {
84 : 0 : nxC = nxCount;
85 : 0 : for ( nx = 0; --nxC; nx++ )
86 : : { // this is not fast, but a one bit/pixel format is rarely used
87 : 0 : rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( (*( rDesc.mpBuf + ( nx >> 3 ) ) >> ( ( nx & 7 ) ^ 7 ) ) ) & 1 );
88 : : }
89 : : }
90 : : }
91 : 0 : break;
92 : :
93 : : case 2 :
94 : : {
95 : 0 : ImplSetCurrentPalette( rDesc );
96 : 0 : for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
97 : : {
98 : 0 : nxC = nxCount;
99 : 0 : for ( nx = 0; --nxC; nx++ )
100 : : { // this is not fast, but a two bits/pixel format is rarely used
101 : 0 : rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( (*( rDesc.mpBuf + ( nx >> 2 ) ) >> ( ( ( nx & 3 ) ^ 3 ) << 1 ) ) ) & 3 );
102 : : }
103 : : }
104 : : }
105 : 0 : break;
106 : :
107 : : case 4 :
108 : : {
109 : 0 : ImplSetCurrentPalette( rDesc );
110 : 0 : for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
111 : : {
112 : 0 : nxC = nxCount;
113 : : sal_Int8 nDat;
114 : 0 : sal_uInt8* pTemp = rDesc.mpBuf;
115 : 0 : for ( nx = 0; --nxC; nx++ )
116 : : {
117 : 0 : nDat = *pTemp++;
118 : 0 : rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( nDat >> 4 ) );
119 : 0 : if ( --nxC )
120 : : {
121 : 0 : nx ++;
122 : 0 : rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( nDat & 15 ) );
123 : : }
124 : : else
125 : 0 : break;
126 : : }
127 : : }
128 : : }
129 : 0 : break;
130 : :
131 : : case 8 :
132 : : {
133 : 0 : ImplSetCurrentPalette( rDesc );
134 : 0 : for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
135 : : {
136 : 0 : sal_uInt8* pTemp = rDesc.mpBuf;
137 : 0 : nxC = nxCount;
138 : 0 : for ( nx = 0; --nxC; nx++ )
139 : : {
140 : 0 : rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( *pTemp++ ) );
141 : : }
142 : : }
143 : : }
144 : 0 : break;
145 : :
146 : : case 24 :
147 : : {
148 : : {
149 : 0 : BitmapColor aBitmapColor;
150 : 0 : for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
151 : : {
152 : 0 : sal_uInt8* pTemp = rDesc.mpBuf;
153 : 0 : nxC = nxCount;
154 : 0 : for ( nx = 0; --nxC; nx++ )
155 : : {
156 : 0 : aBitmapColor.SetRed( (sal_Int8)*pTemp++ );
157 : 0 : aBitmapColor.SetGreen( (sal_Int8)*pTemp++ );
158 : 0 : aBitmapColor.SetBlue( (sal_Int8)*pTemp++ );
159 : 0 : rDesc.mpAcc->SetPixel( ny, nx, aBitmapColor );
160 : : }
161 : 0 : }
162 : : }
163 : : }
164 : 0 : break;
165 : : };
166 : 0 : double nX = rDesc.mnR.X - rDesc.mnQ.X;
167 : 0 : double nY = rDesc.mnR.Y - rDesc.mnQ.Y;
168 : :
169 : 0 : rDesc.mndy = sqrt( nX * nX + nY * nY );
170 : :
171 : 0 : nX = rDesc.mnR.X - rDesc.mnP.X;
172 : 0 : nY = rDesc.mnR.Y - rDesc.mnP.Y;
173 : :
174 : 0 : rDesc.mndx = sqrt( nX * nX + nY * nY );
175 : :
176 : 0 : nX = rDesc.mnR.X - rDesc.mnP.X;
177 : 0 : nY = rDesc.mnR.Y - rDesc.mnP.Y;
178 : :
179 : 0 : rDesc.mnOrientation = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
180 : 0 : if ( nY > 0 )
181 : 0 : rDesc.mnOrientation = 360 - rDesc.mnOrientation;
182 : :
183 : 0 : nX = rDesc.mnQ.X - rDesc.mnR.X;
184 : 0 : nY = rDesc.mnQ.Y - rDesc.mnR.Y;
185 : :
186 : 0 : double fAngle = 0.01745329251994 * ( 360 - rDesc.mnOrientation );
187 : 0 : double fSin = sin(fAngle);
188 : 0 : double fCos = cos(fAngle);
189 : 0 : nX = fCos * nX + fSin * nY;
190 : 0 : nY = -( fSin * nX - fCos * nY );
191 : :
192 : 0 : fAngle = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
193 : 0 : if ( nY > 0 )
194 : 0 : fAngle = 360 - fAngle;
195 : :
196 : 0 : if ( fAngle > 180 ) // wird das bild nach oben oder unten aufgebaut ?
197 : : {
198 : 0 : rDesc.mnOrigin = rDesc.mnP;
199 : : }
200 : : else
201 : : {
202 : 0 : rDesc.mbVMirror = sal_True;
203 : 0 : rDesc.mnOrigin = rDesc.mnP;
204 : 0 : rDesc.mnOrigin.X += rDesc.mnQ.X - rDesc.mnR.X;
205 : 0 : rDesc.mnOrigin.Y += rDesc.mnQ.Y - rDesc.mnR.Y;
206 : : }
207 : : }
208 : : else
209 : 0 : rDesc.mbStatus = sal_False;
210 : : }
211 : : else
212 : 0 : rDesc.mbStatus = sal_False;
213 : : }
214 : : else
215 : 0 : rDesc.mbStatus = sal_False;
216 : :
217 : 0 : if ( rDesc.mpAcc )
218 : : {
219 : 0 : rDesc.mpBitmap->ReleaseAccess( rDesc.mpAcc );
220 : 0 : rDesc.mpAcc = NULL;
221 : : }
222 : 0 : if ( rDesc.mbStatus == sal_False )
223 : : {
224 : 0 : if ( rDesc.mpBitmap )
225 : : {
226 : 0 : delete rDesc.mpBitmap;
227 : 0 : rDesc.mpBitmap = NULL;
228 : : }
229 : : }
230 : 0 : }
231 : :
232 : : // ---------------------------------------------------------------
233 : :
234 : 0 : void CGMBitmap::ImplSetCurrentPalette( CGMBitmapDescriptor& rDesc )
235 : : {
236 : : sal_uInt16 nColors = sal::static_int_cast< sal_uInt16 >(
237 : 0 : 1 << rDesc.mnDstBitsPerPixel);
238 : 0 : rDesc.mpAcc->SetPaletteEntryCount( nColors );
239 : 0 : for ( sal_uInt16 i = 0; i < nColors; i++ )
240 : : {
241 : 0 : rDesc.mpAcc->SetPaletteColor( i, BMCOL( mpCGM->pElement->aLatestColorTable[ i ] ) );
242 : : }
243 : 0 : }
244 : :
245 : : // ---------------------------------------------------------------
246 : :
247 : 0 : sal_Bool CGMBitmap::ImplGetDimensions( CGMBitmapDescriptor& rDesc )
248 : : {
249 : 0 : mpCGM->ImplGetPoint( rDesc.mnP ); // parallelogram p < - > r
250 : 0 : mpCGM->ImplGetPoint( rDesc.mnQ ); // |
251 : 0 : mpCGM->ImplGetPoint( rDesc.mnR ); // q
252 : 0 : sal_uInt32 nPrecision = mpCGM->pElement->nIntegerPrecision;
253 : 0 : rDesc.mnX = mpCGM->ImplGetUI( nPrecision );
254 : 0 : rDesc.mnY = mpCGM->ImplGetUI( nPrecision );
255 : 0 : rDesc.mnLocalColorPrecision = mpCGM->ImplGetI( nPrecision );
256 : 0 : rDesc.mnScanSize = 0;
257 : 0 : switch( rDesc.mnLocalColorPrecision )
258 : : {
259 : : case long(0x80000001) : // monochrome ( bit = 0->backgroundcolor )
260 : : case 0 : // bit = 1->fillcolor
261 : 0 : rDesc.mnDstBitsPerPixel = 1;
262 : 0 : break;
263 : : case 1 : // 2 color indexed ( monochrome )
264 : : case -1 :
265 : 0 : rDesc.mnDstBitsPerPixel = 1;
266 : 0 : break;
267 : : case 2 : // 4 color indexed
268 : : case -2 :
269 : 0 : rDesc.mnDstBitsPerPixel = 2;
270 : 0 : break;
271 : : case 4 : // 16 color indexed
272 : : case -4 :
273 : 0 : rDesc.mnDstBitsPerPixel = 4;
274 : 0 : break;
275 : : case 8 : // 256 color indexed
276 : : case -8 :
277 : 0 : rDesc.mnDstBitsPerPixel = 8;
278 : 0 : rDesc.mnScanSize = rDesc.mnX;
279 : 0 : break;
280 : : case 16 : // NS
281 : : case -16 :
282 : 0 : rDesc.mbStatus = sal_False;
283 : 0 : break;
284 : : case 24 : // 24 bit directColor ( 8 bits each component )
285 : : case -24 :
286 : 0 : rDesc.mnDstBitsPerPixel = 24;
287 : 0 : break;
288 : : case 32 : // NS
289 : : case -32 :
290 : 0 : rDesc.mbStatus = sal_False;
291 : 0 : break;
292 : :
293 : : }
294 : : // mnCompressionMode == 0 : CCOMP_RUNLENGTH
295 : : // == 1 : CCOMP_PACKED ( no compression. each row starts on a 4 byte boundary )
296 : 0 : if ( ( rDesc.mnCompressionMode = mpCGM->ImplGetUI16() ) != 1 )
297 : 0 : rDesc.mbStatus = sal_False;
298 : :
299 : 0 : if ( ( rDesc.mnX || rDesc.mnY ) == 0 )
300 : 0 : rDesc.mbStatus = sal_False;
301 : :
302 : 0 : sal_uInt32 nHeaderSize = 2 + 3 * nPrecision + 3 * mpCGM->ImplGetPointSize();
303 : 0 : rDesc.mnScanSize = ( ( rDesc.mnX * rDesc.mnDstBitsPerPixel + 7 ) >> 3 );
304 : :
305 : : sal_uInt32 nScanSize;
306 : 0 : nScanSize = rDesc.mnScanSize;
307 : 0 : if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // try a scansize without dw alignment
308 : : {
309 : 0 : nScanSize = ( rDesc.mnScanSize + 1 ) & ~1;
310 : 0 : if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // then we'll try word alignment
311 : : {
312 : 0 : nScanSize = ( rDesc.mnScanSize + 3 ) & ~3;
313 : 0 : if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // and last we'll try dword alignment
314 : : {
315 : 0 : nScanSize = ( rDesc.mnScanSize + 1 ) & ~1; // and LAST BUT NOT LEAST we'll try word alignment without aligning the last line
316 : 0 : if ( ( nScanSize * ( rDesc.mnY - 1 ) + rDesc.mnScanSize + nHeaderSize ) != mpCGM->mnElementSize )
317 : : {
318 : 0 : nScanSize = ( rDesc.mnScanSize + 3 ) & ~3;
319 : 0 : if ( ( nScanSize * ( rDesc.mnY - 1 ) + rDesc.mnScanSize + nHeaderSize ) != mpCGM->mnElementSize )
320 : : {
321 : 0 : mpCGM->mnParaSize = 0; // this format is corrupt
322 : 0 : rDesc.mbStatus = sal_False;
323 : : }
324 : : }
325 : : }
326 : : }
327 : : }
328 : 0 : rDesc.mnScanSize = nScanSize;
329 : 0 : if ( rDesc.mbStatus )
330 : : {
331 : 0 : rDesc.mpBuf = mpCGM->mpSource + mpCGM->mnParaSize; // mpBuf now points to the first scanline
332 : 0 : mpCGM->mnParaSize += rDesc.mnScanSize * rDesc.mnY;
333 : : }
334 : 0 : return rDesc.mbStatus;
335 : : }
336 : :
337 : : // ---------------------------------------------------------------
338 : :
339 : 0 : void CGMBitmap::ImplInsert( CGMBitmapDescriptor& rSource, CGMBitmapDescriptor& rDest )
340 : : {
341 : 0 : if ( ( rSource.mnR.Y == rDest.mnQ.Y ) && ( rSource.mnR.X == rDest.mnQ.X ) )
342 : : { // Insert on Bottom
343 : 0 : if ( mpCGM->mnVDCYmul == -1 )
344 : 0 : rDest.mnOrigin = rSource.mnOrigin; // neuer origin
345 : 0 : rDest.mpBitmap->Expand( 0, rSource.mnY );
346 : : rDest.mpBitmap->CopyPixel( Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
347 : 0 : Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap );
348 : 0 : FloatPoint aFloatPoint;
349 : 0 : aFloatPoint.X = rSource.mnQ.X - rSource.mnR.X;
350 : 0 : aFloatPoint.Y = rSource.mnQ.Y - rSource.mnR.Y;
351 : 0 : rDest.mnQ.X += aFloatPoint.X;
352 : 0 : rDest.mnQ.Y += aFloatPoint.Y;
353 : 0 : rDest.mnP = rSource.mnP;
354 : 0 : rDest.mnR = rSource.mnR;
355 : : }
356 : : else
357 : : { // Insert on Top
358 : 0 : if ( mpCGM->mnVDCYmul == 1 )
359 : 0 : rDest.mnOrigin = rSource.mnOrigin; // neuer origin
360 : 0 : rDest.mpBitmap->Expand( 0, rSource.mnY );
361 : : rDest.mpBitmap->CopyPixel( Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
362 : 0 : Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap );
363 : 0 : rDest.mnP = rSource.mnP;
364 : 0 : rDest.mnR = rSource.mnR;
365 : : }
366 : 0 : rDest.mnY += rSource.mnY;
367 : 0 : rDest.mndy += rSource.mndy;
368 : 0 : };
369 : :
370 : : // ---------------------------------------------------------------
371 : :
372 : 0 : CGMBitmap* CGMBitmap::GetNext()
373 : : {
374 : 0 : if ( pCGMBitmapDescriptor->mpBitmap && pCGMBitmapDescriptor->mbStatus )
375 : : {
376 : 0 : CGMBitmap* pCGMTempBitmap = new CGMBitmap( *mpCGM );
377 : 0 : if ( pCGMTempBitmap )
378 : : {
379 : 0 : if ( ( (long)pCGMTempBitmap->pCGMBitmapDescriptor->mnOrientation == (long)pCGMBitmapDescriptor->mnOrientation ) &&
380 : : ( ( ( pCGMTempBitmap->pCGMBitmapDescriptor->mnR.X == pCGMBitmapDescriptor->mnQ.X ) &&
381 : : ( pCGMTempBitmap->pCGMBitmapDescriptor->mnR.Y == pCGMBitmapDescriptor->mnQ.Y ) ) ||
382 : : ( ( pCGMTempBitmap->pCGMBitmapDescriptor->mnQ.X == pCGMBitmapDescriptor->mnR.X ) &&
383 : : ( pCGMTempBitmap->pCGMBitmapDescriptor->mnQ.Y == pCGMBitmapDescriptor->mnR.Y ) ) ) )
384 : : {
385 : 0 : ImplInsert( *(pCGMTempBitmap->pCGMBitmapDescriptor), *(pCGMBitmapDescriptor) );
386 : 0 : delete pCGMTempBitmap;
387 : 0 : return NULL;
388 : : }
389 : : else // we'll replace the pointers and return the old one
390 : : {
391 : 0 : CGMBitmapDescriptor* pTempBD = pCGMBitmapDescriptor;
392 : 0 : pCGMBitmapDescriptor = pCGMTempBitmap->pCGMBitmapDescriptor;
393 : 0 : pCGMTempBitmap->pCGMBitmapDescriptor = pTempBD;
394 : 0 : return pCGMTempBitmap;
395 : : }
396 : : }
397 : 0 : return NULL;
398 : : }
399 : : else
400 : 0 : return NULL;
401 : : }
402 : :
403 : : // ---------------------------------------------------------------
404 : :
405 : 0 : CGMBitmapDescriptor* CGMBitmap::GetBitmap()
406 : : {
407 : 0 : return pCGMBitmapDescriptor;
408 : : }
409 : :
410 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|