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