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