xref: /trunk/main/svx/source/svdraw/svdhdl.cxx (revision 4d196ef4)
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