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  *
11ddde725dSArmin 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_svgio.hxx"
24ddde725dSArmin Le Grand 
25ddde725dSArmin Le Grand #include <svgio/svgreader/svgrectnode.hxx>
26ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolygon.hxx>
27ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolygontools.hxx>
28ddde725dSArmin Le Grand 
29ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
30ddde725dSArmin Le Grand 
31ddde725dSArmin Le Grand namespace svgio
32ddde725dSArmin Le Grand {
33ddde725dSArmin Le Grand     namespace svgreader
34ddde725dSArmin Le Grand     {
SvgRectNode(SvgDocument & rDocument,SvgNode * pParent)35ddde725dSArmin Le Grand         SvgRectNode::SvgRectNode(
36ddde725dSArmin Le Grand             SvgDocument& rDocument,
37ddde725dSArmin Le Grand             SvgNode* pParent)
38ddde725dSArmin Le Grand         :   SvgNode(SVGTokenRect, rDocument, pParent),
39ddde725dSArmin Le Grand             maSvgStyleAttributes(*this),
40ddde725dSArmin Le Grand             maX(0),
41ddde725dSArmin Le Grand             maY(0),
42ddde725dSArmin Le Grand             maWidth(0),
43ddde725dSArmin Le Grand             maHeight(0),
44ddde725dSArmin Le Grand             maRx(0),
45ddde725dSArmin Le Grand             maRy(0),
46ddde725dSArmin Le Grand             mpaTransform(0)
47ddde725dSArmin Le Grand         {
48ddde725dSArmin Le Grand         }
49ddde725dSArmin Le Grand 
~SvgRectNode()50ddde725dSArmin Le Grand         SvgRectNode::~SvgRectNode()
51ddde725dSArmin Le Grand         {
52ddde725dSArmin Le Grand             if(mpaTransform) delete mpaTransform;
53ddde725dSArmin Le Grand         }
54ddde725dSArmin Le Grand 
getSvgStyleAttributes() const55ddde725dSArmin Le Grand         const SvgStyleAttributes* SvgRectNode::getSvgStyleAttributes() const
56ddde725dSArmin Le Grand         {
57ddde725dSArmin Le Grand             static rtl::OUString aClassStr(rtl::OUString::createFromAscii("rect"));
58ddde725dSArmin Le Grand 
5950b37974SArmin Le Grand             return checkForCssStyle(aClassStr, maSvgStyleAttributes);
60ddde725dSArmin Le Grand         }
61ddde725dSArmin Le Grand 
parseAttribute(const rtl::OUString & rTokenName,SVGToken aSVGToken,const rtl::OUString & aContent)62ddde725dSArmin Le Grand         void SvgRectNode::parseAttribute(const rtl::OUString& rTokenName, SVGToken aSVGToken, const rtl::OUString& aContent)
63ddde725dSArmin Le Grand         {
64ddde725dSArmin Le Grand             // call parent
65ddde725dSArmin Le Grand             SvgNode::parseAttribute(rTokenName, aSVGToken, aContent);
66ddde725dSArmin Le Grand 
67ddde725dSArmin Le Grand             // read style attributes
68ddde725dSArmin Le Grand             maSvgStyleAttributes.parseStyleAttribute(rTokenName, aSVGToken, aContent);
69ddde725dSArmin Le Grand 
70ddde725dSArmin Le Grand             // parse own
71ddde725dSArmin Le Grand             switch(aSVGToken)
72ddde725dSArmin Le Grand             {
73ddde725dSArmin Le Grand                 case SVGTokenStyle:
74ddde725dSArmin Le Grand                 {
75ddde725dSArmin Le Grand                     maSvgStyleAttributes.readStyle(aContent);
76ddde725dSArmin Le Grand                     break;
77ddde725dSArmin Le Grand                 }
78ddde725dSArmin Le Grand                 case SVGTokenX:
79ddde725dSArmin Le Grand                 {
80ddde725dSArmin Le Grand                     SvgNumber aNum;
81ddde725dSArmin Le Grand 
82ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
83ddde725dSArmin Le Grand                     {
84ddde725dSArmin Le Grand                         setX(aNum);
85ddde725dSArmin Le Grand                     }
86ddde725dSArmin Le Grand                     break;
87ddde725dSArmin Le Grand                 }
88ddde725dSArmin Le Grand                 case SVGTokenY:
89ddde725dSArmin Le Grand                 {
90ddde725dSArmin Le Grand                     SvgNumber aNum;
91ddde725dSArmin Le Grand 
92ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
93ddde725dSArmin Le Grand                     {
94ddde725dSArmin Le Grand                         setY(aNum);
95ddde725dSArmin Le Grand                     }
96ddde725dSArmin Le Grand                     break;
97ddde725dSArmin Le Grand                 }
98ddde725dSArmin Le Grand                 case SVGTokenWidth:
99ddde725dSArmin Le Grand                 {
100ddde725dSArmin Le Grand                     SvgNumber aNum;
101ddde725dSArmin Le Grand 
102ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
103ddde725dSArmin Le Grand                     {
104ddde725dSArmin Le Grand                         if(aNum.isPositive())
105ddde725dSArmin Le Grand                         {
106ddde725dSArmin Le Grand                             setWidth(aNum);
107ddde725dSArmin Le Grand                         }
108ddde725dSArmin Le Grand                     }
109ddde725dSArmin Le Grand                     break;
110ddde725dSArmin Le Grand                 }
111ddde725dSArmin Le Grand                 case SVGTokenHeight:
112ddde725dSArmin Le Grand                 {
113ddde725dSArmin Le Grand                     SvgNumber aNum;
114ddde725dSArmin Le Grand 
115ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
116ddde725dSArmin Le Grand                     {
117ddde725dSArmin Le Grand                         if(aNum.isPositive())
118ddde725dSArmin Le Grand                         {
119ddde725dSArmin Le Grand                             setHeight(aNum);
120ddde725dSArmin Le Grand                         }
121ddde725dSArmin Le Grand                     }
122ddde725dSArmin Le Grand                     break;
123ddde725dSArmin Le Grand                 }
124ddde725dSArmin Le Grand                 case SVGTokenRx:
125ddde725dSArmin Le Grand                 {
126ddde725dSArmin Le Grand                     SvgNumber aNum;
127ddde725dSArmin Le Grand 
128ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
129ddde725dSArmin Le Grand                     {
130ddde725dSArmin Le Grand                         if(aNum.isPositive())
131ddde725dSArmin Le Grand                         {
132ddde725dSArmin Le Grand                             setRx(aNum);
133ddde725dSArmin Le Grand                         }
134ddde725dSArmin Le Grand                     }
135ddde725dSArmin Le Grand                     break;
136ddde725dSArmin Le Grand                 }
137ddde725dSArmin Le Grand                 case SVGTokenRy:
138ddde725dSArmin Le Grand                 {
139ddde725dSArmin Le Grand                     SvgNumber aNum;
140ddde725dSArmin Le Grand 
141ddde725dSArmin Le Grand                     if(readSingleNumber(aContent, aNum))
142ddde725dSArmin Le Grand                     {
143ddde725dSArmin Le Grand                         if(aNum.isPositive())
144ddde725dSArmin Le Grand                         {
145ddde725dSArmin Le Grand                             setRy(aNum);
146ddde725dSArmin Le Grand                         }
147ddde725dSArmin Le Grand                     }
148ddde725dSArmin Le Grand                     break;
149ddde725dSArmin Le Grand                 }
150ddde725dSArmin Le Grand                 case SVGTokenTransform:
151ddde725dSArmin Le Grand                 {
152ddde725dSArmin Le Grand                     const basegfx::B2DHomMatrix aMatrix(readTransform(aContent, *this));
153ddde725dSArmin Le Grand 
154ddde725dSArmin Le Grand                     if(!aMatrix.isIdentity())
155ddde725dSArmin Le Grand                     {
156ddde725dSArmin Le Grand                         setTransform(&aMatrix);
157ddde725dSArmin Le Grand                     }
158ddde725dSArmin Le Grand                     break;
159ddde725dSArmin Le Grand                 }
160e2bf1e9dSArmin Le Grand                 default:
161e2bf1e9dSArmin Le Grand                 {
162e2bf1e9dSArmin Le Grand                     break;
163e2bf1e9dSArmin Le Grand                 }
164ddde725dSArmin Le Grand             }
165ddde725dSArmin Le Grand         }
166ddde725dSArmin Le Grand 
decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence & rTarget,bool) const167e2bf1e9dSArmin Le Grand         void SvgRectNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DSequence& rTarget, bool /*bReferenced*/) const
168ddde725dSArmin Le Grand         {
169ddde725dSArmin Le Grand             // get size range and create path
170ddde725dSArmin Le Grand             const SvgStyleAttributes* pStyle = getSvgStyleAttributes();
171ddde725dSArmin Le Grand 
172ddde725dSArmin Le Grand             if(pStyle && getWidth().isSet() && getHeight().isSet())
173ddde725dSArmin Le Grand             {
174ddde725dSArmin Le Grand                 const double fWidth(getWidth().solve(*this, xcoordinate));
175ddde725dSArmin Le Grand                 const double fHeight(getHeight().solve(*this, ycoordinate));
176ddde725dSArmin Le Grand 
177ddde725dSArmin Le Grand                 if(fWidth > 0.0 && fHeight > 0.0)
178ddde725dSArmin Le Grand                 {
179ddde725dSArmin Le Grand                     const double fX(getX().isSet() ? getX().solve(*this, xcoordinate) : 0.0);
180ddde725dSArmin Le Grand                     const double fY(getY().isSet() ? getY().solve(*this, ycoordinate) : 0.0);
181ddde725dSArmin Le Grand                     const basegfx::B2DRange aRange(fX, fY, fX + fWidth, fY + fHeight);
182ddde725dSArmin Le Grand                     basegfx::B2DPolygon aPath;
183ddde725dSArmin Le Grand 
184ddde725dSArmin Le Grand                     if(getRx().isSet() || getRy().isSet())
185ddde725dSArmin Le Grand                     {
186ddde725dSArmin Le Grand                         double frX(getRx().isSet() ? getRx().solve(*this, xcoordinate) : 0.0);
187ddde725dSArmin Le Grand                         double frY(getRy().isSet() ? getRy().solve(*this, ycoordinate) : 0.0);
188ddde725dSArmin Le Grand 
189ddde725dSArmin Le Grand                         frX = std::max(0.0, frX);
190ddde725dSArmin Le Grand                         frY = std::max(0.0, frY);
191ddde725dSArmin Le Grand 
192ddde725dSArmin Le Grand                         if(0.0 == frY && frX > 0.0)
193ddde725dSArmin Le Grand                         {
194ddde725dSArmin Le Grand                             frY = frX;
195ddde725dSArmin Le Grand                         }
196ddde725dSArmin Le Grand                         else if(0.0 == frX && frY > 0.0)
197ddde725dSArmin Le Grand                         {
198ddde725dSArmin Le Grand                             frX = frY;
199ddde725dSArmin Le Grand                         }
200ddde725dSArmin Le Grand 
201ddde725dSArmin Le Grand                         frX /= fWidth;
202ddde725dSArmin Le Grand                         frY /= fHeight;
203ddde725dSArmin Le Grand 
204ddde725dSArmin Le Grand                         frX = std::min(0.5, frX);
205ddde725dSArmin Le Grand                         frY = std::min(0.5, frY);
206ddde725dSArmin Le Grand 
207ddde725dSArmin Le Grand                         aPath = basegfx::tools::createPolygonFromRect(aRange, frX * 2.0, frY * 2.0);
208ddde725dSArmin Le Grand                     }
209ddde725dSArmin Le Grand                     else
210ddde725dSArmin Le Grand                     {
211ddde725dSArmin Le Grand                         aPath = basegfx::tools::createPolygonFromRect(aRange);
212ddde725dSArmin Le Grand                     }
213ddde725dSArmin Le Grand 
214ddde725dSArmin Le Grand                     drawinglayer::primitive2d::Primitive2DSequence aNewTarget;
215ddde725dSArmin Le Grand 
216*1f882ec4SArmin Le Grand                     pStyle->add_path(basegfx::B2DPolyPolygon(aPath), aNewTarget, 0);
217ddde725dSArmin Le Grand 
218ddde725dSArmin Le Grand                     if(aNewTarget.hasElements())
219ddde725dSArmin Le Grand                     {
220ddde725dSArmin Le Grand                         pStyle->add_postProcess(rTarget, aNewTarget, getTransform());
221ddde725dSArmin Le Grand                     }
222ddde725dSArmin Le Grand                 }
223ddde725dSArmin Le Grand             }
224ddde725dSArmin Le Grand         }
225ddde725dSArmin Le Grand     } // end of namespace svgreader
226ddde725dSArmin Le Grand } // end of namespace svgio
227ddde725dSArmin Le Grand 
228ddde725dSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
229ddde725dSArmin Le Grand // eof
230