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