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