1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26 #include <com/sun/star/task/XStatusIndicator.hpp>
27 #include <unotools/ucbstreamhelper.hxx>
28 
29 #define CGM_BREAK_ACTION	0xffffffff
30 #include <osl/endian.h>
31 #include <vcl/virdev.hxx>
32 #include <vcl/graph.hxx>
33 #include <tools/stream.hxx>
34 #include <chart.hxx>
35 #include <main.hxx>
36 #include <elements.hxx>
37 #include <outact.hxx>
38 
39 using namespace ::com::sun::star;
40 
41 // ---------------------------------------------------------------
42 
ImplCGMInit()43 void CGM::ImplCGMInit()
44 {
45 	mbIsFinished = mbPicture = mbMetaFile = mbPictureBody = sal_False;
46 
47 	mnActCount = 0;
48 	mnOutdx = 28000;
49 	mnOutdy = 21000;
50 
51 	mpBuf = NULL;
52 	mpChart = NULL;
53 	mpBitmapInUse = NULL;
54 
55 	pCopyOfE = new CGMElements( *this );
56 	pElement = new CGMElements( *this );
57 }
58 
59 // ---------------------------------------------------------------
60 
61 #ifdef CGM_EXPORT_IMPRESS
62 
CGM(sal_uInt32 nMode,uno::Reference<frame::XModel> & rModel)63 CGM::CGM( sal_uInt32 nMode, uno::Reference< frame::XModel > & rModel )	:
64 	mpGraphic				( NULL ),
65 	mpCommentOut			( NULL ),
66 	mbStatus				( sal_True ),
67 	mpOutAct				( new CGMImpressOutAct( *this, rModel ) ),
68 	mnMode					( nMode )
69 {
70 	mnMode |= CGM_EXPORT_IMPRESS;
71 	ImplCGMInit();
72 }
73 #endif
74 
75 // ---------------------------------------------------------------
76 
ImplComment(sal_uInt32 Level,const char * Description)77 void CGM::ImplComment( sal_uInt32 Level, const char* Description )
78 {
79 	if ( mpCommentOut )
80 	{
81 		if ( Level == CGM_DESCRIPTION )
82 		{
83 			*mpCommentOut << "                                  " << Description << "\n";
84 		}
85 		else
86 		{
87 			sal_Int8 nFirst, nSecond, i, nCount = 0;
88 			if ( mnActCount < 10000 )
89 				nCount++;
90 			if ( mnActCount < 1000 )
91 				nCount++;
92 			if ( mnActCount < 100 )
93 				nCount++;
94 			if ( mnActCount < 10 )
95 				nCount++;
96 			for ( i = 0; i <= nCount; i++ )
97 				*mpCommentOut << " ";
98 			mpCommentOut->WriteNumber( mnActCount );
99 
100 			switch( Level & 0xff )
101 			{
102 				case CGM_UNKNOWN_LEVEL :
103 					*mpCommentOut << " L?";
104 				break;
105 				case CGM_UNKNOWN_COMMAND :
106 					*mpCommentOut << " UNKNOWN COMMAND";
107 				break;
108 				case CGM_GDSF_ONLY :
109 					*mpCommentOut << " LI";
110 				break;
111 				default:
112 					*mpCommentOut << " L";
113 					mpCommentOut->WriteNumber( Level & 0xff );
114 				break;
115 			}
116 			*mpCommentOut << " C";
117 			mpCommentOut->WriteNumber( mnElementClass );
118 			*mpCommentOut << " ID-0x";
119 			nFirst = ( mnElementID  > 0x9F ) ? (sal_Int8)( mnElementID >> 4 ) + 'A' - 10: (sal_Int8)( mnElementID >> 4 ) + '0';
120 			nSecond = ( ( mnElementID & 15 ) > 9 ) ? (sal_Int8)( mnElementID & 15 ) + 'A' - 10 : (sal_Int8)( mnElementID & 15 ) + '0';
121 			*mpCommentOut << nFirst << nSecond;
122 			 *mpCommentOut << " Size";
123 			nCount = 1;
124 			if ( mnElementSize < 1000000 )
125 				nCount++;
126 			if ( mnElementSize < 100000 )
127 				nCount++;
128 			if ( mnElementSize < 10000 )
129 				nCount++;
130 			if ( mnElementSize < 1000 )
131 				nCount++;
132 			if ( mnElementSize < 100 )
133 				nCount++;
134 			if ( mnElementSize < 10 )
135 				nCount++;
136 			for ( i = 0; i < nCount; i++ )
137 				*mpCommentOut << " ";
138 			mpCommentOut->WriteNumber( mnElementSize );
139 			*mpCommentOut << " " << Description << "\n";
140 		}
141 	}
142 }
143 
144 // ---------------------------------------------------------------
145 
~CGM()146 CGM::~CGM()
147 {
148 
149 #ifdef CGM_EXPORT_META
150 	if ( mpGraphic )
151 	{
152 		mpGDIMetaFile->Stop();
153 		mpGDIMetaFile->SetPrefMapMode( MapMode() );
154 		mpGDIMetaFile->SetPrefSize( Size( static_cast< long >( mnOutdx ), static_cast< long >( mnOutdy ) ) );
155 		delete mpVirDev;
156 		*mpGraphic = Graphic( *mpGDIMetaFile );
157 	}
158 #endif
159 	sal_Int8* pBuf = (sal_Int8*)maDefRepList.First();
160 	while( pBuf )
161 	{
162 		delete pBuf;
163 		pBuf = (sal_Int8*)maDefRepList.Next();
164 	}
165 	maDefRepList.Clear();
166 	delete mpBitmapInUse;
167 	delete mpCommentOut;
168 	delete mpChart;
169 	delete mpOutAct;
170 	delete pCopyOfE;
171 	delete pElement;
172 	delete [] mpBuf;
173 };
174 
175 // ---------------------------------------------------------------
176 
GetBackGroundColor()177 sal_uInt32 CGM::GetBackGroundColor()
178 {
179 	return ( pElement ) ? pElement->aColorTable[ 0 ] : 0;
180 }
181 
182 // ---------------------------------------------------------------
183 
ImplGetUI16(sal_uInt32)184 sal_uInt32 CGM::ImplGetUI16( sal_uInt32 /*nAlign*/ )
185 {
186 	sal_uInt8* pSource = mpSource + mnParaSize;
187 	mnParaSize += 2;
188 	return ( pSource[ 0 ] << 8 ) +  pSource[ 1 ];
189 };
190 
191 // ---------------------------------------------------------------
192 
ImplGetByte(sal_uInt32 nSource,sal_uInt32 nPrecision)193 sal_uInt8 CGM::ImplGetByte( sal_uInt32 nSource, sal_uInt32 nPrecision )
194 {
195 	return (sal_uInt8)( nSource >> ( ( nPrecision - 1 ) << 3 ) );
196 };
197 
198 // ---------------------------------------------------------------
199 
ImplGetI(sal_uInt32 nPrecision)200 long CGM::ImplGetI( sal_uInt32 nPrecision )
201 {
202 	sal_uInt8* pSource = mpSource + mnParaSize;
203 	mnParaSize += nPrecision;
204 	switch( nPrecision )
205 	{
206 		case 1 :
207 		{
208 			return	(char)*pSource;
209 		}
210 
211 		case 2 :
212 		{
213 			return (sal_Int16)( ( pSource[ 0 ] << 8 ) | pSource[ 1 ] );
214 		}
215 
216 		case 3 :
217 		{
218 			return ( ( pSource[ 0 ] << 24 ) | ( pSource[ 1 ] << 16 ) | pSource[ 2 ] << 8 ) >> 8;
219 		}
220 		case 4:
221 		{
222 			return (sal_Int32)( ( pSource[ 0 ] << 24 ) | ( pSource[ 1 ] << 16 ) | ( pSource[ 2 ] << 8 ) | ( pSource[ 3 ] ) );
223 		}
224 		default:
225 			mbStatus = sal_False;
226 			return 0;
227 	}
228 }
229 
230 // ---------------------------------------------------------------
231 
ImplGetUI(sal_uInt32 nPrecision)232 sal_uInt32 CGM::ImplGetUI( sal_uInt32 nPrecision )
233 {
234 	sal_uInt8* pSource = mpSource + mnParaSize;
235 	mnParaSize += nPrecision;
236 	switch( nPrecision )
237 	{
238 		case 1 :
239 			return	(sal_Int8)*pSource;
240 		case 2 :
241 		{
242 			return (sal_uInt16)( ( pSource[ 0 ] << 8 ) | pSource[ 1 ] );
243 		}
244 		case 3 :
245 		{
246 			return ( pSource[ 0 ] << 16 ) | ( pSource[ 1 ] << 8 ) | pSource[ 2 ];
247 		}
248 		case 4:
249 		{
250 			return (sal_uInt32)( ( pSource[ 0 ] << 24 ) | ( pSource[ 1 ] << 16 ) | ( pSource[ 2 ] << 8 ) | ( pSource[ 3 ] ) );
251 		}
252 		default:
253 			mbStatus = sal_False;
254 			return 0;
255 	}
256 }
257 
258 // ---------------------------------------------------------------
259 
ImplGetSwitch4(sal_uInt8 * pSource,sal_uInt8 * pDest)260 void CGM::ImplGetSwitch4( sal_uInt8* pSource, sal_uInt8* pDest )
261 {
262 	for ( int i = 0; i < 4; i++ )
263 	{
264 		pDest[ i ] = pSource[ i ^ 3 ];			// Little Endian <-> Big Endian switch
265 	}
266 }
267 
268 // ---------------------------------------------------------------
269 
ImplGetSwitch8(sal_uInt8 * pSource,sal_uInt8 * pDest)270 void CGM::ImplGetSwitch8( sal_uInt8* pSource, sal_uInt8* pDest )
271 {
272 	for ( int i = 0; i < 8; i++ )
273 	{
274 		pDest[ i ] = pSource[ i ^ 7 ];			// Little Endian <-> Big Endian switch
275 	}
276 }
277 
278 // ---------------------------------------------------------------
279 
ImplGetFloat(RealPrecision eRealPrecision,sal_uInt32 nRealSize)280 double CGM::ImplGetFloat( RealPrecision eRealPrecision, sal_uInt32 nRealSize )
281 {
282 	void*	pPtr;
283 	sal_uInt8	aBuf[8];
284 	sal_Bool	bCompatible;
285 	double	nRetValue;
286 	double	fDoubleBuf;
287 	float	fFloatBuf;
288 
289 #ifdef OSL_BIGENDIAN
290 		bCompatible = sal_True;
291 #else
292 		bCompatible = sal_False;
293 #endif
294 	if ( bCompatible )
295 		pPtr = mpSource + mnParaSize;
296 	else
297 	{
298 		if ( nRealSize == 4 )
299 			ImplGetSwitch4( mpSource + mnParaSize, &aBuf[0] );
300 		else
301 			ImplGetSwitch8( mpSource + mnParaSize, &aBuf[0] );
302 		pPtr = &aBuf;
303 	}
304 	if ( eRealPrecision == RP_FLOAT )
305 	{
306 		if ( nRealSize == 4 )
307 		{
308 			memcpy( (void*)&fFloatBuf, pPtr, 4 );
309 			nRetValue = (double)fFloatBuf;
310 		}
311 		else
312 		{
313 			memcpy( (void*)&fDoubleBuf, pPtr, 8 );
314 			nRetValue = fDoubleBuf;
315 		}
316 	}
317 	else // ->RP_FIXED
318 	{
319 		long	nVal;
320 		int		nSwitch = ( bCompatible ) ? 0 : 1 ;
321 		if ( nRealSize == 4 )
322 		{
323 			sal_uInt16*	pShort = (sal_uInt16*)pPtr;
324 			nVal = pShort[ nSwitch ];
325 			nVal <<= 16;
326 			nVal |= pShort[ nSwitch ^ 1 ];
327 			nRetValue = (double)nVal;
328 			nRetValue /= 65536;
329 		}
330 		else
331 		{
332 			long* pLong = (long*)pPtr;
333 			nRetValue = (double)abs( pLong[ nSwitch ] );
334 			nRetValue *= 65536;
335 			nVal = (sal_uInt32)( pLong[ nSwitch ^ 1 ] );
336 			nVal >>= 16;
337 			nRetValue += (double)nVal;
338 			if ( pLong[ nSwitch ] < 0 )
339 			{
340 				nRetValue -= nRetValue;
341 			}
342 			nRetValue /= 65536;
343 		}
344 	}
345 	mnParaSize += nRealSize;
346 	return nRetValue;
347 }
348 
349 // ---------------------------------------------------------------
350 
ImplGetPointSize()351 sal_uInt32 CGM::ImplGetPointSize()
352 {
353 	if ( pElement->eVDCType == VDC_INTEGER )
354 		return pElement->nVDCIntegerPrecision << 1;
355 	else
356 		return pElement->nVDCRealSize << 1;
357 }
358 
359 // ---------------------------------------------------------------
360 
ImplGetIX()361 inline double CGM::ImplGetIX()
362 {
363 	return ( ( ImplGetI( pElement->nVDCIntegerPrecision ) + mnVDCXadd ) * mnVDCXmul );
364 }
365 
366 // ---------------------------------------------------------------
367 
ImplGetFX()368 inline double CGM::ImplGetFX()
369 {
370 	return ( ( ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize ) + mnVDCXadd ) * mnVDCXmul );
371 }
372 
373 // ---------------------------------------------------------------
374 
ImplGetIY()375 inline double CGM::ImplGetIY()
376 {
377 	return ( ( ImplGetI( pElement->nVDCIntegerPrecision ) + mnVDCYadd ) * mnVDCYmul );
378 }
379 
380 // ---------------------------------------------------------------
381 
ImplGetFY()382 inline double CGM::ImplGetFY()
383 {
384 	return ( ( ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize ) + mnVDCYadd ) * mnVDCYmul );
385 }
386 
387 // ---------------------------------------------------------------
388 
ImplGetPoint(FloatPoint & rFloatPoint,sal_Bool bMap)389 void CGM::ImplGetPoint( FloatPoint& rFloatPoint, sal_Bool bMap )
390 {
391 	if ( pElement->eVDCType == VDC_INTEGER )
392 	{
393 		rFloatPoint.X = ImplGetIX();
394 		rFloatPoint.Y = ImplGetIY();
395 	}
396 	else // ->floating points
397 	{
398 		rFloatPoint.X = ImplGetFX();
399 		rFloatPoint.Y = ImplGetFY();
400 	}
401 	if ( bMap )
402 		ImplMapPoint( rFloatPoint );
403 }
404 
405 // ---------------------------------------------------------------
406 
ImplGetRectangle(FloatRect & rFloatRect,sal_Bool bMap)407 void CGM::ImplGetRectangle( FloatRect& rFloatRect, sal_Bool bMap )
408 {
409 	if ( pElement->eVDCType == VDC_INTEGER )
410 	{
411 		rFloatRect.Left = ImplGetIX();
412 		rFloatRect.Bottom = ImplGetIY();
413 		rFloatRect.Right = ImplGetIX();
414 		rFloatRect.Top = ImplGetIY();
415 	}
416 	else // ->floating points
417 	{
418 		rFloatRect.Left = ImplGetFX();
419 		rFloatRect.Bottom = ImplGetFY();
420 		rFloatRect.Right = ImplGetFX();
421 		rFloatRect.Top = ImplGetFY();
422 	}
423 	if ( bMap )
424 	{
425 		ImplMapX( rFloatRect.Left );
426 		ImplMapX( rFloatRect.Right );
427 		ImplMapY( rFloatRect.Top );
428 		ImplMapY( rFloatRect.Bottom );
429 		rFloatRect.Justify();
430 	}
431 }
432 
433 // ---------------------------------------------------------------
434 
ImplGetRectangleNS(FloatRect & rFloatRect)435 void CGM::ImplGetRectangleNS( FloatRect& rFloatRect )
436 {
437 	if ( pElement->eVDCType == VDC_INTEGER )
438 	{
439 		rFloatRect.Left = ImplGetI( pElement->nVDCIntegerPrecision );
440 		rFloatRect.Bottom = ImplGetI( pElement->nVDCIntegerPrecision );
441 		rFloatRect.Right = ImplGetI( pElement->nVDCIntegerPrecision );
442 		rFloatRect.Top = ImplGetI( pElement->nVDCIntegerPrecision );
443 	}
444 	else // ->floating points
445 	{
446 		rFloatRect.Left = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
447 		rFloatRect.Bottom = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
448 		rFloatRect.Right = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
449 		rFloatRect.Top = ImplGetFloat( pElement->eVDCRealPrecision, pElement->nVDCRealSize );
450 	}
451 }
452 
453 // ---------------------------------------------------------------
454 
ImplGetBitmapColor(sal_Bool bDirect)455 sal_uInt32 CGM::ImplGetBitmapColor( sal_Bool bDirect )
456 {
457 	// the background color is always a direct color
458 
459 	sal_uInt32	nTmp;
460 	if ( ( pElement->eColorSelectionMode == CSM_DIRECT ) || bDirect )
461 	{
462 		sal_uInt32		nColor = ImplGetByte( ImplGetUI( pElement->nColorPrecision ), 1 );
463 		sal_uInt32		nDiff = pElement->nColorValueExtent[ 3 ] - pElement->nColorValueExtent[ 0 ] + 1;
464 
465 		if ( !nDiff )
466 			nDiff++;
467 		nColor = ( ( nColor - pElement->nColorValueExtent[ 0 ] ) << 8 ) / nDiff;
468 		nTmp = nColor << 16 & 0xff0000;
469 
470 		nColor = ImplGetByte( ImplGetUI( pElement->nColorPrecision ), 1 );
471 		nDiff = pElement->nColorValueExtent[ 4 ] - pElement->nColorValueExtent[ 1 ] + 1;
472 		if ( !nDiff )
473 			nDiff++;
474 		nColor = ( ( nColor - pElement->nColorValueExtent[ 1 ] ) << 8 ) / nDiff;
475 		nTmp |= nColor << 8 & 0xff00;
476 
477 		nColor = ImplGetByte( ImplGetUI( pElement->nColorPrecision ), 1 );
478 		nDiff = pElement->nColorValueExtent[ 5 ] - pElement->nColorValueExtent[ 2 ] + 1;
479 		if ( !nDiff )
480 			nDiff++;
481 		nColor = ( ( nColor - pElement->nColorValueExtent[ 2 ] ) << 8 ) / nDiff;
482 		nTmp |= (sal_uInt8)nColor;
483 	}
484 	else
485 	{
486 		sal_uInt32 nIndex = ImplGetUI( pElement->nColorIndexPrecision );
487 		nTmp = pElement->aColorTable[ (sal_uInt8)( nIndex ) ] ;
488 	}
489 	return nTmp;
490 }
491 
492 // ---------------------------------------------------------------
493 
494 // call this function each time after the mapmode settings has been changed
ImplSetMapMode()495 void CGM::ImplSetMapMode()
496 {
497 	int nAngReverse = 1;
498 	mnVDCdx = pElement->aVDCExtent.Right - pElement->aVDCExtent.Left;
499 
500 	mnVDCXadd = -pElement->aVDCExtent.Left;
501 	mnVDCXmul = 1;
502 	if ( mnVDCdx < 0 )
503 	{
504 		nAngReverse ^= 1;
505 		mnVDCdx = -mnVDCdx;
506 		mnVDCXmul = -1;
507 	}
508 
509 	mnVDCdy = pElement->aVDCExtent.Bottom - pElement->aVDCExtent.Top;
510 	mnVDCYadd = -pElement->aVDCExtent.Top;
511 	mnVDCYmul = 1;
512 	if ( mnVDCdy < 0 )
513 	{
514 		nAngReverse ^= 1;
515 		mnVDCdy = -mnVDCdy;
516 		mnVDCYmul = -1;
517 	}
518 	if ( nAngReverse )
519 		mbAngReverse = sal_True;
520 	else
521 		mbAngReverse = sal_False;
522 
523 	double fQuo1 = mnVDCdx / mnVDCdy;
524 	double fQuo2 = mnOutdx / mnOutdy;
525 	if ( fQuo2 < fQuo1 )
526 	{
527 		mnXFraction = mnOutdx / mnVDCdx;
528 		mnYFraction = mnOutdy * ( fQuo2 / fQuo1 ) / mnVDCdy;
529 	}
530 	else
531 	{
532 		mnXFraction = mnOutdx * ( fQuo1 / fQuo2 ) / mnVDCdx;
533 		mnYFraction = mnOutdy / mnVDCdy;
534 	}
535 }
536 
537 // ---------------------------------------------------------------
538 
ImplMapDouble(double & nNumb)539 void CGM::ImplMapDouble( double& nNumb )
540 {
541 	if ( pElement->eDeviceViewPortMap == DVPM_FORCED )
542 	{
543 		// point is 1mm * ScalingFactor
544 		switch ( pElement->eDeviceViewPortMode )
545 		{
546 			case DVPM_FRACTION :
547 			{
548 				nNumb *= ( mnXFraction + mnYFraction ) / 2;
549 			}
550 			break;
551 
552 			case DVPM_METRIC :
553 			{
554 //				nNumb *= ( 100 * pElement->nDeviceViewPortScale );
555 				nNumb *= ( mnXFraction + mnYFraction ) / 2;
556 				if ( pElement->nDeviceViewPortScale < 0 )
557 					nNumb = -nNumb;
558 			}
559 			break;
560 
561 			case DVPM_DEVICE :
562 			{
563 
564 			}
565 			break;
566 
567 			default:
568 
569 				break;
570 		}
571 	}
572 	else
573 	{
574 
575 
576 	}
577 }
578 
579 // ---------------------------------------------------------------
580 
ImplMapX(double & nNumb)581 void CGM::ImplMapX( double& nNumb )
582 {
583 	if ( pElement->eDeviceViewPortMap == DVPM_FORCED )
584 	{
585 		// point is 1mm * ScalingFactor
586 		switch ( pElement->eDeviceViewPortMode )
587 		{
588 			case DVPM_FRACTION :
589 			{
590 				nNumb *= mnXFraction;
591 			}
592 			break;
593 
594 			case DVPM_METRIC :
595 			{
596 //				nNumb *= ( 100 * pElement->nDeviceViewPortScale );
597 				nNumb *= mnXFraction;
598 				if ( pElement->nDeviceViewPortScale < 0 )
599 					nNumb = -nNumb;
600 			}
601 			break;
602 
603 			case DVPM_DEVICE :
604 			{
605 
606 			}
607 			break;
608 
609 			default:
610 
611 				break;
612 		}
613 	}
614 	else
615 	{
616 
617 
618 	}
619 }
620 
621 
622 // ---------------------------------------------------------------
623 
ImplMapY(double & nNumb)624 void CGM::ImplMapY( double& nNumb )
625 {
626 	if ( pElement->eDeviceViewPortMap == DVPM_FORCED )
627 	{
628 		// point is 1mm * ScalingFactor
629 		switch ( pElement->eDeviceViewPortMode )
630 		{
631 			case DVPM_FRACTION :
632 			{
633 				nNumb *= mnYFraction;
634 			}
635 			break;
636 
637 			case DVPM_METRIC :
638 			{
639 //				nNumb *= ( 100 * pElement->nDeviceViewPortScale );
640 				nNumb *= mnYFraction;
641 				if ( pElement->nDeviceViewPortScale < 0 )
642 					nNumb = -nNumb;
643 			}
644 			break;
645 
646 			case DVPM_DEVICE :
647 			{
648 
649 			}
650 			break;
651 
652 			default:
653 
654 				break;
655 		}
656 	}
657 	else
658 	{
659 
660 
661 	}
662 }
663 
664 
665 // ---------------------------------------------------------------
666 
667 // convert a point to the current VC mapmode (1/100TH mm)
ImplMapPoint(FloatPoint & rFloatPoint)668 void CGM::ImplMapPoint( FloatPoint& rFloatPoint )
669 {
670 	if ( pElement->eDeviceViewPortMap == DVPM_FORCED )
671 	{
672 		// point is 1mm * ScalingFactor
673 		switch ( pElement->eDeviceViewPortMode )
674 		{
675 			case DVPM_FRACTION :
676 			{
677 				rFloatPoint.X *= mnXFraction;
678 				rFloatPoint.Y *= mnYFraction;
679 			}
680 			break;
681 
682 			case DVPM_METRIC :
683 			{
684 				rFloatPoint.X *= mnXFraction;
685 				rFloatPoint.Y *= mnYFraction;
686 				if ( pElement->nDeviceViewPortScale < 0 )
687 				{
688 					rFloatPoint.X = -rFloatPoint.X;
689 					rFloatPoint.Y = -rFloatPoint.Y;
690 				}
691 			}
692 			break;
693 
694 			case DVPM_DEVICE :
695 			{
696 
697 			}
698 			break;
699 
700 			default:
701 
702 				break;
703 		}
704 	}
705 	else
706 	{
707 
708 
709 	}
710 }
711 
712 // ---------------------------------------------------------------
713 
ImplDoClass()714 void CGM::ImplDoClass()
715 {
716 #ifdef CGM_USER_BREAKPOINT
717 #ifdef WNT
718 	if ( mnActCount == CGM_BREAK_ACTION )
719 		_asm int 0x3;
720 #endif
721 #endif
722 	switch ( mnElementClass )
723 	{
724 		case 0 : ImplDoClass0(); break;
725 		case 1 : ImplDoClass1(); break;
726 		case 2 : ImplDoClass2(); break;
727 		case 3 : ImplDoClass3(); break;
728 		case 4 :
729 		{
730 			ImplDoClass4();
731 			mnAct4PostReset = 0;
732 		}
733 		break;
734 		case 5 : ImplDoClass5(); break;
735 		case 6 : ImplDoClass6(); break;
736 		case 7 : ImplDoClass7(); break;
737 		case 8 : ImplDoClass8(); break;
738 		case 9 : ImplDoClass9(); break;
739 		case 15 :ImplDoClass15(); break;
740 		default : ComOut( CGM_UNKNOWN_COMMAND, "" ); break;
741 	}
742 	mnActCount++;
743 };
744 
745 // ---------------------------------------------------------------
746 
ImplDefaultReplacement()747 void CGM::ImplDefaultReplacement()
748 {
749 	sal_uInt8*	pBuf = (sal_uInt8*)maDefRepList.First();
750 	if ( pBuf )
751 	{
752 		sal_uInt32	nElementSize = (sal_uInt32)(sal_uIntPtr)maDefRepSizeList.First();
753 		sal_uInt32	nOldEscape = mnEscape;
754 		sal_uInt32	nOldElementClass = mnElementClass;
755 		sal_uInt32	nOldElementID = mnElementID;
756 		sal_uInt32	nOldElementSize = mnElementSize;
757 		sal_uInt8*	pOldBuf = mpSource;
758 		while( pBuf )
759 		{
760 			sal_uInt32	nCount = 0;
761 			while ( mbStatus && ( nCount < nElementSize ) )
762 			{
763 				mpSource = pBuf + nCount;
764 				mnParaSize = 0;
765 				mnEscape = ImplGetUI16();
766 				mnElementClass = mnEscape >> 12;
767 				mnElementID = ( mnEscape & 0x0fe0 ) >> 5;
768 				mnElementSize = mnEscape & 0x1f;
769 				if ( mnElementSize == 31 )
770 				{
771 					mnElementSize = ImplGetUI16();
772 				}
773 				nCount += mnParaSize;
774 				mnParaSize = 0;
775 				mpSource = pBuf + nCount;
776 				if ( mnElementSize & 1 )
777 					nCount++;
778 				nCount += mnElementSize;
779 				if ( ( mnElementClass != 1 ) || ( mnElementID != 0xc ) )	// rekursion hier nicht moeglich!!
780 					ImplDoClass();
781 			}
782 			nElementSize = (sal_uInt32)(sal_uIntPtr)maDefRepSizeList.Next();
783 			pBuf = (sal_uInt8*)maDefRepList.Next();
784 		}
785 		mnEscape = nOldEscape;
786 		mnElementClass = nOldElementClass;
787 		mnElementID = nOldElementID;
788 		mnParaSize = mnElementSize = nOldElementSize;
789 		mpSource = pOldBuf;
790 	}
791 }
792 
793 // ---------------------------------------------------------------
794 
Write(SvStream & rIStm)795 sal_Bool CGM::Write( SvStream& rIStm )
796 {
797 	if ( !mpBuf )
798 		mpBuf = new sal_uInt8[ 0xffff ];
799 
800 	mnParaSize = 0;
801 	mpSource = mpBuf;
802 	rIStm.Read( mpSource, 2 );
803 	mnEscape = ImplGetUI16();
804 	mnElementClass = mnEscape >> 12;
805 	mnElementID = ( mnEscape & 0x0fe0 ) >> 5;
806 	mnElementSize = mnEscape & 0x1f;
807 
808 	if ( mnElementSize == 31 )
809 	{
810 		rIStm.Read( mpSource + mnParaSize, 2 );
811 		mnElementSize = ImplGetUI16();
812 	}
813 	mnParaSize = 0;
814 	if ( mnElementSize )
815 		rIStm.Read( mpSource + mnParaSize, mnElementSize );
816 
817 	if ( mnElementSize & 1 )
818 		rIStm.SeekRel( 1 );
819 	ImplDoClass();
820 
821 
822 #ifdef CGM_USER_BREAKPOINT
823 #ifdef WNT
824 	if ( !mbStatus || mnParaSize && ( mnElementSize != mnParaSize ) )
825 		_asm int 0x3;
826 #endif
827 #endif
828 
829 	return mbStatus;
830 };
831 
832 // ---------------------------------------------------------------
833 
operator >>(SvStream & rOStm,CGM &)834 SvStream& operator>>( SvStream& rOStm, CGM& /*rCGM*/ )
835 {
836 
837 	return rOStm;
838 };
839 
840 // ---------------------------------------------------------------
841 
842 
843 
844 //================== GraphicImport - die exportierte Funktion ================
845 
ImportCGM(String & rFileName,uno::Reference<frame::XModel> & rXModel,sal_uInt32 nMode,void * pProgressBar)846 extern "C" sal_uInt32 __LOADONCALLAPI ImportCGM( String& rFileName, uno::Reference< frame::XModel > & rXModel, sal_uInt32 nMode, void* pProgressBar )
847 {
848 
849 	sal_uInt32	nStatus = 0;			// retvalue == 0 -> ERROR
850 										//			== 0xffrrggbb -> background color in the lower 24 bits
851 	sal_Bool	bProgressBar = sal_False;
852 
853 	if( rXModel.is() )
854 	{
855 		CGM*		pCGM= NULL;
856 
857 		try
858 		{
859 			pCGM = new CGM( nMode, rXModel );
860 			if ( pCGM && pCGM->IsValid() )
861 			{
862 				if ( nMode & CGM_IMPORT_CGM )
863 				{
864 					SvStream* pIn = ::utl::UcbStreamHelper::CreateStream( rFileName, STREAM_READ );
865 					if ( pIn )
866 					{
867 						pIn->SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
868 						pIn->Seek( STREAM_SEEK_TO_END );
869 						sal_uInt32	nInSize = pIn->Tell();
870 						pIn->Seek( 0 );
871 
872 #ifdef CGM_EXPORT_IMPRESS
873 						uno::Reference< task::XStatusIndicator >  aXStatInd;
874 						sal_uInt32	nNext = 0;
875 						sal_uInt32	nAdd = nInSize / 20;
876 						if ( pProgressBar )
877 							aXStatInd = *(uno::Reference< task::XStatusIndicator > *)pProgressBar;
878 						bProgressBar = aXStatInd.is();
879 						if ( bProgressBar )
880 							aXStatInd->start( rtl::OUString::createFromAscii("CGM Import"), nInSize );
881 #endif
882 
883 						while ( pCGM->IsValid() && ( pIn->Tell() < nInSize ) && !pCGM->IsFinished() )
884 						{
885 
886 #ifdef CGM_EXPORT_IMPRESS
887 
888 
889 							if ( bProgressBar )
890 							{
891 								sal_uInt32 nCurrentPos = pIn->Tell();
892 								if ( nCurrentPos >= nNext )
893 								{
894 									aXStatInd->setValue( nCurrentPos );
895 									nNext = nCurrentPos + nAdd;
896 								}
897 							}
898 #endif
899 
900 							if ( pCGM->Write( *pIn ) == sal_False )
901 								break;
902 						}
903 						if ( pCGM->IsValid() )
904 						{
905 							nStatus = pCGM->GetBackGroundColor() | 0xff000000;
906 						}
907 #ifdef CGM_EXPORT_IMPRESS
908 						if ( bProgressBar )
909 							aXStatInd->end();
910 #endif
911 						delete pIn;
912 					}
913 				}
914 			}
915 		}
916 		catch( ::com::sun::star::uno::Exception& )
917 		{
918 			nStatus = 0;
919 		}
920 		delete pCGM;
921 	}
922 	return nStatus;
923 }
924