1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svx.hxx" 30 31 #include <svx/sdrhittesthelper.hxx> 32 #include <svx/obj3d.hxx> 33 #include <svx/helperhittest3d.hxx> 34 #include <svx/sdrpagewindow.hxx> 35 #include <svx/sdr/contact/viewobjectcontact.hxx> 36 #include <svx/sdr/contact/displayinfo.hxx> 37 #include <svx/sdr/contact/objectcontact.hxx> 38 #include <drawinglayer/processor2d/hittestprocessor2d.hxx> 39 #include <svx/svdpagv.hxx> 40 #include <svx/sdr/contact/viewcontact.hxx> 41 42 //////////////////////////////////////////////////////////////////////////////////////////////////// 43 // #i101872# new Object HitTest as View-tooling 44 45 SdrObject* SdrObjectPrimitiveHit( 46 const SdrObject& rObject, 47 const Point& rPnt, 48 sal_uInt16 nTol, 49 const SdrPageView& rSdrPageView, 50 const SetOfByte* pVisiLayer, 51 bool bTextOnly) 52 { 53 SdrObject* pResult = 0; 54 55 if(rObject.GetSubList() && rObject.GetSubList()->GetObjCount()) 56 { 57 // group or scene with content. Single 3D objects also have a 58 // true == rObject.GetSubList(), but no content 59 pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly); 60 } 61 else 62 { 63 if( rObject.IsVisible() && (!pVisiLayer || pVisiLayer->IsSet(rObject.GetLayer()))) 64 { 65 // single object, 3d object, empty scene or empty group. Check if 66 // it's a single 3D object 67 const E3dCompoundObject* pE3dCompoundObject = dynamic_cast< const E3dCompoundObject* >(&rObject); 68 69 if(pE3dCompoundObject) 70 { 71 const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y()); 72 73 if(checkHitSingle3DObject(aHitPosition, *pE3dCompoundObject)) 74 { 75 pResult = const_cast< E3dCompoundObject* >(pE3dCompoundObject); 76 } 77 } 78 else 79 { 80 // not a single 3D object; Check in first PageWindow using prmitives (only SC 81 // with split views uses multiple PageWindows nowadays) 82 if(rSdrPageView.PageWindowCount()) 83 { 84 const double fLogicTolerance(nTol); 85 const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y()); 86 const sdr::contact::ViewObjectContact& rVOC = rObject.GetViewContact().GetViewObjectContact( 87 rSdrPageView.GetPageWindow(0)->GetObjectContact()); 88 89 if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, fLogicTolerance, bTextOnly)) 90 { 91 pResult = const_cast< SdrObject* >(&rObject); 92 } 93 } 94 } 95 } 96 } 97 98 return pResult; 99 } 100 101 ///////////////////////////////////////////////////////////////////// 102 103 SdrObject* SdrObjListPrimitiveHit( 104 const SdrObjList& rList, 105 const Point& rPnt, 106 sal_uInt16 nTol, 107 const SdrPageView& rSdrPageView, 108 const SetOfByte* pVisiLayer, 109 bool bTextOnly) 110 { 111 sal_uInt32 nObjNum(rList.GetObjCount()); 112 SdrObject* pRetval = 0; 113 114 while(!pRetval && nObjNum > 0) 115 { 116 nObjNum--; 117 SdrObject* pObj = rList.GetObj(nObjNum); 118 119 pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly); 120 } 121 122 return pRetval; 123 } 124 125 ///////////////////////////////////////////////////////////////////// 126 127 bool ViewObjectContactPrimitiveHit( 128 const sdr::contact::ViewObjectContact& rVOC, 129 const basegfx::B2DPoint& rHitPosition, 130 double fLogicHitTolerance, 131 bool bTextOnly) 132 { 133 basegfx::B2DRange aObjectRange(rVOC.getObjectRange()); 134 135 if(!aObjectRange.isEmpty()) 136 { 137 // first do a rough B2DRange based HitTest; do not forget to 138 // include the HitTolerance if given 139 if(basegfx::fTools::more(fLogicHitTolerance, 0.0)) 140 { 141 aObjectRange.grow(fLogicHitTolerance); 142 } 143 144 if(aObjectRange.isInside(rHitPosition)) 145 { 146 // get primitive sequence 147 sdr::contact::DisplayInfo aDisplayInfo; 148 const drawinglayer::primitive2d::Primitive2DSequence& rSequence(rVOC.getPrimitive2DSequence(aDisplayInfo)); 149 150 if(rSequence.hasElements()) 151 { 152 // create a HitTest processor 153 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D = rVOC.GetObjectContact().getViewInformation2D(); 154 drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( 155 rViewInformation2D, 156 rHitPosition, 157 fLogicHitTolerance, 158 bTextOnly); 159 160 // feed it with the primitives 161 aHitTestProcessor2D.process(rSequence); 162 163 // deliver result 164 return aHitTestProcessor2D.getHit(); 165 } 166 } 167 } 168 169 return false; 170 } 171 172 //////////////////////////////////////////////////////////////////////////////////////////////////// 173 // eof 174