[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

jpetsovits at rim.com jpetsovits at rim.com
Thu Apr 8 02:05:05 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 5e979cd20bf59b319f8bafcf0efc52ca7ed90c26
Author: jpetsovits at rim.com <jpetsovits at rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Mar 1 17:41:44 2010 +0000

    2010-03-01  Jakob Petsovits  <jpetsovits at rim.com>
    
            Reviewed by Dirk Schulze.
    
            [OpenVG] Implement support for paths
            https://bugs.webkit.org/show_bug.cgi?id=34366
    
            Adds an implementation of the Path class -
            *almost* complete, but not quite because OpenVG
            does not provide access to the points in a VGPath
            unless one keeps track of all the points by
            themselves, which we decided not to do.
    
            Also hooked up to PainterOpenVG and GraphicsContext.
    
            Further introduced is SharedResourceOpenVG, which is
            intended as base class for paths and other OpenVG
            resources (images, fonts) that WebKit creates as
            long-lived objects. We are at a slight disadvantage
            here as WebKit doesn't have the concept of resources
            belonging to a specific (hardware graphics) context,
            which is the reason why EGLDisplayOpenVG had to
            provide a current display singleton; this class is
            what actually requires that functionality.
    
            Path::addArcTo() uses code by Yong Li <yoli at rim.com>.
    
            * platform/graphics/Path.cpp:
            * platform/graphics/Path.h:
            * platform/graphics/openvg/GraphicsContextOpenVG.cpp:
            (WebCore::GraphicsContext::fillPath):
            (WebCore::GraphicsContext::strokePath):
            (WebCore::GraphicsContext::drawPath):
            (WebCore::GraphicsContext::beginPath):
            (WebCore::GraphicsContext::addPath):
            * platform/graphics/openvg/PainterOpenVG.cpp:
            (WebCore::PainterOpenVG::PainterOpenVG):
            (WebCore::PainterOpenVG::~PainterOpenVG):
            (WebCore::PainterOpenVG::transformPath):
            (WebCore::PainterOpenVG::beginPath):
            (WebCore::PainterOpenVG::addPath):
            (WebCore::PainterOpenVG::currentPath):
            (WebCore::PainterOpenVG::drawPath):
            * platform/graphics/openvg/PainterOpenVG.h:
            * platform/graphics/openvg/PathOpenVG.cpp: Added.
            (WebCore::PlatformPathOpenVG::PlatformPathOpenVG):
            (WebCore::PlatformPathOpenVG::operator=):
            (WebCore::PlatformPathOpenVG::~PlatformPathOpenVG):
            (WebCore::PlatformPathOpenVG::clear):
            (WebCore::PlatformPathOpenVG::createPath):
            (WebCore::Path::Path):
            (WebCore::Path::~Path):
            (WebCore::Path::operator=):
            (WebCore::Path::contains):
            (WebCore::Path::strokeContains):
            (WebCore::Path::translate):
            (WebCore::Path::boundingRect):
            (WebCore::Path::strokeBoundingRect):
            (WebCore::Path::moveTo):
            (WebCore::Path::addLineTo):
            (WebCore::Path::addQuadCurveTo):
            (WebCore::Path::addBezierCurveTo):
            (WebCore::Path::addArcTo):
            (WebCore::Path::closeSubpath):
            (WebCore::Path::addArc):
            (WebCore::Path::addRect):
            (WebCore::Path::addEllipse):
            (WebCore::Path::clear):
            (WebCore::Path::isEmpty):
            (WebCore::Path::hasCurrentPoint):
            (WebCore::Path::debugString):
            (WebCore::Path::apply):
            (WebCore::Path::transform):
            (WebCore::Path::length):
            (WebCore::Path::pointAtLength):
            (WebCore::Path::normalAngleAtLength):
            * platform/graphics/openvg/PlatformPathOpenVG.h: Added.
            (WebCore::PlatformPathOpenVG::vgPath):
            * platform/graphics/openvg/SharedResourceOpenVG.cpp: Added.
            (WebCore::SharedResourceOpenVG::makeSharedContextCurrent):
            (WebCore::SharedResourceOpenVG::makeCompatibleContextCurrent):
            * platform/graphics/openvg/SharedResourceOpenVG.h: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55371 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6e5bac7..330081a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,86 @@
+2010-03-01  Jakob Petsovits  <jpetsovits at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        [OpenVG] Implement support for paths
+        https://bugs.webkit.org/show_bug.cgi?id=34366
+
+        Adds an implementation of the Path class -
+        *almost* complete, but not quite because OpenVG
+        does not provide access to the points in a VGPath
+        unless one keeps track of all the points by
+        themselves, which we decided not to do.
+
+        Also hooked up to PainterOpenVG and GraphicsContext.
+
+        Further introduced is SharedResourceOpenVG, which is
+        intended as base class for paths and other OpenVG
+        resources (images, fonts) that WebKit creates as
+        long-lived objects. We are at a slight disadvantage
+        here as WebKit doesn't have the concept of resources
+        belonging to a specific (hardware graphics) context,
+        which is the reason why EGLDisplayOpenVG had to
+        provide a current display singleton; this class is
+        what actually requires that functionality.
+
+        Path::addArcTo() uses code by Yong Li <yoli at rim.com>.
+
+        * platform/graphics/Path.cpp:
+        * platform/graphics/Path.h:
+        * platform/graphics/openvg/GraphicsContextOpenVG.cpp:
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        (WebCore::GraphicsContext::drawPath):
+        (WebCore::GraphicsContext::beginPath):
+        (WebCore::GraphicsContext::addPath):
+        * platform/graphics/openvg/PainterOpenVG.cpp:
+        (WebCore::PainterOpenVG::PainterOpenVG):
+        (WebCore::PainterOpenVG::~PainterOpenVG):
+        (WebCore::PainterOpenVG::transformPath):
+        (WebCore::PainterOpenVG::beginPath):
+        (WebCore::PainterOpenVG::addPath):
+        (WebCore::PainterOpenVG::currentPath):
+        (WebCore::PainterOpenVG::drawPath):
+        * platform/graphics/openvg/PainterOpenVG.h:
+        * platform/graphics/openvg/PathOpenVG.cpp: Added.
+        (WebCore::PlatformPathOpenVG::PlatformPathOpenVG):
+        (WebCore::PlatformPathOpenVG::operator=):
+        (WebCore::PlatformPathOpenVG::~PlatformPathOpenVG):
+        (WebCore::PlatformPathOpenVG::clear):
+        (WebCore::PlatformPathOpenVG::createPath):
+        (WebCore::Path::Path):
+        (WebCore::Path::~Path):
+        (WebCore::Path::operator=):
+        (WebCore::Path::contains):
+        (WebCore::Path::strokeContains):
+        (WebCore::Path::translate):
+        (WebCore::Path::boundingRect):
+        (WebCore::Path::strokeBoundingRect):
+        (WebCore::Path::moveTo):
+        (WebCore::Path::addLineTo):
+        (WebCore::Path::addQuadCurveTo):
+        (WebCore::Path::addBezierCurveTo):
+        (WebCore::Path::addArcTo):
+        (WebCore::Path::closeSubpath):
+        (WebCore::Path::addArc):
+        (WebCore::Path::addRect):
+        (WebCore::Path::addEllipse):
+        (WebCore::Path::clear):
+        (WebCore::Path::isEmpty):
+        (WebCore::Path::hasCurrentPoint):
+        (WebCore::Path::debugString):
+        (WebCore::Path::apply):
+        (WebCore::Path::transform):
+        (WebCore::Path::length):
+        (WebCore::Path::pointAtLength):
+        (WebCore::Path::normalAngleAtLength):
+        * platform/graphics/openvg/PlatformPathOpenVG.h: Added.
+        (WebCore::PlatformPathOpenVG::vgPath):
+        * platform/graphics/openvg/SharedResourceOpenVG.cpp: Added.
+        (WebCore::SharedResourceOpenVG::makeSharedContextCurrent):
+        (WebCore::SharedResourceOpenVG::makeCompatibleContextCurrent):
+        * platform/graphics/openvg/SharedResourceOpenVG.h: Added.
+
 2010-03-01  Pavel Feldman  <pfeldman at chromium.org>
 
         Not reviewed, bring English.lproj/locallizedStrings.js back to binary (UTF) mode.
diff --git a/WebCore/platform/graphics/Path.cpp b/WebCore/platform/graphics/Path.cpp
index e30703c..af94be7 100644
--- a/WebCore/platform/graphics/Path.cpp
+++ b/WebCore/platform/graphics/Path.cpp
@@ -39,6 +39,7 @@ static const float QUARTER = 0.552f; // approximation of control point positions
                               // to simulate a quarter of a circle.
 namespace WebCore {
 
+#if !PLATFORM(OPENVG)
 static void pathLengthApplierFunction(void* info, const PathElement* element)
 {
     PathTraversalState& traversalState = *static_cast<PathTraversalState*>(info);
@@ -107,6 +108,7 @@ float Path::normalAngleAtLength(float length, bool& ok)
     ok = traversalState.m_success;
     return traversalState.m_normalAngle;
 }
+#endif
 
 Path Path::createRoundedRectangle(const FloatRect& rectangle, const FloatSize& roundingRadii)
 {
diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h
index 533ef8f..b69670f 100644
--- a/WebCore/platform/graphics/Path.h
+++ b/WebCore/platform/graphics/Path.h
@@ -33,6 +33,11 @@
 
 #if PLATFORM(CG)
 typedef struct CGPath PlatformPath;
+#elif PLATFORM(OPENVG)
+namespace WebCore {
+class PlatformPathOpenVG;
+}
+typedef WebCore::PlatformPathOpenVG PlatformPath;
 #elif PLATFORM(QT)
 #include <qpainterpath.h>
 typedef QPainterPath PlatformPath;
diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
index 909fa27..397d792 100644
--- a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -22,6 +22,7 @@
 
 #include "AffineTransform.h"
 #include "GraphicsContextPrivate.h"
+#include "KURL.h"
 #include "NotImplemented.h"
 #include "PainterOpenVG.h"
 #include "SurfaceOpenVG.h"
@@ -143,7 +144,7 @@ void GraphicsContext::fillPath()
     if (paintingDisabled())
         return;
 
-    notImplemented();
+    m_data->drawPath(VG_FILL_PATH, m_common->state.fillRule);
 }
 
 void GraphicsContext::strokePath()
@@ -151,7 +152,15 @@ void GraphicsContext::strokePath()
     if (paintingDisabled())
         return;
 
-    notImplemented();
+    m_data->drawPath(VG_STROKE_PATH, m_common->state.fillRule);
+}
+
+void GraphicsContext::drawPath()
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->drawPath(VG_FILL_PATH | VG_STROKE_PATH, m_common->state.fillRule);
 }
 
 void GraphicsContext::fillRect(const FloatRect& rect)
