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