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