1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
23*b1cdbd2cSJim Jagielski #include "precompiled_svgio.hxx"
24*b1cdbd2cSJim Jagielski 
25*b1cdbd2cSJim Jagielski #include <svgio/svgreader/svgimagenode.hxx>
26*b1cdbd2cSJim Jagielski #include <svgio/svgreader/svgdocument.hxx>
27*b1cdbd2cSJim Jagielski #include <sax/tools/converter.hxx>
28*b1cdbd2cSJim Jagielski #include <tools/stream.hxx>
29*b1cdbd2cSJim Jagielski #include <vcl/bitmapex.hxx>
30*b1cdbd2cSJim Jagielski #include <svtools/filter.hxx>
31*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrixtools.hxx>
32*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
33*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/groupprimitive2d.hxx>
34*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
35*b1cdbd2cSJim Jagielski #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
36*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygontools.hxx>
37*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolygon.hxx>
38*b1cdbd2cSJim Jagielski #include <rtl/uri.hxx>
39*b1cdbd2cSJim Jagielski #include <drawinglayer/geometry/viewinformation2d.hxx>
40*b1cdbd2cSJim Jagielski 
41*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////////////
42*b1cdbd2cSJim Jagielski 
43*b1cdbd2cSJim Jagielski namespace svgio
44*b1cdbd2cSJim Jagielski {
45*b1cdbd2cSJim Jagielski     namespace svgreader
46*b1cdbd2cSJim Jagielski     {
SvgImageNode(SvgDocument & rDocument,SvgNode * pParent)47*b1cdbd2cSJim Jagielski         SvgImageNode::SvgImageNode(
48*b1cdbd2cSJim Jagielski             SvgDocument& rDocument,
49*b1cdbd2cSJim Jagielski             SvgNode* pParent)
50*b1cdbd2cSJim Jagielski         :   SvgNode(SVGTokenRect, rDocument, pParent),
51*b1cdbd2cSJim Jagielski             maSvgStyleAttributes(*this),
52*b1cdbd2cSJim Jagielski             maSvgAspectRatio(),
53*b1cdbd2cSJim Jagielski             mpaTransform(0),
54*b1cdbd2cSJim Jagielski             maX(0),
55*b1cdbd2cSJim Jagielski             maY(0),
56*b1cdbd2cSJim Jagielski             maWidth(0),
57*b1cdbd2cSJim Jagielski             maHeight(0),
58*b1cdbd2cSJim Jagielski             maXLink(),
59*b1cdbd2cSJim Jagielski             maUrl(),
60*b1cdbd2cSJim Jagielski             maMimeType(),
61*b1cdbd2cSJim Jagielski             maData()
62*b1cdbd2cSJim Jagielski         {
63*b1cdbd2cSJim Jagielski         }
64*b1cdbd2cSJim Jagielski 
~SvgImageNode()65*b1cdbd2cSJim Jagielski         SvgImageNode::~SvgImageNode()
66*b1cdbd2cSJim Jagielski         {
67*b1cdbd2cSJim Jagielski             if(mpaTransform) delete mpaTransform;
68*b1cdbd2cSJim Jagielski         }
69*b1cdbd2cSJim Jagielski 
getSvgStyleAttributes() const70*b1cdbd2cSJim Jagielski         const SvgStyleAttributes* SvgImageNode::getSvgStyleAttributes() const
71*b1cdbd2cSJim Jagielski         {
72*b1cdbd2cSJim Jagielski             static rtl::OUString aClassStr(rtl::OUString::createFromAscii("image"));
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski             return checkForCssStyle(aClassStr, maSvgStyleAttributes);
75*b1cdbd2cSJim Jagielski         }
76*b1cdbd2cSJim Jagielski 
parseAttribute(const rtl::OUString & rTokenName,SVGToken aSVGToken,const rtl::OUString & aContent)77*b1cdbd2cSJim Jagielski         void SvgImageNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
78*b1cdbd2cSJim Jagielski         {
79*b1cdbd2cSJim Jagielski             // call parent
80*b1cdbd2cSJim Jagielski             SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
81*b1cdbd2cSJim Jagielski 
82*b1cdbd2cSJim Jagielski             // read style attributes
83*b1cdbd2cSJim Jagielski             maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
84*b1cdbd2cSJim Jagielski 
85*b1cdbd2cSJim Jagielski             // parse own
86*b1cdbd2cSJim Jagielski             switch(aSVGToken)
87*b1cdbd2cSJim Jagielski             {
88*b1cdbd2cSJim Jagielski                 case SVGTokenStyle:
89*b1cdbd2cSJim Jagielski                 {
90*b1cdbd2cSJim Jagielski                     maSvgStyleAttributes.readStyle(aContent);
91*b1cdbd2cSJim Jagielski                     break;
92*b1cdbd2cSJim Jagielski                 }
93*b1cdbd2cSJim Jagielski                 case SVGTokenPreserveAspectRatio:
94*b1cdbd2cSJim Jagielski                 {
95*b1cdbd2cSJim Jagielski                     setSvgAspectRatio(readSvgAspectRatio(aContent));
96*b1cdbd2cSJim Jagielski                     break;
97*b1cdbd2cSJim Jagielski                 }
98*b1cdbd2cSJim Jagielski                 case SVGTokenTransform:
99*b1cdbd2cSJim Jagielski                 {
100*b1cdbd2cSJim Jagielski                     const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
101*b1cdbd2cSJim Jagielski 
102*b1cdbd2cSJim Jagielski                     if(!aMatrix.isIdentity())
103*b1cdbd2cSJim Jagielski                     {
104*b1cdbd2cSJim Jagielski                         setTransform(&aMatrix);
105*b1cdbd2cSJim Jagielski                     }
106*b1cdbd2cSJim Jagielski                     break;
107*b1cdbd2cSJim Jagielski                 }
108*b1cdbd2cSJim Jagielski                 case SVGTokenX:
109*b1cdbd2cSJim Jagielski                 {
110*b1cdbd2cSJim Jagielski                     SvgNumber aNum;
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski                     if(readSingleNumber(aContent, aNum))
113*b1cdbd2cSJim Jagielski                     {
114*b1cdbd2cSJim Jagielski                         setX(aNum);
115*b1cdbd2cSJim Jagielski                     }
116*b1cdbd2cSJim Jagielski                     break;
117*b1cdbd2cSJim Jagielski                 }
118*b1cdbd2cSJim Jagielski                 case SVGTokenY:
119*b1cdbd2cSJim Jagielski                 {
120*b1cdbd2cSJim Jagielski                     SvgNumber aNum;
121*b1cdbd2cSJim Jagielski 
122*b1cdbd2cSJim Jagielski                     if(readSingleNumber(aContent, aNum))
123*b1cdbd2cSJim Jagielski                     {
124*b1cdbd2cSJim Jagielski                         setY(aNum);
125*b1cdbd2cSJim Jagielski                     }
126*b1cdbd2cSJim Jagielski                     break;
127*b1cdbd2cSJim Jagielski                 }
128*b1cdbd2cSJim Jagielski                 case SVGTokenWidth:
129*b1cdbd2cSJim Jagielski                 {
130*b1cdbd2cSJim Jagielski                     SvgNumber aNum;
131*b1cdbd2cSJim Jagielski 
132*b1cdbd2cSJim Jagielski                     if(readSingleNumber(aContent, aNum))
133*b1cdbd2cSJim Jagielski                     {
134*b1cdbd2cSJim Jagielski                         if(aNum.isPositive())
135*b1cdbd2cSJim Jagielski                         {
136*b1cdbd2cSJim Jagielski                             setWidth(aNum);
137*b1cdbd2cSJim Jagielski                         }
138*b1cdbd2cSJim Jagielski                     }
139*b1cdbd2cSJim Jagielski                     break;
140*b1cdbd2cSJim Jagielski                 }
141*b1cdbd2cSJim Jagielski                 case SVGTokenHeight:
142*b1cdbd2cSJim Jagielski                 {
143*b1cdbd2cSJim Jagielski                     SvgNumber aNum;
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski                     if(readSingleNumber(aContent, aNum))
146*b1cdbd2cSJim Jagielski                     {
147*b1cdbd2cSJim Jagielski                         if(aNum.isPositive())
148*b1cdbd2cSJim Jagielski                         {
149*b1cdbd2cSJim Jagielski                             setHeight(aNum);
150*b1cdbd2cSJim Jagielski                         }
151*b1cdbd2cSJim Jagielski                     }
152*b1cdbd2cSJim Jagielski                     break;
153*b1cdbd2cSJim Jagielski                 }
154*b1cdbd2cSJim Jagielski                 case SVGTokenXlinkHref:
155*b1cdbd2cSJim Jagielski                 {
156*b1cdbd2cSJim Jagielski                     const sal_Int32 nLen(aContent.getLength());
157*b1cdbd2cSJim Jagielski 
158*b1cdbd2cSJim Jagielski                     if(nLen)
159*b1cdbd2cSJim Jagielski                     {
160*b1cdbd2cSJim Jagielski                         readImageLink(aContent, maXLink, maUrl, maMimeType, maData);
161*b1cdbd2cSJim Jagielski                     }
162*b1cdbd2cSJim Jagielski                     break;
163*b1cdbd2cSJim Jagielski                 }
164*b1cdbd2cSJim Jagielski                 default:
165*b1cdbd2cSJim Jagielski                 {
166*b1cdbd2cSJim Jagielski                     break;
167*b1cdbd2cSJim Jagielski                 }
168*b1cdbd2cSJim Jagielski             }
169*b1cdbd2cSJim Jagielski         }
170*b1cdbd2cSJim Jagielski 
extractFromGraphic(const Graphic & rGraphic,drawinglayer::primitive2d::Primitive2DSequence & rEmbedded,basegfx::B2DRange & rViewBox,BitmapEx & rBitmapEx)171*b1cdbd2cSJim Jagielski         void extractFromGraphic(
172*b1cdbd2cSJim Jagielski             const Graphic& rGraphic,
173*b1cdbd2cSJim Jagielski             drawinglayer::primitive2d::Primitive2DSequence& rEmbedded,
174*b1cdbd2cSJim Jagielski             basegfx::B2DRange& rViewBox,
175*b1cdbd2cSJim Jagielski             BitmapEx& rBitmapEx)
176*b1cdbd2cSJim Jagielski         {
177*b1cdbd2cSJim Jagielski             if(GRAPHIC_BITMAP == rGraphic.GetType())
178*b1cdbd2cSJim Jagielski             {
179*b1cdbd2cSJim Jagielski                 if(rGraphic.getSvgData().get())
180*b1cdbd2cSJim Jagielski                 {
181*b1cdbd2cSJim Jagielski                     // embedded Svg
182*b1cdbd2cSJim Jagielski                     rEmbedded = rGraphic.getSvgData()->getPrimitive2DSequence();
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski                     // fill aViewBox
185*b1cdbd2cSJim Jagielski                     rViewBox = rGraphic.getSvgData()->getRange();
186*b1cdbd2cSJim Jagielski                 }
187*b1cdbd2cSJim Jagielski                 else
188*b1cdbd2cSJim Jagielski                 {
189*b1cdbd2cSJim Jagielski                     // get bitmap
190*b1cdbd2cSJim Jagielski                     rBitmapEx = rGraphic.GetBitmapEx();
191*b1cdbd2cSJim Jagielski                 }
192*b1cdbd2cSJim Jagielski             }
193*b1cdbd2cSJim Jagielski             else
194*b1cdbd2cSJim Jagielski             {
195*b1cdbd2cSJim Jagielski                 // evtl. convert to bitmap
196*b1cdbd2cSJim Jagielski                 rBitmapEx = rGraphic.GetBitmapEx();
197*b1cdbd2cSJim Jagielski             }
198*b1cdbd2cSJim Jagielski         }
199*b1cdbd2cSJim Jagielski 
decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence & rTarget,bool) const200*b1cdbd2cSJim Jagielski         void SvgImageNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool /*bReferenced*/) const
201*b1cdbd2cSJim Jagielski         {
202*b1cdbd2cSJim Jagielski             // get size range and create path
203*b1cdbd2cSJim Jagielski             const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
204*b1cdbd2cSJim Jagielski 
205*b1cdbd2cSJim Jagielski             if(pStyle && getWidth().isSet() && getHeight().isSet())
206*b1cdbd2cSJim Jagielski             {
207*b1cdbd2cSJim Jagielski                 const double fWidth(getWidth().solve(*this, xcoordinate));
208*b1cdbd2cSJim Jagielski                 const double fHeight(getHeight().solve(*this, ycoordinate));
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski                 if(fWidth > 0.0 && fHeight > 0.0)
211*b1cdbd2cSJim Jagielski                 {
212*b1cdbd2cSJim Jagielski                     BitmapEx aBitmapEx;
213*b1cdbd2cSJim Jagielski                     drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
214*b1cdbd2cSJim Jagielski 
215*b1cdbd2cSJim Jagielski                     // prepare Target and ViewBox for evtl. AspectRatio mappings
216*b1cdbd2cSJim Jagielski                     const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
217*b1cdbd2cSJim Jagielski                     const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
218*b1cdbd2cSJim Jagielski                     const basegfx::B2DRange aTarget(fX, fY, fX + fWidth, fY + fHeight);
219*b1cdbd2cSJim Jagielski                     basegfx::B2DRange aViewBox(aTarget);
220*b1cdbd2cSJim Jagielski 
221*b1cdbd2cSJim Jagielski                     if(maMimeType.getLength() && maData.getLength())
222*b1cdbd2cSJim Jagielski                     {
223*b1cdbd2cSJim Jagielski                         // use embedded base64 encoded data
224*b1cdbd2cSJim Jagielski                         ::com::sun::star::uno::Sequence< sal_Int8 > aPass;
225*b1cdbd2cSJim Jagielski                         ::sax::Converter::decodeBase64(aPass, maData);
226*b1cdbd2cSJim Jagielski 
227*b1cdbd2cSJim Jagielski                         if(aPass.hasElements())
228*b1cdbd2cSJim Jagielski                         {
229*b1cdbd2cSJim Jagielski                             SvMemoryStream aStream(aPass.getArray(), aPass.getLength(), STREAM_READ);
230*b1cdbd2cSJim Jagielski                             Graphic aGraphic;
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski                             if(GRFILTER_OK == GraphicFilter::GetGraphicFilter()->ImportGraphic(
233*b1cdbd2cSJim Jagielski                                 aGraphic,
234*b1cdbd2cSJim Jagielski                                 String(),
235*b1cdbd2cSJim Jagielski                                 aStream))
236*b1cdbd2cSJim Jagielski                             {
237*b1cdbd2cSJim Jagielski                                 extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx);
238*b1cdbd2cSJim Jagielski                             }
239*b1cdbd2cSJim Jagielski                         }
240*b1cdbd2cSJim Jagielski                     }
241*b1cdbd2cSJim Jagielski                     else if(maUrl.getLength())
242*b1cdbd2cSJim Jagielski                     {
243*b1cdbd2cSJim Jagielski                         const rtl::OUString& rPath = getDocument().getAbsolutePath();
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski                         if(rPath.getLength())
246*b1cdbd2cSJim Jagielski                         {
247*b1cdbd2cSJim Jagielski                             const rtl::OUString aAbsUrl(rtl::Uri::convertRelToAbs(rPath, maUrl));
248*b1cdbd2cSJim Jagielski 
249*b1cdbd2cSJim Jagielski                             if(aAbsUrl.getLength())
250*b1cdbd2cSJim Jagielski                             {
251*b1cdbd2cSJim Jagielski                                 SvFileStream aStream(aAbsUrl, STREAM_STD_READ);
252*b1cdbd2cSJim Jagielski                                 Graphic aGraphic;
253*b1cdbd2cSJim Jagielski 
254*b1cdbd2cSJim Jagielski                                 if(GRFILTER_OK == GraphicFilter::GetGraphicFilter()->ImportGraphic(
255*b1cdbd2cSJim Jagielski                                     aGraphic,
256*b1cdbd2cSJim Jagielski                                     aAbsUrl,
257*b1cdbd2cSJim Jagielski                                     aStream))
258*b1cdbd2cSJim Jagielski                                 {
259*b1cdbd2cSJim Jagielski                                     extractFromGraphic(aGraphic, aNewTarget, aViewBox, aBitmapEx);
260*b1cdbd2cSJim Jagielski                                 }
261*b1cdbd2cSJim Jagielski                             }
262*b1cdbd2cSJim Jagielski                         }
263*b1cdbd2cSJim Jagielski                         else
264*b1cdbd2cSJim Jagielski                         {
265*b1cdbd2cSJim Jagielski                             // #123042# detect missing path and assert - content will be missing. The
266*b1cdbd2cSJim Jagielski                             // absolute path to itself needs to be set to correctly import linked
267*b1cdbd2cSJim Jagielski                             // content in a SVG file
268*b1cdbd2cSJim Jagielski                             OSL_ENSURE(false, "SVG graphic with internal links is interpreted, but local AbsolutePath is not set: linked content will be missing (!)");
269*b1cdbd2cSJim Jagielski                         }
270*b1cdbd2cSJim Jagielski                     }
271*b1cdbd2cSJim Jagielski                     else if(maXLink.getLength())
272*b1cdbd2cSJim Jagielski                     {
273*b1cdbd2cSJim Jagielski                         const SvgNode* mpXLink = getDocument().findSvgNodeById(maXLink);
274*b1cdbd2cSJim Jagielski 
275*b1cdbd2cSJim Jagielski                         if(mpXLink && Display_none != mpXLink->getDisplay())
276*b1cdbd2cSJim Jagielski                         {
277*b1cdbd2cSJim Jagielski                             mpXLink->decomposeSvgNode(aNewTarget, true);
278*b1cdbd2cSJim Jagielski 
279*b1cdbd2cSJim Jagielski                             if(aNewTarget.hasElements())
280*b1cdbd2cSJim Jagielski                             {
281*b1cdbd2cSJim Jagielski                                 aViewBox = drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(
282*b1cdbd2cSJim Jagielski                                     aNewTarget,
283*b1cdbd2cSJim Jagielski                                     drawinglayer::geometry::ViewInformation2D());
284*b1cdbd2cSJim Jagielski                             }
285*b1cdbd2cSJim Jagielski                         }
286*b1cdbd2cSJim Jagielski                     }
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski                     if(!aBitmapEx.IsEmpty())
289*b1cdbd2cSJim Jagielski                     {
290*b1cdbd2cSJim Jagielski                         // create content from created bitmap
291*b1cdbd2cSJim Jagielski                         aNewTarget.realloc(1);
292*b1cdbd2cSJim Jagielski                         aNewTarget[0] = new drawinglayer::primitive2d::BitmapPrimitive2D(
293*b1cdbd2cSJim Jagielski                             aBitmapEx,
294*b1cdbd2cSJim Jagielski                             basegfx::B2DHomMatrix());
295*b1cdbd2cSJim Jagielski 
296*b1cdbd2cSJim Jagielski                         // fill aViewBox. No size set yet, use unit size
297*b1cdbd2cSJim Jagielski                         aViewBox = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
298*b1cdbd2cSJim Jagielski                     }
299*b1cdbd2cSJim Jagielski 
300*b1cdbd2cSJim Jagielski                     if(aNewTarget.hasElements())
301*b1cdbd2cSJim Jagielski                     {
302*b1cdbd2cSJim Jagielski                         if(aTarget.equal(aViewBox))
303*b1cdbd2cSJim Jagielski                         {
304*b1cdbd2cSJim Jagielski                             // just add to rTarget
305*b1cdbd2cSJim Jagielski                             drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aNewTarget);
306*b1cdbd2cSJim Jagielski                         }
307*b1cdbd2cSJim Jagielski                         else
308*b1cdbd2cSJim Jagielski                         {
309*b1cdbd2cSJim Jagielski                             // create mapping
310*b1cdbd2cSJim Jagielski                             const SvgAspectRatio& rRatio = getSvgAspectRatio();
311*b1cdbd2cSJim Jagielski 
312*b1cdbd2cSJim Jagielski                             if(rRatio.isSet())
313*b1cdbd2cSJim Jagielski                             {
314*b1cdbd2cSJim Jagielski                                 // let mapping be created from SvgAspectRatio
315*b1cdbd2cSJim Jagielski                                 const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createMapping(aTarget, aViewBox));
316*b1cdbd2cSJim Jagielski 
317*b1cdbd2cSJim Jagielski                                 if(!aEmbeddingTransform.isIdentity())
318*b1cdbd2cSJim Jagielski                                 {
319*b1cdbd2cSJim Jagielski                                     const drawinglayer::primitive2d::Primitive2DReference xRef(
320*b1cdbd2cSJim Jagielski                                         new drawinglayer::primitive2d::TransformPrimitive2D(
321*b1cdbd2cSJim Jagielski                                             aEmbeddingTransform,
322*b1cdbd2cSJim Jagielski                                             aNewTarget));
323*b1cdbd2cSJim Jagielski 
324*b1cdbd2cSJim Jagielski                                     aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
325*b1cdbd2cSJim Jagielski                                 }
326*b1cdbd2cSJim Jagielski 
327*b1cdbd2cSJim Jagielski                                 if(!rRatio.isMeetOrSlice())
328*b1cdbd2cSJim Jagielski                                 {
329*b1cdbd2cSJim Jagielski                                     // need to embed in MaskPrimitive2D to ensure clipping
330*b1cdbd2cSJim Jagielski                                     const drawinglayer::primitive2d::Primitive2DReference xMask(
331*b1cdbd2cSJim Jagielski                                         new drawinglayer::primitive2d::MaskPrimitive2D(
332*b1cdbd2cSJim Jagielski                                             basegfx::B2DPolyPolygon(
333*b1cdbd2cSJim Jagielski                                                 basegfx::tools::createPolygonFromRect(aTarget)),
334*b1cdbd2cSJim Jagielski                                             aNewTarget));
335*b1cdbd2cSJim Jagielski 
336*b1cdbd2cSJim Jagielski                                     aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xMask, 1);
337*b1cdbd2cSJim Jagielski                                 }
338*b1cdbd2cSJim Jagielski                             }
339*b1cdbd2cSJim Jagielski                             else
340*b1cdbd2cSJim Jagielski                             {
341*b1cdbd2cSJim Jagielski                                 // choose default mapping
342*b1cdbd2cSJim Jagielski                                 const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createLinearMapping(aTarget, aViewBox));
343*b1cdbd2cSJim Jagielski 
344*b1cdbd2cSJim Jagielski                                 if(!aEmbeddingTransform.isIdentity())
345*b1cdbd2cSJim Jagielski                                 {
346*b1cdbd2cSJim Jagielski                                     const drawinglayer::primitive2d::Primitive2DReference xRef(
347*b1cdbd2cSJim Jagielski                                         new drawinglayer::primitive2d::TransformPrimitive2D(
348*b1cdbd2cSJim Jagielski                                             aEmbeddingTransform,
349*b1cdbd2cSJim Jagielski                                             aNewTarget));
350*b1cdbd2cSJim Jagielski 
351*b1cdbd2cSJim Jagielski                                     aNewTarget = drawinglayer::primitive2d::Primitive2DSequence(&xRef, 1);
352*b1cdbd2cSJim Jagielski                                 }
353*b1cdbd2cSJim Jagielski                             }
354*b1cdbd2cSJim Jagielski 
355*b1cdbd2cSJim Jagielski                             // embed and add to rTarget, take local extra-transform into account
356*b1cdbd2cSJim Jagielski                             pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
357*b1cdbd2cSJim Jagielski                         }
358*b1cdbd2cSJim Jagielski                     }
359*b1cdbd2cSJim Jagielski                 }
360*b1cdbd2cSJim Jagielski             }
361*b1cdbd2cSJim Jagielski         }
362*b1cdbd2cSJim Jagielski 
363*b1cdbd2cSJim Jagielski     } // end of namespace svgreader
364*b1cdbd2cSJim Jagielski } // end of namespace svgio
365*b1cdbd2cSJim Jagielski 
366*b1cdbd2cSJim Jagielski //////////////////////////////////////////////////////////////////////////////
367*b1cdbd2cSJim Jagielski // eof
368