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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_vcl.hxx" 24 25 #include <vcl/svgdata.hxx> 26 #include <comphelper/processfactory.hxx> 27 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 28 #include <com/sun/star/graphic/XSvgParser.hpp> 29 #include <com/sun/star/graphic/XPrimitive2DRenderer.hpp> 30 #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp> 31 #include <vcl/canvastools.hxx> 32 #include <comphelper/seqstream.hxx> 33 #include <vcl/svapp.hxx> 34 #include <vcl/outdev.hxx> 35 36 ////////////////////////////////////////////////////////////////////////////// 37 38 using namespace ::com::sun::star; 39 40 ////////////////////////////////////////////////////////////////////////////// 41 42 BitmapEx VCL_DLLPUBLIC convertPrimitive2DSequenceToBitmapEx( 43 const Primitive2DSequence& rSequence, 44 const basegfx::B2DRange& rTargetRange, 45 const sal_uInt32 nMaximumQuadraticPixels) 46 { 47 BitmapEx aRetval; 48 49 if(rSequence.hasElements()) 50 { 51 // create replacement graphic from maSequence 52 // create XPrimitive2DRenderer 53 uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory()); 54 const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools")); 55 56 try 57 { 58 const uno::Reference< graphic::XPrimitive2DRenderer > xPrimitive2DRenderer(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW); 59 60 if(xPrimitive2DRenderer.is()) 61 { 62 uno::Sequence< beans::PropertyValue > aViewParameters; 63 geometry::RealRectangle2D aRealRect; 64 65 aRealRect.X1 = rTargetRange.getMinX(); 66 aRealRect.Y1 = rTargetRange.getMinY(); 67 aRealRect.X2 = rTargetRange.getMaxX(); 68 aRealRect.Y2 = rTargetRange.getMaxY(); 69 70 // get system DPI 71 const Size aDPI(Application::GetDefaultDevice()->LogicToPixel(Size(1, 1), MAP_INCH)); 72 73 const uno::Reference< rendering::XBitmap > xBitmap( 74 xPrimitive2DRenderer->rasterize( 75 rSequence, 76 aViewParameters, 77 aDPI.getWidth(), 78 aDPI.getHeight(), 79 aRealRect, 80 nMaximumQuadraticPixels)); 81 82 if(xBitmap.is()) 83 { 84 const uno::Reference< rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW); 85 86 if(xIntBmp.is()) 87 { 88 aRetval = vcl::unotools::bitmapExFromXBitmap(xIntBmp); 89 } 90 } 91 } 92 } 93 catch(const uno::Exception&) 94 { 95 OSL_ENSURE(sal_False, "Got no graphic::XPrimitive2DRenderer (!)" ); 96 } 97 } 98 99 return aRetval; 100 } 101 102 ////////////////////////////////////////////////////////////////////////////// 103 104 void SvgData::ensureReplacement() 105 { 106 ensureSequenceAndRange(); 107 108 if(maReplacement.IsEmpty() && maSequence.hasElements()) 109 { 110 maReplacement = convertPrimitive2DSequenceToBitmapEx(maSequence, getRange()); 111 } 112 } 113 114 ////////////////////////////////////////////////////////////////////////////// 115 116 void SvgData::ensureSequenceAndRange() 117 { 118 if(!maSequence.hasElements() && mnSvgDataArrayLength) 119 { 120 // import SVG to maSequence, also set maRange 121 maRange.reset(); 122 123 // create stream 124 const uno::Sequence< sal_Int8 > aPostData((sal_Int8*)maSvgDataArray.get(), mnSvgDataArrayLength); 125 const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(aPostData)); 126 127 if(myInputStream.is()) 128 { 129 // create SVG interpreter 130 uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory()); 131 const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.SvgTools")); 132 133 try 134 { 135 const uno::Reference< graphic::XSvgParser > xSvgParser(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW); 136 137 if(xSvgParser.is()) 138 { 139 maSequence = xSvgParser->getDecomposition(myInputStream, maPath); 140 } 141 } 142 catch(const uno::Exception&) 143 { 144 OSL_ENSURE(sal_False, "Got no graphic::XSvgParser (!)" ); 145 } 146 } 147 148 if(maSequence.hasElements()) 149 { 150 const sal_Int32 nCount(maSequence.getLength()); 151 geometry::RealRectangle2D aRealRect; 152 uno::Sequence< beans::PropertyValue > aViewParameters; 153 154 for(sal_Int32 a(0L); a < nCount; a++) 155 { 156 // get reference 157 const Primitive2DReference xReference(maSequence[a]); 158 159 if(xReference.is()) 160 { 161 aRealRect = xReference->getRange(aViewParameters); 162 163 maRange.expand( 164 basegfx::B2DRange( 165 aRealRect.X1, 166 aRealRect.Y1, 167 aRealRect.X2, 168 aRealRect.Y2)); 169 } 170 } 171 } 172 } 173 } 174 175 ////////////////////////////////////////////////////////////////////////////// 176 177 SvgData::SvgData(const SvgDataArray& rSvgDataArray, sal_uInt32 nSvgDataArrayLength, const rtl::OUString& rPath) 178 : maSvgDataArray(rSvgDataArray), 179 mnSvgDataArrayLength(nSvgDataArrayLength), 180 maPath(rPath), 181 maRange(), 182 maSequence(), 183 maReplacement() 184 { 185 } 186 187 ////////////////////////////////////////////////////////////////////////////// 188 189 const basegfx::B2DRange& SvgData::getRange() const 190 { 191 const_cast< SvgData* >(this)->ensureSequenceAndRange(); 192 193 return maRange; 194 } 195 196 ////////////////////////////////////////////////////////////////////////////// 197 198 const Primitive2DSequence& SvgData::getPrimitive2DSequence() const 199 { 200 const_cast< SvgData* >(this)->ensureSequenceAndRange(); 201 202 return maSequence; 203 } 204 205 ////////////////////////////////////////////////////////////////////////////// 206 207 const BitmapEx& SvgData::getReplacement() const 208 { 209 const_cast< SvgData* >(this)->ensureReplacement(); 210 211 return maReplacement; 212 } 213 214 ////////////////////////////////////////////////////////////////////////////// 215 // eof 216