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