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