xref: /aoo41x/main/basegfx/source/tools/tools.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basegfx.hxx"
30 
31 #include "basegfx/tools/tools.hxx"
32 #include "basegfx/range/b2drange.hxx"
33 
34 #include <algorithm>
35 
36 
37 namespace basegfx
38 {
39     namespace tools
40     {
41         namespace
42         {
43             inline double distance( const double&					nX,
44                                     const double&					nY,
45                                     const ::basegfx::B2DVector& 	rNormal,
46                                     const double&					nC )
47             {
48                 return nX*rNormal.getX() + nY*rNormal.getY() - nC;
49             }
50 
51             void moveLineOutsideRect( ::basegfx::B2DPoint& 			io_rStart,
52                                       ::basegfx::B2DPoint& 			io_rEnd,
53                                       const ::basegfx::B2DVector&	rMoveDirection,
54                                       const ::basegfx::B2DRange&	rFitTarget		)
55             {
56                 // calc c for normal line form equation n x - c = 0
57                 const double nC( rMoveDirection.scalar( io_rStart ) );
58 
59                 // calc maximum orthogonal distance for all four bound
60                 // rect corners to the line
61                 const double nMaxDistance( ::std::max(
62                                                0.0,
63                                                ::std::max(
64                                                    distance(rFitTarget.getMinX(),
65                                                             rFitTarget.getMinY(),
66                                                             rMoveDirection,
67                                                             nC),
68                                                    ::std::max(
69                                                        distance(rFitTarget.getMinX(),
70                                                                 rFitTarget.getMaxY(),
71                                                                 rMoveDirection,
72                                                                 nC),
73                                                        ::std::max(
74                                                            distance(rFitTarget.getMaxX(),
75                                                                     rFitTarget.getMinY(),
76                                                                     rMoveDirection,
77                                                                     nC),
78                                                            distance(rFitTarget.getMaxX(),
79                                                                     rFitTarget.getMaxY(),
80                                                                     rMoveDirection,
81                                                                     nC) ) ) ) ) );
82 
83                 // now move line points, such that the bound rect
84                 // points are all either 'on' or on the negative side
85                 // of the half-plane
86                 io_rStart += nMaxDistance*rMoveDirection;
87                 io_rEnd   += nMaxDistance*rMoveDirection;
88             }
89         }
90 
91         void infiniteLineFromParallelogram( ::basegfx::B2DPoint& 		io_rLeftTop,
92                                             ::basegfx::B2DPoint& 		io_rLeftBottom,
93                                             ::basegfx::B2DPoint& 		io_rRightTop,
94                                             ::basegfx::B2DPoint& 		io_rRightBottom,
95                                             const ::basegfx::B2DRange&	rFitTarget	)
96         {
97             // For the top and bottom border line of the
98             // parallelogram, we determine the distance to all four
99             // corner points of the bound rect (tl, tr, bl, br). When
100             // using the unit normal form for lines (n x - c = 0), and
101             // choosing n to point 'outwards' the parallelogram, then
102             // all bound rect corner points having positive distance
103             // to the line lie outside the extended gradient rect, and
104             // thus, the corresponding border line must be moved the
105             // maximum distance outwards.
106 
107             // don't use the top and bottom border line direction, and
108             // calculate the normal from them. Instead, use the
109             // vertical lines (lt - lb or rt - rb), as they more
110             // faithfully represent the direction of the
111             // to-be-generated infinite line
112             ::basegfx::B2DVector aDirectionVertical( io_rLeftTop - io_rLeftBottom );
113             aDirectionVertical.normalize();
114 
115             const ::basegfx::B2DVector aNormalTop( aDirectionVertical );
116             const ::basegfx::B2DVector aNormalBottom( -aDirectionVertical );
117 
118             // now extend parallelogram, such that the bound rect
119             // point are included
120             moveLineOutsideRect( io_rLeftTop, io_rRightTop, aNormalTop, rFitTarget );
121             moveLineOutsideRect( io_rLeftBottom, io_rRightBottom, aNormalBottom, rFitTarget );
122         }
123     }
124 }
125