summaryrefslogtreecommitdiff
path: root/binfilter/bf_sch/source/core/sch_calculat.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sch/source/core/sch_calculat.cxx')
-rw-r--r--binfilter/bf_sch/source/core/sch_calculat.cxx206
1 files changed, 206 insertions, 0 deletions
diff --git a/binfilter/bf_sch/source/core/sch_calculat.cxx b/binfilter/bf_sch/source/core/sch_calculat.cxx
new file mode 100644
index 000000000000..e4c0dc4f40b5
--- /dev/null
+++ b/binfilter/bf_sch/source/core/sch_calculat.cxx
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// header for Point, Rectangle
+// header for Polygon
+// header for DBG_ASSERT
+// header for XPolygon, XPolyPolygon
+#include <bf_svx/xpoly.hxx>
+// header for Line
+#include <tools/line.hxx>
+// for performance measurement
+#include <rtl/logfile.hxx>
+
+// Note: Enable the following to skip points in the resulting spline
+// poly-polygon, if they have equal x-values rather than identical points.
+// Unitl now, I think there are situations where the output might differ, if you
+// do so, so it's not enabled by default.
+
+// #define SPLINE_OPTIMIZE_POINTS
+
+#include "calculat.hxx"
+
+#include <algorithm>
+#include <functional>
+namespace binfilter {
+
+using namespace ::std;
+
+
+/*N*/ void SchCalculationHelper::IntersectPolygonWithRectangle( const XPolygon& rPolygon, const Rectangle& rRectangle, XPolyPolygon& aResult )
+/*N*/ {
+/*N*/ RTL_LOGFILE_CONTEXT_AUTHOR( context, "sch", "bm93744", "SchCalculationHelper::IntersectPolygonWithRectangle");
+/*N*/
+/*N*/ aResult.Clear();
+/*N*/
+/*N*/ if( rRectangle.IsInside( rPolygon.GetBoundRect() ) )
+/*N*/ {
+/*N*/ aResult.Insert( rPolygon );
+/*N*/ OSL_TRACE( "IntersectPolygonWithRectangle: result has %d polygons", aResult.Count() );
+/*N*/ return;
+/*N*/ }
+/*N*/
+/*N*/ Point aFrom;
+/*N*/ Point aTo;
+/*N*/ USHORT nCount = rPolygon.GetPointCount();
+/*N*/
+/*N*/ // set last point to a position outside the rectangle, such that the first
+/*N*/ // time clip2d returns true, the comparison to last will always yield false
+/*N*/ Point aLast (rRectangle.TopLeft());
+/*N*/ aLast.Move (-1, -1);
+/*N*/ XPolygon aCurrentPoly;
+/*N*/ USHORT nIdx = 0;
+/*N*/
+/*N*/ for (USHORT i=1; i<nCount; i++)
+/*N*/ {
+/*N*/ aFrom = rPolygon[i-1];
+/*N*/ aTo = rPolygon[i];
+/*N*/ if (clip2d (aFrom, aTo, rRectangle))
+/*N*/ {
+/*N*/ // compose an XPolygon of as many consecutive points as possible
+/*N*/ if (aFrom == aLast)
+/*N*/ {
+/*N*/ if (aTo != aFrom)
+/*N*/ aCurrentPoly.Insert (nIdx++, aTo, XPOLY_NORMAL);
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // create an XPolygon and put it into the XPolyPolygon
+/*N*/ if (aCurrentPoly.GetPointCount() > 0)
+/*N*/ aResult.Insert (aCurrentPoly, XPOLYPOLY_APPEND);
+/*N*/
+/*N*/ // start new sequence
+/*N*/ aCurrentPoly.SetPointCount (0);
+/*N*/ aCurrentPoly.Insert (0, aFrom, XPOLY_NORMAL);
+/*N*/ nIdx = 1;
+/*N*/ if (aTo != aFrom)
+/*N*/ aCurrentPoly.Insert (nIdx++, aTo, XPOLY_NORMAL);
+/*N*/ }
+/*N*/
+/*N*/ aLast = aTo;
+/*N*/ }
+/*N*/ }
+/*N*/ if (aCurrentPoly.GetPointCount() > 0)
+/*N*/ aResult.Insert (aCurrentPoly, XPOLYPOLY_APPEND);
+/*N*/
+/*N*/ OSL_TRACE( "IntersectPolygonWithRectangle: result has %d polygons", aResult.Count() );
+/*N*/ }
+
+
+
+
+
+/*N*/ BOOL SchCalculationHelper::clip2d (Point & rPoint0,
+/*N*/ Point & rPoint1,
+/*N*/ const Rectangle & rRectangle)
+/*N*/ {
+/*N*/ // Direction vector of the line.
+/*N*/ Point aD = rPoint1 - rPoint0;
+/*N*/
+/*N*/ if (aD.X()==0 && aD.Y()==0 && rRectangle.IsInside (rPoint0))
+/*N*/ {
+/*N*/ // Degenerate case of a zero length line.
+/*N*/ return TRUE;
+/*N*/ }
+/*N*/ else
+/*N*/ {
+/*N*/ // Values of the line parameter where the line enters resp. leaves the rectangle.
+/*N*/ double fTE = 0,
+/*N*/ fTL = 1;
+/*N*/
+/*N*/ // Test wether at least a part lies in the four half-planes with respect to
+/*N*/ // the rectangles four edges.
+/*N*/ if (CLIPt (aD.X(), rRectangle.Left() - rPoint0.X(), fTE, fTL))
+/*N*/ if (CLIPt (-aD.X(), rPoint0.X() - rRectangle.Right(), fTE, fTL))
+/*N*/ if (CLIPt (aD.Y(), rRectangle.Top() - rPoint0.Y(), fTE, fTL))
+/*N*/ if (CLIPt (-aD.Y(), rPoint0.Y() - rRectangle.Bottom(), fTE, fTL))
+/*N*/ {
+/*N*/ // At least a part is visible.
+/*N*/ if (fTL < 1)
+/*N*/ {
+/*N*/ // ::com::pute the new end point.
+/*N*/ rPoint1.X() = (long)(rPoint0.X() + fTL * aD.X() + 0.5);
+/*N*/ rPoint1.Y() = (long)(rPoint0.Y() + fTL * aD.Y() + 0.5);
+/*N*/ }
+/*N*/ if (fTE > 0)
+/*N*/ {
+/*N*/ // ::com::pute the new starting point.
+/*N*/ rPoint0.X() = (long)(rPoint0.X() + fTE * aD.X() + 0.5);
+/*N*/ rPoint0.Y() = (long)(rPoint0.Y() + fTE * aD.Y() + 0.5);
+/*N*/ }
+/*N*/ return TRUE;
+/*N*/ }
+/*N*/
+/*N*/ // Line is not visible.
+/*N*/ return FALSE;
+/*N*/ }
+/*N*/ }
+
+
+
+
+/*N*/ BOOL SchCalculationHelper::CLIPt (double fDenom,
+/*N*/ double fNum,
+/*N*/ double & fTE,
+/*N*/ double & fTL)
+/*N*/ {
+/*N*/ double fT;
+/*N*/
+/*N*/ if (fDenom > 0) // Intersection enters: PE
+/*N*/ {
+/*N*/ fT = fNum / fDenom; // Parametric value at the intersection.
+/*N*/ if (fT > fTL) // fTE and fTL crossover
+/*N*/ return FALSE; // therefore reject the line.
+/*N*/ else if (fT > fTE) // A new fTE has been found.
+/*N*/ fTE = fT;
+/*N*/ }
+/*N*/ else if (fDenom < 0) // Intersection leaves: PL
+/*N*/ {
+/*N*/ fT = fNum / fDenom; // Parametric Value at the intersection.
+/*N*/ if (fT < fTE) // fTE and fTL crossover
+/*N*/ return FALSE; // therefore reject the line.
+/*N*/ else if (fT < fTL) // A new fTL has been found.
+/*N*/ fTL = fT;
+/*N*/ }
+/*N*/ else if (fNum > 0)
+/*N*/ return FALSE; // Line lies on the outside of the edge.
+/*N*/
+/*N*/ return TRUE;
+/*N*/ }
+
+
+// --------------------------------------------------------------------------------
+
+// Calculation of Splines
+
+
+// ----------------------------------------
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */