xref: /aoo41x/main/sw/source/core/bastyp/swrect.cxx (revision efeef26f)
1*efeef26fSAndrew Rist /**************************************************************
2*efeef26fSAndrew Rist  *
3*efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*efeef26fSAndrew Rist  * distributed with this work for additional information
6*efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9*efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*efeef26fSAndrew Rist  *
11*efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15*efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*efeef26fSAndrew Rist  * specific language governing permissions and limitations
18*efeef26fSAndrew Rist  * under the License.
19*efeef26fSAndrew Rist  *
20*efeef26fSAndrew Rist  *************************************************************/
21*efeef26fSAndrew Rist 
22*efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #ifdef DBG_UTIL
29cdf0e10cSrcweir #ifndef _STREAM_HXX //autogen
30cdf0e10cSrcweir #include <tools/stream.hxx>
31cdf0e10cSrcweir #endif
32cdf0e10cSrcweir #endif
33cdf0e10cSrcweir #include <stdlib.h>
34cdf0e10cSrcweir #include "swrect.hxx"
35cdf0e10cSrcweir #include <math.h>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir /*************************************************************************
38cdf0e10cSrcweir |*
39cdf0e10cSrcweir |*	SwRect::SwRect()
40cdf0e10cSrcweir |*
41cdf0e10cSrcweir |*	Ersterstellung		MA 02. Feb. 93
42cdf0e10cSrcweir |*	Letzte Aenderung	MA 05. Sep. 93
43cdf0e10cSrcweir |*
44cdf0e10cSrcweir |*************************************************************************/
45cdf0e10cSrcweir 
46cdf0e10cSrcweir 
47cdf0e10cSrcweir 
SwRect(const Rectangle & rRect)48cdf0e10cSrcweir SwRect::SwRect( const Rectangle &rRect ) :
49cdf0e10cSrcweir 	m_Point( rRect.Left(), rRect.Top() )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir 	m_Size.setWidth(rRect.Right() == RECT_EMPTY ? 0 :
52cdf0e10cSrcweir 							rRect.Right()  - rRect.Left() +1);
53cdf0e10cSrcweir 	m_Size.setHeight(rRect.Bottom() == RECT_EMPTY ? 0 :
54cdf0e10cSrcweir 							rRect.Bottom() - rRect.Top() + 1);
55cdf0e10cSrcweir }
56cdf0e10cSrcweir 
57cdf0e10cSrcweir /*************************************************************************
58cdf0e10cSrcweir |*
59cdf0e10cSrcweir |*	SwRect::Center()
60cdf0e10cSrcweir |*
61cdf0e10cSrcweir |*	Ersterstellung		MA 27. Jan. 93
62cdf0e10cSrcweir |*	Letzte Aenderung	MA 27. Jan. 93
63cdf0e10cSrcweir |*
64cdf0e10cSrcweir |*************************************************************************/
Center() const65cdf0e10cSrcweir Point SwRect::Center() const
66cdf0e10cSrcweir {
67cdf0e10cSrcweir 	return Point( Left() + Width()  / 2,
68cdf0e10cSrcweir 				  Top()  + Height() / 2 );
69cdf0e10cSrcweir 
70cdf0e10cSrcweir /*  Wer ruft schon ein Center auf ein "falsches" Rechteck?
71cdf0e10cSrcweir 	const long nRight = Right();
72cdf0e10cSrcweir 	const long nBottom= Bottom();
73cdf0e10cSrcweir 	return Point( min( Left(), nRight ) + long(abs( (nRight - Left())/2) ),
74cdf0e10cSrcweir 				  min( Top(),  nBottom) + long(abs( (nBottom - Top())/2)));
75cdf0e10cSrcweir */
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir /*************************************************************************
79cdf0e10cSrcweir |*
80cdf0e10cSrcweir |*	SwRect::Union()
81cdf0e10cSrcweir |*
82cdf0e10cSrcweir |*	Ersterstellung		MA 27. Jan. 93
83cdf0e10cSrcweir |*	Letzte Aenderung	MA 27. Jan. 93
84cdf0e10cSrcweir |*
85cdf0e10cSrcweir |*************************************************************************/
86cdf0e10cSrcweir 
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 
Union(const SwRect & rRect)89cdf0e10cSrcweir SwRect& SwRect::Union( const SwRect& rRect )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir 	if ( Top() > rRect.Top() )
92cdf0e10cSrcweir 		Top( rRect.Top() );
93cdf0e10cSrcweir 	if ( Left() > rRect.Left() )
94cdf0e10cSrcweir 		Left( rRect.Left() );
95cdf0e10cSrcweir 	long n = rRect.Right();
96cdf0e10cSrcweir 	if ( Right() < n )
97cdf0e10cSrcweir 		Right( n );
98cdf0e10cSrcweir 	n = rRect.Bottom();
99cdf0e10cSrcweir 	if ( Bottom() < n )
100cdf0e10cSrcweir 		Bottom( n );
101cdf0e10cSrcweir 	return *this;
102cdf0e10cSrcweir }
103cdf0e10cSrcweir /*************************************************************************
104cdf0e10cSrcweir |*
105cdf0e10cSrcweir |*	SwRect::Intersection(), _Intersection()
106cdf0e10cSrcweir |*
107cdf0e10cSrcweir |*	Ersterstellung		MA 27. Jan. 93
108cdf0e10cSrcweir |*	Letzte Aenderung	MA 05. Sep. 93
109cdf0e10cSrcweir |*
110cdf0e10cSrcweir |*************************************************************************/
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 
Intersection(const SwRect & rRect)114cdf0e10cSrcweir SwRect& SwRect::Intersection( const SwRect& rRect )
115cdf0e10cSrcweir {
116cdf0e10cSrcweir 	//Hat das Teil ueberhaupt Gemeinsamkeiten mit mir?
117cdf0e10cSrcweir 	if ( IsOver( rRect ) )
118cdf0e10cSrcweir 	{
119cdf0e10cSrcweir 		//Bestimmung der kleineren  rechten sowie unteren und
120cdf0e10cSrcweir 		//           der groesseren linken  sowie oberen Kante.
121cdf0e10cSrcweir 		if ( Left() < rRect.Left() )
122cdf0e10cSrcweir 			Left( rRect.Left() );
123cdf0e10cSrcweir 		if ( Top() < rRect.Top() )
124cdf0e10cSrcweir 			Top( rRect.Top() );
125cdf0e10cSrcweir 		long n = rRect.Right();
126cdf0e10cSrcweir 		if ( Right() > n )
127cdf0e10cSrcweir 			Right( n );
128cdf0e10cSrcweir 		n = rRect.Bottom();
129cdf0e10cSrcweir 		if ( Bottom() > n )
130cdf0e10cSrcweir 			Bottom( n );
131cdf0e10cSrcweir 	}
132cdf0e10cSrcweir 	else
133cdf0e10cSrcweir 		//Def.: Bei einer leeren Intersection wird nur die SSize genullt.
134cdf0e10cSrcweir 		SSize(0, 0);
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	return *this;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 
_Intersection(const SwRect & rRect)141cdf0e10cSrcweir SwRect& SwRect::_Intersection( const SwRect& rRect )
142cdf0e10cSrcweir {
143cdf0e10cSrcweir 	//Bestimmung der kleineren  rechten sowie unteren und
144cdf0e10cSrcweir 	//           der groesseren linken  sowie oberen Kante.
145cdf0e10cSrcweir 	if ( Left() < rRect.Left() )
146cdf0e10cSrcweir 		Left( rRect.Left() );
147cdf0e10cSrcweir 	if ( Top() < rRect.Top() )
148cdf0e10cSrcweir 		Top( rRect.Top() );
149cdf0e10cSrcweir 	long n = rRect.Right();
150cdf0e10cSrcweir 	if ( Right() > n )
151cdf0e10cSrcweir 		Right( n );
152cdf0e10cSrcweir 	n = rRect.Bottom();
153cdf0e10cSrcweir 	if ( Bottom() > n )
154cdf0e10cSrcweir 		Bottom( n );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 	return *this;
157cdf0e10cSrcweir }
158cdf0e10cSrcweir /*************************************************************************
159cdf0e10cSrcweir |*
160cdf0e10cSrcweir |*	SwRect::IsInside()
161cdf0e10cSrcweir |*
162cdf0e10cSrcweir |*	Ersterstellung		MA 27. Jan. 93
163cdf0e10cSrcweir |*	Letzte Aenderung	MA 27. Jan. 93
164cdf0e10cSrcweir |*
165cdf0e10cSrcweir |*************************************************************************/
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 
IsInside(const SwRect & rRect) const169cdf0e10cSrcweir sal_Bool SwRect::IsInside( const SwRect& rRect ) const
170cdf0e10cSrcweir {
171cdf0e10cSrcweir 	const long nRight  = Right();
172cdf0e10cSrcweir 	const long nBottom = Bottom();
173cdf0e10cSrcweir 	const long nrRight = rRect.Right();
174cdf0e10cSrcweir 	const long nrBottom= rRect.Bottom();
175cdf0e10cSrcweir 	return (Left() <= rRect.Left()) && (rRect.Left()<= nRight)  &&
176cdf0e10cSrcweir 		   (Left() <= nrRight)		&& (nrRight		<= nRight)  &&
177cdf0e10cSrcweir 		   (Top()  <= rRect.Top())	&& (rRect.Top() <= nBottom) &&
178cdf0e10cSrcweir 		   (Top()  <= nrBottom)		&& (nrBottom	<= nBottom);
179cdf0e10cSrcweir }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 
IsInside(const Point & rPoint) const183cdf0e10cSrcweir sal_Bool SwRect::IsInside( const Point& rPoint ) const
184cdf0e10cSrcweir {
185cdf0e10cSrcweir 	return    (Left()  <= rPoint.X())
186cdf0e10cSrcweir 		   && (Top()   <= rPoint.Y())
187cdf0e10cSrcweir 		   && (Right() >= rPoint.X())
188cdf0e10cSrcweir 		   && (Bottom()>= rPoint.Y());
189cdf0e10cSrcweir }
190cdf0e10cSrcweir /* -----------------------------11.04.00 15:46--------------------------------
191cdf0e10cSrcweir 	mouse moving of table borders
192cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
IsNear(const Point & rPoint,long nTolerance) const193cdf0e10cSrcweir sal_Bool SwRect::IsNear( const Point& rPoint, long nTolerance ) const
194cdf0e10cSrcweir {
195cdf0e10cSrcweir 	return    IsInside(rPoint) ||
196cdf0e10cSrcweir 		(((Left() - nTolerance)  <= rPoint.X())
197cdf0e10cSrcweir 		   && ((Top()  - nTolerance)  <= rPoint.Y())
198cdf0e10cSrcweir 		   && ((Right() + nTolerance) >= rPoint.X())
199cdf0e10cSrcweir 		   && ((Bottom()  + nTolerance)>= rPoint.Y()));
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir /*************************************************************************
203cdf0e10cSrcweir |*
204cdf0e10cSrcweir |*	SwRect::IsOver()
205cdf0e10cSrcweir |*
206cdf0e10cSrcweir |*	Ersterstellung		MA 25. Feb. 94
207cdf0e10cSrcweir |*	Letzte Aenderung	MA 27. Jun. 96
208cdf0e10cSrcweir |*
209cdf0e10cSrcweir |*************************************************************************/
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 
IsOver(const SwRect & rRect) const213cdf0e10cSrcweir sal_Bool SwRect::IsOver( const SwRect& rRect ) const
214cdf0e10cSrcweir {
215cdf0e10cSrcweir 	return	  (Top()   <= rRect.Bottom())
216cdf0e10cSrcweir 		   && (Left()  <= rRect.Right())
217cdf0e10cSrcweir 		   && (Right() >= rRect.Left())
218cdf0e10cSrcweir 		   && (Bottom()>= rRect.Top()) ? sal_True : sal_False;
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir /*************************************************************************
222cdf0e10cSrcweir |*
223cdf0e10cSrcweir |*	SwRect::Justify()
224cdf0e10cSrcweir |*
225cdf0e10cSrcweir |*	Ersterstellung		MA 10. Oct. 94
226cdf0e10cSrcweir |*	Letzte Aenderung	MA 23. Oct. 96
227cdf0e10cSrcweir |*
228cdf0e10cSrcweir |*************************************************************************/
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 
231cdf0e10cSrcweir 
Justify()232cdf0e10cSrcweir void SwRect::Justify()
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	if ( m_Size.getHeight() < 0 )
235cdf0e10cSrcweir 	{
236cdf0e10cSrcweir 		m_Point.Y() += m_Size.getHeight() + 1;
237cdf0e10cSrcweir 		m_Size.setHeight(-m_Size.getHeight());
238cdf0e10cSrcweir 	}
239cdf0e10cSrcweir 	if ( m_Size.getWidth() < 0 )
240cdf0e10cSrcweir 	{
241cdf0e10cSrcweir 		m_Point.X() += m_Size.getWidth() + 1;
242cdf0e10cSrcweir 		m_Size.setWidth(-m_Size.getWidth());
243cdf0e10cSrcweir 	}
244cdf0e10cSrcweir }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
247cdf0e10cSrcweir // Similiar to the inline methods, but we need the function pointers
248cdf0e10cSrcweir 
_Width(const long nNew)249cdf0e10cSrcweir void SwRect::_Width( const long nNew ) { m_Size.setWidth(nNew); }
_Height(const long nNew)250cdf0e10cSrcweir void SwRect::_Height( const long nNew ) { m_Size.setHeight(nNew); }
_Left(const long nLeft)251cdf0e10cSrcweir void SwRect::_Left( const long nLeft ){ m_Size.Width() += m_Point.getX() - nLeft; m_Point.setX(nLeft); }
_Right(const long nRight)252cdf0e10cSrcweir void SwRect::_Right( const long nRight ){ m_Size.setWidth(nRight - m_Point.getX()); }
_Top(const long nTop)253cdf0e10cSrcweir void SwRect::_Top( const long nTop ){ m_Size.Height() += m_Point.getY() - nTop; m_Point.setY(nTop); }
_Bottom(const long nBottom)254cdf0e10cSrcweir void SwRect::_Bottom( const long nBottom ){ m_Size.setHeight(nBottom - m_Point.getY()); }
255cdf0e10cSrcweir 
_Width() const256cdf0e10cSrcweir long SwRect::_Width() const{ return m_Size.getWidth(); }
_Height() const257cdf0e10cSrcweir long SwRect::_Height() const{ return m_Size.getHeight(); }
_Left() const258cdf0e10cSrcweir long SwRect::_Left() const{ return m_Point.getX(); }
_Right() const259cdf0e10cSrcweir long SwRect::_Right() const{ return m_Point.getX() + m_Size.getWidth(); }
_Top() const260cdf0e10cSrcweir long SwRect::_Top() const{ return m_Point.getY(); }
_Bottom() const261cdf0e10cSrcweir long SwRect::_Bottom() const{ return m_Point.getY() + m_Size.getHeight(); }
262cdf0e10cSrcweir 
AddWidth(const long nAdd)263cdf0e10cSrcweir void SwRect::AddWidth( const long nAdd ) { m_Size.Width() += nAdd; }
AddHeight(const long nAdd)264cdf0e10cSrcweir void SwRect::AddHeight( const long nAdd ) { m_Size.Height() += nAdd; }
SubLeft(const long nSub)265cdf0e10cSrcweir void SwRect::SubLeft( const long nSub ){ m_Size.Width() += nSub; m_Point.X() -= nSub; }
AddRight(const long nAdd)266cdf0e10cSrcweir void SwRect::AddRight( const long nAdd ){ m_Size.Width() += nAdd; }
SubTop(const long nSub)267cdf0e10cSrcweir void SwRect::SubTop( const long nSub ){ m_Size.Height() += nSub; m_Point.Y() -= nSub; }
AddBottom(const long nAdd)268cdf0e10cSrcweir void SwRect::AddBottom( const long nAdd ){ m_Size.Height() += nAdd; }
SetPosX(const long nNew)269cdf0e10cSrcweir void SwRect::SetPosX( const long nNew ){ m_Point.setX(nNew); }
SetPosY(const long nNew)270cdf0e10cSrcweir void SwRect::SetPosY( const long nNew ){ m_Point.setY(nNew); }
_Size() const271cdf0e10cSrcweir const Size  SwRect::_Size() const { return SSize(); }
SwappedSize() const272cdf0e10cSrcweir const Size  SwRect::SwappedSize() const { return Size( m_Size.getHeight(), m_Size.getWidth() ); }
TopLeft() const273cdf0e10cSrcweir const Point SwRect::TopLeft() const { return Pos(); }
TopRight() const274cdf0e10cSrcweir const Point SwRect::TopRight() const { return Point( m_Point.getX() + m_Size.getWidth(), m_Point.getY() ); }
BottomLeft() const275cdf0e10cSrcweir const Point SwRect::BottomLeft() const { return Point( m_Point.getX(), m_Point.getY() + m_Size.getHeight() ); }
BottomRight() const276cdf0e10cSrcweir const Point SwRect::BottomRight() const
277cdf0e10cSrcweir     { return Point( m_Point.getX() + m_Size.getWidth(), m_Point.getY() + m_Size.getHeight() ); }
GetLeftDistance(long nLimit) const278cdf0e10cSrcweir long SwRect::GetLeftDistance( long nLimit ) const { return m_Point.getX() - nLimit; }
GetBottomDistance(long nLim) const279cdf0e10cSrcweir long SwRect::GetBottomDistance( long nLim ) const { return nLim - m_Point.getY() - m_Size.getHeight();}
GetTopDistance(long nLimit) const280cdf0e10cSrcweir long SwRect::GetTopDistance( long nLimit ) const { return m_Point.getY() - nLimit; }
GetRightDistance(long nLim) const281cdf0e10cSrcweir long SwRect::GetRightDistance( long nLim ) const { return nLim - m_Point.getX() - m_Size.getWidth(); }
OverStepLeft(long nLimit) const282cdf0e10cSrcweir sal_Bool SwRect::OverStepLeft( long nLimit ) const
283cdf0e10cSrcweir     { return nLimit > m_Point.getX() && m_Point.getX() + m_Size.getWidth() > nLimit; }
OverStepBottom(long nLimit) const284cdf0e10cSrcweir sal_Bool SwRect::OverStepBottom( long nLimit ) const
285cdf0e10cSrcweir     { return nLimit > m_Point.getY() && m_Point.getY() + m_Size.getHeight() > nLimit; }
OverStepTop(long nLimit) const286cdf0e10cSrcweir sal_Bool SwRect::OverStepTop( long nLimit ) const
287cdf0e10cSrcweir     { return nLimit > m_Point.getY() && m_Point.getY() + m_Size.getHeight() > nLimit; }
OverStepRight(long nLimit) const288cdf0e10cSrcweir sal_Bool SwRect::OverStepRight( long nLimit ) const
289cdf0e10cSrcweir     { return nLimit > m_Point.getX() && m_Point.getX() + m_Size.getWidth() > nLimit; }
SetLeftAndWidth(long nLeft,long nNew)290cdf0e10cSrcweir void SwRect::SetLeftAndWidth( long nLeft, long nNew )
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     m_Point.setX(nLeft);
293cdf0e10cSrcweir     m_Size.setWidth(nNew);
294cdf0e10cSrcweir }
SetTopAndHeight(long nTop,long nNew)295cdf0e10cSrcweir void SwRect::SetTopAndHeight( long nTop, long nNew )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     m_Point.setY(nTop);
298cdf0e10cSrcweir     m_Size.setHeight(nNew);
299cdf0e10cSrcweir }
SetRightAndWidth(long nRight,long nNew)300cdf0e10cSrcweir void SwRect::SetRightAndWidth( long nRight, long nNew )
301cdf0e10cSrcweir {
302cdf0e10cSrcweir     m_Point.setX(nRight - nNew);
303cdf0e10cSrcweir     m_Size.setWidth(nNew);
304cdf0e10cSrcweir }
SetBottomAndHeight(long nBottom,long nNew)305cdf0e10cSrcweir void SwRect::SetBottomAndHeight( long nBottom, long nNew )
306cdf0e10cSrcweir {
307cdf0e10cSrcweir     m_Point.setY(nBottom - nNew);
308cdf0e10cSrcweir     m_Size.setHeight(nNew);
309cdf0e10cSrcweir }
SetUpperLeftCorner(const Point & rNew)310cdf0e10cSrcweir void SwRect::SetUpperLeftCorner(  const Point& rNew )
311cdf0e10cSrcweir     { m_Point = rNew; }
SetUpperRightCorner(const Point & rNew)312cdf0e10cSrcweir void SwRect::SetUpperRightCorner(  const Point& rNew )
313cdf0e10cSrcweir     { m_Point = Point(rNew.nA - m_Size.getWidth(), rNew.nB); }
SetLowerLeftCorner(const Point & rNew)314cdf0e10cSrcweir void SwRect::SetLowerLeftCorner(  const Point& rNew )
315cdf0e10cSrcweir     { m_Point = Point(rNew.nA, rNew.nB - m_Size.getHeight()); }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir #ifdef DBG_UTIL
318cdf0e10cSrcweir /*************************************************************************
319cdf0e10cSrcweir  *					operator<<( ostream&, SwRect&)
320cdf0e10cSrcweir  *************************************************************************/
321cdf0e10cSrcweir 
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 
operator <<(SvStream & rStream,const SwRect & rRect)324cdf0e10cSrcweir SvStream &operator<<( SvStream &rStream, const SwRect &rRect )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir 	rStream << '[' << rRect.Top()   << '/' << rRect.Left()
327cdf0e10cSrcweir 			<< ',' << rRect.Width() << 'x' << rRect.Height() << "] ";
328cdf0e10cSrcweir 	return rStream;
329cdf0e10cSrcweir }
330cdf0e10cSrcweir #endif
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 
333