@@ -193,7 +202,7 @@ void GraphicsContext::beginPath()
     if (paintingDisabled())
         return;
 
-    notImplemented();
+    m_data->beginPath();
 }
 
 void GraphicsContext::addPath(const Path& path)
@@ -201,7 +210,7 @@ void GraphicsContext::addPath(const Path& path)
     if (paintingDisabled())
         return;
 
-    notImplemented();
+    m_data->addPath(path);
 }
 
 void GraphicsContext::clip(const FloatRect& rect)
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
index fd75ec1..d243c57 100644
--- a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
@@ -29,6 +29,7 @@
 #include "IntRect.h"
 #include "IntSize.h"
 #include "NotImplemented.h"
+#include "PlatformPathOpenVG.h"
 #include "SurfaceOpenVG.h"
 #include "VGUtils.h"
 
@@ -340,12 +341,14 @@ struct PlatformPainterState {
 PainterOpenVG::PainterOpenVG()
     : m_state(0)
     , m_surface(0)
+    , m_currentPath(0)
 {
 }
 
 PainterOpenVG::PainterOpenVG(SurfaceOpenVG* surface)
     : m_state(0)
     , m_surface(0)
+    , m_currentPath(0)
 {
     ASSERT(surface);
     begin(surface);
@@ -354,6 +357,7 @@ PainterOpenVG::PainterOpenVG(SurfaceOpenVG* surface)
 PainterOpenVG::~PainterOpenVG()
 {
     end();
+    delete m_currentPath;
 }
 
 void PainterOpenVG::begin(SurfaceOpenVG* surface)
@@ -441,6 +445,28 @@ void PainterOpenVG::setTransformation(const AffineTransform& transformation)
     m_state->applyTransformation(this);
 }
 
+void PainterOpenVG::transformPath(VGPath dst, VGPath src, const AffineTransform& transformation)
+{
+    vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+
+    // Save the transform state
+    VGfloat currentMatrix[9];
+    vgGetMatrix(currentMatrix);
+    ASSERT_VG_NO_ERROR();
+
+    // Load the new transform
+    vgLoadMatrix(VGMatrix(transformation).toVGfloat());
+    ASSERT_VG_NO_ERROR();
+
+    // Apply the new transform
+    vgTransformPath(dst, src);
+    ASSERT_VG_NO_ERROR();
+
+    // Restore the transform state
+    vgLoadMatrix(currentMatrix);
+    ASSERT_VG_NO_ERROR();
+}
+
 CompositeOperator PainterOpenVG::compositeOperation() const
 {
     ASSERT(m_state);
@@ -621,6 +647,47 @@ void PainterOpenVG::translate(float dx, float dy)
     setTransformation(transformation);
 }
 
+void PainterOpenVG::beginPath()
+{
+    delete m_currentPath;
+    m_currentPath = new Path();
+}
+
+void PainterOpenVG::addPath(const Path& path)
+{
+    m_currentPath->platformPath()->makeCompatibleContextCurrent();
+
+    vgAppendPath(m_currentPath->platformPath()->vgPath(), path.platformPath()->vgPath());
+    ASSERT_VG_NO_ERROR();
+}
+
+Path* PainterOpenVG::currentPath() const
+{
+    return m_currentPath;
+}
+
+void PainterOpenVG::drawPath(VGbitfield specifiedPaintModes, WindRule fillRule)
+{
+    ASSERT(m_state);
+
+    VGbitfield paintModes = 0;
+    if (!m_state->strokeDisabled())
+        paintModes |= VG_STROKE_PATH;
+    if (!m_state->fillDisabled())
+        paintModes |= VG_FILL_PATH;
+
+    paintModes &= specifiedPaintModes;
+
+    if (!paintModes)
+        return;
+
+    m_surface->makeCurrent();
+
+    vgSeti(VG_FILL_RULE, toVGFillRule(fillRule));
+    vgDrawPath(m_currentPath->platformPath()->vgPath(), paintModes);
+    ASSERT_VG_NO_ERROR();
+}
+
 void PainterOpenVG::intersectScissorRect(const FloatRect& rect)
 {
     // Scissor rectangles are defined by float values, but e.g. painting
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.h b/WebCore/platform/graphics/openvg/PainterOpenVG.h
index 9982283..6071ee7 100644
--- a/WebCore/platform/graphics/openvg/PainterOpenVG.h
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.h
@@ -36,6 +36,7 @@ class FloatPoint;
 class FloatRect;
 class IntRect;
 class IntSize;
+class Path;
 class SurfaceOpenVG;
 
 struct PlatformPainterState;
@@ -61,6 +62,8 @@ public:
     void setTransformation(const AffineTransform&);
     void concatTransformation(const AffineTransform&);
 
+    static void transformPath(VGPath dst, VGPath src, const AffineTransform&);
+
     CompositeOperator compositeOperation() const;
     void setCompositeOperation(CompositeOperator);
     float opacity() const;
@@ -96,6 +99,11 @@ public:
     void rotate(float radians);
     void translate(float dx, float dy);
 
+    void beginPath();
+    void addPath(const Path&);
+    Path* currentPath() const;
+    void drawPath(VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH), WindRule fillRule = RULE_NONZERO);
+
     void intersectClipRect(const FloatRect&);
 
     void save(PainterOpenVG::SaveMode saveMode = CreateNewState);
@@ -114,6 +122,7 @@ private:
     Vector<PlatformPainterState*> m_stateStack;
     PlatformPainterState* m_state;
     SurfaceOpenVG* m_surface;
+    Path* m_currentPath;
 };
 
 }
