| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_basegfx.hxx" |
| |
| #include "basegfx/tools/tools.hxx" |
| #include "basegfx/range/b2drange.hxx" |
| |
| #include <algorithm> |
| |
| |
| namespace basegfx |
| { |
| namespace tools |
| { |
| namespace |
| { |
| inline double distance( const double& nX, |
| const double& nY, |
| const ::basegfx::B2DVector& rNormal, |
| const double& nC ) |
| { |
| return nX*rNormal.getX() + nY*rNormal.getY() - nC; |
| } |
| |
| void moveLineOutsideRect( ::basegfx::B2DPoint& io_rStart, |
| ::basegfx::B2DPoint& io_rEnd, |
| const ::basegfx::B2DVector& rMoveDirection, |
| const ::basegfx::B2DRange& rFitTarget ) |
| { |
| // calc c for normal line form equation n x - c = 0 |
| const double nC( rMoveDirection.scalar( io_rStart ) ); |
| |
| // calc maximum orthogonal distance for all four bound |
| // rect corners to the line |
| const double nMaxDistance( ::std::max( |
| 0.0, |
| ::std::max( |
| distance(rFitTarget.getMinX(), |
| rFitTarget.getMinY(), |
| rMoveDirection, |
| nC), |
| ::std::max( |
| distance(rFitTarget.getMinX(), |
| rFitTarget.getMaxY(), |
| rMoveDirection, |
| nC), |
| ::std::max( |
| distance(rFitTarget.getMaxX(), |
| rFitTarget.getMinY(), |
| rMoveDirection, |
| nC), |
| distance(rFitTarget.getMaxX(), |
| rFitTarget.getMaxY(), |
| rMoveDirection, |
| nC) ) ) ) ) ); |
| |
| // now move line points, such that the bound rect |
| // points are all either 'on' or on the negative side |
| // of the half-plane |
| io_rStart += nMaxDistance*rMoveDirection; |
| io_rEnd += nMaxDistance*rMoveDirection; |
| } |
| } |
| |
| void infiniteLineFromParallelogram( ::basegfx::B2DPoint& io_rLeftTop, |
| ::basegfx::B2DPoint& io_rLeftBottom, |
| ::basegfx::B2DPoint& io_rRightTop, |
| ::basegfx::B2DPoint& io_rRightBottom, |
| const ::basegfx::B2DRange& rFitTarget ) |
| { |
| // For the top and bottom border line of the |
| // parallelogram, we determine the distance to all four |
| // corner points of the bound rect (tl, tr, bl, br). When |
| // using the unit normal form for lines (n x - c = 0), and |
| // choosing n to point 'outwards' the parallelogram, then |
| // all bound rect corner points having positive distance |
| // to the line lie outside the extended gradient rect, and |
| // thus, the corresponding border line must be moved the |
| // maximum distance outwards. |
| |
| // don't use the top and bottom border line direction, and |
| // calculate the normal from them. Instead, use the |
| // vertical lines (lt - lb or rt - rb), as they more |
| // faithfully represent the direction of the |
| // to-be-generated infinite line |
| ::basegfx::B2DVector aDirectionVertical( io_rLeftTop - io_rLeftBottom ); |
| aDirectionVertical.normalize(); |
| |
| const ::basegfx::B2DVector aNormalTop( aDirectionVertical ); |
| const ::basegfx::B2DVector aNormalBottom( -aDirectionVertical ); |
| |
| // now extend parallelogram, such that the bound rect |
| // point are included |
| moveLineOutsideRect( io_rLeftTop, io_rRightTop, aNormalTop, rFitTarget ); |
| moveLineOutsideRect( io_rLeftBottom, io_rRightBottom, aNormalBottom, rFitTarget ); |
| } |
| } |
| } |