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 #include <svx/sdr/overlay/overlayselection.hxx> 31 #include <basegfx/polygon/b2dpolygontools.hxx> 32 #include <basegfx/polygon/b2dpolygon.hxx> 33 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 34 #include <svtools/optionsdrawinglayer.hxx> 35 #include <vcl/svapp.hxx> 36 #include <vcl/outdev.hxx> 37 #include <drawinglayer/primitive2d/invertprimitive2d.hxx> 38 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 39 #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 40 #include <svx/sdr/overlay/overlaymanager.hxx> 41 42 ////////////////////////////////////////////////////////////////////////////// 43 44 namespace sdr 45 { 46 namespace overlay 47 { 48 // combine rages geometrically to a single, ORed polygon 49 basegfx::B2DPolyPolygon impCombineRangesToPolyPolygon(const std::vector< basegfx::B2DRange >& rRanges) 50 { 51 const sal_uInt32 nCount(rRanges.size()); 52 basegfx::B2DPolyPolygon aRetval; 53 54 for(sal_uInt32 a(0); a < nCount; a++) 55 { 56 const basegfx::B2DPolygon aDiscretePolygon(basegfx::tools::createPolygonFromRect(rRanges[a])); 57 58 if(0 == a) 59 { 60 aRetval.append(aDiscretePolygon); 61 } 62 else 63 { 64 aRetval = basegfx::tools::solvePolygonOperationOr(aRetval, basegfx::B2DPolyPolygon(aDiscretePolygon)); 65 } 66 } 67 68 return aRetval; 69 } 70 71 // check if wanted type OVERLAY_TRANSPARENT or OVERLAY_SOLID 72 // is possible. If not, fallback to invert mode (classic mode) 73 OverlayType impCheckPossibleOverlayType(OverlayType aOverlayType) 74 { 75 if(OVERLAY_INVERT != aOverlayType) 76 { 77 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 78 79 if(!aSvtOptionsDrawinglayer.IsTransparentSelection()) 80 { 81 // not possible when switched off by user 82 return OVERLAY_INVERT; 83 } 84 else 85 { 86 const OutputDevice *pOut = Application::GetDefaultDevice(); 87 88 if(pOut->GetSettings().GetStyleSettings().GetHighContrastMode()) 89 { 90 // not possible when in high contrast mode 91 return OVERLAY_INVERT; 92 } 93 94 if(!pOut->supportsOperation(OutDevSupport_TransparentRect)) 95 { 96 // not possible when no fast transparence paint is supported on the system 97 return OVERLAY_INVERT; 98 } 99 } 100 } 101 102 return aOverlayType; 103 } 104 105 drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::createOverlayObjectPrimitive2DSequence() 106 { 107 drawinglayer::primitive2d::Primitive2DSequence aRetval; 108 const sal_uInt32 nCount(getRanges().size()); 109 110 if(nCount) 111 { 112 // create range primitives 113 const bool bInvert(OVERLAY_INVERT == maLastOverlayType); 114 basegfx::BColor aRGBColor(getBaseColor().getBColor()); 115 aRetval.realloc(nCount); 116 117 if(bInvert) 118 { 119 // force color to white for invert to get a full invert 120 aRGBColor = basegfx::BColor(1.0, 1.0, 1.0); 121 } 122 123 for(sal_uInt32 a(0);a < nCount; a++) 124 { 125 const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(maRanges[a])); 126 aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( 127 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( 128 basegfx::B2DPolyPolygon(aPolygon), 129 aRGBColor)); 130 } 131 132 if(bInvert) 133 { 134 // embed all in invert primitive 135 const drawinglayer::primitive2d::Primitive2DReference aInvert( 136 new drawinglayer::primitive2d::InvertPrimitive2D( 137 aRetval)); 138 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); 139 } 140 else if(OVERLAY_TRANSPARENT == maLastOverlayType) 141 { 142 // embed all rectangles in transparent paint 143 const double fTransparence(mnLastTransparence / 100.0); 144 const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence( 145 new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( 146 aRetval, 147 fTransparence)); 148 149 if(getBorder()) 150 { 151 const basegfx::B2DPolyPolygon aPolyPolygon(impCombineRangesToPolyPolygon(getRanges())); 152 const drawinglayer::primitive2d::Primitive2DReference aSelectionOutline( 153 new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( 154 aPolyPolygon, 155 aRGBColor)); 156 157 // add both to result 158 aRetval.realloc(2); 159 aRetval[0] = aUnifiedTransparence; 160 aRetval[1] = aSelectionOutline; 161 } 162 else 163 { 164 // just add transparent part 165 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1); 166 } 167 } 168 } 169 170 return aRetval; 171 } 172 173 OverlaySelection::OverlaySelection( 174 OverlayType eType, 175 const Color& rColor, 176 const std::vector< basegfx::B2DRange >& rRanges, 177 bool bBorder) 178 : OverlayObject(rColor), 179 meOverlayType(eType), 180 maRanges(rRanges), 181 maLastOverlayType(eType), 182 mnLastTransparence(0), 183 mbBorder(bBorder) 184 { 185 // no AA for selection overlays 186 allowAntiAliase(false); 187 } 188 189 OverlaySelection::~OverlaySelection() 190 { 191 if(getOverlayManager()) 192 { 193 getOverlayManager()->remove(*this); 194 } 195 } 196 197 drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::getOverlayObjectPrimitive2DSequence() const 198 { 199 // get current values 200 const OverlayType aNewOverlayType(impCheckPossibleOverlayType(meOverlayType)); 201 const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 202 const sal_uInt16 nNewTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent()); 203 204 if(getPrimitive2DSequence().hasElements()) 205 { 206 if(aNewOverlayType != maLastOverlayType 207 || nNewTransparence != mnLastTransparence) 208 { 209 // conditions of last local decomposition have changed, delete 210 const_cast< OverlaySelection* >(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); 211 } 212 } 213 214 if(!getPrimitive2DSequence().hasElements()) 215 { 216 // remember new values 217 const_cast< OverlaySelection* >(this)->maLastOverlayType = aNewOverlayType; 218 const_cast< OverlaySelection* >(this)->mnLastTransparence = nNewTransparence; 219 } 220 221 // call base implementation 222 return OverlayObject::getOverlayObjectPrimitive2DSequence(); 223 } 224 225 void OverlaySelection::setRanges(const std::vector< basegfx::B2DRange >& rNew) 226 { 227 if(rNew != maRanges) 228 { 229 maRanges = rNew; 230 objectChange(); 231 } 232 } 233 } // end of namespace overlay 234 } // end of namespace sdr 235 236 ////////////////////////////////////////////////////////////////////////////// 237 // eof 238