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