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