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