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
convertPrimitive2DSequenceToBitmapEx(const Primitive2DSequence & rSequence,const basegfx::B2DRange & rTargetRange,const sal_uInt32 nMaximumQuadraticPixels)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
ensureReplacement()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
ensureSequenceAndRange()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
SvgData(const SvgDataArray & rSvgDataArray,sal_uInt32 nSvgDataArrayLength,const rtl::OUString & rPath)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
getRange() const189 const basegfx::B2DRange& SvgData::getRange() const
190 {
191 const_cast< SvgData* >(this)->ensureSequenceAndRange();
192
193 return maRange;
194 }
195
196 //////////////////////////////////////////////////////////////////////////////
197
getPrimitive2DSequence() const198 const Primitive2DSequence& SvgData::getPrimitive2DSequence() const
199 {
200 const_cast< SvgData* >(this)->ensureSequenceAndRange();
201
202 return maSequence;
203 }
204
205 //////////////////////////////////////////////////////////////////////////////
206
getReplacement() const207 const BitmapEx& SvgData::getReplacement() const
208 {
209 const_cast< SvgData* >(this)->ensureReplacement();
210
211 return maReplacement;
212 }
213
214 //////////////////////////////////////////////////////////////////////////////
215 // eof
216