xref: /aoo42x/main/vcl/source/gdi/svgdata.cxx (revision 2758680c)
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