xref: /aoo41x/main/tools/source/generic/gen.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_tools.hxx"
30 #include <tools/debug.hxx>
31 #include <tools/gen.hxx>
32 #include <tools/stream.hxx>
33 
34 // =======================================================================
35 
36 SvStream& operator>>( SvStream& rIStream, Pair& rPair )
37 {
38 	DBG_ASSERTWARNING( rIStream.GetVersion(), "Pair::>> - Solar-Version not set on rIStream" );
39 
40 	if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
41 	{
42 		unsigned char	cId;
43 		unsigned char	cAry[8];
44 		int 			i;
45 		int 			i1;
46 		int 			i2;
47 		sal_uInt32			nNum;
48 
49 		rIStream >> cId;
50 		i1 = (cId & 0x70) >> 4;
51 		i2 = cId & 0x07;
52 		rIStream.Read( cAry, i1+i2 );
53 
54 		nNum = 0;
55 		i = i1;
56 		while ( i )
57 		{
58 			i--;
59 			nNum <<= 8;
60 			nNum |= cAry[i];
61 		}
62 		if ( cId & 0x80 )
63 			nNum ^= 0xFFFFFFFF;
64 		rPair.nA = (sal_Int32)nNum;
65 
66 		nNum = 0;
67 		i = i1+i2;
68 		while ( i > i1 )
69 		{
70 			i--;
71 			nNum <<= 8;
72 			nNum |= cAry[i];
73 		}
74 		if ( cId & 0x08 )
75 			nNum ^= 0xFFFFFFFF;
76 		rPair.nB = (sal_Int32)nNum;
77 	}
78 	else
79 	{
80 		rIStream >> rPair.nA >> rPair.nB;
81 	}
82 
83 	return rIStream;
84 }
85 
86 // -----------------------------------------------------------------------
87 
88 SvStream& operator<<( SvStream& rOStream, const Pair& rPair )
89 {
90 	DBG_ASSERTWARNING( rOStream.GetVersion(), "Pair::<< - Solar-Version not set on rOStream" );
91 
92 	if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
93 	{
94 		unsigned char	cAry[9];
95 		int 			i = 1;
96 		sal_uInt32			nNum;
97 
98 		cAry[0] = 0;
99 
100 		nNum = (sal_uInt32)(sal_Int32)rPair.nA;
101 		if ( rPair.nA < 0 )
102 		{
103 			cAry[0] |= 0x80;
104 			nNum ^= 0xFFFFFFFF;
105 		}
106 		if ( nNum )
107 		{
108 			cAry[i] = (unsigned char)(nNum & 0xFF);
109 			nNum >>= 8;
110 			i++;
111 
112 			if ( nNum )
113 			{
114 				cAry[i] = (unsigned char)(nNum & 0xFF);
115 				nNum >>= 8;
116 				i++;
117 
118 				if ( nNum )
119 				{
120 					cAry[i] = (unsigned char)(nNum & 0xFF);
121 					nNum >>= 8;
122 					i++;
123 
124 					if ( nNum )
125 					{
126 						cAry[i] = (unsigned char)(nNum & 0xFF);
127 						nNum >>= 8;
128 						i++;
129 						cAry[0] |= 0x40;
130 					}
131 					else
132 						cAry[0] |= 0x30;
133 				}
134 				else
135 					cAry[0] |= 0x20;
136 			}
137 			else
138 				cAry[0] |= 0x10;
139 		}
140 
141 		nNum = (sal_uInt32)(sal_Int32)rPair.nB;
142 		if ( rPair.nB < 0 )
143 		{
144 			cAry[0] |= 0x08;
145 			nNum ^= 0xFFFFFFFF;
146 		}
147 		if ( nNum )
148 		{
149 			cAry[i] = (unsigned char)(nNum & 0xFF);
150 			nNum >>= 8;
151 			i++;
152 
153 			if ( nNum )
154 			{
155 				cAry[i] = (unsigned char)(nNum & 0xFF);
156 				nNum >>= 8;
157 				i++;
158 
159 				if ( nNum )
160 				{
161 					cAry[i] = (unsigned char)(nNum & 0xFF);
162 					nNum >>= 8;
163 					i++;
164 
165 					if ( nNum )
166 					{
167 						cAry[i] = (unsigned char)(nNum & 0xFF);
168 						nNum >>= 8;
169 						i++;
170 						cAry[0] |= 0x04;
171 					}
172 					else
173 						cAry[0] |= 0x03;
174 				}
175 				else
176 					cAry[0] |= 0x02;
177 			}
178 			else
179 				cAry[0] |= 0x01;
180 		}
181 
182 		rOStream.Write( cAry, i );
183 	}
184 	else
185 	{
186 		rOStream << rPair.nA << rPair.nB;
187 	}
188 
189 	return rOStream;
190 }
191 
192 /*************************************************************************
193 |*
194 |*    Rectangle::SetSize()
195 |*
196 |*    Beschreibung      GEN.SDW
197 |*    Ersterstellung    DV 29.10.91
198 |*    Letzte Aenderung  MM 21.04.94
199 |*
200 *************************************************************************/
201 
202 void Rectangle::SetSize( const Size& rSize )
203 {
204     if ( rSize.Width() < 0 )
205         nRight  = nLeft + rSize.Width() +1;
206     else if ( rSize.Width() > 0 )
207         nRight  = nLeft + rSize.Width() -1;
208     else
209         nRight = RECT_EMPTY;
210 
211     if ( rSize.Height() < 0 )
212         nBottom  = nTop + rSize.Height() +1;
213     else if ( rSize.Height() > 0 )
214         nBottom  = nTop + rSize.Height() -1;
215     else
216         nBottom = RECT_EMPTY;
217 }
218 
219 /*************************************************************************
220 |*
221 |*    Rectangle::Union()
222 |*
223 |*    Beschreibung      GEN.SDW
224 |*    Ersterstellung    TH 20.10.92
225 |*    Letzte Aenderung  MM 21.04.94
226 |*
227 *************************************************************************/
228 
229 Rectangle& Rectangle::Union( const Rectangle& rRect )
230 {
231     if ( rRect.IsEmpty() )
232         return *this;
233 
234     if ( IsEmpty() )
235         *this = rRect;
236     else
237     {
238         nLeft  =  Min( Min( nLeft, rRect.nLeft ), Min( nRight, rRect.nRight )   );
239         nRight  = Max( Max( nLeft, rRect.nLeft ), Max( nRight, rRect.nRight )   );
240         nTop    = Min( Min( nTop, rRect.nTop ),   Min( nBottom, rRect.nBottom ) );
241         nBottom = Max( Max( nTop, rRect.nTop ),   Max( nBottom, rRect.nBottom ) );
242     }
243 
244     return *this;
245 }
246 
247 /*************************************************************************
248 |*
249 |*    Rectangle::Intersection()
250 |*
251 |*    Beschreibung      GEN.SDW
252 |*    Ersterstellung    TH 20.10.92
253 |*    Letzte Aenderung  MM 21.04.94
254 |*
255 *************************************************************************/
256 
257 Rectangle& Rectangle::Intersection( const Rectangle& rRect )
258 {
259     if ( IsEmpty() )
260         return *this;
261     if ( rRect.IsEmpty() )
262     {
263         *this = Rectangle();
264         return *this;
265     }
266 
267     // nicht mit umgedrehten Rechtecken arbeiten
268     Rectangle aTmpRect( rRect );
269     Justify();
270     aTmpRect.Justify();
271 
272     // Schnitt bilden
273     nLeft  = Max( nLeft, aTmpRect.nLeft );
274     nRight = Min( nRight, aTmpRect.nRight );
275     nTop   = Max( nTop, aTmpRect.nTop );
276     nBottom= Min( nBottom, aTmpRect.nBottom );
277 
278     // Feststellen ob Schnitt leer
279     if ( nRight < nLeft || nBottom < nTop )
280         *this = Rectangle();
281 
282     return *this;
283 }
284 
285 /*************************************************************************
286 |*
287 |*    Rectangle::Justify()
288 |*
289 |*    Beschreibung      GEN.SDW
290 |*    Ersterstellung    DV 07.03.91
291 |*    Letzte Aenderung  DV 07.03.91
292 |*
293 *************************************************************************/
294 
295 void Rectangle::Justify()
296 {
297     long nHelp;
298 
299     // Abfrage, ob Right kleiner Left
300     if ( (nRight < nLeft) && (nRight != RECT_EMPTY) )
301     {
302         nHelp = nLeft;
303         nLeft = nRight;
304         nRight = nHelp;
305     }
306 
307     // Abfrage, ob Bottom kleiner Top
308     if ( (nBottom < nTop) && (nBottom != RECT_EMPTY) )
309     {
310         nHelp = nBottom;
311         nBottom = nTop;
312         nTop = nHelp;
313     }
314 }
315 
316 /*************************************************************************
317 |*
318 |*    Rectangle::IsInside()
319 |*
320 |*    Beschreibung      GEN.SDW
321 |*    Ersterstellung    TH 19.03.90
322 |*    Letzte Aenderung  MM 21.04.94
323 |*
324 *************************************************************************/
325 
326 sal_Bool Rectangle::IsInside( const Point& rPoint ) const
327 {
328     if ( IsEmpty() )
329         return sal_False;
330 
331     sal_Bool bRet = sal_True;
332     if ( nLeft <= nRight )
333     {
334         if ( (rPoint.X() < nLeft) || (rPoint.X() > nRight) )
335             bRet = sal_False;
336     }
337     else
338     {
339         if ( (rPoint.X() > nLeft) || (rPoint.X() < nRight) )
340             bRet = sal_False;
341     }
342     if ( nTop <= nBottom )
343     {
344         if ( (rPoint.Y() < nTop) || (rPoint.Y() > nBottom) )
345             bRet = sal_False;
346     }
347     else
348     {
349         if ( (rPoint.Y() > nTop) || (rPoint.Y() < nBottom) )
350             bRet = sal_False;
351     }
352     return bRet;
353 }
354 
355 /*************************************************************************
356 |*
357 |*    Rectangle::IsInside()
358 |*
359 |*    Beschreibung      GEN.SDW
360 |*    Ersterstellung    TH 19.03.90
361 |*    Letzte Aenderung  MM 21.04.94
362 |*
363 *************************************************************************/
364 
365 sal_Bool Rectangle::IsInside( const Rectangle& rRect ) const
366 {
367     if ( IsInside( rRect.TopLeft() ) && IsInside( rRect.BottomRight() ) )
368         return sal_True;
369     else
370         return sal_False;
371 }
372 
373 /*************************************************************************
374 |*
375 |*    Rectangle::IsOver()
376 |*
377 |*    Beschreibung      GEN.SDW
378 |*    Ersterstellung    TH 19.03.90
379 |*    Letzte Aenderung  MM 21.04.94
380 |*
381 *************************************************************************/
382 
383 sal_Bool Rectangle::IsOver( const Rectangle& rRect ) const
384 {
385     // Wenn sie sich nicht schneiden, ueberlappen sie auch nicht
386     return !GetIntersection( rRect ).IsEmpty();
387 }
388 
389 // =======================================================================
390 
391 SvStream& operator>>( SvStream& rIStream, Rectangle& rRect )
392 {
393 	DBG_ASSERTWARNING( rIStream.GetVersion(), "Rectangle::>> - Solar-Version not set on rIStream" );
394 
395 	if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
396 	{
397 		unsigned char	cIdAry[2];
398 		unsigned char	cAry[16];
399 		int 			i;
400 		int 			iLast;
401 		int 			i1;
402 		int 			i2;
403 		int 			i3;
404 		int 			i4;
405 		sal_uInt32			nNum;
406 
407 		rIStream.Read( cIdAry, 2 );
408 		i1 = (cIdAry[0] & 0x70) >> 4;
409 		i2 = cIdAry[0] & 0x07;
410 		i3 = (cIdAry[1] & 0x70) >> 4;
411 		i4 = cIdAry[1] & 0x07;
412 		rIStream.Read( cAry, i1+i2+i3+i4 );
413 
414 		nNum = 0;
415 		i = i1;
416 		iLast = i;
417 		while ( i )
418 		{
419 			i--;
420 			nNum <<= 8;
421 			nNum |= cAry[i];
422 		}
423 		iLast = i1;
424 		if ( cIdAry[0] & 0x80 )
425 			nNum ^= 0xFFFFFFFF;
426 		rRect.nLeft = (sal_Int32)nNum;
427 
428 		nNum = 0;
429 		i = iLast+i2;
430 		while ( i > iLast )
431 		{
432 			i--;
433 			nNum <<= 8;
434 			nNum |= cAry[i];
435 		}
436 		iLast += i2;
437 		if ( cIdAry[0] & 0x08 )
438 			nNum ^= 0xFFFFFFFF;
439 		rRect.nTop = (sal_Int32)nNum;
440 
441 		nNum = 0;
442 		i = iLast+i3;
443 		while ( i > iLast )
444 		{
445 			i--;
446 			nNum <<= 8;
447 			nNum |= cAry[i];
448 		}
449 		iLast += i3;
450 		if ( cIdAry[1] & 0x80 )
451 			nNum ^= 0xFFFFFFFF;
452 		rRect.nRight = (sal_Int32)nNum;
453 
454 		nNum = 0;
455 		i = iLast+i4;
456 		while ( i > iLast )
457 		{
458 			i--;
459 			nNum <<= 8;
460 			nNum |= cAry[i];
461 		}
462 		if ( cIdAry[1] & 0x08 )
463 			nNum ^= 0xFFFFFFFF;
464 		rRect.nBottom = (sal_Int32)nNum;
465 	}
466 	else
467 	{
468 		rIStream >> rRect.nLeft >> rRect.nTop >> rRect.nRight >> rRect.nBottom;
469 	}
470 
471 	return rIStream;
472 }
473 
474 // -----------------------------------------------------------------------
475 
476 SvStream& operator<<( SvStream& rOStream, const Rectangle& rRect )
477 {
478 	DBG_ASSERTWARNING( rOStream.GetVersion(), "Rectangle::<< - Solar-Version not set on rOStream" );
479 
480 	if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
481 	{
482 		unsigned char	cAry[18];
483 		int 			i = 2;
484 		sal_uInt32			nNum;
485 
486 		cAry[0] = 0;
487 		cAry[1] = 0;
488 
489 		nNum = (sal_uInt32)(sal_Int32)rRect.nLeft;
490 		if ( rRect.nLeft < 0 )
491 		{
492 			cAry[0] |= 0x80;
493 			nNum ^= 0xFFFFFFFF;
494 		}
495 		if ( nNum )
496 		{
497 			cAry[i] = (unsigned char)(nNum & 0xFF);
498 			nNum >>= 8;
499 			i++;
500 
501 			if ( nNum )
502 			{
503 				cAry[i] = (unsigned char)(nNum & 0xFF);
504 				nNum >>= 8;
505 				i++;
506 
507 				if ( nNum )
508 				{
509 					cAry[i] = (unsigned char)(nNum & 0xFF);
510 					nNum >>= 8;
511 					i++;
512 
513 					if ( nNum )
514 					{
515 						cAry[i] = (unsigned char)(nNum & 0xFF);
516 						nNum >>= 8;
517 						i++;
518 						cAry[0] |= 0x40;
519 					}
520 					else
521 						cAry[0] |= 0x30;
522 				}
523 				else
524 					cAry[0] |= 0x20;
525 			}
526 			else
527 				cAry[0] |= 0x10;
528 		}
529 
530 		nNum = (sal_uInt32)(sal_Int32)rRect.nTop;
531 		if ( rRect.nTop < 0 )
532 		{
533 			cAry[0] |= 0x08;
534 			nNum ^= 0xFFFFFFFF;
535 		}
536 		if ( nNum )
537 		{
538 			cAry[i] = (unsigned char)(nNum & 0xFF);
539 			nNum >>= 8;
540 			i++;
541 
542 			if ( nNum )
543 			{
544 				cAry[i] = (unsigned char)(nNum & 0xFF);
545 				nNum >>= 8;
546 				i++;
547 
548 				if ( nNum )
549 				{
550 					cAry[i] = (unsigned char)(nNum & 0xFF);
551 					nNum >>= 8;
552 					i++;
553 
554 					if ( nNum )
555 					{
556 						cAry[i] = (unsigned char)(nNum & 0xFF);
557 						nNum >>= 8;
558 						i++;
559 						cAry[0] |= 0x04;
560 					}
561 					else
562 						cAry[0] |= 0x03;
563 				}
564 				else
565 					cAry[0] |= 0x02;
566 			}
567 			else
568 				cAry[0] |= 0x01;
569 		}
570 
571 		nNum = (sal_uInt32)(sal_Int32)rRect.nRight;
572 		if ( rRect.nRight < 0 )
573 		{
574 			cAry[1] |= 0x80;
575 			nNum ^= 0xFFFFFFFF;
576 		}
577 		if ( nNum )
578 		{
579 			cAry[i] = (unsigned char)(nNum & 0xFF);
580 			nNum >>= 8;
581 			i++;
582 
583 			if ( nNum )
584 			{
585 				cAry[i] = (unsigned char)(nNum & 0xFF);
586 				nNum >>= 8;
587 				i++;
588 
589 				if ( nNum )
590 				{
591 					cAry[i] = (unsigned char)(nNum & 0xFF);
592 					nNum >>= 8;
593 					i++;
594 
595 					if ( nNum )
596 					{
597 						cAry[i] = (unsigned char)(nNum & 0xFF);
598 						nNum >>= 8;
599 						i++;
600 						cAry[1] |= 0x40;
601 					}
602 					else
603 						cAry[1] |= 0x30;
604 				}
605 				else
606 					cAry[1] |= 0x20;
607 			}
608 			else
609 				cAry[1] |= 0x10;
610 		}
611 
612 		nNum = (sal_uInt32)(sal_Int32)rRect.nBottom;
613 		if ( rRect.nBottom < 0 )
614 		{
615 			cAry[1] |= 0x08;
616 			nNum ^= 0xFFFFFFFF;
617 		}
618 		if ( nNum )
619 		{
620 			cAry[i] = (unsigned char)(nNum & 0xFF);
621 			nNum >>= 8;
622 			i++;
623 
624 			if ( nNum )
625 			{
626 				cAry[i] = (unsigned char)(nNum & 0xFF);
627 				nNum >>= 8;
628 				i++;
629 
630 				if ( nNum )
631 				{
632 					cAry[i] = (unsigned char)(nNum & 0xFF);
633 					nNum >>= 8;
634 					i++;
635 
636 					if ( nNum )
637 					{
638 						cAry[i] = (unsigned char)(nNum & 0xFF);
639 						nNum >>= 8;
640 						i++;
641 						cAry[1] |= 0x04;
642 					}
643 					else
644 						cAry[1] |= 0x03;
645 				}
646 				else
647 					cAry[1] |= 0x02;
648 			}
649 			else
650 				cAry[1] |= 0x01;
651 		}
652 
653 		rOStream.Write( cAry, i );
654 	}
655 	else
656 	{
657 		rOStream << rRect.nLeft << rRect.nTop << rRect.nRight << rRect.nBottom;
658 	}
659 
660 	return rOStream;
661 }
662