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