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