xref: /aoo41x/main/vcl/source/gdi/svgdata.cxx (revision 8718d260)
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  *
112b45cf47SArmin 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 
42*8718d260SArmin Le Grand BitmapEx VCL_DLLPUBLIC convertPrimitive2DSequenceToBitmapEx(
43*8718d260SArmin Le Grand     const Primitive2DSequence& rSequence,
44*8718d260SArmin Le Grand     const basegfx::B2DRange& rTargetRange)
45ddde725dSArmin Le Grand {
46*8718d260SArmin Le Grand     BitmapEx aRetval;
47ddde725dSArmin Le Grand 
48*8718d260SArmin Le Grand     if(rSequence.hasElements())
49ddde725dSArmin Le Grand     {
50ddde725dSArmin Le Grand         // create replacement graphic from maSequence
51ddde725dSArmin Le Grand         // create XPrimitive2DRenderer
52ddde725dSArmin Le Grand         uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
53ddde725dSArmin Le Grand         const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools"));
54ddde725dSArmin Le Grand 
55ddde725dSArmin Le Grand         try
56ddde725dSArmin Le Grand         {
57ddde725dSArmin Le Grand             const uno::Reference< graphic::XPrimitive2DRenderer > xPrimitive2DRenderer(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
58ddde725dSArmin Le Grand 
59ddde725dSArmin Le Grand             if(xPrimitive2DRenderer.is())
60ddde725dSArmin Le Grand             {
61ddde725dSArmin Le Grand                 uno::Sequence< beans::PropertyValue > aViewParameters;
62ddde725dSArmin Le Grand                 geometry::RealRectangle2D aRealRect;
63ddde725dSArmin Le Grand 
64*8718d260SArmin Le Grand                 aRealRect.X1 = rTargetRange.getMinX();
65*8718d260SArmin Le Grand                 aRealRect.Y1 = rTargetRange.getMinY();
66*8718d260SArmin Le Grand                 aRealRect.X2 = rTargetRange.getMaxX();
67*8718d260SArmin Le Grand                 aRealRect.Y2 = rTargetRange.getMaxY();
682758680cSArmin Le Grand 
692758680cSArmin Le Grand                 // get system DPI
702758680cSArmin Le Grand                 const Size aDPI(Application::GetDefaultDevice()->LogicToPixel(Size(1, 1), MAP_INCH));
712758680cSArmin Le Grand 
72ddde725dSArmin Le Grand                 const uno::Reference< rendering::XBitmap > xBitmap(
73ddde725dSArmin Le Grand                     xPrimitive2DRenderer->rasterize(
74*8718d260SArmin Le Grand                         rSequence,
75ddde725dSArmin Le Grand                         aViewParameters,
762758680cSArmin Le Grand                         aDPI.getWidth(),
772758680cSArmin Le Grand                         aDPI.getHeight(),
78ddde725dSArmin Le Grand                         aRealRect,
79ddde725dSArmin Le Grand                         500000));
80ddde725dSArmin Le Grand 
81ddde725dSArmin Le Grand                 if(xBitmap.is())
82ddde725dSArmin Le Grand                 {
83ddde725dSArmin Le Grand                     const uno::Reference< rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW);
84ddde725dSArmin Le Grand 
85ddde725dSArmin Le Grand                     if(xIntBmp.is())
86ddde725dSArmin Le Grand                     {
87*8718d260SArmin Le Grand                         aRetval = vcl::unotools::bitmapExFromXBitmap(xIntBmp);
88ddde725dSArmin Le Grand                     }
89ddde725dSArmin Le Grand                 }
90ddde725dSArmin Le Grand             }
91ddde725dSArmin Le Grand         }
92ddde725dSArmin Le Grand         catch(const uno::Exception&)
93ddde725dSArmin Le Grand         {
94ddde725dSArmin Le Grand             OSL_ENSURE(sal_False, "Got no graphic::XPrimitive2DRenderer (!)" );
95ddde725dSArmin Le Grand         }
96ddde725dSArmin Le Grand     }
97*8718d260SArmin Le Grand 
98*8718d260SArmin Le Grand     return aRetval;
99*8718d260SArmin Le Grand }
100*8718d260SArmin Le Grand 
101*8718d260SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
102*8718d260SArmin Le Grand 
103*8718d260SArmin Le Grand void SvgData::ensureReplacement()
104*8718d260SArmin Le Grand {
105*8718d260SArmin Le Grand     ensureSequenceAndRange();
106*8718d260SArmin Le Grand 
107*8718d260SArmin Le Grand     if(maReplacement.IsEmpty() && maSequence.hasElements())
108*8718d260SArmin Le Grand     {
109*8718d260SArmin Le Grand         maReplacement = convertPrimitive2DSequenceToBitmapEx(maSequence, getRange());
110*8718d260SArmin Le Grand     }
111ddde725dSArmin Le Grand }
112ddde725dSArmin Le Grand 
113ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
114ddde725dSArmin Le Grand 
115ddde725dSArmin Le Grand void SvgData::ensureSequenceAndRange()
116ddde725dSArmin Le Grand {
117ddde725dSArmin Le Grand     if(!maSequence.hasElements() && mnSvgDataArrayLength)
118ddde725dSArmin Le Grand     {
119ddde725dSArmin Le Grand         // import SVG to maSequence, also set maRange
120ddde725dSArmin Le Grand         maRange.reset();
121ddde725dSArmin Le Grand 
122ddde725dSArmin Le Grand         // create stream
123ddde725dSArmin Le Grand         const uno::Sequence< sal_Int8 > aPostData((sal_Int8*)maSvgDataArray.get(), mnSvgDataArrayLength);
124ddde725dSArmin Le Grand         const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(aPostData));
125ddde725dSArmin Le Grand 
126ddde725dSArmin Le Grand         if(myInputStream.is())
127ddde725dSArmin Le Grand         {
128ddde725dSArmin Le Grand             // create SVG interpreter
129ddde725dSArmin Le Grand             uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
130ddde725dSArmin Le Grand             const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.SvgTools"));
131ddde725dSArmin Le Grand 
132ddde725dSArmin Le Grand             try
133ddde725dSArmin Le Grand             {
134ddde725dSArmin Le Grand                 const uno::Reference< graphic::XSvgParser > xSvgParser(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
135ddde725dSArmin Le Grand 
136ddde725dSArmin Le Grand                 if(xSvgParser.is())
137ddde725dSArmin Le Grand                 {
138ddde725dSArmin Le Grand                     maSequence = xSvgParser->getDecomposition(myInputStream, maPath);
139ddde725dSArmin Le Grand                 }
140ddde725dSArmin Le Grand             }
141ddde725dSArmin Le Grand             catch(const uno::Exception&)
142ddde725dSArmin Le Grand             {
143ddde725dSArmin Le Grand                 OSL_ENSURE(sal_False, "Got no graphic::XSvgParser (!)" );
144ddde725dSArmin Le Grand             }
145ddde725dSArmin Le Grand         }
146ddde725dSArmin Le Grand 
147ddde725dSArmin Le Grand         if(maSequence.hasElements())
148ddde725dSArmin Le Grand         {
149ddde725dSArmin Le Grand             const sal_Int32 nCount(maSequence.getLength());
150ddde725dSArmin Le Grand             geometry::RealRectangle2D aRealRect;
151ddde725dSArmin Le Grand             uno::Sequence< beans::PropertyValue > aViewParameters;
152ddde725dSArmin Le Grand 
153ddde725dSArmin Le Grand             for(sal_Int32 a(0L); a < nCount; a++)
154ddde725dSArmin Le Grand             {
155ddde725dSArmin Le Grand                 // get reference
156ddde725dSArmin Le Grand                 const Primitive2DReference xReference(maSequence[a]);
157ddde725dSArmin Le Grand 
158ddde725dSArmin Le Grand                 if(xReference.is())
159ddde725dSArmin Le Grand                 {
160ddde725dSArmin Le Grand                     aRealRect = xReference->getRange(aViewParameters);
161ddde725dSArmin Le Grand 
162ddde725dSArmin Le Grand                     maRange.expand(
163ddde725dSArmin Le Grand                         basegfx::B2DRange(
164ddde725dSArmin Le Grand                             aRealRect.X1,
165ddde725dSArmin Le Grand                             aRealRect.Y1,
166ddde725dSArmin Le Grand                             aRealRect.X2,
167ddde725dSArmin Le Grand                             aRealRect.Y2));
168ddde725dSArmin Le Grand                 }
169ddde725dSArmin Le Grand             }
170ddde725dSArmin Le Grand         }
171ddde725dSArmin Le Grand     }
172ddde725dSArmin Le Grand }
173ddde725dSArmin Le Grand 
174ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
175ddde725dSArmin Le Grand 
176ddde725dSArmin Le Grand SvgData::SvgData(const SvgDataArray& rSvgDataArray, sal_uInt32 nSvgDataArrayLength, const rtl::OUString& rPath)
177ddde725dSArmin Le Grand :   maSvgDataArray(rSvgDataArray),
178ddde725dSArmin Le Grand     mnSvgDataArrayLength(nSvgDataArrayLength),
179ddde725dSArmin Le Grand     maPath(rPath),
180ddde725dSArmin Le Grand     maRange(),
181ddde725dSArmin Le Grand     maSequence(),
182ddde725dSArmin Le Grand     maReplacement()
183ddde725dSArmin Le Grand {
184ddde725dSArmin Le Grand }
185ddde725dSArmin Le Grand 
186ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
187ddde725dSArmin Le Grand 
188ddde725dSArmin Le Grand const basegfx::B2DRange& SvgData::getRange() const
189ddde725dSArmin Le Grand {
190ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureSequenceAndRange();
191ddde725dSArmin Le Grand 
192ddde725dSArmin Le Grand     return maRange;
193ddde725dSArmin Le Grand }
194ddde725dSArmin Le Grand 
195ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
196ddde725dSArmin Le Grand 
197ddde725dSArmin Le Grand const Primitive2DSequence& SvgData::getPrimitive2DSequence() const
198ddde725dSArmin Le Grand {
199ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureSequenceAndRange();
200ddde725dSArmin Le Grand 
201ddde725dSArmin Le Grand     return maSequence;
202ddde725dSArmin Le Grand }
203ddde725dSArmin Le Grand 
204ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
205ddde725dSArmin Le Grand 
206ddde725dSArmin Le Grand const BitmapEx& SvgData::getReplacement() const
207ddde725dSArmin Le Grand {
208ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureReplacement();
209ddde725dSArmin Le Grand 
210ddde725dSArmin Le Grand     return maReplacement;
211ddde725dSArmin Le Grand }
212ddde725dSArmin Le Grand 
213ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
214ddde725dSArmin Le Grand // eof
215