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/numeric/ftools.hxx" 33 #include "basegfx/range/b2drange.hxx" 34 35 36 namespace basegfx 37 { 38 namespace tools 39 { 40 namespace 41 { 42 // see Foley/vanDam, pp. 122 for the Liang-Barsky line 43 // clipping algorithm 44 inline bool liangBarskyClipT( double nDenom, 45 double nNumerator, 46 double& io_rTE, 47 double& io_rTL ) 48 { 49 double t; 50 if( nDenom > 0 ) 51 { 52 t = nNumerator / nDenom; 53 if( t > io_rTL ) 54 return false; 55 else if( t > io_rTE ) 56 io_rTE = t; 57 } 58 else if( nDenom < 0 ) 59 { 60 t = nNumerator / nDenom; 61 if( t < io_rTE ) 62 return false; 63 else 64 io_rTL = t; 65 } 66 else if( nNumerator > 0 ) 67 { 68 return false; 69 } 70 71 return true; 72 } 73 } 74 75 // see Foley/vanDam, pp. 122 for the Liang-Barsky line 76 // clipping algorithm 77 bool liangBarskyClip2D( ::basegfx::B2DPoint& io_rStart, 78 ::basegfx::B2DPoint& io_rEnd, 79 const ::basegfx::B2DRange& rClipRect ) 80 { 81 const double nDX( io_rEnd.getX() - io_rStart.getX() ); 82 const double nDY( io_rEnd.getY() - io_rStart.getY() ); 83 84 if( ::basegfx::fTools::equalZero( nDX ) && 85 ::basegfx::fTools::equalZero( nDY ) ) 86 { 87 return rClipRect.isInside( io_rStart ); 88 } 89 else 90 { 91 double nTE( 0.0 ); 92 double nTL( 1.0 ); 93 if( liangBarskyClipT(nDX, rClipRect.getMinX() - io_rStart.getX(), 94 nTE, nTL ) ) // inside wrt. left edge 95 { 96 if( liangBarskyClipT(-nDX, io_rStart.getX() - rClipRect.getMaxX(), 97 nTE, nTL ) ) // inside wrt. right edge 98 { 99 if( liangBarskyClipT(nDY, rClipRect.getMinY() - io_rStart.getY(), 100 nTE, nTL ) ) // inside wrt. bottom edge 101 { 102 if( liangBarskyClipT(-nDY, io_rStart.getY() - rClipRect.getMaxY(), 103 nTE, nTL ) ) // inside wrt. top edge 104 { 105 // compute actual intersection points, 106 // if nTL has changed 107 if( nTL < 1.0 ) 108 { 109 io_rEnd.setX( io_rStart.getX() + nTL*nDX ); 110 io_rEnd.setY( io_rStart.getY() + nTL*nDY ); 111 } 112 113 // compute actual intersection points, 114 // if nTE has changed 115 if( nTE > 0.0 ) 116 { 117 io_rStart.setX( io_rStart.getX() + nTE*nDX ); 118 io_rStart.setY( io_rStart.getY() + nTE*nDY ); 119 } 120 121 // line is (at least partially) visible 122 return true; 123 } 124 } 125 } 126 } 127 } 128 129 return false; 130 } 131 } 132 } 133