xref: /aoo41x/main/vcl/source/gdi/svgdata.cxx (revision 9f63b866)
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 
convertPrimitive2DSequenceToBitmapEx(const Primitive2DSequence & rSequence,const basegfx::B2DRange & rTargetRange,const sal_uInt32 nMaximumQuadraticPixels)428718d260SArmin Le Grand BitmapEx VCL_DLLPUBLIC convertPrimitive2DSequenceToBitmapEx(
438718d260SArmin Le Grand     const Primitive2DSequence& rSequence,
44*9f63b866SArmin Le Grand     const basegfx::B2DRange& rTargetRange,
45*9f63b866SArmin Le Grand     const sal_uInt32 nMaximumQuadraticPixels)
46ddde725dSArmin Le Grand {
478718d260SArmin Le Grand     BitmapEx aRetval;
48ddde725dSArmin Le Grand 
498718d260SArmin Le Grand     if(rSequence.hasElements())
50ddde725dSArmin Le Grand     {
51ddde725dSArmin Le Grand         // create replacement graphic from maSequence
52ddde725dSArmin Le Grand         // create XPrimitive2DRenderer
53ddde725dSArmin Le Grand         uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
54ddde725dSArmin Le Grand         const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools"));
55ddde725dSArmin Le Grand 
56ddde725dSArmin Le Grand         try
57ddde725dSArmin Le Grand         {
58ddde725dSArmin Le Grand             const uno::Reference< graphic::XPrimitive2DRenderer > xPrimitive2DRenderer(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
59ddde725dSArmin Le Grand 
60ddde725dSArmin Le Grand             if(xPrimitive2DRenderer.is())
61ddde725dSArmin Le Grand             {
62ddde725dSArmin Le Grand                 uno::Sequence< beans::PropertyValue > aViewParameters;
63ddde725dSArmin Le Grand                 geometry::RealRectangle2D aRealRect;
64ddde725dSArmin Le Grand 
658718d260SArmin Le Grand                 aRealRect.X1 = rTargetRange.getMinX();
668718d260SArmin Le Grand                 aRealRect.Y1 = rTargetRange.getMinY();
678718d260SArmin Le Grand                 aRealRect.X2 = rTargetRange.getMaxX();
688718d260SArmin Le Grand                 aRealRect.Y2 = rTargetRange.getMaxY();
692758680cSArmin Le Grand 
702758680cSArmin Le Grand                 // get system DPI
712758680cSArmin Le Grand                 const Size aDPI(Application::GetDefaultDevice()->LogicToPixel(Size(1, 1), MAP_INCH));
722758680cSArmin Le Grand 
73ddde725dSArmin Le Grand                 const uno::Reference< rendering::XBitmap > xBitmap(
74ddde725dSArmin Le Grand                     xPrimitive2DRenderer->rasterize(
758718d260SArmin Le Grand                         rSequence,
76ddde725dSArmin Le Grand                         aViewParameters,
772758680cSArmin Le Grand                         aDPI.getWidth(),
782758680cSArmin Le Grand                         aDPI.getHeight(),
79ddde725dSArmin Le Grand                         aRealRect,
80*9f63b866SArmin Le Grand                         nMaximumQuadraticPixels));
81ddde725dSArmin Le Grand 
82ddde725dSArmin Le Grand                 if(xBitmap.is())
83ddde725dSArmin Le Grand                 {
84ddde725dSArmin Le Grand                     const uno::Reference< rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW);
85ddde725dSArmin Le Grand 
86ddde725dSArmin Le Grand                     if(xIntBmp.is())
87ddde725dSArmin Le Grand                     {
888718d260SArmin Le Grand                         aRetval = vcl::unotools::bitmapExFromXBitmap(xIntBmp);
89ddde725dSArmin Le Grand                     }
90ddde725dSArmin Le Grand                 }
91ddde725dSArmin Le Grand             }
92ddde725dSArmin Le Grand         }
93ddde725dSArmin Le Grand         catch(const uno::Exception&)
94ddde725dSArmin Le Grand         {
95ddde725dSArmin Le Grand             OSL_ENSURE(sal_False, "Got no graphic::XPrimitive2DRenderer (!)" );
96ddde725dSArmin Le Grand         }
97ddde725dSArmin Le Grand     }
988718d260SArmin Le Grand 
998718d260SArmin Le Grand     return aRetval;
1008718d260SArmin Le Grand }
1018718d260SArmin Le Grand 
1028718d260SArmin Le Grand //////////////////////////////////////////////////////////////////////////////
1038718d260SArmin Le Grand 
ensureReplacement()1048718d260SArmin Le Grand void SvgData::ensureReplacement()
1058718d260SArmin Le Grand {
1068718d260SArmin Le Grand     ensureSequenceAndRange();
1078718d260SArmin Le Grand 
1088718d260SArmin Le Grand     if(maReplacement.IsEmpty() && maSequence.hasElements())
1098718d260SArmin Le Grand     {
1108718d260SArmin Le Grand         maReplacement = convertPrimitive2DSequenceToBitmapEx(maSequence, getRange());
1118718d260SArmin Le Grand     }
112ddde725dSArmin Le Grand }
113ddde725dSArmin Le Grand 
114ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
115ddde725dSArmin Le Grand 
ensureSequenceAndRange()116ddde725dSArmin Le Grand void SvgData::ensureSequenceAndRange()
117ddde725dSArmin Le Grand {
118ddde725dSArmin Le Grand     if(!maSequence.hasElements() && mnSvgDataArrayLength)
119ddde725dSArmin Le Grand     {
120ddde725dSArmin Le Grand         // import SVG to maSequence, also set maRange
121ddde725dSArmin Le Grand         maRange.reset();
122ddde725dSArmin Le Grand 
123ddde725dSArmin Le Grand         // create stream
124ddde725dSArmin Le Grand         const uno::Sequence< sal_Int8 > aPostData((sal_Int8*)maSvgDataArray.get(), mnSvgDataArrayLength);
125ddde725dSArmin Le Grand         const uno::Reference< io::XInputStream > myInputStream(new comphelper::SequenceInputStream(aPostData));
126ddde725dSArmin Le Grand 
127ddde725dSArmin Le Grand         if(myInputStream.is())
128ddde725dSArmin Le Grand         {
129ddde725dSArmin Le Grand             // create SVG interpreter
130ddde725dSArmin Le Grand             uno::Reference< lang::XMultiServiceFactory > xFactory(::comphelper::getProcessServiceFactory());
131ddde725dSArmin Le Grand             const rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.SvgTools"));
132ddde725dSArmin Le Grand 
133ddde725dSArmin Le Grand             try
134ddde725dSArmin Le Grand             {
135ddde725dSArmin Le Grand                 const uno::Reference< graphic::XSvgParser > xSvgParser(xFactory->createInstance(aServiceName), uno::UNO_QUERY_THROW);
136ddde725dSArmin Le Grand 
137ddde725dSArmin Le Grand                 if(xSvgParser.is())
138ddde725dSArmin Le Grand                 {
139ddde725dSArmin Le Grand                     maSequence = xSvgParser->getDecomposition(myInputStream, maPath);
140ddde725dSArmin Le Grand                 }
141ddde725dSArmin Le Grand             }
142ddde725dSArmin Le Grand             catch(const uno::Exception&)
143ddde725dSArmin Le Grand             {
144ddde725dSArmin Le Grand                 OSL_ENSURE(sal_False, "Got no graphic::XSvgParser (!)" );
145ddde725dSArmin Le Grand             }
146ddde725dSArmin Le Grand         }
147ddde725dSArmin Le Grand 
148ddde725dSArmin Le Grand         if(maSequence.hasElements())
149ddde725dSArmin Le Grand         {
150ddde725dSArmin Le Grand             const sal_Int32 nCount(maSequence.getLength());
151ddde725dSArmin Le Grand             geometry::RealRectangle2D aRealRect;
152ddde725dSArmin Le Grand             uno::Sequence< beans::PropertyValue > aViewParameters;
153ddde725dSArmin Le Grand 
154ddde725dSArmin Le Grand             for(sal_Int32 a(0L); a < nCount; a++)
155ddde725dSArmin Le Grand             {
156ddde725dSArmin Le Grand                 // get reference
157ddde725dSArmin Le Grand                 const Primitive2DReference xReference(maSequence[a]);
158ddde725dSArmin Le Grand 
159ddde725dSArmin Le Grand                 if(xReference.is())
160ddde725dSArmin Le Grand                 {
161ddde725dSArmin Le Grand                     aRealRect = xReference->getRange(aViewParameters);
162ddde725dSArmin Le Grand 
163ddde725dSArmin Le Grand                     maRange.expand(
164ddde725dSArmin Le Grand                         basegfx::B2DRange(
165ddde725dSArmin Le Grand                             aRealRect.X1,
166ddde725dSArmin Le Grand                             aRealRect.Y1,
167ddde725dSArmin Le Grand                             aRealRect.X2,
168ddde725dSArmin Le Grand                             aRealRect.Y2));
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(const SvgDataArray & rSvgDataArray,sal_uInt32 nSvgDataArrayLength,const rtl::OUString & rPath)177ddde725dSArmin Le Grand SvgData::SvgData(const SvgDataArray& rSvgDataArray, sal_uInt32 nSvgDataArrayLength, const rtl::OUString& rPath)
178ddde725dSArmin Le Grand :   maSvgDataArray(rSvgDataArray),
179ddde725dSArmin Le Grand     mnSvgDataArrayLength(nSvgDataArrayLength),
180ddde725dSArmin Le Grand     maPath(rPath),
181ddde725dSArmin Le Grand     maRange(),
182ddde725dSArmin Le Grand     maSequence(),
183ddde725dSArmin Le Grand     maReplacement()
184ddde725dSArmin Le Grand {
185ddde725dSArmin Le Grand }
186ddde725dSArmin Le Grand 
187ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
188ddde725dSArmin Le Grand 
getRange() const189ddde725dSArmin Le Grand const basegfx::B2DRange& SvgData::getRange() const
190ddde725dSArmin Le Grand {
191ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureSequenceAndRange();
192ddde725dSArmin Le Grand 
193ddde725dSArmin Le Grand     return maRange;
194ddde725dSArmin Le Grand }
195ddde725dSArmin Le Grand 
196ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
197ddde725dSArmin Le Grand 
getPrimitive2DSequence() const198ddde725dSArmin Le Grand const Primitive2DSequence& SvgData::getPrimitive2DSequence() const
199ddde725dSArmin Le Grand {
200ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureSequenceAndRange();
201ddde725dSArmin Le Grand 
202ddde725dSArmin Le Grand     return maSequence;
203ddde725dSArmin Le Grand }
204ddde725dSArmin Le Grand 
205ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
206ddde725dSArmin Le Grand 
getReplacement() const207ddde725dSArmin Le Grand const BitmapEx& SvgData::getReplacement() const
208ddde725dSArmin Le Grand {
209ddde725dSArmin Le Grand     const_cast< SvgData* >(this)->ensureReplacement();
210ddde725dSArmin Le Grand 
211ddde725dSArmin Le Grand     return maReplacement;
212ddde725dSArmin Le Grand }
213ddde725dSArmin Le Grand 
214ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
215ddde725dSArmin Le Grand // eof
216