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 <svx/sdrhittesthelper.hxx> 28 #include <svx/obj3d.hxx> 29 #include <svx/helperhittest3d.hxx> 30 #include <svx/sdrpagewindow.hxx> 31 #include <svx/sdr/contact/viewobjectcontact.hxx> 32 #include <svx/sdr/contact/displayinfo.hxx> 33 #include <svx/sdr/contact/objectcontact.hxx> 34 #include <drawinglayer/processor2d/hittestprocessor2d.hxx> 35 #include <svx/svdpagv.hxx> 36 #include <svx/sdr/contact/viewcontact.hxx> 37 38 //////////////////////////////////////////////////////////////////////////////////////////////////// 39 // #i101872# new Object HitTest as View-tooling 40 41 SdrObject* SdrObjectPrimitiveHit( 42 const SdrObject& rObject, 43 const Point& rPnt, 44 sal_uInt16 nTol, 45 const SdrPageView& rSdrPageView, 46 const SetOfByte* pVisiLayer, 47 bool bTextOnly) 48 { 49 SdrObject* pResult = 0; 50 51 if(rObject.GetSubList() && rObject.GetSubList()->GetObjCount()) 52 { 53 // group or scene with content. Single 3D objects also have a 54 // true == rObject.GetSubList(), but no content 55 pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly); 56 } 57 else 58 { 59 if( rObject.IsVisible() && (!pVisiLayer || pVisiLayer->IsSet(rObject.GetLayer()))) 60 { 61 // single object, 3d object, empty scene or empty group. Check if 62 // it's a single 3D object 63 const E3dCompoundObject* pE3dCompoundObject = dynamic_cast< const E3dCompoundObject* >(&rObject); 64 65 if(pE3dCompoundObject) 66 { 67 const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y()); 68 69 if(checkHitSingle3DObject(aHitPosition, *pE3dCompoundObject)) 70 { 71 pResult = const_cast< E3dCompoundObject* >(pE3dCompoundObject); 72 } 73 } 74 else 75 { 76 // not a single 3D object; Check in first PageWindow using prmitives (only SC 77 // with split views uses multiple PageWindows nowadays) 78 if(rSdrPageView.PageWindowCount()) 79 { 80 const double fLogicTolerance(nTol); 81 const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y()); 82 const sdr::contact::ViewObjectContact& rVOC = rObject.GetViewContact().GetViewObjectContact( 83 rSdrPageView.GetPageWindow(0)->GetObjectContact()); 84 85 if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, fLogicTolerance, bTextOnly)) 86 { 87 pResult = const_cast< SdrObject* >(&rObject); 88 } 89 } 90 } 91 } 92 } 93 94 return pResult; 95 } 96 97 ///////////////////////////////////////////////////////////////////// 98 99 SdrObject* SdrObjListPrimitiveHit( 100 const SdrObjList& rList, 101 const Point& rPnt, 102 sal_uInt16 nTol, 103 const SdrPageView& rSdrPageView, 104 const SetOfByte* pVisiLayer, 105 bool bTextOnly) 106 { 107 sal_uInt32 nObjNum(rList.GetObjCount()); 108 SdrObject* pRetval = 0; 109 110 while(!pRetval && nObjNum > 0) 111 { 112 nObjNum--; 113 SdrObject* pObj = rList.GetObj(nObjNum); 114 115 pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly); 116 } 117 118 return pRetval; 119 } 120 121 ///////////////////////////////////////////////////////////////////// 122 123 bool ViewObjectContactPrimitiveHit( 124 const sdr::contact::ViewObjectContact& rVOC, 125 const basegfx::B2DPoint& rHitPosition, 126 double fLogicHitTolerance, 127 bool bTextOnly) 128 { 129 basegfx::B2DRange aObjectRange(rVOC.getObjectRange()); 130 131 if(!aObjectRange.isEmpty()) 132 { 133 // first do a rough B2DRange based HitTest; do not forget to 134 // include the HitTolerance if given 135 if(basegfx::fTools::more(fLogicHitTolerance, 0.0)) 136 { 137 aObjectRange.grow(fLogicHitTolerance); 138 } 139 140 if(aObjectRange.isInside(rHitPosition)) 141 { 142 // get primitive sequence 143 sdr::contact::DisplayInfo aDisplayInfo; 144 const drawinglayer::primitive2d::Primitive2DSequence& rSequence(rVOC.getPrimitive2DSequence(aDisplayInfo)); 145 146 if(rSequence.hasElements()) 147 { 148 // create a HitTest processor 149 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D = rVOC.GetObjectContact().getViewInformation2D(); 150 drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( 151 rViewInformation2D, 152 rHitPosition, 153 fLogicHitTolerance, 154 bTextOnly); 155 156 // feed it with the primitives 157 aHitTestProcessor2D.process(rSequence); 158 159 // deliver result 160 return aHitTestProcessor2D.getHit(); 161 } 162 } 163 } 164 165 return false; 166 } 167 168 //////////////////////////////////////////////////////////////////////////////////////////////////// 169 // eof 170