xref: /trunk/main/basegfx/source/tools/tools.cxx (revision 09dbbe93)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basegfx.hxx"
26 
27 #include "basegfx/tools/tools.hxx"
28 #include "basegfx/range/b2drange.hxx"
29 
30 #include <algorithm>
31 
32 
33 namespace basegfx
34 {
35     namespace tools
36     {
37         namespace
38         {
distance(const double & nX,const double & nY,const::basegfx::B2DVector & rNormal,const double & nC)39             inline double distance( const double&					nX,
40                                     const double&					nY,
41                                     const ::basegfx::B2DVector& 	rNormal,
42                                     const double&					nC )
43             {
44                 return nX*rNormal.getX() + nY*rNormal.getY() - nC;
45             }
46 
moveLineOutsideRect(::basegfx::B2DPoint & io_rStart,::basegfx::B2DPoint & io_rEnd,const::basegfx::B2DVector & rMoveDirection,const::basegfx::B2DRange & rFitTarget)47             void moveLineOutsideRect( ::basegfx::B2DPoint& 			io_rStart,
48                                       ::basegfx::B2DPoint& 			io_rEnd,
49                                       const ::basegfx::B2DVector&	rMoveDirection,
50                                       const ::basegfx::B2DRange&	rFitTarget		)
51             {
52                 // calc c for normal line form equation n x - c = 0
53                 const double nC( rMoveDirection.scalar( io_rStart ) );
54 
55                 // calc maximum orthogonal distance for all four bound
56                 // rect corners to the line
57                 const double nMaxDistance( ::std::max(
58                                                0.0,
59                                                ::std::max(
60                                                    distance(rFitTarget.getMinX(),
61                                                             rFitTarget.getMinY(),
62                                                             rMoveDirection,
63                                                             nC),
64                                                    ::std::max(
65                                                        distance(rFitTarget.getMinX(),
66                                                                 rFitTarget.getMaxY(),
67                                                                 rMoveDirection,
68                                                                 nC),
69                                                        ::std::max(
70                                                            distance(rFitTarget.getMaxX(),
71                                                                     rFitTarget.getMinY(),
72                                                                     rMoveDirection,
73                                                                     nC),
74                                                            distance(rFitTarget.getMaxX(),
75                                                                     rFitTarget.getMaxY(),
76                                                                     rMoveDirection,
77                                                                     nC) ) ) ) ) );
78 
79                 // now move line points, such that the bound rect
80                 // points are all either 'on' or on the negative side
81                 // of the half-plane
82                 io_rStart += nMaxDistance*rMoveDirection;
83                 io_rEnd   += nMaxDistance*rMoveDirection;
84             }
85         }
86 
infiniteLineFromParallelogram(::basegfx::B2DPoint & io_rLeftTop,::basegfx::B2DPoint & io_rLeftBottom,::basegfx::B2DPoint & io_rRightTop,::basegfx::B2DPoint & io_rRightBottom,const::basegfx::B2DRange & rFitTarget)87         void infiniteLineFromParallelogram( ::basegfx::B2DPoint& 		io_rLeftTop,
88                                             ::basegfx::B2DPoint& 		io_rLeftBottom,
89                                             ::basegfx::B2DPoint& 		io_rRightTop,
90                                             ::basegfx::B2DPoint& 		io_rRightBottom,
91                                             const ::basegfx::B2DRange&	rFitTarget	)
92         {
93             // For the top and bottom border line of the
94             // parallelogram, we determine the distance to all four
95             // corner points of the bound rect (tl, tr, bl, br). When
96             // using the unit normal form for lines (n x - c = 0), and
97             // choosing n to point 'outwards' the parallelogram, then
98             // all bound rect corner points having positive distance
99             // to the line lie outside the extended gradient rect, and
100             // thus, the corresponding border line must be moved the
101             // maximum distance outwards.
102 
103             // don't use the top and bottom border line direction, and
104             // calculate the normal from them. Instead, use the
105             // vertical lines (lt - lb or rt - rb), as they more
106             // faithfully represent the direction of the
107             // to-be-generated infinite line
108             ::basegfx::B2DVector aDirectionVertical( io_rLeftTop - io_rLeftBottom );
109             aDirectionVertical.normalize();
110 
111             const ::basegfx::B2DVector aNormalTop( aDirectionVertical );
112             const ::basegfx::B2DVector aNormalBottom( -aDirectionVertical );
113 
114             // now extend parallelogram, such that the bound rect
115             // point are included
116             moveLineOutsideRect( io_rLeftTop, io_rRightTop, aNormalTop, rFitTarget );
117             moveLineOutsideRect( io_rLeftBottom, io_rRightBottom, aNormalBottom, rFitTarget );
118         }
119     }
120 }
121