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