--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebCore/platform/symbian/PathSymbian.cpp Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,275 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "config.h"
+#include "Path.h"
+#include "PathSymbian.h"
+
+using namespace WebCore;
+
+/*
+The following code is based on an algorithm presented in "Algorithms" by Robert Sedgewick,
+Addison-Wesley, 1988, 2nd ed. ISBN 0201066734
+*/
+
+bool pointInPolygon(WTF::Vector<FloatPoint>& rgpts, const FloatPoint& ptTest);
+
+bool pointInPolyRect(WTF::Vector<FloatPoint>& rgpts, const FloatPoint& ptTest, FloatRect *prbound) ;
+
+bool intersects(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3, const FloatPoint& p4) ;
+
+int CCW(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2) ;
+
+bool pointInPolygon(WTF::Vector<FloatPoint>& rgpts, const FloatPoint& ptTest)
+{
+ int wnumpts = rgpts.size();
+ if (!wnumpts)
+ return false;
+ FloatRect r;
+ int i ;
+ FloatPoint pt1, pt2 ;
+ int wnumintsct = 0 ;
+
+ if (!pointInPolyRect(rgpts,ptTest,&r)) return false;
+
+ pt1 = ptTest ;
+ pt2 = FloatPoint(r.right() + 50, ptTest.y()) ;
+
+ // Now go through each of the lines in the polygon and see if it
+ // intersects
+ for (i = 0 ; i < wnumpts-1 ; i++) {
+ if (intersects(pt1, pt2, rgpts[i], rgpts[i+1]))
+ wnumintsct++ ;
+ }
+
+ // And the last line
+ if (intersects(pt1, pt2, rgpts[wnumpts-1], rgpts[0]))
+ wnumintsct++ ;
+
+ return (wnumintsct&1) ;
+}
+
+
+bool pointInPolyRect(WTF::Vector<FloatPoint>& rgpts, const FloatPoint& ptTest, FloatRect *res)
+{
+ int wnumpts = rgpts.size();
+ if (!wnumpts)
+ return false;
+
+ FloatRect r ;
+ int xmin, xmax, ymin, ymax ;
+ FloatPoint *ppt ;
+ int i ;
+
+ xmin = ymin = INT_MAX ;
+ xmax = ymax = -INT_MAX ;
+
+ for (i=0; i < wnumpts ; i++) {
+ ppt = &rgpts[i];
+ if (ppt->x() < xmin)
+ xmin = ppt->x() ;
+ if (ppt->x() > xmax)
+ xmax = ppt->x() ;
+ if (ppt->y() < ymin)
+ ymin = ppt->y() ;
+ if (ppt->y() > ymax)
+ ymax = ppt->y() ;
+ }
+ r = FloatRect(xmin, ymin, xmax-xmin, ymax-ymin);
+
+ if (res)
+ *res = r;
+
+ return r.contains(ptTest.x(),ptTest.y());
+}
+
+bool intersects(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3, const FloatPoint& p4)
+{
+ return ((( CCW(p1, p2, p3) * CCW(p1, p2, p4)) <= 0)
+ && (( CCW(p3, p4, p1) * CCW(p3, p4, p2) <= 0) )) ;
+}
+
+
+int CCW(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
+
+{
+ int dx1, dx2 ;
+ int dy1, dy2 ;
+
+ dx1 = p1.x() - p0.x() ; dx2 = p2.x() - p0.x() ;
+ dy1 = p1.y() - p0.y() ; dy2 = p2.y() - p0.y() ;
+
+ /* This is basically a slope comparison: we don't do divisions because
+ * of divide by zero possibilities with pure horizontal and pure
+ * vertical lines.
+ */
+ return ((dx1 * dy2 > dy1 * dx2) ? 1 : -1) ;
+}
+
+
+// FIXME: PlatformPath only supports Rectangle, Ellipse and Polygon right now
+
+PlatformPath::~PlatformPath()
+{
+}
+
+void PlatformPath::addRect( const FloatRect& rect )
+{
+ m_type = Rectangle;
+ m_boundingRect = rect;
+}
+
+bool PlatformPath::contains( const FloatPoint& point, WindRule rule )
+{
+ if( m_type == Rectangle )
+ return m_boundingRect.contains( point );
+ else if( m_type == Polygon )
+ return pointInPolygon( m_points, point );
+ else if( m_type == Ellipse ) {
+ /**
+ in order for point(x,y) to stay in the ellipse,
+ it has to fulfill the ellipse equation:
+ sqr(dx)/sqr(a) + sqr(dy)/sqr(b) <= 1
+ where 'a' is half the long axis of the ellipse, and 'b' is half the short axis
+ x = a * cos(t) and y = b * sin(t)
+ (see "http://www.3dsoftware.com/Math/PlaneCurves/EllipseAlgebra" for details)
+ **/
+ const FloatRect& r = m_boundingRect;
+ int r2x = (r.width() * r.width()) / 4; // sqr(a)
+ int r2y = (r.height() * r.height()) / 4; // sqr(b)
+
+ if (!r2x || !r2y) /*avoid division by zero*/
+ return false;
+
+ int cx = (r.x() + r.width()/2); // center of ellipse, x
+ int cy = (r.y() + r.height()/2); // center of ellipse, y
+ int dx = point.x() - cx; // dx
+ int dy = point.y() - cy; // dy
+ return (dx*dx*r2y + dy*dy*r2x <= r2x*r2y);
+ }
+ else
+ return false;
+}
+
+void PlatformPath::addLineTo( const FloatPoint& point )
+{
+ if( m_type == Unknown )
+ m_type = Polygon;
+
+ m_points.append( point );
+}
+
+void PlatformPath::addEllipse( const FloatRect& rect )
+{
+ m_type = Ellipse;
+ m_boundingRect = rect;
+}
+
+void PlatformPath::closeSubPath()
+{
+ // since the above intersection algorithm takes an extra step to test
+ // last line segment in this polygon, we don't need to close the polygon here.
+}
+
+void PlatformPath::translate( const FloatSize& sz )
+{
+ float deltaX = sz.width();
+ float deltaY = sz.height();
+
+ if (m_type == Polygon) {
+ for (int i = 0 ; i < m_points.size() ; i++) {
+ m_points[i] = FloatPoint(m_points[i].x()+deltaX, m_points[i].y()+deltaY);
+ }
+ } else {
+ m_boundingRect.setX(m_boundingRect.x()+deltaX);
+ m_boundingRect.setY(m_boundingRect.y()+deltaY);
+ }
+}
+
+// WebCore::Path member functions
+
+Path::Path()
+{
+ m_path = new PlatformPath();
+}
+
+Path::~Path()
+{
+ delete m_path;
+}
+
+Path::Path(const Path& p)
+{
+ m_path = new PlatformPath();
+ // deep copy
+ *m_path = *(p.m_path);
+}
+
+Path& Path::operator=(const Path& other)
+{
+ if( !m_path )
+ m_path = new PlatformPath();
+ // deep copy
+ *m_path = *(other.m_path);
+
+ return *this;
+}
+
+bool Path::contains(const FloatPoint& point, WindRule rule) const
+{
+ return m_path->contains( point, rule );
+}
+
+void Path::addRect(const FloatRect& rect)
+{
+ m_path->addRect( rect );
+}
+
+FloatRect Path::boundingRect() const
+{
+ return m_path->m_boundingRect;
+}
+
+void Path::translate(const FloatSize& sz)
+{
+ m_path->translate( sz );
+}
+
+void Path::addEllipse(const FloatRect& rect )
+{
+ m_path->addEllipse( rect );
+}
+
+void Path::addLineTo(const FloatPoint& point)
+{
+ m_path->addLineTo( point );
+}
+
+void Path::closeSubpath()
+{
+ m_path->closeSubPath();
+}
+
+void Path::clear()
+{
+ m_path->m_type = PlatformPath::Unknown;
+ m_path->m_points.clear();
+ m_path->m_boundingRect = FloatRect();
+}
+
+// END OF FILE