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