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