xref: /aoo42x/main/svx/source/svdraw/svdhdl.cxx (revision 5a4c63b7)
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_svx.hxx"
26 
27 #include <algorithm>
28 
29 #include <svx/svdhdl.hxx>
30 #include <svx/svdpagv.hxx>
31 #include <svx/svdetc.hxx>
32 #include <svx/svdmrkv.hxx>
33 #include <vcl/window.hxx>
34 
35 #include <vcl/virdev.hxx>
36 #include <tools/poly.hxx>
37 #include <vcl/bmpacc.hxx>
38 
39 #include <svx/sxekitm.hxx>
40 #include "svx/svdstr.hrc"
41 #include "svx/svdglob.hxx"
42 
43 #include <svx/svdmodel.hxx>
44 #include "gradtrns.hxx"
45 #include <svx/xflgrit.hxx>
46 #include <svx/svdundo.hxx>
47 #include <svx/dialmgr.hxx>
48 #include <svx/xflftrit.hxx>
49 
50 // #105678#
51 #include <svx/svdopath.hxx>
52 #include <basegfx/vector/b2dvector.hxx>
53 #include <basegfx/polygon/b2dpolygon.hxx>
54 #include <svx/sdr/overlay/overlaymanager.hxx>
55 #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
56 #include <svx/sdr/overlay/overlaybitmapex.hxx>
57 #include <svx/sdr/overlay/overlayline.hxx>
58 #include <svx/sdr/overlay/overlaytriangle.hxx>
59 #include <svx/sdr/overlay/overlayrectangle.hxx>
60 #include <svx/sdrpagewindow.hxx>
61 #include <svx/sdrpaintwindow.hxx>
62 #include <vcl/svapp.hxx>
63 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
64 #include <vcl/lazydelete.hxx>
65 
66 #include <basegfx/polygon/b2dpolygontools.hxx>
67 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
68 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
69 #include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
70 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
71 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
72 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
73 
74 ////////////////////////////////////////////////////////////////////////////////////////////////////
75 // #i15222#
76 // Due to the resource problems in Win95/98 with bitmap resources I
77 // will change this handle bitmap providing class. Old version was splitting
78 // and preparing all small handle bitmaps in device bitmap format, now this will
79 // be done on the fly. Thus, there is only the one big bitmap remembered. With
80 // three source bitmaps, this will be 3 system bitmap resources instead of hundreds.
81 // The price for that needs to be evaluated. Maybe we will need another change here
82 // if this is too expensive.
83 class SdrHdlBitmapSet
84 {
85 	// the bitmap holding all infos
86 	BitmapEx					maMarkersBitmap;
87 
88 	// the cropped Bitmaps for reusage
89 	::std::vector< BitmapEx >	maRealMarkers;
90 
91 	// elpers
92 	BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle);
93 
94 public:
95 	SdrHdlBitmapSet(sal_uInt16 nResId);
96 	~SdrHdlBitmapSet();
97 
98 	const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd=0);
99 };
100 
101 ////////////////////////////////////////////////////////////////////////////////////////////////////
102 #define KIND_COUNT			(14)
103 #define INDEX_COUNT			(6)
104 #define INDIVIDUAL_COUNT	(5)
105 
106 SdrHdlBitmapSet::SdrHdlBitmapSet(sal_uInt16 nResId)
107 :	maMarkersBitmap(ResId(nResId, *ImpGetResMgr())), // just use resource with alpha channel
108 	// 14 kinds (BitmapMarkerKind) use index [0..5], 5 extra
109 	maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT)
110 {
111 }
112 
113 SdrHdlBitmapSet::~SdrHdlBitmapSet()
114 {
115 }
116 
117 BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle)
118 {
119 	BitmapEx& rTargetBitmap = maRealMarkers[nIndex];
120 
121 	if(rTargetBitmap.IsEmpty())
122 	{
123 		rTargetBitmap = maMarkersBitmap;
124 		rTargetBitmap.Crop(rRectangle);
125 	}
126 
127 	return rTargetBitmap;
128 }
129 
130 // change getting of bitmap to use the big resource bitmap
131 const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd)
132 {
133 	// fill in size and source position in maMarkersBitmap
134 	const sal_uInt16 nYPos(nInd * 11);
135 
136 	switch(eKindOfMarker)
137 	{
138 		default:
139 		{
140 			DBG_ERROR( "unknown kind of marker" );
141 			// no break here, return Rect_7x7 as default
142 		}
143 		case Rect_7x7:
144 		{
145 			return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, Rectangle(Point(0, nYPos), Size(7, 7)));
146 		}
147 
148 		case Rect_9x9:
149 		{
150 			return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, Rectangle(Point(7, nYPos), Size(9, 9)));
151 		}
152 
153 		case Rect_11x11:
154 		{
155 			return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, Rectangle(Point(16, nYPos), Size(11, 11)));
156 		}
157 
158 		case Rect_13x13:
159 		{
160 			const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd);
161 
162 			switch(nInd)
163 			{
164 				case 0:
165 				{
166 					return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 66), Size(13, 13)));
167 				}
168 				case 1:
169 				{
170 					return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 66), Size(13, 13)));
171 				}
172 				case 2:
173 				{
174 					return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 79), Size(13, 13)));
175 				}
176 				case 3:
177 				{
178 					return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 79), Size(13, 13)));
179 				}
180 				case 4:
181 				{
182 					return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 79), Size(13, 13)));
183 				}
184 				default: // case 5:
185 				{
186 					return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 66), Size(13, 13)));
187 				}
188 			}
189 		}
190 
191 		case Circ_7x7:
192 		case Customshape_7x7:
193 		{
194 			return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, Rectangle(Point(27, nYPos), Size(7, 7)));
195 		}
196 
197 		case Circ_9x9:
198 		case Customshape_9x9:
199 		{
200 			return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, Rectangle(Point(34, nYPos), Size(9, 9)));
201 		}
202 
203 		case Circ_11x11:
204 		case Customshape_11x11:
205 		{
206 			return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, Rectangle(Point(43, nYPos), Size(11, 11)));
207 		}
208 
209 		case Elli_7x9:
210 		{
211 			return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, Rectangle(Point(54, nYPos), Size(7, 9)));
212 		}
213 
214 		case Elli_9x11:
215 		{
216 			return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, Rectangle(Point(61, nYPos), Size(9, 11)));
217 		}
218 
219 		case Elli_9x7:
220 		{
221 			return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, Rectangle(Point(70, nYPos), Size(9, 7)));
222 		}
223 
224 		case Elli_11x9:
225 		{
226 			return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, Rectangle(Point(79, nYPos), Size(11, 9)));
227 		}
228 
229 		case RectPlus_7x7:
230 		{
231 			return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, Rectangle(Point(90, nYPos), Size(7, 7)));
232 		}
233 
234 		case RectPlus_9x9:
235 		{
236 			return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, Rectangle(Point(97, nYPos), Size(9, 9)));
237 		}
238 
239 		case RectPlus_11x11:
240 		{
241 			return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, Rectangle(Point(106, nYPos), Size(11, 11)));
242 		}
243 
244 		case Crosshair:
245 		{
246 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, Rectangle(Point(0, 68), Size(15, 15)));
247 		}
248 
249 		case Glue:
250 		{
251 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, Rectangle(Point(15, 74), Size(9, 9)));
252 		}
253 
254 		case Glue_Unselected:
255 		{
256 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, Rectangle(Point(15, 83), Size(9, 9)));
257 		}
258 
259 		case Anchor: // #101688# AnchorTR for SW
260 		case AnchorTR:
261 		{
262 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, Rectangle(Point(24, 68), Size(24, 24)));
263 		}
264 
265 		// #98388# add AnchorPressed to be able to animate anchor control
266 		case AnchorPressed:
267 		case AnchorPressedTR:
268 		{
269 			return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 4, Rectangle(Point(48, 68), Size(24, 24)));
270 		}
271 	}
272 
273 	// cannot happen since all paths return something; return Rect_7x7 as default (see switch)
274 	return maRealMarkers[0];
275 }
276 
277 ////////////////////////////////////////////////////////////////////////////////////////////////////
278 
279 SdrHdlBitmapSet& getSimpleSet()
280 {
281 	static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aSimpleSet(new SdrHdlBitmapSet(SIP_SA_MARKERS));
282 	return *aSimpleSet.get();
283 }
284 
285 SdrHdlBitmapSet& getModernSet()
286 {
287 	static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aModernSet(new SdrHdlBitmapSet(SIP_SA_FINE_MARKERS));
288 	return *aModernSet.get();
289 }
290 
291 SdrHdlBitmapSet& getHighContrastSet()
292 {
293 	static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aHighContrastSet(new SdrHdlBitmapSet(SIP_SA_ACCESSIBILITY_MARKERS));
294 	return *aHighContrastSet.get();
295 }
296 
297 ////////////////////////////////////////////////////////////////////////////////////////////////////
298 
299 SdrHdl::SdrHdl():
300 	pObj(NULL),
301 	pPV(NULL),
302 	pHdlList(NULL),
303 	eKind(HDL_MOVE),
304 	nDrehWink(0),
305 	nObjHdlNum(0),
306 	nPolyNum(0),
307 	nPPntNum(0),
308 	nSourceHdlNum(0),
309 	bSelect(sal_False),
310 	b1PixMore(sal_False),
311 	bPlusHdl(sal_False),
312 	mbMoveOutside(false),
313 	mbMouseOver(false)
314 {
315 }
316 
317 SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind):
318 	pObj(NULL),
319 	pPV(NULL),
320 	pHdlList(NULL),
321 	aPos(rPnt),
322 	eKind(eNewKind),
323 	nDrehWink(0),
324 	nObjHdlNum(0),
325 	nPolyNum(0),
326 	nPPntNum(0),
327 	nSourceHdlNum(0),
328 	bSelect(sal_False),
329 	b1PixMore(sal_False),
330 	bPlusHdl(sal_False),
331 	mbMoveOutside(false),
332 	mbMouseOver(false)
333 {
334 }
335 
336 SdrHdl::~SdrHdl()
337 {
338 	GetRidOfIAObject();
339 }
340 
341 void SdrHdl::Set1PixMore(sal_Bool bJa)
342 {
343 	if(b1PixMore != bJa)
344 	{
345 		b1PixMore = bJa;
346 
347 		// create new display
348 		Touch();
349 	}
350 }
351 
352 void SdrHdl::SetMoveOutside( bool bMoveOutside )
353 {
354 	if(mbMoveOutside != bMoveOutside)
355 	{
356 		mbMoveOutside = bMoveOutside;
357 
358 		// create new display
359 		Touch();
360 	}
361 }
362 
363 void SdrHdl::SetDrehWink(long n)
364 {
365 	if(nDrehWink != n)
366 	{
367 		nDrehWink = n;
368 
369 		// create new display
370 		Touch();
371 	}
372 }
373 
374 void SdrHdl::SetPos(const Point& rPnt)
375 {
376 	if(aPos != rPnt)
377 	{
378 		// remember new position
379 		aPos = rPnt;
380 
381 		// create new display
382 		Touch();
383 	}
384 }
385 
386 void SdrHdl::SetSelected(sal_Bool bJa)
387 {
388 	if(bSelect != bJa)
389 	{
390 		// remember new value
391 		bSelect = bJa;
392 
393 		// create new display
394 		Touch();
395 	}
396 }
397 
398 void SdrHdl::SetHdlList(SdrHdlList* pList)
399 {
400 	if(pHdlList != pList)
401 	{
402 		// remember list
403 		pHdlList = pList;
404 
405 		// now it's possible to create graphic representation
406 		Touch();
407 	}
408 }
409 
410 void SdrHdl::SetObj(SdrObject* pNewObj)
411 {
412 	if(pObj != pNewObj)
413 	{
414 		// remember new object
415 		pObj = pNewObj;
416 
417 		// graphic representation may have changed
418 		Touch();
419 	}
420 }
421 
422 void SdrHdl::Touch()
423 {
424 	// force update of graphic representation
425 	CreateB2dIAObject();
426 }
427 
428 void SdrHdl::GetRidOfIAObject()
429 {
430 	//OLMaIAOGroup.Delete();
431 
432 	// OVERLAYMANAGER
433 	maOverlayGroup.clear();
434 }
435 
436 void SdrHdl::CreateB2dIAObject()
437 {
438 	// first throw away old one
439 	GetRidOfIAObject();
440 
441 	if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden())
442 	{
443 		BitmapColorIndex eColIndex = LightGreen;
444 		BitmapMarkerKind eKindOfMarker = Rect_7x7;
445 
446 		sal_Bool bRot = pHdlList->IsRotateShear();
447 		if(pObj)
448 			eColIndex = (bSelect) ? Cyan : LightCyan;
449 		if(bRot)
450 		{
451 			// Rotation handles in red
452 			if(pObj && bSelect)
453 				eColIndex = Red;
454 			else
455 				eColIndex = LightRed;
456 		}
457 
458 		switch(eKind)
459 		{
460 			case HDL_MOVE:
461 			{
462 				eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
463 				break;
464 			}
465 			case HDL_UPLFT:
466 			case HDL_UPRGT:
467 			case HDL_LWLFT:
468 			case HDL_LWRGT:
469 			{
470 				// Corner handles
471 				if(bRot)
472 				{
473 					eKindOfMarker = Circ_7x7;
474 				}
475 				else
476 				{
477 					eKindOfMarker = Rect_7x7;
478 				}
479 				break;
480 			}
481 			case HDL_UPPER:
482 			case HDL_LOWER:
483 			{
484 				// Upper/Lower handles
485 				if(bRot)
486 				{
487 					eKindOfMarker = Elli_9x7;
488 				}
489 				else
490 				{
491 					eKindOfMarker = Rect_7x7;
492 				}
493 				break;
494 			}
495 			case HDL_LEFT:
496 			case HDL_RIGHT:
497 			{
498 				// Left/Right handles
499 				if(bRot)
500 				{
501 					eKindOfMarker = Elli_7x9;
502 				}
503 				else
504 				{
505 					eKindOfMarker = Rect_7x7;
506 				}
507 				break;
508 			}
509 			case HDL_POLY:
510 			{
511 				if(bRot)
512 				{
513 					eKindOfMarker = (b1PixMore) ? Circ_9x9 : Circ_7x7;
514 				}
515 				else
516 				{
517 					eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7;
518 				}
519 				break;
520 			}
521 			case HDL_BWGT: // weight at poly
522 			{
523 				eKindOfMarker = Circ_7x7;
524 				break;
525 			}
526 			case HDL_CIRC:
527 			{
528 				eKindOfMarker = Rect_11x11;
529 				break;
530 			}
531 			case HDL_REF1:
532 			case HDL_REF2:
533 			{
534 				eKindOfMarker = Crosshair;
535 				break;
536 			}
537 			case HDL_GLUE:
538 			{
539 				eKindOfMarker = Glue;
540 				break;
541 			}
542 			case HDL_GLUE_UNSEL:
543 			{
544 				eKindOfMarker = Glue_Unselected;
545 				break;
546 			}
547 			case HDL_ANCHOR:
548 			{
549 				eKindOfMarker = Anchor;
550 				break;
551 			}
552 			case HDL_USER:
553 			{
554 				break;
555 			}
556 			// #101688# top right anchor for SW
557 			case HDL_ANCHOR_TR:
558 			{
559 				eKindOfMarker = AnchorTR;
560 				break;
561 			}
562 
563 			// for SJ and the CustomShapeHandles:
564 			case HDL_CUSTOMSHAPE1:
565 			{
566 				eKindOfMarker = (b1PixMore) ? Customshape_9x9 : Customshape_7x7;
567 				eColIndex = Yellow;
568 				break;
569 			}
570 			default:
571 				break;
572 		}
573 
574 		SdrMarkView* pView = pHdlList->GetView();
575 		SdrPageView* pPageView = pView->GetSdrPageView();
576 
577 		if(pPageView)
578 		{
579 			for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
580 			{
581 				// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
582 				const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
583 
584 				if(rPageWindow.GetPaintWindow().OutputToWindow())
585 				{
586 					Point aMoveOutsideOffset(0, 0);
587 
588 					// add offset if necessary
589 					if(pHdlList->IsMoveOutside() || mbMoveOutside)
590 					{
591 						OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice();
592 						Size aOffset = rOutDev.PixelToLogic(Size(4, 4));
593 
594 						if(eKind == HDL_UPLFT || eKind == HDL_UPPER || eKind == HDL_UPRGT)
595 							aMoveOutsideOffset.Y() -= aOffset.Width();
596 						if(eKind == HDL_LWLFT || eKind == HDL_LOWER || eKind == HDL_LWRGT)
597 							aMoveOutsideOffset.Y() += aOffset.Height();
598 						if(eKind == HDL_UPLFT || eKind == HDL_LEFT  || eKind == HDL_LWLFT)
599 							aMoveOutsideOffset.X() -= aOffset.Width();
600 						if(eKind == HDL_UPRGT || eKind == HDL_RIGHT || eKind == HDL_LWRGT)
601 							aMoveOutsideOffset.X() += aOffset.Height();
602 					}
603 
604 					if(rPageWindow.GetOverlayManager())
605 					{
606 						basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
607 						::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
608 							aPosition,
609 							eColIndex,
610 							eKindOfMarker,
611 							aMoveOutsideOffset);
612 
613 						// OVERLAYMANAGER
614 						if(pNewOverlayObject)
615 						{
616 							rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
617 							maOverlayGroup.append(*pNewOverlayObject);
618 						}
619 					}
620 				}
621 			}
622 		}
623 	}
624 }
625 
626 BitmapMarkerKind SdrHdl::GetNextBigger(BitmapMarkerKind eKnd) const
627 {
628 	BitmapMarkerKind eRetval(eKnd);
629 
630 	switch(eKnd)
631 	{
632 		case Rect_7x7:			eRetval = Rect_9x9;			break;
633 		case Rect_9x9:			eRetval = Rect_11x11;		break;
634 		case Rect_11x11:		eRetval = Rect_13x13;		break;
635 		//case Rect_13x13:		eRetval = ;	break;
636 
637 		case Circ_7x7:			eRetval = Circ_9x9;			break;
638 		case Circ_9x9:			eRetval = Circ_11x11;		break;
639 		//case Circ_11x11:		eRetval = ;	break;
640 
641 		case Customshape_7x7:		eRetval = Customshape_9x9;		break;
642 		case Customshape_9x9:		eRetval = Customshape_11x11;	break;
643 		//case Customshape_11x11:	eRetval = ;	break;
644 
645 		case Elli_7x9:			eRetval = Elli_9x11;		break;
646 		//case Elli_9x11:			eRetval = ;	break;
647 
648 		case Elli_9x7:			eRetval = Elli_11x9;		break;
649 		//case Elli_11x9:			eRetval = ;	break;
650 
651 		case RectPlus_7x7:		eRetval = RectPlus_9x9;		break;
652 		case RectPlus_9x9:		eRetval = RectPlus_11x11;	break;
653 		//case RectPlus_11x11:	eRetval = ;	break;
654 
655 		//case Crosshair:			eRetval = ;	break;
656 		//case Glue:				eRetval = ;	break;
657 
658 		// #98388# let anchor blink with its pressed state
659 		case Anchor:			eRetval = AnchorPressed;	break;
660 
661 		// #101688# same for AnchorTR
662 		case AnchorTR:			eRetval = AnchorPressedTR;	break;
663 		default:
664 			break;
665 	}
666 
667 	return eRetval;
668 }
669 
670 // #101928#
671 BitmapEx SdrHdl::ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd, sal_Bool bFine, sal_Bool bIsHighContrast)
672 {
673 	if(bIsHighContrast)
674 	{
675 		return getHighContrastSet().GetBitmapEx(eKindOfMarker, nInd);
676 	}
677 	else
678 	{
679 		if(bFine)
680 		{
681 			return getModernSet().GetBitmapEx(eKindOfMarker, nInd);
682 		}
683 		else
684 		{
685 			return getSimpleSet().GetBitmapEx(eKindOfMarker, nInd);
686 		}
687 	}
688 }
689 
690 ::sdr::overlay::OverlayObject* SdrHdl::CreateOverlayObject(
691 	const basegfx::B2DPoint& rPos,
692 	BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset)
693 {
694 	::sdr::overlay::OverlayObject* pRetval = 0L;
695 	sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
696 	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
697 	sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
698 
699 	// support bigger sizes
700 	sal_Bool bForceBiggerSize(sal_False);
701 
702 	if(pHdlList->GetHdlSize() > 3)
703 	{
704 		switch(eKindOfMarker)
705 		{
706 			case Anchor:
707 			case AnchorPressed:
708 			case AnchorTR:
709 			case AnchorPressedTR:
710 			{
711 				// #121463# For anchor, do not simply make bigger because of HdlSize,
712 				// do it dependent of IsSelected() which Writer can set in drag mode
713 				if(IsSelected())
714 				{
715 					bForceBiggerSize = sal_True;
716 				}
717 				break;
718 			}
719 			default:
720 			{
721 				bForceBiggerSize = sal_True;
722 				break;
723 			}
724 		}
725 	}
726 
727 	// #101928# ...for high contrast, too.
728 	if(!bForceBiggerSize && bIsHighContrast)
729 	{
730 		// #107925#
731 		// ...but not for anchors, else they will not blink when activated
732 		if(Anchor != eKindOfMarker && AnchorTR != eKindOfMarker)
733 		{
734 			bForceBiggerSize = sal_True;
735 		}
736 	}
737 
738 	if(bForceBiggerSize)
739 	{
740 		eKindOfMarker = GetNextBigger(eKindOfMarker);
741 	}
742 
743 	// #97016# II This handle has the focus, visualize it
744 	if(IsFocusHdl() && pHdlList && pHdlList->GetFocusHdl() == this)
745 	{
746 		// create animated handle
747 		BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker);
748 
749 		if(eNextBigger == eKindOfMarker)
750 		{
751 			// this may happen for the not supported getting-bigger types.
752 			// Choose an alternative here
753 			switch(eKindOfMarker)
754 			{
755 				case Rect_13x13:		eNextBigger = Rect_11x11;	break;
756 				case Circ_11x11:		eNextBigger = Elli_11x9;	break;
757 				case Elli_9x11:			eNextBigger = Elli_11x9;	break;
758 				case Elli_11x9:			eNextBigger = Elli_9x11;	break;
759 				case RectPlus_11x11:	eNextBigger = Rect_13x13;	break;
760 
761 				case Crosshair:
762 					eNextBigger = Glue;
763 					break;
764 
765 				case Glue:
766 					eNextBigger = Glue_Unselected;
767 					break;
768 				default:
769 					break;
770 			}
771 		}
772 
773 		// create animated hdl
774 		// #101928# use ImpGetBitmapEx(...) now
775 		BitmapEx aBmpEx1 = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
776 		BitmapEx aBmpEx2 = ImpGetBitmapEx(eNextBigger, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
777 
778 		// #i53216# Use system cursor blink time. Use the unsigned value.
779 		const sal_uInt32 nBlinkTime((sal_uInt32)Application::GetSettings().GetStyleSettings().GetCursorBlinkTime());
780 
781 		if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
782 		{
783 			// #98388# when anchor is used take upper left as reference point inside the handle
784 			pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime);
785 		}
786 		else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
787 		{
788 			// #101688# AnchorTR for SW, take top right as (0,0)
789 			pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
790 				(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1), 0,
791 				(sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1), 0);
792 		}
793 		else
794 		{
795 			// create centered handle as default
796 			pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime,
797 				(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
798 				(sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
799 				(sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
800 				(sal_uInt16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1);
801 		}
802 	}
803 	else
804 	{
805 		// create normal handle
806 		// #101928# use ImpGetBitmapEx(...) now
807 		BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast);
808 
809 		if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed)
810 		{
811 			// #98388# upper left as reference point inside the handle for AnchorPressed, too
812 			pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx);
813 		}
814 		else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR)
815 		{
816 			// #101688# AnchorTR for SW, take top right as (0,0)
817 			pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx,
818 				(sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1), 0);
819 		}
820 		else
821 		{
822 			sal_uInt16 nCenX((sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1L) >> 1);
823 			sal_uInt16 nCenY((sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1L) >> 1);
824 
825 			if(aMoveOutsideOffset.X() > 0)
826 			{
827 				nCenX = 0;
828 			}
829 			else if(aMoveOutsideOffset.X() < 0)
830 			{
831 				nCenX = (sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1);
832 			}
833 
834 			if(aMoveOutsideOffset.Y() > 0)
835 			{
836 				nCenY = 0;
837 			}
838 			else if(aMoveOutsideOffset.Y() < 0)
839 			{
840 				nCenY = (sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1);
841 			}
842 
843 			// create centered handle as default
844 			pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, nCenX, nCenY);
845 		}
846 	}
847 
848 	return pRetval;
849 }
850 
851 bool SdrHdl::IsHdlHit(const Point& rPnt) const
852 {
853 	// OVERLAYMANAGER
854 	basegfx::B2DPoint aPosition(rPnt.X(), rPnt.Y());
855 	return maOverlayGroup.isHitLogic(aPosition);
856 }
857 
858 Pointer SdrHdl::GetPointer() const
859 {
860 	PointerStyle ePtr=POINTER_MOVE;
861 	const sal_Bool bSize=eKind>=HDL_UPLFT && eKind<=HDL_LWRGT;
862 	const sal_Bool bRot=pHdlList!=NULL && pHdlList->IsRotateShear();
863 	const sal_Bool bDis=pHdlList!=NULL && pHdlList->IsDistortShear();
864 	if (bSize && pHdlList!=NULL && (bRot || bDis)) {
865 		switch (eKind) {
866 			case HDL_UPLFT: case HDL_UPRGT:
867 			case HDL_LWLFT: case HDL_LWRGT: ePtr=bRot ? POINTER_ROTATE : POINTER_REFHAND; break;
868 			case HDL_LEFT : case HDL_RIGHT: ePtr=POINTER_VSHEAR; break;
869 			case HDL_UPPER: case HDL_LOWER: ePtr=POINTER_HSHEAR; break;
870 			default:
871 				break;
872 		}
873 	} else {
874 		// Fuer Resize von gedrehten Rechtecken die Mauszeiger etwas mitdrehen
875 		if (bSize && nDrehWink!=0) {
876 			long nHdlWink=0;
877 			switch (eKind) {
878 				case HDL_LWRGT: nHdlWink=31500;	break;
879 				case HDL_LOWER: nHdlWink=27000;	break;
880 				case HDL_LWLFT: nHdlWink=22500;	break;
881 				case HDL_LEFT : nHdlWink=18000;	break;
882 				case HDL_UPLFT: nHdlWink=13500;	break;
883 				case HDL_UPPER: nHdlWink=9000;	break;
884 				case HDL_UPRGT: nHdlWink=4500;	break;
885 				case HDL_RIGHT: nHdlWink=0;		break;
886 				default:
887 					break;
888 			}
889 			nHdlWink+=nDrehWink+2249; // und etwas drauf (zum runden)
890 			while (nHdlWink<0) nHdlWink+=36000;
891 			while (nHdlWink>=36000) nHdlWink-=36000;
892 			nHdlWink/=4500;
893 			switch ((sal_uInt8)nHdlWink) {
894 				case 0: ePtr=POINTER_ESIZE;		break;
895 				case 1: ePtr=POINTER_NESIZE;	break;
896 				case 2: ePtr=POINTER_NSIZE;		break;
897 				case 3: ePtr=POINTER_NWSIZE;	break;
898 				case 4: ePtr=POINTER_WSIZE;		break;
899 				case 5: ePtr=POINTER_SWSIZE;	break;
900 				case 6: ePtr=POINTER_SSIZE;		break;
901 				case 7: ePtr=POINTER_SESIZE;	break;
902 			} // switch
903 		} else {
904 			switch (eKind) {
905 				case HDL_UPLFT: ePtr=POINTER_NWSIZE;	break;
906 				case HDL_UPPER: ePtr=POINTER_NSIZE;		break;
907 				case HDL_UPRGT: ePtr=POINTER_NESIZE;	break;
908 				case HDL_LEFT : ePtr=POINTER_WSIZE;		break;
909 				case HDL_RIGHT: ePtr=POINTER_ESIZE;		break;
910 				case HDL_LWLFT: ePtr=POINTER_SWSIZE;	break;
911 				case HDL_LOWER: ePtr=POINTER_SSIZE;		break;
912 				case HDL_LWRGT: ePtr=POINTER_SESIZE;	break;
913 				case HDL_POLY : ePtr=POINTER_MOVEPOINT;	break;
914 				case HDL_CIRC : ePtr=POINTER_HAND;		break;
915 				case HDL_REF1 : ePtr=POINTER_REFHAND;	break;
916 				case HDL_REF2 : ePtr=POINTER_REFHAND;	break;
917 				case HDL_BWGT : ePtr=POINTER_MOVEBEZIERWEIGHT;	break;
918 				case HDL_GLUE : ePtr=POINTER_MOVEPOINT;	break;
919 				case HDL_GLUE_UNSEL : ePtr=POINTER_MOVEPOINT;	break;
920 				case HDL_CUSTOMSHAPE1 : ePtr=POINTER_HAND;	break;
921 				default:
922 					break;
923 			}
924 		}
925 	}
926 	return Pointer(ePtr);
927 }
928 
929 // #97016# II
930 sal_Bool SdrHdl::IsFocusHdl() const
931 {
932 	switch(eKind)
933 	{
934 		case HDL_UPLFT:		// top left
935 		case HDL_UPPER:		// top
936 		case HDL_UPRGT:		// top right
937 		case HDL_LEFT:		// left
938 		case HDL_RIGHT:		// right
939 		case HDL_LWLFT:		// bottom left
940 		case HDL_LOWER:		// bottom
941 		case HDL_LWRGT:		// bottom right
942 		{
943 			// if it's an activated TextEdit, it's moved to extended points
944 			if(pHdlList && pHdlList->IsMoveOutside())
945 				return sal_False;
946 			else
947 				return sal_True;
948 		}
949 
950 		case HDL_MOVE:		// Handle zum Verschieben des Objekts
951 		case HDL_POLY:		// Punktselektion an Polygon oder Bezierkurve
952 		case HDL_BWGT:		// Gewicht an einer Bezierkurve
953 		case HDL_CIRC:		// Winkel an Kreissegmenten, Eckenradius am Rect
954 		case HDL_REF1:		// Referenzpunkt 1, z.B. Rotationsmitte
955 		case HDL_REF2:		// Referenzpunkt 2, z.B. Endpunkt der Spiegelachse
956 		//case HDL_MIRX:		// Die Spiegelachse selbst
957 		case HDL_GLUE:		// glue point
958 		case HDL_GLUE_UNSEL: // glue point unselected
959 
960 		// #98388# do NOT activate here, let SW implement their own SdrHdl and
961 		// overload IsFocusHdl() there to make the anchor accessible
962 		//case HDL_ANCHOR:		// anchor symbol (SD, SW)
963 		// #101688# same for AnchorTR
964 		//case HDL_ANCHOR_TR:	// anchor symbol (SD, SW)
965 
966 		//case HDL_TRNS:		// interactive transparency
967 		//case HDL_GRAD:		// interactive gradient
968 		//case HDL_COLR:		// interactive color
969 
970 		// for SJ and the CustomShapeHandles:
971 		case HDL_CUSTOMSHAPE1:
972 
973 		case HDL_USER:
974 		{
975 			return sal_True;
976 		}
977 
978 		default:
979 		{
980 			return sal_False;
981 		}
982 	}
983 }
984 
985 void SdrHdl::onMouseEnter(const MouseEvent& /*rMEvt*/)
986 {
987 }
988 
989 void SdrHdl::onMouseLeave()
990 {
991 }
992 
993 bool SdrHdl::isMouseOver() const
994 {
995 	return mbMouseOver;
996 }
997 
998 ////////////////////////////////////////////////////////////////////////////////////////////////////
999 // class SdrHdlColor
1000 
1001 SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, sal_Bool bLum)
1002 :	SdrHdl(rRef, HDL_COLR),
1003 	aMarkerSize(rSize),
1004 	bUseLuminance(bLum)
1005 {
1006 	if(IsUseLuminance())
1007 		aCol = GetLuminance(aCol);
1008 
1009 	// remember color
1010 	aMarkerColor = aCol;
1011 }
1012 
1013 SdrHdlColor::~SdrHdlColor()
1014 {
1015 }
1016 
1017 void SdrHdlColor::CreateB2dIAObject()
1018 {
1019 	// first throw away old one
1020 	GetRidOfIAObject();
1021 
1022 	if(pHdlList)
1023 	{
1024 		SdrMarkView* pView = pHdlList->GetView();
1025 
1026 		if(pView && !pView->areMarkHandlesHidden())
1027 		{
1028 			SdrPageView* pPageView = pView->GetSdrPageView();
1029 
1030 			if(pPageView)
1031 			{
1032 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1033 				{
1034 					// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
1035 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1036 
1037 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1038 					{
1039 						if(rPageWindow.GetOverlayManager())
1040 						{
1041 							Bitmap aBmpCol(CreateColorDropper(aMarkerColor));
1042 							basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1043 							::sdr::overlay::OverlayObject* pNewOverlayObject = new
1044 								::sdr::overlay::OverlayBitmapEx(
1045 									aPosition,
1046 									BitmapEx(aBmpCol),
1047 									(sal_uInt16)(aBmpCol.GetSizePixel().Width() - 1) >> 1,
1048 									(sal_uInt16)(aBmpCol.GetSizePixel().Height() - 1) >> 1
1049 								);
1050 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1051 
1052 							// OVERLAYMANAGER
1053 							if(pNewOverlayObject)
1054 							{
1055 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1056 								maOverlayGroup.append(*pNewOverlayObject);
1057 							}
1058 						}
1059 					}
1060 				}
1061 			}
1062 		}
1063 	}
1064 }
1065 
1066 Bitmap SdrHdlColor::CreateColorDropper(Color aCol)
1067 {
1068 	// get the Bitmap
1069 	Bitmap aRetval(aMarkerSize, 24);
1070 	aRetval.Erase(aCol);
1071 
1072 	// get write access
1073 	BitmapWriteAccess* pWrite = aRetval.AcquireWriteAccess();
1074 	DBG_ASSERT(pWrite, "Got NO write access to a new Bitmap !!!");
1075 
1076 	if(pWrite)
1077 	{
1078 		// draw outer border
1079 		sal_Int32 nWidth = aMarkerSize.Width();
1080 		sal_Int32 nHeight = aMarkerSize.Height();
1081 
1082 		pWrite->SetLineColor(Color(COL_LIGHTGRAY));
1083 		pWrite->DrawLine(Point(0, 0), Point(0, nHeight - 1));
1084 		pWrite->DrawLine(Point(1, 0), Point(nWidth - 1, 0));
1085 		pWrite->SetLineColor(Color(COL_GRAY));
1086 		pWrite->DrawLine(Point(1, nHeight - 1), Point(nWidth - 1, nHeight - 1));
1087 		pWrite->DrawLine(Point(nWidth - 1, 1), Point(nWidth - 1, nHeight - 2));
1088 
1089 		// draw lighter UpperLeft
1090 		const Color aLightColor(
1091 			(sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetRed() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
1092 			(sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetGreen() + (sal_Int16)0x0040), (sal_Int16)0x00ff)),
1093 			(sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetBlue() + (sal_Int16)0x0040), (sal_Int16)0x00ff)));
1094 		pWrite->SetLineColor(aLightColor);
1095 		pWrite->DrawLine(Point(1, 1), Point(1, nHeight - 2));
1096 		pWrite->DrawLine(Point(2, 1), Point(nWidth - 2, 1));
1097 
1098 		// draw darker LowerRight
1099 		const Color aDarkColor(
1100 			(sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetRed() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
1101 			(sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetGreen() - (sal_Int16)0x0040), (sal_Int16)0x0000)),
1102 			(sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetBlue() - (sal_Int16)0x0040), (sal_Int16)0x0000)));
1103 		pWrite->SetLineColor(aDarkColor);
1104 		pWrite->DrawLine(Point(2, nHeight - 2), Point(nWidth - 2, nHeight - 2));
1105 		pWrite->DrawLine(Point(nWidth - 2, 2), Point(nWidth - 2, nHeight - 3));
1106 
1107 		// get rid of write access
1108 		delete pWrite;
1109 	}
1110 
1111 	return aRetval;
1112 }
1113 
1114 Color SdrHdlColor::GetLuminance(const Color& rCol)
1115 {
1116 	sal_uInt8 aLum = rCol.GetLuminance();
1117 	Color aRetval(aLum, aLum, aLum);
1118 	return aRetval;
1119 }
1120 
1121 void SdrHdlColor::CallColorChangeLink()
1122 {
1123 	aColorChangeHdl.Call(this);
1124 }
1125 
1126 void SdrHdlColor::SetColor(Color aNew, sal_Bool bCallLink)
1127 {
1128 	if(IsUseLuminance())
1129 		aNew = GetLuminance(aNew);
1130 
1131 	if(aMarkerColor != aNew)
1132 	{
1133 		// remember new color
1134 		aMarkerColor = aNew;
1135 
1136 		// create new display
1137 		Touch();
1138 
1139 		// tell about change
1140 		if(bCallLink)
1141 			CallColorChangeLink();
1142 	}
1143 }
1144 
1145 void SdrHdlColor::SetSize(const Size& rNew)
1146 {
1147 	if(rNew != aMarkerSize)
1148 	{
1149 		// remember new size
1150 		aMarkerSize = rNew;
1151 
1152 		// create new display
1153 		Touch();
1154 	}
1155 }
1156 
1157 ////////////////////////////////////////////////////////////////////////////////////////////////////
1158 // class SdrHdlGradient
1159 
1160 SdrHdlGradient::SdrHdlGradient(const Point& rRef1, const Point& rRef2, sal_Bool bGrad)
1161 :	SdrHdl(rRef1, bGrad ? HDL_GRAD : HDL_TRNS),
1162 	pColHdl1(NULL),
1163 	pColHdl2(NULL),
1164 	a2ndPos(rRef2),
1165 	bGradient(bGrad)
1166 {
1167 }
1168 
1169 SdrHdlGradient::~SdrHdlGradient()
1170 {
1171 }
1172 
1173 void SdrHdlGradient::Set2ndPos(const Point& rPnt)
1174 {
1175 	if(a2ndPos != rPnt)
1176 	{
1177 		// remember new position
1178 		a2ndPos = rPnt;
1179 
1180 		// create new display
1181 		Touch();
1182 	}
1183 }
1184 
1185 void SdrHdlGradient::CreateB2dIAObject()
1186 {
1187 	// first throw away old one
1188 	GetRidOfIAObject();
1189 
1190 	if(pHdlList)
1191 	{
1192 		SdrMarkView* pView = pHdlList->GetView();
1193 
1194 		if(pView && !pView->areMarkHandlesHidden())
1195 		{
1196 			SdrPageView* pPageView = pView->GetSdrPageView();
1197 
1198 			if(pPageView)
1199 			{
1200 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1201 				{
1202 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1203 
1204 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1205 					{
1206 						if(rPageWindow.GetOverlayManager())
1207 						{
1208 							// striped line in between
1209 							basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y());
1210 							double fVecLen = aVec.getLength();
1211 							double fLongPercentArrow = (1.0 - 0.05) * fVecLen;
1212 							double fHalfArrowWidth = (0.05 * 0.5) * fVecLen;
1213 							aVec.normalize();
1214 							basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX());
1215 							sal_Int32 nMidX = (sal_Int32)(aPos.X() + aVec.getX() * fLongPercentArrow);
1216 							sal_Int32 nMidY = (sal_Int32)(aPos.Y() + aVec.getY() * fLongPercentArrow);
1217 							Point aMidPoint(nMidX, nMidY);
1218 
1219 							basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1220 							basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y());
1221 
1222 							::sdr::overlay::OverlayObject* pNewOverlayObject = new
1223 								::sdr::overlay::OverlayLineStriped(
1224 									aPosition, aMidPos
1225 								);
1226 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1227 
1228 							pNewOverlayObject->setBaseColor(IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE));
1229 							rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1230 							maOverlayGroup.append(*pNewOverlayObject);
1231 
1232 							// arrowhead
1233 							Point aLeft(aMidPoint.X() + (sal_Int32)(aPerpend.getX() * fHalfArrowWidth),
1234 										aMidPoint.Y() + (sal_Int32)(aPerpend.getY() * fHalfArrowWidth));
1235 							Point aRight(aMidPoint.X() - (sal_Int32)(aPerpend.getX() * fHalfArrowWidth),
1236 										aMidPoint.Y() - (sal_Int32)(aPerpend.getY() * fHalfArrowWidth));
1237 
1238 							basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y());
1239 							basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y());
1240 							basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y());
1241 
1242 							pNewOverlayObject = new
1243 								::sdr::overlay::OverlayTriangle(
1244 									aPositionLeft,
1245 									aPosition2,
1246 									aPositionRight,
1247 									IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE)
1248 								);
1249 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1250 
1251 							rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1252 							maOverlayGroup.append(*pNewOverlayObject);
1253 						}
1254 					}
1255 				}
1256 			}
1257 		}
1258 	}
1259 }
1260 
1261 IMPL_LINK(SdrHdlGradient, ColorChangeHdl, SdrHdl*, /*pHdl*/)
1262 {
1263 	if(GetObj())
1264 		FromIAOToItem(GetObj(), sal_True, sal_True);
1265 	return 0;
1266 }
1267 
1268 void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, sal_Bool bSetItemOnObject, sal_Bool bUndo)
1269 {
1270 	// from IAO positions and colors to gradient
1271 	const SfxItemSet& rSet = _pObj->GetMergedItemSet();
1272 
1273 	GradTransformer aGradTransformer;
1274 	GradTransGradient aOldGradTransGradient;
1275 	GradTransGradient aGradTransGradient;
1276 	GradTransVector aGradTransVector;
1277 
1278 	String aString;
1279 
1280 	aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y());
1281 	aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y());
1282 	if(pColHdl1)
1283 		aGradTransVector.aCol1 = pColHdl1->GetColor();
1284 	if(pColHdl2)
1285 		aGradTransVector.aCol2 = pColHdl2->GetColor();
1286 
1287 	if(IsGradient())
1288 		aOldGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
1289 	else
1290 		aOldGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue();
1291 
1292 	// transform vector data to gradient
1293 	aGradTransformer.VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle);
1294 
1295 	if(bSetItemOnObject)
1296 	{
1297 		SdrModel* pModel = _pObj->GetModel();
1298 		SfxItemSet aNewSet(pModel->GetItemPool());
1299 
1300 		if(IsGradient())
1301 		{
1302 			aString = String();
1303 			XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient);
1304 			aNewSet.Put(aNewGradItem);
1305 		}
1306 		else
1307 		{
1308 			aString = String();
1309 			XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient);
1310 			aNewSet.Put(aNewTransItem);
1311 		}
1312 
1313 		if(bUndo && pModel->IsUndoEnabled())
1314 		{
1315 			pModel->BegUndo(SVX_RESSTR(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE));
1316 			pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*_pObj));
1317 			pModel->EndUndo();
1318 		}
1319 
1320 		pObj->SetMergedItemSetAndBroadcast(aNewSet);
1321 	}
1322 
1323 	// back transformation, set values on pIAOHandle
1324 	aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, _pObj);
1325 
1326 	SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1327 	Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1328 	if(pColHdl1)
1329 	{
1330 		pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY())));
1331 		pColHdl1->SetColor(aGradTransVector.aCol1);
1332 	}
1333 	if(pColHdl2)
1334 	{
1335 		pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY())));
1336 		pColHdl2->SetColor(aGradTransVector.aCol2);
1337 	}
1338 }
1339 
1340 ////////////////////////////////////////////////////////////////////////////////////////////////////
1341 
1342 SdrHdlLine::~SdrHdlLine() {}
1343 
1344 void SdrHdlLine::CreateB2dIAObject()
1345 {
1346 	// first throw away old one
1347 	GetRidOfIAObject();
1348 
1349 	if(pHdlList)
1350 	{
1351 		SdrMarkView* pView = pHdlList->GetView();
1352 
1353 		if(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2)
1354 		{
1355 			SdrPageView* pPageView = pView->GetSdrPageView();
1356 
1357 			if(pPageView)
1358 			{
1359 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1360 				{
1361 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1362 
1363 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1364 					{
1365 						if(rPageWindow.GetOverlayManager())
1366 						{
1367 							basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1368 							basegfx::B2DPoint aPosition2(pHdl2->GetPos().X(), pHdl2->GetPos().Y());
1369 
1370 							::sdr::overlay::OverlayObject* pNewOverlayObject = new
1371 								::sdr::overlay::OverlayLineStriped(
1372 									aPosition1,
1373 									aPosition2
1374 								);
1375 							DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1376 
1377 							// OVERLAYMANAGER
1378 							if(pNewOverlayObject)
1379 							{
1380 								// color(?)
1381 								pNewOverlayObject->setBaseColor(Color(COL_LIGHTRED));
1382 
1383 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1384 								maOverlayGroup.append(*pNewOverlayObject);
1385 							}
1386 						}
1387 					}
1388 				}
1389 			}
1390 		}
1391 	}
1392 }
1393 
1394 Pointer SdrHdlLine::GetPointer() const
1395 {
1396 	return Pointer(POINTER_REFHAND);
1397 }
1398 
1399 ////////////////////////////////////////////////////////////////////////////////////////////////////
1400 
1401 SdrHdlBezWgt::~SdrHdlBezWgt() {}
1402 
1403 void SdrHdlBezWgt::CreateB2dIAObject()
1404 {
1405 	// call parent
1406 	SdrHdl::CreateB2dIAObject();
1407 
1408 	// create lines
1409 	if(pHdlList)
1410 	{
1411 		SdrMarkView* pView = pHdlList->GetView();
1412 
1413 		if(pView && !pView->areMarkHandlesHidden())
1414 		{
1415 			SdrPageView* pPageView = pView->GetSdrPageView();
1416 
1417 			if(pPageView)
1418 			{
1419 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1420 				{
1421 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1422 
1423 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1424 					{
1425 						if(rPageWindow.GetOverlayManager())
1426 						{
1427 							basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y());
1428 							basegfx::B2DPoint aPosition2(aPos.X(), aPos.Y());
1429 
1430 							if(!aPosition1.equal(aPosition2))
1431 							{
1432 								::sdr::overlay::OverlayObject* pNewOverlayObject = new
1433 									::sdr::overlay::OverlayLineStriped(
1434 										aPosition1,
1435 										aPosition2
1436 									);
1437 								DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1438 
1439 								// OVERLAYMANAGER
1440 								if(pNewOverlayObject)
1441 								{
1442 									// line part is not hittable
1443 									pNewOverlayObject->setHittable(sal_False);
1444 
1445 									// color(?)
1446 									pNewOverlayObject->setBaseColor(Color(COL_LIGHTBLUE));
1447 
1448 									rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1449 									maOverlayGroup.append(*pNewOverlayObject);
1450 								}
1451 							}
1452 						}
1453 					}
1454 				}
1455 			}
1456 		}
1457 	}
1458 }
1459 
1460 ////////////////////////////////////////////////////////////////////////////////////////////////////
1461 
1462 E3dVolumeMarker::E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly)
1463 {
1464 	aWireframePoly = rWireframePoly;
1465 }
1466 
1467 void E3dVolumeMarker::CreateB2dIAObject()
1468 {
1469 	// create lines
1470 	if(pHdlList)
1471 	{
1472 		SdrMarkView* pView = pHdlList->GetView();
1473 
1474 		if(pView && !pView->areMarkHandlesHidden())
1475 		{
1476 			SdrPageView* pPageView = pView->GetSdrPageView();
1477 
1478 			if(pPageView)
1479 			{
1480 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1481 				{
1482 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1483 
1484 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1485 					{
1486 						if(rPageWindow.GetOverlayManager() && aWireframePoly.count())
1487 							{
1488 								::sdr::overlay::OverlayObject* pNewOverlayObject = new
1489 								::sdr::overlay::OverlayPolyPolygonStripedAndFilled(
1490 									aWireframePoly);
1491 								DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!");
1492 
1493 								// OVERLAYMANAGER
1494 								if(pNewOverlayObject)
1495 								{
1496 									pNewOverlayObject->setBaseColor(Color(COL_BLACK));
1497 
1498 									rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1499 									maOverlayGroup.append(*pNewOverlayObject);
1500 								}
1501 							}
1502 						}
1503 					}
1504 				}
1505 			}
1506 		}
1507 	}
1508 
1509 ////////////////////////////////////////////////////////////////////////////////////////////////////
1510 
1511 ImpEdgeHdl::~ImpEdgeHdl()
1512 {
1513 }
1514 
1515 void ImpEdgeHdl::CreateB2dIAObject()
1516 {
1517 	if(nObjHdlNum <= 1 && pObj)
1518 	{
1519 		// first throw away old one
1520 		GetRidOfIAObject();
1521 
1522 		BitmapColorIndex eColIndex = LightCyan;
1523 		BitmapMarkerKind eKindOfMarker = Rect_7x7;
1524 
1525 		if(pHdlList)
1526 		{
1527 			SdrMarkView* pView = pHdlList->GetView();
1528 
1529 			if(pView && !pView->areMarkHandlesHidden())
1530 			{
1531 				const SdrEdgeObj* pEdge = (SdrEdgeObj*)pObj;
1532 
1533 				if(pEdge->GetConnectedNode(nObjHdlNum == 0) != NULL)
1534 					eColIndex = LightRed;
1535 
1536 				if(nPPntNum < 2)
1537 				{
1538 					// Handle with plus sign inside
1539 					eKindOfMarker = Circ_7x7;
1540 				}
1541 
1542 				SdrPageView* pPageView = pView->GetSdrPageView();
1543 
1544 				if(pPageView)
1545 				{
1546 					for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1547 					{
1548 						const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1549 
1550 						if(rPageWindow.GetPaintWindow().OutputToWindow())
1551 						{
1552 							if(rPageWindow.GetOverlayManager())
1553 							{
1554 								basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1555 
1556 								::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
1557 									aPosition,
1558 									eColIndex,
1559 									eKindOfMarker);
1560 
1561 								// OVERLAYMANAGER
1562 								if(pNewOverlayObject)
1563 								{
1564 									rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1565 									maOverlayGroup.append(*pNewOverlayObject);
1566 								}
1567 							}
1568 						}
1569 					}
1570 				}
1571 			}
1572 		}
1573 	}
1574 	else
1575 	{
1576 		// call parent
1577 		SdrHdl::CreateB2dIAObject();
1578 	}
1579 }
1580 
1581 void ImpEdgeHdl::SetLineCode(SdrEdgeLineCode eCode)
1582 {
1583 	if(eLineCode != eCode)
1584 	{
1585 		// remember new value
1586 		eLineCode = eCode;
1587 
1588 		// create new display
1589 		Touch();
1590 	}
1591 }
1592 
1593 Pointer ImpEdgeHdl::GetPointer() const
1594 {
1595 	SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
1596 	if (pEdge==NULL)
1597 		return SdrHdl::GetPointer();
1598 	if (nObjHdlNum<=1)
1599 		return Pointer(POINTER_MOVEPOINT); //Pointer(POINTER_DRAW_CONNECT);
1600 	if (IsHorzDrag())
1601 		return Pointer(POINTER_ESIZE);
1602 	else
1603 		return Pointer(POINTER_SSIZE);
1604 }
1605 
1606 sal_Bool ImpEdgeHdl::IsHorzDrag() const
1607 {
1608 	SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj);
1609 	if (pEdge==NULL)
1610 		return sal_False;
1611 	if (nObjHdlNum<=1)
1612 		return sal_False;
1613 
1614 	SdrEdgeKind eEdgeKind = ((SdrEdgeKindItem&)(pEdge->GetObjectItem(SDRATTR_EDGEKIND))).GetValue();
1615 
1616 	const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo;
1617 	if (eEdgeKind==SDREDGE_ORTHOLINES || eEdgeKind==SDREDGE_BEZIER)
1618 	{
1619 		return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack);
1620 	}
1621 	else if (eEdgeKind==SDREDGE_THREELINES)
1622 	{
1623 		long nWink=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2;
1624 		if (nWink==0 || nWink==18000)
1625 			return sal_True;
1626 		else
1627 			return sal_False;
1628 	}
1629 	return sal_False;
1630 }
1631 
1632 ////////////////////////////////////////////////////////////////////////////////////////////////////
1633 
1634 ImpMeasureHdl::~ImpMeasureHdl()
1635 {
1636 }
1637 
1638 void ImpMeasureHdl::CreateB2dIAObject()
1639 {
1640 	// first throw away old one
1641 	GetRidOfIAObject();
1642 
1643 	if(pHdlList)
1644 	{
1645 		SdrMarkView* pView = pHdlList->GetView();
1646 
1647 		if(pView && !pView->areMarkHandlesHidden())
1648 		{
1649 			BitmapColorIndex eColIndex = LightCyan;
1650 			BitmapMarkerKind eKindOfMarker = Rect_9x9;
1651 
1652 			if(nObjHdlNum > 1)
1653 			{
1654 				eKindOfMarker = Rect_7x7;
1655 			}
1656 
1657 			if(bSelect)
1658 			{
1659 				eColIndex = Cyan;
1660 			}
1661 
1662 			SdrPageView* pPageView = pView->GetSdrPageView();
1663 
1664 			if(pPageView)
1665 			{
1666 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1667 				{
1668 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1669 
1670 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1671 					{
1672 						if(rPageWindow.GetOverlayManager())
1673 						{
1674 							basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
1675 
1676 							::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject(
1677 								aPosition,
1678 								eColIndex,
1679 								eKindOfMarker);
1680 
1681 							// OVERLAYMANAGER
1682 							if(pNewOverlayObject)
1683 							{
1684 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1685 								maOverlayGroup.append(*pNewOverlayObject);
1686 							}
1687 						}
1688 					}
1689 				}
1690 			}
1691 		}
1692 	}
1693 }
1694 
1695 Pointer ImpMeasureHdl::GetPointer() const
1696 {
1697 	switch (nObjHdlNum)
1698 	{
1699 		case 0: case 1: return Pointer(POINTER_HAND);
1700 		case 2: case 3: return Pointer(POINTER_MOVEPOINT);
1701 		case 4: case 5: return SdrHdl::GetPointer(); // will be rotated accordingly
1702 	} // switch
1703 	return Pointer(POINTER_NOTALLOWED);
1704 }
1705 
1706 ////////////////////////////////////////////////////////////////////////////////////////////////////
1707 
1708 ImpTextframeHdl::ImpTextframeHdl(const Rectangle& rRect) :
1709 	SdrHdl(rRect.TopLeft(),HDL_MOVE),
1710 	maRect(rRect)
1711 {
1712 }
1713 
1714 void ImpTextframeHdl::CreateB2dIAObject()
1715 {
1716 	// first throw away old one
1717 	GetRidOfIAObject();
1718 
1719 	if(pHdlList)
1720 	{
1721 		SdrMarkView* pView = pHdlList->GetView();
1722 
1723 		if(pView && !pView->areMarkHandlesHidden())
1724 		{
1725 			SdrPageView* pPageView = pView->GetSdrPageView();
1726 
1727 			if(pPageView)
1728 			{
1729 				for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
1730 				{
1731 					const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1732 
1733 					if(rPageWindow.GetPaintWindow().OutputToWindow())
1734 					{
1735 						if(rPageWindow.GetOverlayManager())
1736 						{
1737 							const basegfx::B2DPoint aTopLeft(maRect.Left(), maRect.Top());
1738 							const basegfx::B2DPoint aBottomRight(maRect.Right(), maRect.Bottom());
1739 							const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
1740 							const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
1741 							const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
1742 
1743 							::sdr::overlay::OverlayRectangle* pNewOverlayObject = new ::sdr::overlay::OverlayRectangle(
1744 								aTopLeft,
1745 								aBottomRight,
1746 								aHilightColor,
1747 								fTransparence,
1748 								3.0,
1749 								3.0,
1750 								nDrehWink * -F_PI18000,
1751 								500,
1752 								true); // allow animation; the Handle is not shown at text edit time
1753 
1754 							pNewOverlayObject->setHittable(false);
1755 
1756 							// OVERLAYMANAGER
1757 							if(pNewOverlayObject)
1758 							{
1759 								rPageWindow.GetOverlayManager()->add(*pNewOverlayObject);
1760 								maOverlayGroup.append(*pNewOverlayObject);
1761 							}
1762 						}
1763 					}
1764 				}
1765 			}
1766 		}
1767 	}
1768 }
1769 
1770 ////////////////////////////////////////////////////////////////////////////////////////////////////
1771 
1772 class ImpSdrHdlListSorter: public ContainerSorter {
1773 public:
1774 	ImpSdrHdlListSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
1775 	virtual int Compare(const void* pElem1, const void* pElem2) const;
1776 };
1777 
1778 int ImpSdrHdlListSorter::Compare(const void* pElem1, const void* pElem2) const
1779 {
1780 	SdrHdlKind eKind1=((SdrHdl*)pElem1)->GetKind();
1781 	SdrHdlKind eKind2=((SdrHdl*)pElem2)->GetKind();
1782 	// Level 1: Erst normale Handles, dann Glue, dann User, dann Plushandles, dann Retpunkt-Handles
1783 	unsigned n1=1;
1784 	unsigned n2=1;
1785 	if (eKind1!=eKind2)
1786 	{
1787 		if (eKind1==HDL_REF1 || eKind1==HDL_REF2 || eKind1==HDL_MIRX) n1=5;
1788 		else if (eKind1==HDL_GLUE || eKind1==HDL_GLUE_UNSEL) n1=2;
1789 		else if (eKind1==HDL_USER) n1=3;
1790 		else if (eKind1==HDL_SMARTTAG) n1=0;
1791 		if (eKind2==HDL_REF1 || eKind2==HDL_REF2 || eKind2==HDL_MIRX) n2=5;
1792 		else if (eKind2==HDL_GLUE || eKind1==HDL_GLUE_UNSEL) n2=2;
1793 		else if (eKind2==HDL_USER) n2=3;
1794 		else if (eKind2==HDL_SMARTTAG) n2=0;
1795 	}
1796 	if (((SdrHdl*)pElem1)->IsPlusHdl()) n1=4;
1797 	if (((SdrHdl*)pElem2)->IsPlusHdl()) n2=4;
1798 	if (n1==n2)
1799 	{
1800 		// Level 2: PageView (Pointer)
1801 		SdrPageView* pPV1=((SdrHdl*)pElem1)->GetPageView();
1802 		SdrPageView* pPV2=((SdrHdl*)pElem2)->GetPageView();
1803 		if (pPV1==pPV2)
1804 		{
1805 			// Level 3: Position (x+y)
1806 			SdrObject* pObj1=((SdrHdl*)pElem1)->GetObj();
1807 			SdrObject* pObj2=((SdrHdl*)pElem2)->GetObj();
1808 			if (pObj1==pObj2)
1809 			{
1810 				sal_uInt32 nNum1=((SdrHdl*)pElem1)->GetObjHdlNum();
1811 				sal_uInt32 nNum2=((SdrHdl*)pElem2)->GetObjHdlNum();
1812 				if (nNum1==nNum2)
1813 				{ // #48763#
1814 					if (eKind1==eKind2)
1815 						return (long)pElem1<(long)pElem2 ? -1 : 1; // Notloesung, um immer die gleiche Sortierung zu haben
1816 					return (sal_uInt16)eKind1<(sal_uInt16)eKind2 ? -1 : 1;
1817 				}
1818 				else
1819 					return nNum1<nNum2 ? -1 : 1;
1820 			}
1821 			else
1822 			{
1823 				return (long)pObj1<(long)pObj2 ? -1 : 1;
1824 			}
1825 		}
1826 		else
1827 		{
1828 			return (long)pPV1<(long)pPV2 ? -1 : 1;
1829 		}
1830 	}
1831 	else
1832 	{
1833 		return n1<n2 ? -1 : 1;
1834 	}
1835 }
1836 
1837 SdrMarkView* SdrHdlList::GetView() const
1838 {
1839 	return pView;
1840 }
1841 
1842 // #105678# Help struct for re-sorting handles
1843 struct ImplHdlAndIndex
1844 {
1845 	SdrHdl*						mpHdl;
1846 	sal_uInt32					mnIndex;
1847 };
1848 
1849 // #105678# Help method for sorting handles taking care of OrdNums, keeping order in
1850 // single objects and re-sorting polygon handles intuitively
1851 extern "C" int __LOADONCALLAPI ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 )
1852 {
1853 	const ImplHdlAndIndex* p1 = (ImplHdlAndIndex*)pVoid1;
1854 	const ImplHdlAndIndex* p2 = (ImplHdlAndIndex*)pVoid2;
1855 
1856 	if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj())
1857 	{
1858 		if(p1->mpHdl->GetObj() && p1->mpHdl->GetObj()->ISA(SdrPathObj))
1859 		{
1860 			// same object and a path object
1861 			if((p1->mpHdl->GetKind() == HDL_POLY || p1->mpHdl->GetKind() == HDL_BWGT)
1862 				&& (p2->mpHdl->GetKind() == HDL_POLY || p2->mpHdl->GetKind() == HDL_BWGT))
1863 			{
1864 				// both handles are point or control handles
1865 				if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum())
1866 				{
1867 					if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum())
1868 					{
1869 						return -1;
1870 					}
1871 					else
1872 					{
1873 						return 1;
1874 					}
1875 				}
1876 				else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum())
1877 				{
1878 					return -1;
1879 				}
1880 				else
1881 				{
1882 					return 1;
1883 				}
1884 			}
1885 		}
1886 	}
1887 	else
1888 	{
1889 		if(!p1->mpHdl->GetObj())
1890 		{
1891 			return -1;
1892 		}
1893 		else if(!p2->mpHdl->GetObj())
1894 		{
1895 			return 1;
1896 		}
1897 		else
1898 		{
1899 			// different objects, use OrdNum for sort
1900 			const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum();
1901 			const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum();
1902 
1903 			if(nOrdNum1 < nOrdNum2)
1904 			{
1905 				return -1;
1906 			}
1907 			else
1908 			{
1909 				return 1;
1910 			}
1911 		}
1912 	}
1913 
1914 	// fallback to indices
1915 	if(p1->mnIndex < p2->mnIndex)
1916 	{
1917 		return -1;
1918 	}
1919 	else
1920 	{
1921 		return 1;
1922 	}
1923 }
1924 
1925 ////////////////////////////////////////////////////////////////////////////////////////////////////
1926 // #97016# II
1927 
1928 void SdrHdlList::TravelFocusHdl(sal_Bool bForward)
1929 {
1930 	// security correction
1931 	if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex >= GetHdlCount())
1932 		mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
1933 
1934 	if(aList.Count())
1935 	{
1936 		// take care of old handle
1937 		const sal_uIntPtr nOldHdlNum(mnFocusIndex);
1938 		SdrHdl* pOld = GetHdl(nOldHdlNum);
1939 		//SDOsal_Bool bRefresh(sal_False);
1940 
1941 		if(pOld)
1942 		{
1943 			// switch off old handle
1944 			mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
1945 			pOld->Touch();
1946 			//SDObRefresh = sal_True;
1947 		}
1948 
1949 		// #105678# Alloc pointer array for sorted handle list
1950 		ImplHdlAndIndex* pHdlAndIndex = new ImplHdlAndIndex[aList.Count()];
1951 
1952 		// #105678# build sorted handle list
1953 		sal_uInt32 a;
1954 		for( a = 0; a < aList.Count(); a++)
1955 		{
1956 			pHdlAndIndex[a].mpHdl = (SdrHdl*)aList.GetObject(a);
1957 			pHdlAndIndex[a].mnIndex = a;
1958 		}
1959 
1960 		// #105678# qsort all entries
1961 		qsort(pHdlAndIndex, aList.Count(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc);
1962 
1963 		// #105678# look for old num in sorted array
1964 		sal_uIntPtr nOldHdl(nOldHdlNum);
1965 
1966 		if(nOldHdlNum != CONTAINER_ENTRY_NOTFOUND)
1967 		{
1968 			for(a = 0; a < aList.Count(); a++)
1969 			{
1970 				if(pHdlAndIndex[a].mpHdl == pOld)
1971 				{
1972 					nOldHdl = a;
1973 					break;
1974 				}
1975 			}
1976 		}
1977 
1978 		// #105678# build new HdlNum
1979 		sal_uIntPtr nNewHdl(nOldHdl);
1980 
1981 		// #105678# do the focus travel
1982 		if(bForward)
1983 		{
1984 			if(nOldHdl != CONTAINER_ENTRY_NOTFOUND)
1985 			{
1986 				if(nOldHdl == aList.Count() - 1)
1987 				{
1988 					// end forward run
1989 					nNewHdl = CONTAINER_ENTRY_NOTFOUND;
1990 				}
1991 				else
1992 				{
1993 					// simply the next handle
1994 					nNewHdl++;
1995 				}
1996 			}
1997 			else
1998 			{
1999 				// start forward run at first entry
2000 				nNewHdl = 0;
2001 			}
2002 		}
2003 		else
2004 		{
2005 			if(nOldHdl == CONTAINER_ENTRY_NOTFOUND)
2006 			{
2007 				// start backward run at last entry
2008 				nNewHdl = aList.Count() - 1;
2009 
2010 			}
2011 			else
2012 			{
2013 				if(nOldHdl == 0)
2014 				{
2015 					// end backward run
2016 					nNewHdl = CONTAINER_ENTRY_NOTFOUND;
2017 				}
2018 				else
2019 				{
2020 					// simply the previous handle
2021 					nNewHdl--;
2022 				}
2023 			}
2024 		}
2025 
2026 		// #105678# build new HdlNum
2027 		sal_uInt32 nNewHdlNum(nNewHdl);
2028 
2029 		// look for old num in sorted array
2030 		if(nNewHdl != CONTAINER_ENTRY_NOTFOUND)
2031 		{
2032 			SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl;
2033 
2034 			for(a = 0; a < aList.Count(); a++)
2035 			{
2036 				if((SdrHdl*)aList.GetObject(a) == pNew)
2037 				{
2038 					nNewHdlNum = a;
2039 					break;
2040 				}
2041 			}
2042 		}
2043 
2044 		// take care of next handle
2045 		if(nOldHdlNum != nNewHdlNum)
2046 		{
2047 			mnFocusIndex = nNewHdlNum;
2048 			SdrHdl* pNew = GetHdl(mnFocusIndex);
2049 
2050 			if(pNew)
2051 			{
2052 				pNew->Touch();
2053 				//SDObRefresh = sal_True;
2054 			}
2055 		}
2056 
2057 		// #105678# free mem again
2058 		delete [] pHdlAndIndex;
2059 	}
2060 }
2061 
2062 SdrHdl* SdrHdlList::GetFocusHdl() const
2063 {
2064 	if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex < GetHdlCount())
2065 		return GetHdl(mnFocusIndex);
2066 	else
2067 		return 0L;
2068 }
2069 
2070 void SdrHdlList::SetFocusHdl(SdrHdl* pNew)
2071 {
2072 	if(pNew)
2073 	{
2074 		SdrHdl* pActual = GetFocusHdl();
2075 
2076 		if(!pActual || pActual != pNew)
2077 		{
2078 			sal_uIntPtr nNewHdlNum = GetHdlNum(pNew);
2079 
2080 			if(nNewHdlNum != CONTAINER_ENTRY_NOTFOUND)
2081 			{
2082 				//SDOsal_Bool bRefresh(sal_False);
2083 				mnFocusIndex = nNewHdlNum;
2084 
2085 				if(pActual)
2086 				{
2087 					pActual->Touch();
2088 					//SDObRefresh = sal_True;
2089 				}
2090 
2091 				if(pNew)
2092 				{
2093 					pNew->Touch();
2094 					//SDObRefresh = sal_True;
2095 				}
2096 
2097 				//OLMif(bRefresh)
2098 				//OLM{
2099 				//OLM	if(pView)
2100 				//OLM		pView->RefreshAllIAOManagers();
2101 				//OLM}
2102 			}
2103 		}
2104 	}
2105 }
2106 
2107 void SdrHdlList::ResetFocusHdl()
2108 {
2109 	SdrHdl* pHdl = GetFocusHdl();
2110 
2111 	mnFocusIndex = CONTAINER_ENTRY_NOTFOUND;
2112 
2113 	if(pHdl)
2114 	{
2115 		pHdl->Touch();
2116 	}
2117 }
2118 
2119 ////////////////////////////////////////////////////////////////////////////////////////////////////
2120 
2121 SdrHdlList::SdrHdlList(SdrMarkView* pV)
2122 :	mnFocusIndex(CONTAINER_ENTRY_NOTFOUND),
2123 	pView(pV),
2124 	aList(1024,32,32)
2125 {
2126 	nHdlSize = 3;
2127 	bRotateShear = sal_False;
2128 	bMoveOutside = sal_False;
2129 	bDistortShear = sal_False;
2130 	bFineHandles = sal_True; // new default: Handles are fine handles
2131 }
2132 
2133 SdrHdlList::~SdrHdlList()
2134 {
2135 	Clear();
2136 }
2137 
2138 void SdrHdlList::SetHdlSize(sal_uInt16 nSiz)
2139 {
2140 	if(nHdlSize != nSiz)
2141 	{
2142 		// remember new value
2143 		nHdlSize = nSiz;
2144 
2145 		// propagate change to IAOs
2146 		for(sal_uInt32 i=0; i<GetHdlCount(); i++)
2147 		{
2148 			SdrHdl* pHdl = GetHdl(i);
2149 			pHdl->Touch();
2150 		}
2151 	}
2152 }
2153 
2154 void SdrHdlList::SetMoveOutside(sal_Bool bOn)
2155 {
2156 	if(bMoveOutside != bOn)
2157 	{
2158 		// remember new value
2159 		bMoveOutside = bOn;
2160 
2161 		// propagate change to IAOs
2162 		for(sal_uInt32 i=0; i<GetHdlCount(); i++)
2163 		{
2164 			SdrHdl* pHdl = GetHdl(i);
2165 			pHdl->Touch();
2166 		}
2167 	}
2168 }
2169 
2170 void SdrHdlList::SetRotateShear(sal_Bool bOn)
2171 {
2172 	bRotateShear = bOn;
2173 }
2174 
2175 void SdrHdlList::SetDistortShear(sal_Bool bOn)
2176 {
2177 	bDistortShear = bOn;
2178 }
2179 
2180 void SdrHdlList::SetFineHdl(sal_Bool bOn)
2181 {
2182 	if(bFineHandles != bOn)
2183 	{
2184 		// remember new state
2185 		bFineHandles = bOn;
2186 
2187 		// propagate change to IAOs
2188 		for(sal_uInt32 i=0; i<GetHdlCount(); i++)
2189 		{
2190 			SdrHdl* pHdl = GetHdl(i);
2191 			pHdl->Touch();
2192 		}
2193 	}
2194 }
2195 
2196 SdrHdl* SdrHdlList::RemoveHdl(sal_uIntPtr nNum)
2197 {
2198 	SdrHdl* pRetval = (SdrHdl*)aList.Remove(nNum);
2199 
2200 	return pRetval;
2201 }
2202 
2203 void SdrHdlList::Clear()
2204 {
2205 	for (sal_uIntPtr i=0; i<GetHdlCount(); i++)
2206 	{
2207 		SdrHdl* pHdl=GetHdl(i);
2208 		delete pHdl;
2209 	}
2210 	aList.Clear();
2211 
2212 	bRotateShear=sal_False;
2213 	bDistortShear=sal_False;
2214 }
2215 
2216 void SdrHdlList::Sort()
2217 {
2218 	// #97016# II: remember current focused handle
2219 	SdrHdl* pPrev = GetFocusHdl();
2220 
2221 	ImpSdrHdlListSorter aSort(aList);
2222 	aSort.DoSort();
2223 
2224 	// #97016# II: get now and compare
2225 	SdrHdl* pNow = GetFocusHdl();
2226 
2227 	if(pPrev != pNow)
2228 	{
2229 		//SDOsal_Bool bRefresh(sal_False);
2230 
2231 		if(pPrev)
2232 		{
2233 			pPrev->Touch();
2234 			//SDObRefresh = sal_True;
2235 		}
2236 
2237 		if(pNow)
2238 		{
2239 			pNow->Touch();
2240 			//SDObRefresh = sal_True;
2241 		}
2242 	}
2243 }
2244 
2245 sal_uIntPtr SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const
2246 {
2247 	if (pHdl==NULL)
2248 		return CONTAINER_ENTRY_NOTFOUND;
2249 	sal_uIntPtr nPos=aList.GetPos(pHdl);
2250 	return nPos;
2251 }
2252 
2253 void SdrHdlList::AddHdl(SdrHdl* pHdl, sal_Bool bAtBegin)
2254 {
2255 	if (pHdl!=NULL)
2256 	{
2257 		if (bAtBegin)
2258 		{
2259 			aList.Insert(pHdl,sal_uIntPtr(0));
2260 		}
2261 		else
2262 		{
2263 			aList.Insert(pHdl,CONTAINER_APPEND);
2264 		}
2265 		pHdl->SetHdlList(this);
2266 	}
2267 }
2268 
2269 SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt, sal_Bool bBack, sal_Bool bNext, SdrHdl* pHdl0) const
2270 {
2271 	SdrHdl* pRet=NULL;
2272 	sal_uIntPtr nAnz=GetHdlCount();
2273 	sal_uIntPtr nNum=bBack ? 0 : nAnz;
2274 	while ((bBack ? nNum<nAnz : nNum>0) && pRet==NULL)
2275 	{
2276 		if (!bBack)
2277 			nNum--;
2278 		SdrHdl* pHdl=GetHdl(nNum);
2279 		if (bNext)
2280 		{
2281 			if (pHdl==pHdl0)
2282 				bNext=sal_False;
2283 		}
2284 		else
2285 		{
2286 			if (pHdl->IsHdlHit(rPnt))
2287 				pRet=pHdl;
2288 		}
2289 		if (bBack)
2290 			nNum++;
2291 	}
2292 	return pRet;
2293 }
2294 
2295 SdrHdl* SdrHdlList::GetHdl(SdrHdlKind eKind1) const
2296 {
2297 	SdrHdl* pRet=NULL;
2298 	for (sal_uIntPtr i=0; i<GetHdlCount() && pRet==NULL; i++)
2299 	{
2300 		SdrHdl* pHdl=GetHdl(i);
2301 		if (pHdl->GetKind()==eKind1)
2302 			pRet=pHdl;
2303 	}
2304 	return pRet;
2305 }
2306 
2307 // --------------------------------------------------------------------
2308 // SdrCropHdl
2309 // --------------------------------------------------------------------
2310 
2311 SdrCropHdl::SdrCropHdl(
2312 	const Point& rPnt,
2313 	SdrHdlKind eNewKind,
2314 	double fShearX,
2315 	double fRotation)
2316 :	SdrHdl(rPnt, eNewKind),
2317 	mfShearX(fShearX),
2318 	mfRotation(fRotation)
2319 {
2320 }
2321 
2322 // --------------------------------------------------------------------
2323 
2324 BitmapEx SdrCropHdl::GetHandlesBitmap( bool bIsFineHdl, bool bIsHighContrast )
2325 {
2326 	if( bIsHighContrast )
2327 	{
2328 		static BitmapEx* pHighContrastBitmap = 0;
2329 		if( pHighContrastBitmap == 0 )
2330 			pHighContrastBitmap = new BitmapEx(ResId(SIP_SA_ACCESSIBILITY_CROP_MARKERS, *ImpGetResMgr()));
2331 		return *pHighContrastBitmap;
2332 	}
2333 	else if( bIsFineHdl )
2334 	{
2335 		static BitmapEx* pModernBitmap = 0;
2336 		if( pModernBitmap == 0 )
2337 			pModernBitmap = new BitmapEx(ResId(SIP_SA_CROP_FINE_MARKERS, *ImpGetResMgr()));
2338 		return *pModernBitmap;
2339 	}
2340 	else
2341 	{
2342 		static BitmapEx* pSimpleBitmap = 0;
2343 		if( pSimpleBitmap == 0 )
2344 			pSimpleBitmap = new BitmapEx(ResId(SIP_SA_CROP_MARKERS, *ImpGetResMgr()));
2345 		return *pSimpleBitmap;
2346 	}
2347 }
2348 
2349 // --------------------------------------------------------------------
2350 
2351 BitmapEx SdrCropHdl::GetBitmapForHandle( const BitmapEx& rBitmap, int nSize )
2352 {
2353 	int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0;
2354 
2355 	if( nSize <= 3 )
2356 	{
2357 		nPixelSize = 13;
2358 		nOffset = 0;
2359 	}
2360 	else if( nSize <=4 )
2361 	{
2362 		nPixelSize = 17;
2363 		nOffset = 39;
2364 	}
2365 	else
2366 	{
2367 		nPixelSize = 21;
2368 		nOffset = 90;
2369 	}
2370 
2371 	switch( eKind )
2372 	{
2373 		case HDL_UPLFT: nX = 0; nY = 0; break;
2374 		case HDL_UPPER: nX = 1; nY = 0; break;
2375 		case HDL_UPRGT: nX = 2; nY = 0; break;
2376 		case HDL_LEFT:  nX = 0; nY = 1; break;
2377 		case HDL_RIGHT: nX = 2; nY = 1; break;
2378 		case HDL_LWLFT: nX = 0; nY = 2; break;
2379 		case HDL_LOWER: nX = 1; nY = 2; break;
2380 		case HDL_LWRGT: nX = 2; nY = 2; break;
2381 		default: break;
2382 	}
2383 
2384 	Rectangle aSourceRect( Point( nX * (nPixelSize) + nOffset, nY * (nPixelSize)), Size(nPixelSize, nPixelSize) );
2385 
2386 	BitmapEx aRetval(rBitmap);
2387 	aRetval.Crop(aSourceRect);
2388 	return aRetval;
2389 }
2390 
2391 // --------------------------------------------------------------------
2392 
2393 void SdrCropHdl::CreateB2dIAObject()
2394 {
2395 	// first throw away old one
2396 	GetRidOfIAObject();
2397 
2398 	SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0;
2399 	SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
2400 
2401 	if( pPageView && !pView->areMarkHandlesHidden() )
2402 	{
2403 		sal_Bool bIsFineHdl(pHdlList->IsFineHdl());
2404 		const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2405 		sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode());
2406 		int nHdlSize = pHdlList->GetHdlSize();
2407 		if( bIsHighContrast )
2408 			nHdlSize = 4;
2409 
2410 		const BitmapEx aHandlesBitmap( GetHandlesBitmap( bIsFineHdl, bIsHighContrast ) );
2411 		BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) );
2412 
2413 		for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
2414 		{
2415 			// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
2416 			const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
2417 
2418 			if(rPageWindow.GetPaintWindow().OutputToWindow())
2419 			{
2420 				if(rPageWindow.GetOverlayManager())
2421 				{
2422 					basegfx::B2DPoint aPosition(aPos.X(), aPos.Y());
2423 
2424 					::sdr::overlay::OverlayObject* pOverlayObject = 0L;
2425 
2426 					// animate focused handles
2427 					if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this))
2428 					{
2429 						if( nHdlSize >= 2 )
2430 							nHdlSize = 1;
2431 
2432 						BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) );
2433 
2434 						const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime());
2435 
2436 						pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx(
2437 							aPosition,
2438 							aBmpEx1,
2439 							aBmpEx2,
2440 							nBlinkTime,
2441 							(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2442 							(sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2443 							(sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1,
2444 							(sal_uInt16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1,
2445 							mfShearX,
2446 							mfRotation);
2447 					}
2448 					else
2449 					{
2450 						// create centered handle as default
2451 						pOverlayObject = new ::sdr::overlay::OverlayBitmapEx(
2452 							aPosition,
2453 							aBmpEx1,
2454 							(sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1,
2455 							(sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1,
2456 							0.0,
2457 							mfShearX,
2458 							mfRotation);
2459 					}
2460 
2461 					// OVERLAYMANAGER
2462 					if(pOverlayObject)
2463 					{
2464 						rPageWindow.GetOverlayManager()->add(*pOverlayObject);
2465 						maOverlayGroup.append(*pOverlayObject);
2466 					}
2467 				}
2468 			}
2469 		}
2470 	}
2471 }
2472 
2473 ////////////////////////////////////////////////////////////////////////////////////////////////////
2474 // with the correction of crop handling I could get rid of the extra mirroring flag, adapted stuff
2475 // accordingly
2476 
2477 SdrCropViewHdl::SdrCropViewHdl(
2478 	const basegfx::B2DHomMatrix& rObjectTransform,
2479 	const Graphic& rGraphic,
2480 	double fCropLeft,
2481 	double fCropTop,
2482 	double fCropRight,
2483 	double fCropBottom)
2484 :	SdrHdl(Point(), HDL_USER),
2485 	maObjectTransform(rObjectTransform),
2486 	maGraphic(rGraphic),
2487 	mfCropLeft(fCropLeft),
2488 	mfCropTop(fCropTop),
2489 	mfCropRight(fCropRight),
2490 	mfCropBottom(fCropBottom)
2491 {
2492 }
2493 
2494 void SdrCropViewHdl::CreateB2dIAObject()
2495 {
2496 	GetRidOfIAObject();
2497 	SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0;
2498 	SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0;
2499 
2500 	if(pPageView && pView->areMarkHandlesHidden())
2501 	{
2502 		return;
2503 	}
2504 
2505 	// decompose to have current translate and scale
2506 	basegfx::B2DVector aScale, aTranslate;
2507 	double fRotate, fShearX;
2508 
2509 	maObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
2510 
2511 	if(aScale.equalZero())
2512 	{
2513 		return;
2514 	}
2515 
2516 	// detect 180 degree rotation, this is the same as mirrored in X and Y,
2517 	// thus change to mirroring. Prefer mirroring here. Use the equal call
2518 	// with getSmallValue here, the original which uses rtl::math::approxEqual
2519 	// is too correct here. Maybe this changes with enhanced precision in aw080
2520 	// to the better so that this can be reduced to the more precise call again
2521 	if(basegfx::fTools::equal(fabs(fRotate), F_PI, 0.000000001))
2522 	{
2523 		aScale.setX(aScale.getX() * -1.0);
2524 		aScale.setY(aScale.getY() * -1.0);
2525 		fRotate = 0.0;
2526 	}
2527 
2528 	// remember mirroring, reset at Scale and adapt crop values for usage;
2529 	// mirroring can stay in the object transformation, so do not have to
2530 	// cope with it here (except later for the CroppedImage transformation,
2531 	// see below)
2532 	const bool bMirroredX(aScale.getX() < 0.0);
2533 	const bool bMirroredY(aScale.getY() < 0.0);
2534 	double fCropLeft(mfCropLeft);
2535 	double fCropTop(mfCropTop);
2536 	double fCropRight(mfCropRight);
2537 	double fCropBottom(mfCropBottom);
2538 
2539 	if(bMirroredX)
2540 	{
2541 		aScale.setX(-aScale.getX());
2542 	}
2543 
2544 	if(bMirroredY)
2545 	{
2546 		aScale.setY(-aScale.getY());
2547 	}
2548 
2549 	// create target translate and scale
2550 	const basegfx::B2DVector aTargetScale(
2551 		aScale.getX() + fCropRight + fCropLeft,
2552 		aScale.getY() + fCropBottom + fCropTop);
2553 	const basegfx::B2DVector aTargetTranslate(
2554 		aTranslate.getX() - fCropLeft,
2555 		aTranslate.getY() - fCropTop);
2556 
2557 	// create ranges to make comparisons
2558 	const basegfx::B2DRange aCurrentForCompare(
2559 		aTranslate.getX(), aTranslate.getY(),
2560 		aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
2561 	basegfx::B2DRange aCropped(
2562 		aTargetTranslate.getX(), aTargetTranslate.getY(),
2563 		aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
2564 
2565 	if(aCropped.isEmpty())
2566 	{
2567 		// nothing to return since cropped content is completely empty
2568 		return;
2569 	}
2570 
2571 	if(aCurrentForCompare.equal(aCropped))
2572 	{
2573 		// no crop at all
2574 		return;
2575 	}
2576 
2577 	// back-transform to have values in unit coordinates
2578 	basegfx::B2DHomMatrix aBackToUnit;
2579 	aBackToUnit.translate(-aTranslate.getX(), -aTranslate.getY());
2580 	aBackToUnit.scale(
2581 		basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : 1.0 / aScale.getX(),
2582 		basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : 1.0 / aScale.getY());
2583 
2584 	// transform cropped back to unit coordinates
2585 	aCropped.transform(aBackToUnit);
2586 
2587 	// prepare crop PolyPolygon
2588 	basegfx::B2DPolygon aGraphicOutlinePolygon(
2589 		basegfx::tools::createPolygonFromRect(
2590 			aCropped));
2591 	basegfx::B2DPolyPolygon aCropPolyPolygon(aGraphicOutlinePolygon);
2592 
2593 	// current range is unit range
2594 	basegfx::B2DRange aOverlap(0.0, 0.0, 1.0, 1.0);
2595 
2596 	aOverlap.intersect(aCropped);
2597 
2598 	if(!aOverlap.isEmpty())
2599 	{
2600 		aCropPolyPolygon.append(
2601 			basegfx::tools::createPolygonFromRect(
2602 				aOverlap));
2603 	}
2604 
2605 	// transform to object coordinates to prepare for clip
2606 	aCropPolyPolygon.transform(maObjectTransform);
2607 	aGraphicOutlinePolygon.transform(maObjectTransform);
2608 
2609 	// create cropped transformation
2610 	basegfx::B2DHomMatrix aCroppedTransform;
2611 	const bool bCombinedMirrorX(bMirroredX);
2612 
2613 	aCroppedTransform.scale(
2614 		aCropped.getWidth(),
2615 		aCropped.getHeight());
2616 	aCroppedTransform.translate(
2617 		aCropped.getMinX(),
2618 		aCropped.getMinY());
2619 	aCroppedTransform = maObjectTransform * aCroppedTransform;
2620 
2621 	// prepare graphic primitive (transformed)
2622 	const drawinglayer::primitive2d::Primitive2DReference aGraphic(
2623 		new drawinglayer::primitive2d::GraphicPrimitive2D(
2624 			aCroppedTransform,
2625 			maGraphic));
2626 
2627 	// prepare outline polygon for whole graphic
2628 	const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
2629 	const basegfx::BColor aHilightColor(aSvtOptionsDrawinglayer.getHilightColor().getBColor());
2630 	const drawinglayer::primitive2d::Primitive2DReference aGraphicOutline(
2631 		new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
2632 		aGraphicOutlinePolygon,
2633 		aHilightColor));
2634 
2635 	// combine these
2636 	drawinglayer::primitive2d::Primitive2DSequence aCombination(2);
2637 	aCombination[0] = aGraphic;
2638 	aCombination[1] = aGraphicOutline;
2639 
2640 	// embed to MaskPrimitive2D
2641 	const drawinglayer::primitive2d::Primitive2DReference aMaskedGraphic(
2642 		new drawinglayer::primitive2d::MaskPrimitive2D(
2643 			aCropPolyPolygon,
2644 			aCombination));
2645 
2646 	// embed to UnifiedTransparencePrimitive2D
2647 	const drawinglayer::primitive2d::Primitive2DReference aTransparenceMaskedGraphic(
2648 		new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
2649 			drawinglayer::primitive2d::Primitive2DSequence(&aMaskedGraphic, 1),
2650 			0.8));
2651 
2652 	const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aTransparenceMaskedGraphic, 1);
2653 
2654 	for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++)
2655 	{
2656 		// const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
2657 		const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
2658 
2659 		if(rPageWindow.GetPaintWindow().OutputToWindow())
2660 		{
2661 			if(rPageWindow.GetOverlayManager())
2662 			{
2663 				::sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence);
2664 				DBG_ASSERT(pNew, "Got NO new IAO!");
2665 
2666 				if(pNew)
2667 				{
2668 					// only informative object, no hit
2669 					pNew->setHittable(false);
2670 
2671 					rPageWindow.GetOverlayManager()->add(*pNew);
2672 					maOverlayGroup.append(*pNew);
2673 				}
2674 			}
2675 		}
2676 	}
2677 }
2678 
2679 ////////////////////////////////////////////////////////////////////////////////////////////////////
2680 // eof
2681