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