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_canvas.hxx"
26 
27 #include <canvas/debug.hxx>
28 #include <canvas/canvastools.hxx>
29 
30 #include <rtl/math.hxx>
31 
32 #include <basegfx/matrix/b2dhommatrix.hxx>
33 #include <basegfx/polygon/b2dpolygontools.hxx>
34 #include <basegfx/point/b2dpoint.hxx>
35 #include <basegfx/range/b2drectangle.hxx>
36 #include <basegfx/tools/canvastools.hxx>
37 #include <basegfx/numeric/ftools.hxx>
38 #include <basegfx/tools/tools.hxx>
39 
40 #include <limits>
41 
42 #include <canvas/parametricpolypolygon.hxx>
43 
44 
45 using namespace ::com::sun::star;
46 
47 namespace canvas
48 {
getAvailableServiceNames()49     uno::Sequence<rtl::OUString> ParametricPolyPolygon::getAvailableServiceNames()
50     {
51         uno::Sequence<rtl::OUString> aRet(3);
52         aRet[0] = rtl::OUString::createFromAscii("LinearGradient");
53         aRet[1] = rtl::OUString::createFromAscii("EllipticalGradient");
54         aRet[2] = rtl::OUString::createFromAscii("RectangularGradient");
55 
56         return aRet;
57     }
58 
create(const uno::Reference<rendering::XGraphicDevice> & rDevice,const::rtl::OUString & rServiceName,const uno::Sequence<uno::Any> & rArgs)59     ParametricPolyPolygon* ParametricPolyPolygon::create(
60         const uno::Reference< rendering::XGraphicDevice >& rDevice,
61         const ::rtl::OUString& rServiceName,
62         const uno::Sequence< uno::Any >& rArgs )
63     {
64         uno::Sequence< uno::Sequence< double > > colorSequence(2);
65         uno::Sequence< double > colorStops(2);
66         double fAspectRatio=1.0;
67 
68         // defaults
69         uno::Sequence< rendering::RGBColor > rgbColors(1);
70         rgbColors[0] = rendering::RGBColor(0,0,0);
71         colorSequence[0] = rDevice->getDeviceColorSpace()->convertFromRGB(rgbColors);
72         rgbColors[0] = rendering::RGBColor(1,1,1);
73         colorSequence[1] = rDevice->getDeviceColorSpace()->convertFromRGB(rgbColors);
74         colorStops[0] = 0;
75         colorStops[1] = 1;
76 
77         // extract args
78         for( sal_Int32 i=0; i<rArgs.getLength(); ++i )
79         {
80             beans::PropertyValue aProp;
81             if( (rArgs[i] >>= aProp) )
82             {
83                 if( aProp.Name.equalsAscii("Colors") )
84                 {
85                     aProp.Value >>= colorSequence;
86                 }
87                 else if( aProp.Name.equalsAscii("Stops") )
88                 {
89                     aProp.Value >>= colorStops;
90                 }
91                 else if( aProp.Name.equalsAscii("AspectRatio") )
92                 {
93                     aProp.Value >>= fAspectRatio;
94                 }
95             }
96         }
97 
98         if( rServiceName.equalsAscii("LinearGradient") )
99         {
100             return createLinearHorizontalGradient(rDevice, colorSequence, colorStops);
101         }
102         else if( rServiceName.equalsAscii("EllipticalGradient") )
103         {
104             return createEllipticalGradient(rDevice, colorSequence, colorStops, fAspectRatio);
105         }
106         else if( rServiceName.equalsAscii("RectangularGradient") )
107         {
108             return createRectangularGradient(rDevice, colorSequence, colorStops, fAspectRatio);
109         }
110         else if( rServiceName.equalsAscii("VerticalLineHatch") )
111         {
112             // TODO: NYI
113         }
114         else if( rServiceName.equalsAscii("OrthogonalLinesHatch") )
115         {
116             // TODO: NYI
117         }
118         else if( rServiceName.equalsAscii("ThreeCrossingLinesHatch") )
119         {
120             // TODO: NYI
121         }
122         else if( rServiceName.equalsAscii("FourCrossingLinesHatch") )
123         {
124             // TODO: NYI
125         }
126 
127         return NULL;
128     }
129 
createLinearHorizontalGradient(const uno::Reference<rendering::XGraphicDevice> & rDevice,const uno::Sequence<uno::Sequence<double>> & colors,const uno::Sequence<double> & stops)130     ParametricPolyPolygon* ParametricPolyPolygon::createLinearHorizontalGradient(
131         const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
132         const uno::Sequence< uno::Sequence< double > >&		colors,
133         const uno::Sequence< double >& 						stops )
134     {
135         // TODO(P2): hold gradient brush statically, and only setup
136         // the colors
137         return new ParametricPolyPolygon( rDevice, GRADIENT_LINEAR, colors, stops );
138     }
139 
createEllipticalGradient(const uno::Reference<rendering::XGraphicDevice> & rDevice,const uno::Sequence<uno::Sequence<double>> & colors,const uno::Sequence<double> & stops,double fAspectRatio)140     ParametricPolyPolygon* ParametricPolyPolygon::createEllipticalGradient(
141         const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
142         const uno::Sequence< uno::Sequence< double > >&		colors,
143         const uno::Sequence< double >& 						stops,
144         double                                              fAspectRatio )
145     {
146         // TODO(P2): hold gradient polygon statically, and only setup
147         // the colors
148         return new ParametricPolyPolygon(
149             rDevice,
150             ::basegfx::tools::createPolygonFromCircle(
151                 ::basegfx::B2DPoint(0,0), 1 ),
152             GRADIENT_ELLIPTICAL,
153             colors, stops, fAspectRatio );
154     }
155 
createRectangularGradient(const uno::Reference<rendering::XGraphicDevice> & rDevice,const uno::Sequence<uno::Sequence<double>> & colors,const uno::Sequence<double> & stops,double fAspectRatio)156     ParametricPolyPolygon* ParametricPolyPolygon::createRectangularGradient( const uno::Reference< rendering::XGraphicDevice >& rDevice,
157                                                                              const uno::Sequence< uno::Sequence< double > >&	colors,
158                                                                              const uno::Sequence< double >& 					stops,
159                                                                              double                                             fAspectRatio )
160     {
161         // TODO(P2): hold gradient polygon statically, and only setup
162         // the colors
163         return new ParametricPolyPolygon(
164             rDevice,
165             ::basegfx::tools::createPolygonFromRect(
166                 ::basegfx::B2DRectangle( -1, -1, 1, 1 ) ),
167             GRADIENT_RECTANGULAR,
168             colors, stops, fAspectRatio );
169     }
170 
disposing()171     void SAL_CALL ParametricPolyPolygon::disposing()
172     {
173         ::osl::MutexGuard aGuard( m_aMutex );
174 
175         mxDevice.clear();
176     }
177 
getOutline(double)178     uno::Reference< rendering::XPolyPolygon2D > SAL_CALL ParametricPolyPolygon::getOutline( double /*t*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException)
179     {
180         ::osl::MutexGuard aGuard( m_aMutex );
181 
182         // TODO(F1): outline NYI
183         return uno::Reference< rendering::XPolyPolygon2D >();
184     }
185 
getColor(double)186     uno::Sequence< double > SAL_CALL ParametricPolyPolygon::getColor( double /*t*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException)
187     {
188         ::osl::MutexGuard aGuard( m_aMutex );
189 
190         // TODO(F1): color NYI
191         return uno::Sequence< double >();
192     }
193 
getPointColor(const geometry::RealPoint2D &)194     uno::Sequence< double > SAL_CALL ParametricPolyPolygon::getPointColor( const geometry::RealPoint2D& /*point*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException)
195     {
196         ::osl::MutexGuard aGuard( m_aMutex );
197 
198         // TODO(F1): point color NYI
199         return uno::Sequence< double >();
200     }
201 
getColorSpace()202     uno::Reference< rendering::XColorSpace > SAL_CALL ParametricPolyPolygon::getColorSpace() throw (uno::RuntimeException)
203     {
204         ::osl::MutexGuard aGuard( m_aMutex );
205 
206         return mxDevice.is() ? mxDevice->getDeviceColorSpace() : uno::Reference< rendering::XColorSpace >();
207     }
208 
209 #define IMPLEMENTATION_NAME "Canvas::ParametricPolyPolygon"
210 #define SERVICE_NAME "com.sun.star.rendering.ParametricPolyPolygon"
211 
getImplementationName()212     ::rtl::OUString SAL_CALL ParametricPolyPolygon::getImplementationName(  ) throw (uno::RuntimeException)
213     {
214         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
215     }
216 
supportsService(const::rtl::OUString & ServiceName)217     sal_Bool SAL_CALL ParametricPolyPolygon::supportsService( const ::rtl::OUString& ServiceName ) throw (uno::RuntimeException)
218     {
219         return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
220     }
221 
getSupportedServiceNames()222     uno::Sequence< ::rtl::OUString > SAL_CALL ParametricPolyPolygon::getSupportedServiceNames(  ) throw (uno::RuntimeException)
223     {
224         uno::Sequence< ::rtl::OUString > aRet(1);
225         aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
226 
227         return aRet;
228     }
229 
~ParametricPolyPolygon()230     ParametricPolyPolygon::~ParametricPolyPolygon()
231     {
232     }
233 
ParametricPolyPolygon(const uno::Reference<rendering::XGraphicDevice> & rDevice,const::basegfx::B2DPolygon & rGradientPoly,GradientType eType,const uno::Sequence<uno::Sequence<double>> & rColors,const uno::Sequence<double> & rStops)234     ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
235                                                   const ::basegfx::B2DPolygon&							rGradientPoly,
236                                                   GradientType                                          eType,
237                                                   const uno::Sequence< uno::Sequence< double > >&		rColors,
238                                                   const uno::Sequence< double >& 						rStops ) :
239         ParametricPolyPolygon_Base( m_aMutex ),
240         mxDevice( rDevice ),
241         maValues( rGradientPoly,
242                   rColors,
243                   rStops,
244                   1.0,
245                   eType )
246     {
247     }
248 
ParametricPolyPolygon(const uno::Reference<rendering::XGraphicDevice> & rDevice,const::basegfx::B2DPolygon & rGradientPoly,GradientType eType,const uno::Sequence<uno::Sequence<double>> & rColors,const uno::Sequence<double> & rStops,double nAspectRatio)249     ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
250                                                   const ::basegfx::B2DPolygon&							rGradientPoly,
251                                                   GradientType                                          eType,
252                                                   const uno::Sequence< uno::Sequence< double > >&		rColors,
253                                                   const uno::Sequence< double >& 						rStops,
254                                                   double												nAspectRatio ) :
255         ParametricPolyPolygon_Base( m_aMutex ),
256         mxDevice( rDevice ),
257         maValues( rGradientPoly,
258                   rColors,
259                   rStops,
260                   nAspectRatio,
261                   eType )
262     {
263     }
264 
ParametricPolyPolygon(const uno::Reference<rendering::XGraphicDevice> & rDevice,GradientType eType,const uno::Sequence<uno::Sequence<double>> & rColors,const uno::Sequence<double> & rStops)265     ParametricPolyPolygon::ParametricPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
266                                                   GradientType	 										eType,
267                                                   const uno::Sequence< uno::Sequence< double > >&		rColors,
268                                                   const uno::Sequence< double >& 						rStops ) :
269         ParametricPolyPolygon_Base( m_aMutex ),
270         mxDevice( rDevice ),
271         maValues( ::basegfx::B2DPolygon(),
272                   rColors,
273                   rStops,
274                   1.0,
275                   eType )
276     {
277     }
278 
getValues() const279     ParametricPolyPolygon::Values ParametricPolyPolygon::getValues() const
280     {
281         ::osl::MutexGuard aGuard( m_aMutex );
282 
283         return maValues;
284     }
285 
286 }
287