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