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