xref: /AOO41X/main/vcl/source/gdi/svgdata.cxx (revision ddde725d65c83fe3ba1186d46f6e3e08f12ba47e)
1*ddde725dSArmin Le Grand /**************************************************************
2*ddde725dSArmin Le Grand  *
3*ddde725dSArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
4*ddde725dSArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
5*ddde725dSArmin Le Grand  * distributed with this work for additional information
6*ddde725dSArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
7*ddde725dSArmin Le Grand  * to you under the Apache License, Version 2.0 (the
8*ddde725dSArmin Le Grand  * "License"); you may not use this file except in compliance
9*ddde725dSArmin Le Grand  * with the License.  You may obtain a copy of the License at
10*ddde725dSArmin Le Grand  *
11*ddde725dSArmin Le Grand  *   http:\\www.apache.org\licenses\LICENSE-2.0
12*ddde725dSArmin Le Grand  *
13*ddde725dSArmin Le Grand  * Unless required by applicable law or agreed to in writing,
14*ddde725dSArmin Le Grand  * software distributed under the License is distributed on an
15*ddde725dSArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*ddde725dSArmin Le Grand  * KIND, either express or implied.  See the License for the
17*ddde725dSArmin Le Grand  * specific language governing permissions and limitations
18*ddde725dSArmin Le Grand  * under the License.
19*ddde725dSArmin Le Grand  *
20*ddde725dSArmin Le Grand  *************************************************************/
21*ddde725dSArmin Le Grand 
22*ddde725dSArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
23*ddde725dSArmin Le Grand #include "precompiled_vcl.hxx"
24*ddde725dSArmin Le Grand 
25*ddde725dSArmin Le Grand #include <vcl/svgdata.hxx>
26*ddde725dSArmin Le Grand #include <comphelper/processfactory.hxx>
27*ddde725dSArmin Le Grand #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28*ddde725dSArmin Le Grand #include <com/sun/star/graphic/XSvgParser.hpp>
29*ddde725dSArmin Le Grand #include <com/sun/star/graphic/XPrimitive2DRenderer.hpp>
30*ddde725dSArmin Le Grand #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
31*ddde725dSArmin Le Grand #include <vcl/canvastools.hxx>
32*ddde725dSArmin Le Grand #include <comphelper/seqstream.hxx>
33*ddde725dSArmin Le Grand 
34*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
35*ddde725dSArmin Le Grand 
36*ddde725dSArmin Le Grand using namespace ::com::sun::star;
37*ddde725dSArmin Le Grand 
38*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
39*ddde725dSArmin Le Grand 
40*ddde725dSArmin Le Grand void SvgData::ensureReplacement()
41*ddde725dSArmin Le Grand {
42*ddde725dSArmin Le Grand     ensureSequenceAndRange();
43*ddde725dSArmin Le Grand 
44*ddde725dSArmin Le Grand     if(maReplacement.IsEmpty() && maSequence.hasElements())
45*ddde725dSArmin Le Grand     {
46*ddde725dSArmin Le Grand         // create replacement graphic from maSequence
47*ddde725dSArmin Le Grand         // create XPrimitive2DRenderer
48*ddde725dSArmin Le Grand         uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
49*ddde725dSArmin Le Grand         const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools"));
50*ddde725dSArmin Le Grand 
51*ddde725dSArmin Le Grand         try
52*ddde725dSArmin Le Grand         {
53*ddde725dSArmin Le Grand             const uno::Reference< graphic::XPrimitive2DRenderer > xPrimitive2DRenderer(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
54*ddde725dSArmin Le Grand 
55*ddde725dSArmin Le Grand             if(xPrimitive2DRenderer.is())
56*ddde725dSArmin Le Grand             {
57*ddde725dSArmin Le Grand                 uno::Sequence< beans::PropertyValue > aViewParameters;
58*ddde725dSArmin Le Grand                 const basegfx::B2DRange& rRange(getRange());
59*ddde725dSArmin Le Grand                 geometry::RealRectangle2D aRealRect;
60*ddde725dSArmin Le Grand 
61*ddde725dSArmin Le Grand                 aRealRect.X1 = rRange.getMinX();
62*ddde725dSArmin Le Grand                 aRealRect.Y1 = rRange.getMinY();
63*ddde725dSArmin Le Grand                 aRealRect.X2 = rRange.getMaxX();
64*ddde725dSArmin Le Grand                 aRealRect.Y2 = rRange.getMaxY();
65*ddde725dSArmin Le Grand 
66*ddde725dSArmin Le Grand                 const uno::Reference< rendering::XBitmap > xBitmap(
67*ddde725dSArmin Le Grand                     xPrimitive2DRenderer->rasterize(
68*ddde725dSArmin Le Grand                         maSequence,
69*ddde725dSArmin Le Grand                         aViewParameters,
70*ddde725dSArmin Le Grand                         72,
71*ddde725dSArmin Le Grand                         72,
72*ddde725dSArmin Le Grand                         aRealRect,
73*ddde725dSArmin Le Grand                         500000));
74*ddde725dSArmin Le Grand 
75*ddde725dSArmin Le Grand                 if(xBitmap.is())
76*ddde725dSArmin Le Grand                 {
77*ddde725dSArmin Le Grand                     const uno::Reference< rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW);
78*ddde725dSArmin Le Grand 
79*ddde725dSArmin Le Grand                     if(xIntBmp.is())
80*ddde725dSArmin Le Grand                     {
81*ddde725dSArmin Le Grand                         maReplacement = vcl::unotools::bitmapExFromXBitmap(xIntBmp);
82*ddde725dSArmin Le Grand                     }
83*ddde725dSArmin Le Grand                 }
84*ddde725dSArmin Le Grand             }
85*ddde725dSArmin Le Grand         }
86*ddde725dSArmin Le Grand         catch(const uno::Exception&)
87*ddde725dSArmin Le Grand         {
88*ddde725dSArmin Le Grand             OSL_ENSURE(sal_False, "Got no graphic::XPrimitive2DRenderer (!)" );
89*ddde725dSArmin Le Grand         }
90*ddde725dSArmin Le Grand     }
91*ddde725dSArmin Le Grand }
92*ddde725dSArmin Le Grand 
93*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
94*ddde725dSArmin Le Grand 
95*ddde725dSArmin Le Grand void SvgData::ensureSequenceAndRange()
96*ddde725dSArmin Le Grand {
97*ddde725dSArmin Le Grand     if(!maSequence.hasElements() && mnSvgDataArrayLength)
98*ddde725dSArmin Le Grand     {
99*ddde725dSArmin Le Grand         // import SVG to maSequence, also set maRange
100*ddde725dSArmin Le Grand         maRange.reset();
101*ddde725dSArmin Le Grand 
102*ddde725dSArmin Le Grand         // create stream
103*ddde725dSArmin Le Grand         const uno::Sequence< sal_Int8 > aPostData((sal_Int8*)maSvgDataArray.get(), mnSvgDataArrayLength);
104*ddde725dSArmin Le Grand         const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(aPostData));
105*ddde725dSArmin Le Grand 
106*ddde725dSArmin Le Grand         if(myInputStream.is())
107*ddde725dSArmin Le Grand         {
108*ddde725dSArmin Le Grand             // create SVG interpreter
109*ddde725dSArmin Le Grand             uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
110*ddde725dSArmin Le Grand             const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.SvgTools"));
111*ddde725dSArmin Le Grand 
112*ddde725dSArmin Le Grand             try
113*ddde725dSArmin Le Grand             {
114*ddde725dSArmin Le Grand                 const uno::Reference< graphic::XSvgParser > xSvgParser(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
115*ddde725dSArmin Le Grand 
116*ddde725dSArmin Le Grand                 if(xSvgParser.is())
117*ddde725dSArmin Le Grand                 {
118*ddde725dSArmin Le Grand                     maSequence = xSvgParser->getDecomposition(myInputStream, maPath);
119*ddde725dSArmin Le Grand                 }
120*ddde725dSArmin Le Grand             }
121*ddde725dSArmin Le Grand             catch(const uno::Exception&)
122*ddde725dSArmin Le Grand             {
123*ddde725dSArmin Le Grand                 OSL_ENSURE(sal_False, "Got no graphic::XSvgParser (!)" );
124*ddde725dSArmin Le Grand             }
125*ddde725dSArmin Le Grand         }
126*ddde725dSArmin Le Grand 
127*ddde725dSArmin Le Grand         if(maSequence.hasElements())
128*ddde725dSArmin Le Grand         {
129*ddde725dSArmin Le Grand             const sal_Int32 nCount(maSequence.getLength());
130*ddde725dSArmin Le Grand             geometry::RealRectangle2D aRealRect;
131*ddde725dSArmin Le Grand             uno::Sequence< beans::PropertyValue > aViewParameters;
132*ddde725dSArmin Le Grand 
133*ddde725dSArmin Le Grand             for(sal_Int32 a(0L); a < nCount; a++)
134*ddde725dSArmin Le Grand             {
135*ddde725dSArmin Le Grand                 // get reference
136*ddde725dSArmin Le Grand                 const Primitive2DReference xReference(maSequence[a]);
137*ddde725dSArmin Le Grand 
138*ddde725dSArmin Le Grand                 if(xReference.is())
139*ddde725dSArmin Le Grand                 {
140*ddde725dSArmin Le Grand                     aRealRect = xReference->getRange(aViewParameters);
141*ddde725dSArmin Le Grand 
142*ddde725dSArmin Le Grand                     maRange.expand(
143*ddde725dSArmin Le Grand                         basegfx::B2DRange(
144*ddde725dSArmin Le Grand                             aRealRect.X1,
145*ddde725dSArmin Le Grand                             aRealRect.Y1,
146*ddde725dSArmin Le Grand                             aRealRect.X2,
147*ddde725dSArmin Le Grand                             aRealRect.Y2));
148*ddde725dSArmin Le Grand                 }
149*ddde725dSArmin Le Grand             }
150*ddde725dSArmin Le Grand         }
151*ddde725dSArmin Le Grand     }
152*ddde725dSArmin Le Grand }
153*ddde725dSArmin Le Grand 
154*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
155*ddde725dSArmin Le Grand 
156*ddde725dSArmin Le Grand SvgData::SvgData(const SvgDataArray& rSvgDataArray, sal_uInt32 nSvgDataArrayLength, const rtl::OUString& rPath)
157*ddde725dSArmin Le Grand :   maSvgDataArray(rSvgDataArray),
158*ddde725dSArmin Le Grand     mnSvgDataArrayLength(nSvgDataArrayLength),
159*ddde725dSArmin Le Grand     maPath(rPath),
160*ddde725dSArmin Le Grand     maRange(),
161*ddde725dSArmin Le Grand     maSequence(),
162*ddde725dSArmin Le Grand     maReplacement()
163*ddde725dSArmin Le Grand {
164*ddde725dSArmin Le Grand }
165*ddde725dSArmin Le Grand 
166*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
167*ddde725dSArmin Le Grand 
168*ddde725dSArmin Le Grand const basegfx::B2DRange& SvgData::getRange() const
169*ddde725dSArmin Le Grand {
170*ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureSequenceAndRange();
171*ddde725dSArmin Le Grand 
172*ddde725dSArmin Le Grand     return maRange;
173*ddde725dSArmin Le Grand }
174*ddde725dSArmin Le Grand 
175*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
176*ddde725dSArmin Le Grand 
177*ddde725dSArmin Le Grand const Primitive2DSequence& SvgData::getPrimitive2DSequence() const
178*ddde725dSArmin Le Grand {
179*ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureSequenceAndRange();
180*ddde725dSArmin Le Grand 
181*ddde725dSArmin Le Grand     return maSequence;
182*ddde725dSArmin Le Grand }
183*ddde725dSArmin Le Grand 
184*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
185*ddde725dSArmin Le Grand 
186*ddde725dSArmin Le Grand const BitmapEx& SvgData::getReplacement() const
187*ddde725dSArmin Le Grand {
188*ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureReplacement();
189*ddde725dSArmin Le Grand 
190*ddde725dSArmin Le Grand     return maReplacement;
191*ddde725dSArmin Le Grand }
192*ddde725dSArmin Le Grand 
193*ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
194*ddde725dSArmin Le Grand // eof
195