1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_svx.hxx" 26*b1cdbd2cSJim Jagielski #include <svx/sdr/overlay/overlayselection.hxx> 27*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx> 28*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygon.hxx> 29*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 30*b1cdbd2cSJim Jagielski #include <svtools/optionsdrawinglayer.hxx> 31*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx> 32*b1cdbd2cSJim Jagielski #include <vcl/outdev.hxx> 33*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/invertprimitive2d.hxx> 34*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> 35*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 36*b1cdbd2cSJim Jagielski #include <svx/sdr/overlay/overlaymanager.hxx> 37*b1cdbd2cSJim Jagielski 38*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 39*b1cdbd2cSJim Jagielski 40*b1cdbd2cSJim Jagielski namespace sdr 41*b1cdbd2cSJim Jagielski { 42*b1cdbd2cSJim Jagielski namespace overlay 43*b1cdbd2cSJim Jagielski { 44*b1cdbd2cSJim Jagielski // combine rages geometrically to a single, ORed polygon impCombineRangesToPolyPolygon(const std::vector<basegfx::B2DRange> & rRanges)45*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon impCombineRangesToPolyPolygon(const std::vector< basegfx::B2DRange >& rRanges) 46*b1cdbd2cSJim Jagielski { 47*b1cdbd2cSJim Jagielski const sal_uInt32 nCount(rRanges.size()); 48*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon aRetval; 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0); a < nCount; a++) 51*b1cdbd2cSJim Jagielski { 52*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aDiscretePolygon(basegfx::tools::createPolygonFromRect(rRanges[a])); 53*b1cdbd2cSJim Jagielski 54*b1cdbd2cSJim Jagielski if(0 == a) 55*b1cdbd2cSJim Jagielski { 56*b1cdbd2cSJim Jagielski aRetval.append(aDiscretePolygon); 57*b1cdbd2cSJim Jagielski } 58*b1cdbd2cSJim Jagielski else 59*b1cdbd2cSJim Jagielski { 60*b1cdbd2cSJim Jagielski aRetval = basegfx::tools::solvePolygonOperationOr(aRetval, basegfx::B2DPolyPolygon(aDiscretePolygon)); 61*b1cdbd2cSJim Jagielski } 62*b1cdbd2cSJim Jagielski } 63*b1cdbd2cSJim Jagielski 64*b1cdbd2cSJim Jagielski return aRetval; 65*b1cdbd2cSJim Jagielski } 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski // check if wanted type OVERLAY_TRANSPARENT or OVERLAY_SOLID 68*b1cdbd2cSJim Jagielski // is possible. If not, fallback to invert mode (classic mode) impCheckPossibleOverlayType(OverlayType aOverlayType)69*b1cdbd2cSJim Jagielski OverlayType impCheckPossibleOverlayType(OverlayType aOverlayType) 70*b1cdbd2cSJim Jagielski { 71*b1cdbd2cSJim Jagielski if(OVERLAY_INVERT != aOverlayType) 72*b1cdbd2cSJim Jagielski { 73*b1cdbd2cSJim Jagielski const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 74*b1cdbd2cSJim Jagielski 75*b1cdbd2cSJim Jagielski if(!aSvtOptionsDrawinglayer.IsTransparentSelection()) 76*b1cdbd2cSJim Jagielski { 77*b1cdbd2cSJim Jagielski // not possible when switched off by user 78*b1cdbd2cSJim Jagielski return OVERLAY_INVERT; 79*b1cdbd2cSJim Jagielski } 80*b1cdbd2cSJim Jagielski else 81*b1cdbd2cSJim Jagielski { 82*b1cdbd2cSJim Jagielski const OutputDevice *pOut = Application::GetDefaultDevice(); 83*b1cdbd2cSJim Jagielski 84*b1cdbd2cSJim Jagielski if(pOut->GetSettings().GetStyleSettings().GetHighContrastMode()) 85*b1cdbd2cSJim Jagielski { 86*b1cdbd2cSJim Jagielski // not possible when in high contrast mode 87*b1cdbd2cSJim Jagielski return OVERLAY_INVERT; 88*b1cdbd2cSJim Jagielski } 89*b1cdbd2cSJim Jagielski 90*b1cdbd2cSJim Jagielski if(!pOut->supportsOperation(OutDevSupport_TransparentRect)) 91*b1cdbd2cSJim Jagielski { 92*b1cdbd2cSJim Jagielski // not possible when no fast transparence paint is supported on the system 93*b1cdbd2cSJim Jagielski return OVERLAY_INVERT; 94*b1cdbd2cSJim Jagielski } 95*b1cdbd2cSJim Jagielski } 96*b1cdbd2cSJim Jagielski } 97*b1cdbd2cSJim Jagielski 98*b1cdbd2cSJim Jagielski return aOverlayType; 99*b1cdbd2cSJim Jagielski } 100*b1cdbd2cSJim Jagielski createOverlayObjectPrimitive2DSequence()101*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::createOverlayObjectPrimitive2DSequence() 102*b1cdbd2cSJim Jagielski { 103*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::Primitive2DSequence aRetval; 104*b1cdbd2cSJim Jagielski const sal_uInt32 nCount(getRanges().size()); 105*b1cdbd2cSJim Jagielski 106*b1cdbd2cSJim Jagielski if(nCount) 107*b1cdbd2cSJim Jagielski { 108*b1cdbd2cSJim Jagielski // create range primitives 109*b1cdbd2cSJim Jagielski const bool bInvert(OVERLAY_INVERT == maLastOverlayType); 110*b1cdbd2cSJim Jagielski basegfx::BColor aRGBColor(getBaseColor().getBColor()); 111*b1cdbd2cSJim Jagielski aRetval.realloc(nCount); 112*b1cdbd2cSJim Jagielski 113*b1cdbd2cSJim Jagielski if(bInvert) 114*b1cdbd2cSJim Jagielski { 115*b1cdbd2cSJim Jagielski // force color to white for invert to get a full invert 116*b1cdbd2cSJim Jagielski aRGBColor = basegfx::BColor(1.0, 1.0, 1.0); 117*b1cdbd2cSJim Jagielski } 118*b1cdbd2cSJim Jagielski 119*b1cdbd2cSJim Jagielski for(sal_uInt32 a(0);a < nCount; a++) 120*b1cdbd2cSJim Jagielski { 121*b1cdbd2cSJim Jagielski const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(maRanges[a])); 122*b1cdbd2cSJim Jagielski aRetval[a] = drawinglayer::primitive2d::Primitive2DReference( 123*b1cdbd2cSJim Jagielski new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( 124*b1cdbd2cSJim Jagielski basegfx::B2DPolyPolygon(aPolygon), 125*b1cdbd2cSJim Jagielski aRGBColor)); 126*b1cdbd2cSJim Jagielski } 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski if(bInvert) 129*b1cdbd2cSJim Jagielski { 130*b1cdbd2cSJim Jagielski // embed all in invert primitive 131*b1cdbd2cSJim Jagielski const drawinglayer::primitive2d::Primitive2DReference aInvert( 132*b1cdbd2cSJim Jagielski new drawinglayer::primitive2d::InvertPrimitive2D( 133*b1cdbd2cSJim Jagielski aRetval)); 134*b1cdbd2cSJim Jagielski aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aInvert, 1); 135*b1cdbd2cSJim Jagielski } 136*b1cdbd2cSJim Jagielski else if(OVERLAY_TRANSPARENT == maLastOverlayType) 137*b1cdbd2cSJim Jagielski { 138*b1cdbd2cSJim Jagielski // embed all rectangles in transparent paint 139*b1cdbd2cSJim Jagielski const double fTransparence(mnLastTransparence / 100.0); 140*b1cdbd2cSJim Jagielski const drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparence( 141*b1cdbd2cSJim Jagielski new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( 142*b1cdbd2cSJim Jagielski aRetval, 143*b1cdbd2cSJim Jagielski fTransparence)); 144*b1cdbd2cSJim Jagielski 145*b1cdbd2cSJim Jagielski if(getBorder()) 146*b1cdbd2cSJim Jagielski { 147*b1cdbd2cSJim Jagielski const basegfx::B2DPolyPolygon aPolyPolygon(impCombineRangesToPolyPolygon(getRanges())); 148*b1cdbd2cSJim Jagielski const drawinglayer::primitive2d::Primitive2DReference aSelectionOutline( 149*b1cdbd2cSJim Jagielski new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( 150*b1cdbd2cSJim Jagielski aPolyPolygon, 151*b1cdbd2cSJim Jagielski aRGBColor)); 152*b1cdbd2cSJim Jagielski 153*b1cdbd2cSJim Jagielski // add both to result 154*b1cdbd2cSJim Jagielski aRetval.realloc(2); 155*b1cdbd2cSJim Jagielski aRetval[0] = aUnifiedTransparence; 156*b1cdbd2cSJim Jagielski aRetval[1] = aSelectionOutline; 157*b1cdbd2cSJim Jagielski } 158*b1cdbd2cSJim Jagielski else 159*b1cdbd2cSJim Jagielski { 160*b1cdbd2cSJim Jagielski // just add transparent part 161*b1cdbd2cSJim Jagielski aRetval = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparence, 1); 162*b1cdbd2cSJim Jagielski } 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski } 165*b1cdbd2cSJim Jagielski 166*b1cdbd2cSJim Jagielski return aRetval; 167*b1cdbd2cSJim Jagielski } 168*b1cdbd2cSJim Jagielski OverlaySelection(OverlayType eType,const Color & rColor,const std::vector<basegfx::B2DRange> & rRanges,bool bBorder)169*b1cdbd2cSJim Jagielski OverlaySelection::OverlaySelection( 170*b1cdbd2cSJim Jagielski OverlayType eType, 171*b1cdbd2cSJim Jagielski const Color& rColor, 172*b1cdbd2cSJim Jagielski const std::vector< basegfx::B2DRange >& rRanges, 173*b1cdbd2cSJim Jagielski bool bBorder) 174*b1cdbd2cSJim Jagielski : OverlayObject(rColor), 175*b1cdbd2cSJim Jagielski meOverlayType(eType), 176*b1cdbd2cSJim Jagielski maRanges(rRanges), 177*b1cdbd2cSJim Jagielski maLastOverlayType(eType), 178*b1cdbd2cSJim Jagielski mnLastTransparence(0), 179*b1cdbd2cSJim Jagielski mbBorder(bBorder) 180*b1cdbd2cSJim Jagielski { 181*b1cdbd2cSJim Jagielski // no AA for selection overlays 182*b1cdbd2cSJim Jagielski allowAntiAliase(false); 183*b1cdbd2cSJim Jagielski } 184*b1cdbd2cSJim Jagielski ~OverlaySelection()185*b1cdbd2cSJim Jagielski OverlaySelection::~OverlaySelection() 186*b1cdbd2cSJim Jagielski { 187*b1cdbd2cSJim Jagielski if(getOverlayManager()) 188*b1cdbd2cSJim Jagielski { 189*b1cdbd2cSJim Jagielski getOverlayManager()->remove(*this); 190*b1cdbd2cSJim Jagielski } 191*b1cdbd2cSJim Jagielski } 192*b1cdbd2cSJim Jagielski getOverlayObjectPrimitive2DSequence() const193*b1cdbd2cSJim Jagielski drawinglayer::primitive2d::Primitive2DSequence OverlaySelection::getOverlayObjectPrimitive2DSequence() const 194*b1cdbd2cSJim Jagielski { 195*b1cdbd2cSJim Jagielski // get current values 196*b1cdbd2cSJim Jagielski const OverlayType aNewOverlayType(impCheckPossibleOverlayType(meOverlayType)); 197*b1cdbd2cSJim Jagielski const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; 198*b1cdbd2cSJim Jagielski const sal_uInt16 nNewTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent()); 199*b1cdbd2cSJim Jagielski 200*b1cdbd2cSJim Jagielski if(getPrimitive2DSequence().hasElements()) 201*b1cdbd2cSJim Jagielski { 202*b1cdbd2cSJim Jagielski if(aNewOverlayType != maLastOverlayType 203*b1cdbd2cSJim Jagielski || nNewTransparence != mnLastTransparence) 204*b1cdbd2cSJim Jagielski { 205*b1cdbd2cSJim Jagielski // conditions of last local decomposition have changed, delete 206*b1cdbd2cSJim Jagielski const_cast< OverlaySelection* >(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DSequence()); 207*b1cdbd2cSJim Jagielski } 208*b1cdbd2cSJim Jagielski } 209*b1cdbd2cSJim Jagielski 210*b1cdbd2cSJim Jagielski if(!getPrimitive2DSequence().hasElements()) 211*b1cdbd2cSJim Jagielski { 212*b1cdbd2cSJim Jagielski // remember new values 213*b1cdbd2cSJim Jagielski const_cast< OverlaySelection* >(this)->maLastOverlayType = aNewOverlayType; 214*b1cdbd2cSJim Jagielski const_cast< OverlaySelection* >(this)->mnLastTransparence = nNewTransparence; 215*b1cdbd2cSJim Jagielski } 216*b1cdbd2cSJim Jagielski 217*b1cdbd2cSJim Jagielski // call base implementation 218*b1cdbd2cSJim Jagielski return OverlayObject::getOverlayObjectPrimitive2DSequence(); 219*b1cdbd2cSJim Jagielski } 220*b1cdbd2cSJim Jagielski setRanges(const std::vector<basegfx::B2DRange> & rNew)221*b1cdbd2cSJim Jagielski void OverlaySelection::setRanges(const std::vector< basegfx::B2DRange >& rNew) 222*b1cdbd2cSJim Jagielski { 223*b1cdbd2cSJim Jagielski if(rNew != maRanges) 224*b1cdbd2cSJim Jagielski { 225*b1cdbd2cSJim Jagielski maRanges = rNew; 226*b1cdbd2cSJim Jagielski objectChange(); 227*b1cdbd2cSJim Jagielski } 228*b1cdbd2cSJim Jagielski } 229*b1cdbd2cSJim Jagielski } // end of namespace overlay 230*b1cdbd2cSJim Jagielski } // end of namespace sdr 231*b1cdbd2cSJim Jagielski 232*b1cdbd2cSJim Jagielski ////////////////////////////////////////////////////////////////////////////// 233*b1cdbd2cSJim Jagielski // eof 234