diff --git a/WebCore/platform/graphics/openvg/PathOpenVG.cpp b/WebCore/platform/graphics/openvg/PathOpenVG.cpp
new file mode 100644
index 0000000..2c366ee
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/PathOpenVG.cpp
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "Path.h"
+
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+#include "PainterOpenVG.h"
+#include "PlatformPathOpenVG.h"
+#include "PlatformString.h"
+#include "StrokeStyleApplier.h"
+#include "VGUtils.h"
+
+#include <openvg.h>
+#include <wtf/MathExtras.h>
+
+#define WEBKIT_VG_PATH_CAPABILITIES VG_PATH_CAPABILITY_ALL
+
+#define FUZZY_COMPARE(number, reference, delta) \
+    (number >= (reference - delta) && number <= (reference + delta))
+
+namespace WebCore {
+
+PlatformPathOpenVG::PlatformPathOpenVG()
+    : SharedResourceOpenVG()
+{
+    createPath();
+}
+
+PlatformPathOpenVG::PlatformPathOpenVG(const PlatformPathOpenVG& other)
+    : SharedResourceOpenVG()
+    , m_currentPoint(other.m_currentPoint)
+    , m_subpathStartPoint(other.m_subpathStartPoint)
+{
+    createPath();
+    // makeCompatibleContextCurrent() is called by createPath(), so not necessary here.
+    vgAppendPath(m_vgPath, other.m_vgPath);
+    ASSERT_VG_NO_ERROR();
+}
+
+PlatformPathOpenVG& PlatformPathOpenVG::operator=(const PlatformPathOpenVG& other)
+{
+    if (&other != this) {
+        clear();
+        // makeCompatibleContextCurrent() is called by clear(), so not necessary here.
+        vgAppendPath(m_vgPath, other.m_vgPath);
+        ASSERT_VG_NO_ERROR();
+    }
+    return *this;
+}
+
+PlatformPathOpenVG::~PlatformPathOpenVG()
+{
+    makeCompatibleContextCurrent();
+
+    vgDestroyPath(m_vgPath);
+    ASSERT_VG_NO_ERROR();
+}
+
+void PlatformPathOpenVG::clear()
+{
+    makeCompatibleContextCurrent();
+
+    vgClearPath(m_vgPath, WEBKIT_VG_PATH_CAPABILITIES);
+    ASSERT_VG_NO_ERROR();
+
+    m_subpathStartPoint.setX(0);
+    m_subpathStartPoint.setY(0);
+    m_currentPoint = m_subpathStartPoint;
+}
+
+void PlatformPathOpenVG::createPath()
+{
+    makeSharedContextCurrent();
+
+    m_vgPath = vgCreatePath(
+        VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+        1.0 /* scale */, 0.0 /* bias */,
+        0 /* expected number of segments */,
+        0 /* expected number of total coordinates */,
+        WEBKIT_VG_PATH_CAPABILITIES);
+    ASSERT_VG_NO_ERROR();
+}
+
+
+Path::Path()
+{
+    m_path = new PlatformPathOpenVG();
+}
+
+Path::~Path()
+{
+    delete m_path;
+}
+
+Path::Path(const Path& other)
+{
+    m_path = new PlatformPathOpenVG(*(other.m_path));
+}
+
+Path& Path::operator=(const Path& other)
+{
+    *m_path = *(other.m_path);
+    return *this;
+}
+
+bool Path::contains(const FloatPoint& point, WindRule rule) const
+{
+    notImplemented();
+
+    // OpenVG has no path-contains function, so for now we approximate by
+    // using the bounding rect of the path.
+    return boundingRect().contains(point);
+}
+
+bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const
+{
+    notImplemented();
+
+    // OpenVG has no path-contains function, so for now we approximate by
+    // using the stroke bounding rect of the path.
+    return (const_cast<Path*>(this))->strokeBoundingRect().contains(point);
+}
+
+void Path::translate(const FloatSize& size)
+{
+    AffineTransform transformation;
+    transformation.translate(size.width(), size.height());
+    transform(transformation);
+}
+
+FloatRect Path::boundingRect() const
+{
+    VGfloat minX;
+    VGfloat minY;
+    VGfloat width;
+    VGfloat height;
+
+    m_path->makeCompatibleContextCurrent();
+    vgPathBounds(m_path->vgPath(), &minX, &minY, &width, &height);
+    ASSERT_VG_NO_ERROR();
+
+    return FloatRect(FloatPoint(minX, minY), FloatSize(width, height));
+}
+
+FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
+{
+    notImplemented();
+
+    // vgPathBounds() ignores stroke parameters, and we don't currently have
+    // an approximation that takes stroke parameters into account.
+    return boundingRect();
+}
+
+void Path::moveTo(const FloatPoint& point)
+{
+    static const VGubyte pathSegments[] = { VG_MOVE_TO_ABS };
+    const VGfloat pathData[] = { point.x(), point.y() };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 1, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = m_path->m_subpathStartPoint = point;
+}
+
+void Path::addLineTo(const FloatPoint& point)
+{
+    static const VGubyte pathSegments[] = { VG_LINE_TO_ABS };
+    const VGfloat pathData[] = { point.x(), point.y() };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 1, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = point;
+}
+
+void Path::addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint)
+{
+    static const VGubyte pathSegments[] = { VG_QUAD_TO_ABS };
+    const VGfloat pathData[] = { controlPoint.x(), controlPoint.y(), endPoint.x(), endPoint.y() };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 1, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = endPoint;
+}
+
+void Path::addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint)
+{
+    static const VGubyte pathSegments[] = { VG_CUBIC_TO_ABS };
+    const VGfloat pathData[] = { controlPoint1.x(), controlPoint1.y(), controlPoint2.x(), controlPoint2.y(), endPoint.x(), endPoint.y() };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 1, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = endPoint;
+}
+
+void Path::addArcTo(const FloatPoint& point1, const FloatPoint& point2, float radius)
+{
+    // See http://philip.html5.org/tests/canvas/suite/tests/spec.html#arcto.
+
+    const FloatPoint& point0 = m_path->m_currentPoint;
+    if (!radius || point0 == point1 || point1 == point2) {
+        addLineTo(point1);
+        return;
+    }
+
+    FloatSize v01 = point0 - point1;
+    FloatSize v21 = point2 - point1;
+
+    // sin(A - B) = sin(A) * cos(B) - sin(B) * cos(A)
+    double cross = v01.width() * v21.height() - v01.height() * v21.width();
+
+    if (fabs(cross) < 1E-10) {
+        // on one line
+        addLineTo(point1);
+        return;
+    }
+
+    double d01 = hypot(v01.width(), v01.height());
+    double d21 = hypot(v21.width(), v21.height());
+    double angle = (piDouble - fabs(asin(cross / (d01 * d21)))) * 0.5;
+    double span = radius * tan(angle);
+    double rate = span / d01;
+    FloatPoint startPoint = FloatPoint(point1.x() + v01.width() * rate,
+                                       point1.y() + v01.height() * rate);
+    rate = span / d21;
+    FloatPoint endPoint = FloatPoint(point1.x() + v21.width() * rate,
+                                     point1.y() + v21.height() * rate);
+
+    // Fa: large arc flag, makes the difference between SCWARC_TO and LCWARC_TO
+    //     respectively SCCWARC_TO and LCCWARC_TO arcs. We always use small
+    //     arcs for arcTo(), as the arc is defined as the "shortest arc" of the
+    //     circle specified in HTML 5.
+
+    // Fs: sweep flag, specifying whether the arc is drawn in increasing (true)
+    //     or decreasing (0) direction.
+    const bool anticlockwise = cross < 0;
+
+    // Translate the large arc and sweep flags into an OpenVG segment command.
+    const VGubyte segmentCommand = anticlockwise ? VG_SCCWARC_TO_ABS : VG_SCWARC_TO_ABS;
+
+    const VGubyte pathSegments[] = {
+        VG_LINE_TO_ABS,
+        segmentCommand
+    };
+    const VGfloat pathData[] = {
+        startPoint.x(), startPoint.y(),
+        radius, radius, 0, endPoint.x(), endPoint.y()
+    };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 2, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = endPoint;
+}
+
+void Path::closeSubpath()
+{
+    static const VGubyte pathSegments[] = { VG_CLOSE_PATH };
+    // pathData must not be 0, but certain compilers also don't create
+    // zero-size arrays. So let's use a random aligned value (sizeof(VGfloat)),
+    // it won't be accessed anyways as VG_CLOSE_PATH doesn't take coordinates.
+    static const VGfloat* pathData = reinterpret_cast<VGfloat*>(sizeof(VGfloat));
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 1, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = m_path->m_subpathStartPoint;
+}
+
+void Path::addArc(const FloatPoint& center, float radius, float startAngle, float endAngle, bool anticlockwise)
+{
+    // The OpenVG spec says nothing about inf as radius or start/end angle.
+    // WebKit seems to pass those (e.g. https://bugs.webkit.org/show_bug.cgi?id=16449),
+    // so abort instead of risking undefined behavior.
+    if (!isfinite(radius) || !isfinite(startAngle) || !isfinite(endAngle))
+        return;
+
+    // For some reason, the HTML 5 spec defines the angle as going clockwise
+    // from the positive X axis instead of going standard anticlockwise.
+    // So let's make it a proper angle in order to keep sanity.
+    startAngle = fmod((2.0 * piDouble) - startAngle, 2.0 * piDouble);
+    endAngle = fmod((2.0 * piDouble) - endAngle, 2.0 * piDouble);
+
+    // Make it so that endAngle > startAngle. fmod() above takes care of
+    // keeping the difference below 360 degrees.
+    if (endAngle <= startAngle)
+        endAngle += 2.0 * piDouble;
+
+    const VGfloat angleDelta = anticlockwise
+        ? (endAngle - startAngle)
+        : (startAngle - endAngle + (2.0 * piDouble));
+
+    // OpenVG uses endpoint parameterization while this method receives its
+    // values in center parameterization. It lacks an ellipse rotation
+    // parameter so we use 0 for that, and also the radius is only a single
+    // value which makes for rh == rv. In order to convert from endpoint to
+    // center parameterization, we use the formulas from the OpenVG/SVG specs:
+
+    // (x,y) = (cos rot, -sin rot; sin rot, -cos rot) * (rh * cos angle, rv * sin angle) + (center.x, center.y)
+    // rot is 0, which simplifies this a bit:
+    // (x,y) = (1, 0; 0, -1) * (rh * cos angle, rv * sin angle) + (center.x, center.y)
+    //       = (1 * rh * cos angle + 0 * rv * sin angle, 0 * rh * cos angle + -1 * rv * sin angle) + (center.x, center.y)
+    //       = (rh * cos angle, -rv * sin angle) + (center.x, center.y)
+    // (Set angle = {startAngle, endAngle} to retrieve the respective endpoints.)
+
+    const VGfloat startX = radius * cos(startAngle) + center.x();
+    const VGfloat startY = -radius * sin(startAngle) + center.y();
+    const VGfloat endX = radius * cos(endAngle) + center.x();
+    const VGfloat endY = -radius * sin(endAngle) + center.y();
+
+    // Fa: large arc flag, makes the difference between SCWARC_TO and LCWARC_TO
+    //     respectively SCCWARC_TO and LCCWARC_TO arcs.
+    const bool largeArc = (angleDelta > piDouble);
+
+    // Fs: sweep flag, specifying whether the arc is drawn in increasing (true)
+    //     or decreasing (0) direction. No need to calculate this value, as it
+    //     we already get it passed as a parameter (Fs == !anticlockwise).
+
+    // Translate the large arc and sweep flags into an OpenVG segment command.
+    // As OpenVG thinks of everything upside down, we need to reverse the
+    // anticlockwise parameter in order to get the specified rotation.
+    const VGubyte segmentCommand = !anticlockwise
+        ? (largeArc ? VG_LCCWARC_TO_ABS : VG_SCCWARC_TO_ABS)
+        : (largeArc ? VG_LCWARC_TO_ABS : VG_SCWARC_TO_ABS);
+
+    // So now, we've got all the parameters in endpoint parameterization format
+    // as OpenVG requires it. Which means we can just pass it like this.
+    const VGubyte pathSegments[] = {
+        hasCurrentPoint() ? VG_LINE_TO_ABS : VG_MOVE_TO_ABS,
+        segmentCommand
+    };
+    const VGfloat pathData[] = {
+        startX, startY,
+        radius, radius, 0, endX, endY
+    };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 2, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint.setX(endX);
+    m_path->m_currentPoint.setY(endY);
+}
+
+void Path::addRect(const FloatRect& rect)
+{
+    static const VGubyte pathSegments[] = {
+        VG_MOVE_TO_ABS,
+        VG_HLINE_TO_REL,
+        VG_VLINE_TO_REL,
+        VG_HLINE_TO_REL,
+        VG_CLOSE_PATH
+    };
+    const VGfloat pathData[] = {
+        rect.x(), rect.y(),
+        rect.width(),
+        rect.height(),
+        -rect.width()
+    };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 5, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+
+    m_path->m_currentPoint = m_path->m_subpathStartPoint = rect.location();
+}
+
+void Path::addEllipse(const FloatRect& rect)
+{
+    static const VGubyte pathSegments[] = {
+        VG_MOVE_TO_ABS,
+        VG_SCCWARC_TO_REL,
+        VG_SCCWARC_TO_REL,
+        VG_CLOSE_PATH
+    };
+    const VGfloat pathData[] = {
+        rect.x() + rect.width() / 2.0, rect.y(),
+        rect.width() / 2.0, rect.height() / 2.0, 0, 0, rect.height(),
+        rect.width() / 2.0, rect.height() / 2.0, 0, 0, -rect.height()
+    };
+
+    m_path->makeCompatibleContextCurrent();
+    vgAppendPathData(m_path->vgPath(), 4, pathSegments, pathData);
+    ASSERT_VG_NO_ERROR();
+}
+
+void Path::clear()
+{
+    m_path->clear();
+}
+
+bool Path::isEmpty() const
+{
+    m_path->makeCompatibleContextCurrent();
+    return !vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS);
+}
+
+bool Path::hasCurrentPoint() const
+{
+    m_path->makeCompatibleContextCurrent();
+    return vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS) > 0;
+}
+
+String Path::debugString() const
+{
+    String debugString = "";
+
+    // OpenVG provides no means to retrieve path segment information.
+    // This is a bit unfortunate, we might need to store the segments in
+    // memory if we want to implement this function properly.
+    notImplemented();
+
+    return debugString;
+}
+
+void Path::apply(void* info, PathApplierFunction function) const
+{
+    // OpenVG provides no means to retrieve path segment information.
+    // This is *very* unfortunate, we might need to store the segments in
+    // memory if we want to implement this function properly.
+    // See http://www.khronos.org/message_boards/viewtopic.php?f=6&t=1887
+    notImplemented();
+}
+
+void Path::transform(const AffineTransform& transformation)
+{
+    PlatformPathOpenVG* dst = new PlatformPathOpenVG();
+    // dst->makeCompatibleContextCurrent() is called by the platform path
+    // constructor, therefore not necessary to call it again here.
+    PainterOpenVG::transformPath(dst->vgPath(), m_path->vgPath(), transformation);
+    delete m_path;
+    m_path = dst;
+
+    m_path->m_currentPoint = transform.mapPoint(m_path->m_currentPoint);
+    m_path->m_subpathStartPoint = transform.mapPoint(m_path->m_subpathStartPoint);
+}
+
+
+// Path::length(), Path::pointAtLength() and Path::normalAngleAtLength() are
+// reimplemented here instead of in Path.cpp, because OpenVG has its own
+// functions and Path::apply() doesn't really work as long as we rely on VGPath
+// as primary path storage.
+
+float Path::length()
+{
+    m_path->makeCompatibleContextCurrent();
+    VGfloat length = vgPathLength(m_path->vgPath(), 0, vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS));
+    ASSERT_VG_NO_ERROR();
+    return length;
+}
+
+FloatPoint Path::pointAtLength(float length, bool& ok)
+{
+    VGfloat x = 0, y = 0;
+    m_path->makeCompatibleContextCurrent();
+
+    vgPointAlongPath(m_path->vgPath(), 0, vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS),
+                     length, &x, &y, 0, 0);
+    ok = (vgGetError() == VG_NO_ERROR);
+    return FloatPoint(x, y);
+}
+
+float Path::normalAngleAtLength(float length, bool& ok)
+{
+    VGfloat tangentX, tangentY;
+    m_path->makeCompatibleContextCurrent();
+
+    vgPointAlongPath(m_path->vgPath(), 0, vgGetParameteri(m_path->vgPath(), VG_PATH_NUM_SEGMENTS),
+                     length, 0, 0, &tangentX, &tangentY);
+    ok = (vgGetError() == VG_NO_ERROR);
+    return atan2f(tangentY, tangentX) * 180.0 / piFloat; // convert to degrees
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/PlatformPathOpenVG.h b/WebCore/platform/graphics/openvg/PlatformPathOpenVG.h
new file mode 100644
index 0000000..286da53
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/PlatformPathOpenVG.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PlatformPathOpenVG_h
+#define PlatformPathOpenVG_h
+
+#include "FloatPoint.h"
+#include "SharedResourceOpenVG.h"
+
+#include <openvg.h>
+
+namespace WebCore {
+
+class PlatformPathOpenVG : public SharedResourceOpenVG {
+public:
+    PlatformPathOpenVG();
+    PlatformPathOpenVG(const PlatformPathOpenVG&);
+    ~PlatformPathOpenVG();
+
+    PlatformPathOpenVG& operator=(const PlatformPathOpenVG&);
+
+    VGPath vgPath() { return m_vgPath; }
+    void clear();
+
+public:
+    FloatPoint m_currentPoint;
+    FloatPoint m_subpathStartPoint;
+
+private:
+    void createPath();
+
+    VGPath m_vgPath;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/SharedResourceOpenVG.cpp b/WebCore/platform/graphics/openvg/SharedResourceOpenVG.cpp
new file mode 100644
index 0000000..a843db5
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/SharedResourceOpenVG.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "SharedResourceOpenVG.h"
+
+#include "SurfaceOpenVG.h"
+
+#if PLATFORM(EGL)
+#include "EGLDisplayOpenVG.h"
+#endif
+
+namespace WebCore {
+
+void SharedResourceOpenVG::makeSharedContextCurrent()
+{
+#if PLATFORM(EGL)
+    EGLDisplayOpenVG::current()->sharedPlatformSurface()->makeCurrent();
+#endif
+}
+
+void SharedResourceOpenVG::makeCompatibleContextCurrent()
+{
+#if PLATFORM(EGL)
+    EGLDisplayOpenVG::current()->sharedPlatformSurface()->makeCompatibleCurrent();
+#endif
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/SharedResourceOpenVG.h b/WebCore/platform/graphics/openvg/SharedResourceOpenVG.h
new file mode 100644
index 0000000..436ae90
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/SharedResourceOpenVG.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SharedResourceOpenVG_h
+#define SharedResourceOpenVG_h
+
+namespace WebCore {
+
+class SharedResourceOpenVG {
+public:
+    void makeSharedContextCurrent();
+    void makeCompatibleContextCurrent();
+};
+
+}
+
+#endif

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list