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