[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

jpetsovits at rim.com jpetsovits at rim.com
Thu Feb 4 21:32:19 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 5750c0701a5a436f2c3aabfd085614ae344cef47
Author: jpetsovits at rim.com <jpetsovits at rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jan 29 15:43:08 2010 +0000

    2010-01-29  Jakob Petsovits  <jpetsovits at rim.com>
    
            Reviewed by Nikolas Zimmermann.
    
            [OpenVG] Implement a basic GraphicsContext on top of a new PainterOpenVG class
            https://bugs.webkit.org/show_bug.cgi?id=33405
    
            PainterOpenVG provides painter state management that works
            on a single (EGL) context, and apart from painter state
            implements a single drawing operation (for now), drawRect().
    
            It is a generic painter class that cooperates with
            SurfaceOpenVG to enable robust surface/context switching
            (given that EGL doesn't notify us if somebody switches
            the surface/context behind our backs), and provides
            painting operations close to OpenVG's way of working
            that GraphicsContext, Path, Image, Font and other WebKit
            platform classes can use to draw on.
    
            Initial code for state management and OpenVG scissoring by
            Eli Fidler <efidler at rim.com>. VGRect/VGMatrix and the bulk
            of the transformations code by Adam Treat <atreat at rim.com>.
            Preliminary drawFocusRing() implementation by Yong Li <yoli at rim.com>.
    
            * platform/graphics/FloatRect.h:
            * platform/graphics/GraphicsContext.cpp:
            * platform/graphics/GraphicsContext.h:
            * platform/graphics/openvg/GraphicsContextOpenVG.cpp: Added.
            (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
            (WebCore::GraphicsContext::GraphicsContext):
            (WebCore::GraphicsContext::~GraphicsContext):
            (WebCore::GraphicsContext::platformContext):
            (WebCore::GraphicsContext::getCTM):
            (WebCore::GraphicsContext::savePlatformState):
            (WebCore::GraphicsContext::restorePlatformState):
            (WebCore::GraphicsContext::drawRect):
            (WebCore::GraphicsContext::drawLine):
            (WebCore::GraphicsContext::drawEllipse):
            (WebCore::GraphicsContext::strokeArc):
            (WebCore::GraphicsContext::drawConvexPolygon):
            (WebCore::GraphicsContext::fillPath):
            (WebCore::GraphicsContext::strokePath):
            (WebCore::GraphicsContext::fillRect):
            (WebCore::GraphicsContext::fillRoundedRect):
            (WebCore::GraphicsContext::beginPath):
            (WebCore::GraphicsContext::addPath):
            (WebCore::GraphicsContext::clip):
            (WebCore::GraphicsContext::clipPath):
            (WebCore::GraphicsContext::drawFocusRing):
            (WebCore::GraphicsContext::drawLineForText):
            (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
            (WebCore::GraphicsContext::roundToDevicePixels):
            (WebCore::GraphicsContext::setPlatformShadow):
            (WebCore::GraphicsContext::clearPlatformShadow):
            (WebCore::GraphicsContext::beginTransparencyLayer):
            (WebCore::GraphicsContext::endTransparencyLayer):
            (WebCore::GraphicsContext::clearRect):
            (WebCore::GraphicsContext::strokeRect):
            (WebCore::GraphicsContext::setLineCap):
            (WebCore::GraphicsContext::setLineDash):
            (WebCore::GraphicsContext::setLineJoin):
            (WebCore::GraphicsContext::setMiterLimit):
            (WebCore::GraphicsContext::setAlpha):
            (WebCore::GraphicsContext::setCompositeOperation):
            (WebCore::GraphicsContext::canvasClip):
            (WebCore::GraphicsContext::clipOut):
            (WebCore::GraphicsContext::scale):
            (WebCore::GraphicsContext::rotate):
            (WebCore::GraphicsContext::translate):
            (WebCore::GraphicsContext::origin):
            (WebCore::GraphicsContext::clipOutEllipseInRect):
            (WebCore::GraphicsContext::clipToImageBuffer):
            (WebCore::GraphicsContext::addInnerRoundedRectClip):
            (WebCore::GraphicsContext::concatCTM):
            (WebCore::GraphicsContext::setURLForRect):
            (WebCore::GraphicsContext::setPlatformStrokeColor):
            (WebCore::GraphicsContext::setPlatformStrokeStyle):
            (WebCore::GraphicsContext::setPlatformStrokeThickness):
            (WebCore::GraphicsContext::setPlatformFillColor):
            (WebCore::GraphicsContext::setPlatformShouldAntialias):
            (WebCore::GraphicsContext::setImageInterpolationQuality):
            (WebCore::GraphicsContext::imageInterpolationQuality):
            * platform/graphics/openvg/PainterOpenVG.cpp: Added.
            (WebCore::isNonRotatedAffineTransformation):
            (WebCore::toVGCapStyle):
            (WebCore::toVGJoinStyle):
            (WebCore::toVGFillRule):
            (WebCore::colorToVGColor):
            (WebCore::setVGSolidColor):
            (WebCore::PlatformPainterState::PlatformPainterState):
            (WebCore::PlatformPainterState::copyPaintState):
            (WebCore::PlatformPainterState::applyState):
            (WebCore::PlatformPainterState::applyBlending):
            (WebCore::PlatformPainterState::applyTransformationMatrix):
            (WebCore::PlatformPainterState::applyScissorRect):
            (WebCore::PlatformPainterState::applyStrokeStyle):
            (WebCore::PlatformPainterState::strokeDisabled):
            (WebCore::PlatformPainterState::fillDisabled):
            (WebCore::PainterOpenVG::PainterOpenVG):
            (WebCore::PainterOpenVG::~PainterOpenVG):
            (WebCore::PainterOpenVG::begin):
            (WebCore::PainterOpenVG::end):
            (WebCore::PainterOpenVG::destroyPainterStates):
            (WebCore::PainterOpenVG::applyState):
            (WebCore::PainterOpenVG::blitToSurface):
            (WebCore::PainterOpenVG::transformationMatrix):
            (WebCore::PainterOpenVG::concatTransformationMatrix):
            (WebCore::PainterOpenVG::setTransformationMatrix):
            (WebCore::PainterOpenVG::compositeOperation):
            (WebCore::PainterOpenVG::setCompositeOperation):
            (WebCore::PainterOpenVG::opacity):
            (WebCore::PainterOpenVG::setOpacity):
            (WebCore::PainterOpenVG::strokeThickness):
            (WebCore::PainterOpenVG::setStrokeThickness):
            (WebCore::PainterOpenVG::strokeStyle):
            (WebCore::PainterOpenVG::setStrokeStyle):
            (WebCore::PainterOpenVG::setLineDash):
            (WebCore::PainterOpenVG::setLineCap):
            (WebCore::PainterOpenVG::setLineJoin):
            (WebCore::PainterOpenVG::setMiterLimit):
            (WebCore::PainterOpenVG::strokeColor):
            (WebCore::PainterOpenVG::setStrokeColor):
            (WebCore::PainterOpenVG::fillColor):
            (WebCore::PainterOpenVG::setFillColor):
            (WebCore::PainterOpenVG::antialiasingEnabled):
            (WebCore::PainterOpenVG::setAntialiasingEnabled):
            (WebCore::PainterOpenVG::scale):
            (WebCore::PainterOpenVG::rotate):
            (WebCore::PainterOpenVG::translate):
            (WebCore::PainterOpenVG::intersectScissorRect):
            (WebCore::PainterOpenVG::intersectClipRect):
            (WebCore::PainterOpenVG::drawRect):
            (WebCore::PainterOpenVG::save):
            (WebCore::PainterOpenVG::restore):
            * platform/graphics/openvg/PainterOpenVG.h: Added.
            (WebCore::PainterOpenVG::):
            (WebCore::PainterOpenVG::surface):
            * platform/graphics/openvg/SurfaceOpenVG.cpp:
            (WebCore::SurfaceOpenVG::SurfaceOpenVG):
            (WebCore::SurfaceOpenVG::~SurfaceOpenVG):
            (WebCore::SurfaceOpenVG::makeCurrent):
            (WebCore::SurfaceOpenVG::makeCompatibleCurrent):
            (WebCore::SurfaceOpenVG::setActivePainter):
            (WebCore::SurfaceOpenVG::activePainter):
            * platform/graphics/openvg/SurfaceOpenVG.h:
            (WebCore::SurfaceOpenVG::):
            * platform/graphics/openvg/VGUtils.cpp: Added.
            (WebCore::VGMatrix::VGMatrix):
            (WebCore::VGMatrix::operator TransformationMatrix):
            (WebCore::TransformationMatrix::operator VGMatrix):
            (WebCore::VGRect::VGRect):
            (WebCore::VGRect::operator FloatRect):
            (WebCore::FloatRect::operator VGRect):
            * platform/graphics/openvg/VGUtils.h:
            (WebCore::VGMatrix::toVGfloat):
            (WebCore::VGRect::toVGfloat):
            * platform/graphics/transforms/TransformationMatrix.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54063 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 500b136..55ed6e0 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,161 @@
+2010-01-29  Jakob Petsovits  <jpetsovits at rim.com>
+
+        Reviewed by Nikolas Zimmermann.
+
+        [OpenVG] Implement a basic GraphicsContext on top of a new PainterOpenVG class
+        https://bugs.webkit.org/show_bug.cgi?id=33405
+
+        PainterOpenVG provides painter state management that works
+        on a single (EGL) context, and apart from painter state
+        implements a single drawing operation (for now), drawRect().
+
+        It is a generic painter class that cooperates with
+        SurfaceOpenVG to enable robust surface/context switching
+        (given that EGL doesn't notify us if somebody switches
+        the surface/context behind our backs), and provides
+        painting operations close to OpenVG's way of working
+        that GraphicsContext, Path, Image, Font and other WebKit
+        platform classes can use to draw on.
+
+        Initial code for state management and OpenVG scissoring by
+        Eli Fidler <efidler at rim.com>. VGRect/VGMatrix and the bulk
+        of the transformations code by Adam Treat <atreat at rim.com>.
+        Preliminary drawFocusRing() implementation by Yong Li <yoli at rim.com>.
+
+        * platform/graphics/FloatRect.h:
+        * platform/graphics/GraphicsContext.cpp:
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/openvg/GraphicsContextOpenVG.cpp: Added.
+        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContext::GraphicsContext):
+        (WebCore::GraphicsContext::~GraphicsContext):
+        (WebCore::GraphicsContext::platformContext):
+        (WebCore::GraphicsContext::getCTM):
+        (WebCore::GraphicsContext::savePlatformState):
+        (WebCore::GraphicsContext::restorePlatformState):
+        (WebCore::GraphicsContext::drawRect):
+        (WebCore::GraphicsContext::drawLine):
+        (WebCore::GraphicsContext::drawEllipse):
+        (WebCore::GraphicsContext::strokeArc):
+        (WebCore::GraphicsContext::drawConvexPolygon):
+        (WebCore::GraphicsContext::fillPath):
+        (WebCore::GraphicsContext::strokePath):
+        (WebCore::GraphicsContext::fillRect):
+        (WebCore::GraphicsContext::fillRoundedRect):
+        (WebCore::GraphicsContext::beginPath):
+        (WebCore::GraphicsContext::addPath):
+        (WebCore::GraphicsContext::clip):
+        (WebCore::GraphicsContext::clipPath):
+        (WebCore::GraphicsContext::drawFocusRing):
+        (WebCore::GraphicsContext::drawLineForText):
+        (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
+        (WebCore::GraphicsContext::roundToDevicePixels):
+        (WebCore::GraphicsContext::setPlatformShadow):
+        (WebCore::GraphicsContext::clearPlatformShadow):
+        (WebCore::GraphicsContext::beginTransparencyLayer):
+        (WebCore::GraphicsContext::endTransparencyLayer):
+        (WebCore::GraphicsContext::clearRect):
+        (WebCore::GraphicsContext::strokeRect):
+        (WebCore::GraphicsContext::setLineCap):
+        (WebCore::GraphicsContext::setLineDash):
+        (WebCore::GraphicsContext::setLineJoin):
+        (WebCore::GraphicsContext::setMiterLimit):
+        (WebCore::GraphicsContext::setAlpha):
+        (WebCore::GraphicsContext::setCompositeOperation):
+        (WebCore::GraphicsContext::canvasClip):
+        (WebCore::GraphicsContext::clipOut):
+        (WebCore::GraphicsContext::scale):
+        (WebCore::GraphicsContext::rotate):
+        (WebCore::GraphicsContext::translate):
+        (WebCore::GraphicsContext::origin):
+        (WebCore::GraphicsContext::clipOutEllipseInRect):
+        (WebCore::GraphicsContext::clipToImageBuffer):
+        (WebCore::GraphicsContext::addInnerRoundedRectClip):
+        (WebCore::GraphicsContext::concatCTM):
+        (WebCore::GraphicsContext::setURLForRect):
+        (WebCore::GraphicsContext::setPlatformStrokeColor):
+        (WebCore::GraphicsContext::setPlatformStrokeStyle):
+        (WebCore::GraphicsContext::setPlatformStrokeThickness):
+        (WebCore::GraphicsContext::setPlatformFillColor):
+        (WebCore::GraphicsContext::setPlatformShouldAntialias):
+        (WebCore::GraphicsContext::setImageInterpolationQuality):
+        (WebCore::GraphicsContext::imageInterpolationQuality):
+        * platform/graphics/openvg/PainterOpenVG.cpp: Added.
+        (WebCore::isNonRotatedAffineTransformation):
+        (WebCore::toVGCapStyle):
+        (WebCore::toVGJoinStyle):
+        (WebCore::toVGFillRule):
+        (WebCore::colorToVGColor):
+        (WebCore::setVGSolidColor):
+        (WebCore::PlatformPainterState::PlatformPainterState):
+        (WebCore::PlatformPainterState::copyPaintState):
+        (WebCore::PlatformPainterState::applyState):
+        (WebCore::PlatformPainterState::applyBlending):
+        (WebCore::PlatformPainterState::applyTransformationMatrix):
+        (WebCore::PlatformPainterState::applyScissorRect):
+        (WebCore::PlatformPainterState::applyStrokeStyle):
+        (WebCore::PlatformPainterState::strokeDisabled):
+        (WebCore::PlatformPainterState::fillDisabled):
+        (WebCore::PainterOpenVG::PainterOpenVG):
+        (WebCore::PainterOpenVG::~PainterOpenVG):
+        (WebCore::PainterOpenVG::begin):
+        (WebCore::PainterOpenVG::end):
+        (WebCore::PainterOpenVG::destroyPainterStates):
+        (WebCore::PainterOpenVG::applyState):
+        (WebCore::PainterOpenVG::blitToSurface):
+        (WebCore::PainterOpenVG::transformationMatrix):
+        (WebCore::PainterOpenVG::concatTransformationMatrix):
+        (WebCore::PainterOpenVG::setTransformationMatrix):
+        (WebCore::PainterOpenVG::compositeOperation):
+        (WebCore::PainterOpenVG::setCompositeOperation):
+        (WebCore::PainterOpenVG::opacity):
+        (WebCore::PainterOpenVG::setOpacity):
+        (WebCore::PainterOpenVG::strokeThickness):
+        (WebCore::PainterOpenVG::setStrokeThickness):
+        (WebCore::PainterOpenVG::strokeStyle):
+        (WebCore::PainterOpenVG::setStrokeStyle):
+        (WebCore::PainterOpenVG::setLineDash):
+        (WebCore::PainterOpenVG::setLineCap):
+        (WebCore::PainterOpenVG::setLineJoin):
+        (WebCore::PainterOpenVG::setMiterLimit):
+        (WebCore::PainterOpenVG::strokeColor):
+        (WebCore::PainterOpenVG::setStrokeColor):
+        (WebCore::PainterOpenVG::fillColor):
+        (WebCore::PainterOpenVG::setFillColor):
+        (WebCore::PainterOpenVG::antialiasingEnabled):
+        (WebCore::PainterOpenVG::setAntialiasingEnabled):
+        (WebCore::PainterOpenVG::scale):
+        (WebCore::PainterOpenVG::rotate):
+        (WebCore::PainterOpenVG::translate):
+        (WebCore::PainterOpenVG::intersectScissorRect):
+        (WebCore::PainterOpenVG::intersectClipRect):
+        (WebCore::PainterOpenVG::drawRect):
+        (WebCore::PainterOpenVG::save):
+        (WebCore::PainterOpenVG::restore):
+        * platform/graphics/openvg/PainterOpenVG.h: Added.
+        (WebCore::PainterOpenVG::):
+        (WebCore::PainterOpenVG::surface):
+        * platform/graphics/openvg/SurfaceOpenVG.cpp:
+        (WebCore::SurfaceOpenVG::SurfaceOpenVG):
+        (WebCore::SurfaceOpenVG::~SurfaceOpenVG):
+        (WebCore::SurfaceOpenVG::makeCurrent):
+        (WebCore::SurfaceOpenVG::makeCompatibleCurrent):
+        (WebCore::SurfaceOpenVG::setActivePainter):
+        (WebCore::SurfaceOpenVG::activePainter):
+        * platform/graphics/openvg/SurfaceOpenVG.h:
+        (WebCore::SurfaceOpenVG::):
+        * platform/graphics/openvg/VGUtils.cpp: Added.
+        (WebCore::VGMatrix::VGMatrix):
+        (WebCore::VGMatrix::operator TransformationMatrix):
+        (WebCore::TransformationMatrix::operator VGMatrix):
+        (WebCore::VGRect::VGRect):
+        (WebCore::VGRect::operator FloatRect):
+        (WebCore::FloatRect::operator VGRect):
+        * platform/graphics/openvg/VGUtils.h:
+        (WebCore::VGMatrix::toVGfloat):
+        (WebCore::VGRect::toVGfloat):
+        * platform/graphics/transforms/TransformationMatrix.h:
+
 2010-01-29  Philippe Normand  <pnormand at igalia.com>
 
         Reviewed by Gustavo Noronha Silva.
diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h
index b4772c7..74a6293 100644
--- a/WebCore/platform/graphics/FloatRect.h
+++ b/WebCore/platform/graphics/FloatRect.h
@@ -61,6 +61,10 @@ struct SkRect;
 
 namespace WebCore {
 
+#if PLATFORM(OPENVG)
+class VGRect;
+#endif
+
 class IntRect;
 
 class FloatRect {
@@ -154,6 +158,10 @@ public:
     operator SkRect() const;
 #endif
 
+#if PLATFORM(OPENVG)
+    operator VGRect() const;
+#endif
+
 private:
     FloatPoint m_location;
     FloatSize m_size;
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index 8b412d6..1763911 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -506,7 +506,7 @@ void GraphicsContext::setPlatformTextDrawingMode(int mode)
 }
 #endif
 
-#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA) && !PLATFORM(HAIKU)
+#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !PLATFORM(SKIA) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG)
 void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle&)
 {
 }
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 443af3c..23d1290 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -41,6 +41,11 @@
 typedef struct CGContext PlatformGraphicsContext;
 #elif PLATFORM(CAIRO)
 typedef struct _cairo PlatformGraphicsContext;
+#elif PLATFORM(OPENVG)
+namespace WebCore {
+class SurfaceOpenVG;
+}
+typedef class WebCore::SurfaceOpenVG PlatformGraphicsContext;
 #elif PLATFORM(QT)
 QT_BEGIN_NAMESPACE
 class QPainter;
diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
new file mode 100644
index 0000000..b315a02
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -0,0 +1,579 @@
+/*
+ * 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 "GraphicsContext.h"
+
+#include "GraphicsContextPrivate.h"
+#include "NotImplemented.h"
+#include "PainterOpenVG.h"
+#include "SurfaceOpenVG.h"
+#include "TransformationMatrix.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+#include <wtf/UnusedParam.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(EGL)
+#include "EGLDisplayOpenVG.h"
+#include "EGLUtils.h"
+#include <egl.h>
+#endif
+
+namespace WebCore {
+
+// typedef'ing doesn't work, let's inherit from PainterOpenVG instead
+class GraphicsContextPlatformPrivate : public PainterOpenVG {
+public:
+    GraphicsContextPlatformPrivate(SurfaceOpenVG* surface)
+        : PainterOpenVG(surface)
+    {
+    }
+};
+
+GraphicsContext::GraphicsContext(SurfaceOpenVG* surface)
+    : m_common(createGraphicsContextPrivate())
+    , m_data(surface ? new GraphicsContextPlatformPrivate(surface) : 0)
+{
+    setPaintingDisabled(!surface);
+}
+
+GraphicsContext::~GraphicsContext()
+{
+    destroyGraphicsContextPrivate(m_common);
+    delete m_data;
+}
+
+PlatformGraphicsContext* GraphicsContext::platformContext() const
+{
+    if (paintingDisabled())
+        return 0;
+
+    return m_data->baseSurface();
+}
+
+TransformationMatrix GraphicsContext::getCTM() const
+{
+    if (paintingDisabled())
+        return TransformationMatrix();
+
+    return m_data->transformationMatrix();
+}
+
+void GraphicsContext::savePlatformState()
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->save();
+}
+
+void GraphicsContext::restorePlatformState()
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->restore();
+}
+
+void GraphicsContext::drawRect(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->drawRect(rect);
+}
+
+void GraphicsContext::drawLine(const IntPoint& from, const IntPoint& to)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(from);
+    UNUSED_PARAM(to);
+}
+
+/**
+ * Draw the largest ellipse that fits into the given rectangle.
+ */
+void GraphicsContext::drawEllipse(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+}
+
+void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+    UNUSED_PARAM(startAngle);
+    UNUSED_PARAM(angleSpan);
+}
+
+void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(numPoints);
+    UNUSED_PARAM(points);
+    UNUSED_PARAM(shouldAntialias);
+}
+
+void GraphicsContext::fillPath()
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+}
+
+void GraphicsContext::strokePath()
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->drawRect(rect, VG_FILL_PATH);
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    PainterOpenVG* painter = m_data;
+    Color oldColor = painter->fillColor();
+    painter->setFillColor(color);
+    painter->drawRect(rect, VG_FILL_PATH);
+    painter->setFillColor(oldColor);
+
+    UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+    UNUSED_PARAM(topLeft);
+    UNUSED_PARAM(topRight);
+    UNUSED_PARAM(bottomLeft);
+    UNUSED_PARAM(bottomRight);
+    UNUSED_PARAM(color);
+    UNUSED_PARAM(colorSpace);
+}
+
+void GraphicsContext::beginPath()
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+}
+
+void GraphicsContext::addPath(const Path& path)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+}
+
+void GraphicsContext::clip(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->intersectClipRect(rect);
+}
+
+void GraphicsContext::clipPath(WindRule clipRule)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(clipRule);
+}
+
+void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color)
+{
+    if (paintingDisabled())
+        return;
+
+    if (rects.isEmpty())
+        return;
+
+    // FIXME: We just unite all focus ring rects into one for now.
+    // We should outline the edge of the full region.
+    offset += (width - 1) / 2;
+    IntRect finalFocusRect;
+
+    for (unsigned i = 0; i < rects.size(); i++) {
+        IntRect focusRect = rects[i];
+        focusRect.inflate(offset);
+        finalFocusRect.unite(focusRect);
+    }
+
+    PainterOpenVG* painter = m_data;
+    StrokeStyle oldStyle = painter->strokeStyle();
+    Color oldStrokeColor = painter->strokeColor();
+    painter->setStrokeStyle(DashedStroke);
+    painter->setStrokeColor(color);
+    strokeRect(FloatRect(finalFocusRect), 1.f);
+    painter->setStrokeStyle(oldStyle);
+    painter->setStrokeColor(oldStrokeColor);
+}
+
+void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
+{
+    if (paintingDisabled())
+        return;
+
+    if (width <= 0)
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(origin);
+    UNUSED_PARAM(width);
+    UNUSED_PARAM(printing);
+}
+
+void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(origin);
+    UNUSED_PARAM(width);
+    UNUSED_PARAM(grammar);
+}
+
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return FloatRect();
+
+    return FloatRect(enclosingIntRect(m_data->transformationMatrix().mapRect(rect)));
+}
+
+void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(size);
+    UNUSED_PARAM(blur);
+    UNUSED_PARAM(color);
+    UNUSED_PARAM(colorSpace);
+}
+
+void GraphicsContext::clearPlatformShadow()
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+}
+
+void GraphicsContext::beginTransparencyLayer(float opacity)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(opacity);
+}
+
+void GraphicsContext::endTransparencyLayer()
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+}
+
+void GraphicsContext::clearRect(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    PainterOpenVG* painter = m_data;
+
+    CompositeOperator op = painter->compositeOperation();
+    painter->setCompositeOperation(CompositeClear);
+    painter->drawRect(rect, VG_FILL_PATH);
+    painter->setCompositeOperation(op);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->drawRect(rect, VG_STROKE_PATH);
+}
+
+void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
+{
+    if (paintingDisabled())
+        return;
+
+    PainterOpenVG* painter = m_data;
+
+    float oldThickness = painter->strokeThickness();
+    painter->setStrokeThickness(lineWidth);
+    painter->drawRect(rect, VG_STROKE_PATH);
+    painter->setStrokeThickness(oldThickness);
+}
+
+void GraphicsContext::setLineCap(LineCap lc)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setLineCap(lc);
+}
+
+void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setLineDash(dashes, dashOffset);
+}
+
+void GraphicsContext::setLineJoin(LineJoin lj)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setLineJoin(lj);
+}
+
+void GraphicsContext::setMiterLimit(float limit)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setMiterLimit(limit);
+}
+
+void GraphicsContext::setAlpha(float opacity)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setOpacity(opacity);
+}
+
+void GraphicsContext::setCompositeOperation(CompositeOperator op)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setCompositeOperation(op);
+}
+
+void GraphicsContext::clip(const Path& path)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(path);
+}
+
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
+void GraphicsContext::clipOut(const Path& path)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(path);
+}
+
+void GraphicsContext::scale(const FloatSize& scaleFactors)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->scale(scaleFactors);
+}
+
+void GraphicsContext::rotate(float radians)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->rotate(radians);
+}
+
+void GraphicsContext::translate(float dx, float dy)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->translate(dx, dy);
+}
+
+IntPoint GraphicsContext::origin()
+{
+    if (paintingDisabled())
+        return IntPoint();
+
+    TransformationMatrix matrix = m_data->transformationMatrix();
+    return IntPoint(roundf(matrix.m41()), roundf(matrix.m42()));
+}
+
+void GraphicsContext::clipOut(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+}
+
+void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+}
+
+void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+    UNUSED_PARAM(imageBuffer);
+}
+
+void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
+{
+    if (paintingDisabled())
+        return;
+
+    notImplemented();
+    UNUSED_PARAM(rect);
+    UNUSED_PARAM(thickness);
+}
+
+void GraphicsContext::concatCTM(const TransformationMatrix& transform)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->concatTransformationMatrix(transform);
+}
+
+void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
+{
+    notImplemented();
+    UNUSED_PARAM(link);
+    UNUSED_PARAM(destRect);
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setStrokeColor(color);
+
+    UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setStrokeStyle(strokeStyle);
+}
+
+void GraphicsContext::setPlatformStrokeThickness(float thickness)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setStrokeThickness(thickness);
+}
+
+void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setFillColor(color);
+
+    UNUSED_PARAM(colorSpace); // FIXME
+}
+
+void GraphicsContext::setPlatformShouldAntialias(bool enable)
+{
+    if (paintingDisabled())
+        return;
+
+    m_data->setAntialiasingEnabled(enable);
+}
+
+void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
+{
+    notImplemented();
+}
+
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+    notImplemented();
+    return InterpolationDefault;
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.cpp b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
new file mode 100644
index 0000000..b03d5f3
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.cpp
@@ -0,0 +1,745 @@
+/*
+ * 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 "PainterOpenVG.h"
+
+#include "Color.h"
+#include "DashArray.h"
+#include "FloatPoint.h"
+#include "FloatQuad.h"
+#include "FloatRect.h"
+#include "IntRect.h"
+#include "IntSize.h"
+#include "NotImplemented.h"
+#include "SurfaceOpenVG.h"
+#include "TransformationMatrix.h"
+#include "VGUtils.h"
+
+#if PLATFORM(EGL)
+#include "EGLUtils.h"
+#endif
+
+#include <vgu.h>
+
+#include <wtf/Assertions.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+static bool isNonRotatedAffineTransformation(const TransformationMatrix& matrix)
+{
+    return matrix.m12() <= FLT_EPSILON && matrix.m13() <= FLT_EPSILON && matrix.m14() <= FLT_EPSILON
+        && matrix.m21() <= FLT_EPSILON && matrix.m23() <= FLT_EPSILON && matrix.m24() <= FLT_EPSILON
+        && matrix.m31() <= FLT_EPSILON && matrix.m32() <= FLT_EPSILON && matrix.m34() <= FLT_EPSILON
+        && matrix.m44() >= 1 - FLT_EPSILON;
+}
+
+static VGCapStyle toVGCapStyle(LineCap lineCap)
+{
+    switch (lineCap) {
+    case RoundCap:
+        return VG_CAP_ROUND;
+    case SquareCap:
+        return VG_CAP_SQUARE;
+    case ButtCap:
+    default:
+        return VG_CAP_BUTT;
+    }
+}
+
+static VGJoinStyle toVGJoinStyle(LineJoin lineJoin)
+{
+    switch (lineJoin) {
+    case RoundJoin:
+        return VG_JOIN_ROUND;
+    case BevelJoin:
+        return VG_JOIN_BEVEL;
+    case MiterJoin:
+    default:
+        return VG_JOIN_MITER;
+    }
+}
+
+static VGFillRule toVGFillRule(WindRule fillRule)
+{
+    return fillRule == RULE_EVENODD ? VG_EVEN_ODD : VG_NON_ZERO;
+}
+
+static VGuint colorToVGColor(const Color& color)
+{
+    VGuint vgColor = color.red();
+    vgColor = (vgColor << 8) | color.green();
+    vgColor = (vgColor << 8) | color.blue();
+    vgColor = (vgColor << 8) | color.alpha();
+    return vgColor;
+}
+
+static void setVGSolidColor(VGPaintMode paintMode, const Color& color)
+{
+    VGPaint paint = vgCreatePaint();
+    vgSetParameteri(paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
+    vgSetColor(paint, colorToVGColor(color));
+    vgSetPaint(paint, paintMode);
+    vgDestroyPaint(paint);
+    ASSERT_VG_NO_ERROR();
+}
+
+
+struct PlatformPainterState {
+    TransformationMatrix surfaceTransformationMatrix;
+    CompositeOperator compositeOperation;
+    float opacity;
+
+    bool scissoringEnabled;
+    FloatRect scissorRect;
+
+    Color fillColor;
+    StrokeStyle strokeStyle;
+    Color strokeColor;
+    float strokeThickness;
+    LineCap strokeLineCap;
+    LineJoin strokeLineJoin;
+    float strokeMiterLimit;
+    DashArray strokeDashArray;
+    float strokeDashOffset;
+
+    bool antialiasingEnabled;
+
+    PlatformPainterState()
+        : compositeOperation(CompositeSourceOver)
+        , opacity(1.0)
+        , scissoringEnabled(false)
+        , fillColor(Color::black)
+        , strokeStyle(NoStroke)
+        , strokeThickness(0.0)
+        , strokeLineCap(ButtCap)
+        , strokeLineJoin(MiterJoin)
+        , strokeMiterLimit(4.0)
+        , strokeDashOffset(0.0)
+        , antialiasingEnabled(true)
+    {
+    }
+
+    PlatformPainterState(const PlatformPainterState& state)
+    {
+        surfaceTransformationMatrix = state.surfaceTransformationMatrix;
+
+        scissoringEnabled = state.scissoringEnabled;
+        scissorRect = state.scissorRect;
+        copyPaintState(&state);
+    }
+
+    void copyPaintState(const PlatformPainterState* other)
+    {
+        compositeOperation = other->compositeOperation;
+        opacity = other->opacity;
+
+        fillColor = other->fillColor;
+        strokeStyle = other->strokeStyle;
+        strokeColor = other->strokeColor;
+        strokeThickness = other->strokeThickness;
+        strokeLineCap = other->strokeLineCap;
+        strokeLineJoin = other->strokeLineJoin;
+        strokeMiterLimit = other->strokeMiterLimit;
+        strokeDashArray = other->strokeDashArray;
+        strokeDashOffset = other->strokeDashOffset;
+
+        antialiasingEnabled = other->antialiasingEnabled;
+    }
+
+    void applyState(PainterOpenVG* painter)
+    {
+        ASSERT(painter);
+
+        setVGSolidColor(VG_FILL_PATH, fillColor);
+        setVGSolidColor(VG_STROKE_PATH, strokeColor);
+
+        vgSetf(VG_STROKE_LINE_WIDTH, strokeThickness);
+        vgSeti(VG_STROKE_CAP_STYLE, toVGCapStyle(strokeLineCap));
+        vgSeti(VG_STROKE_JOIN_STYLE, toVGJoinStyle(strokeLineJoin));
+        vgSetf(VG_STROKE_MITER_LIMIT, strokeMiterLimit);
+
+        if (antialiasingEnabled)
+            vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_FASTER);
+        else
+            vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);
+
+        applyBlending(painter);
+        applyStrokeStyle();
+
+        applyTransformationMatrix(painter);
+        applyScissorRect();
+    }
+
+    void applyBlending(PainterOpenVG* painter)
+    {
+        VGBlendMode blendMode = VG_BLEND_SRC_OVER;
+
+        switch (compositeOperation) {
+        case CompositeClear: {
+            // Clear means "set to fully transparent regardless of SRC".
+            // We implement that by multiplying DST with white color
+            // (= no changes) and an alpha of 1.0 - opacity, so the destination
+            // pixels will be fully transparent when opacity == 1.0 and
+            // unchanged when opacity == 0.0.
+            blendMode = VG_BLEND_DST_IN;
+            const VGfloat values[] = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 - opacity };
+            vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+            vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+            ASSERT_VG_NO_ERROR();
+            break;
+        }
+        case CompositeCopy:
+            blendMode = VG_BLEND_SRC;
+            break;
+        case CompositeSourceOver:
+            blendMode = VG_BLEND_SRC_OVER;
+            break;
+        case CompositeSourceIn:
+            blendMode = VG_BLEND_SRC_IN;
+            break;
+        case CompositeSourceOut:
+            notImplemented();
+            break;
+        case CompositeSourceAtop:
+            notImplemented();
+            break;
+        case CompositeDestinationOver:
+            blendMode = VG_BLEND_DST_OVER;
+            break;
+        case CompositeDestinationIn:
+            blendMode = VG_BLEND_DST_IN;
+            break;
+        case CompositeDestinationOut:
+            notImplemented();
+            break;
+        case CompositeDestinationAtop:
+            notImplemented();
+            break;
+        case CompositeXOR:
+            notImplemented();
+            break;
+        case CompositePlusDarker:
+            blendMode = VG_BLEND_DARKEN;
+            break;
+        case CompositeHighlight:
+            notImplemented();
+            break;
+        case CompositePlusLighter:
+            blendMode = VG_BLEND_LIGHTEN;
+            break;
+        }
+
+        if (compositeOperation != CompositeClear) {
+            if (opacity >= (1.0 - FLT_EPSILON))
+                vgSeti(VG_COLOR_TRANSFORM, VG_FALSE);
+            else if (blendMode == VG_BLEND_SRC) {
+                blendMode = VG_BLEND_SRC_OVER;
+                VGfloat values[] = { 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, opacity };
+                vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+                vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+            } else {
+                VGfloat values[] = { 1.0, 1.0, 1.0, opacity, 0.0, 0.0, 0.0, 0.0 };
+                vgSetfv(VG_COLOR_TRANSFORM_VALUES, 8, values);
+                vgSeti(VG_COLOR_TRANSFORM, VG_TRUE);
+            }
+            ASSERT_VG_NO_ERROR();
+        }
+
+        vgSeti(VG_BLEND_MODE, blendMode);
+        ASSERT_VG_NO_ERROR();
+    }
+
+    void applyTransformationMatrix(PainterOpenVG* painter)
+    {
+        // There are *five* separate transforms that can be applied to OpenVG as of 1.1
+        // but it is not clear that we need to set them separately.  Instead we set them
+        // all right here and let this be a call to essentially set the world transformation!
+        VGMatrix vgMatrix(surfaceTransformationMatrix);
+        const VGfloat* vgFloatArray = vgMatrix.toVGfloat();
+
+        vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
+        vgLoadMatrix(vgFloatArray);
+        ASSERT_VG_NO_ERROR();
+
+        vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
+        vgLoadMatrix(vgFloatArray);
+        ASSERT_VG_NO_ERROR();
+
+#ifdef OPENVG_VERSION_1_1
+        vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
+        vgLoadMatrix(vgFloatArray);
+        ASSERT_VG_NO_ERROR();
+#endif
+    }
+
+    void applyScissorRect()
+    {
+        if (scissoringEnabled) {
+            vgSeti(VG_SCISSORING, VG_TRUE);
+            vgSetfv(VG_SCISSOR_RECTS, 4, VGRect(scissorRect).toVGfloat());
+        } else
+            vgSeti(VG_SCISSORING, VG_FALSE);
+
+        ASSERT_VG_NO_ERROR();
+    }
+
+    void applyStrokeStyle()
+    {
+        if (strokeStyle == DottedStroke) {
+            VGfloat vgFloatArray[2] = { 1.0, 1.0 };
+            vgSetfv(VG_STROKE_DASH_PATTERN, 2, vgFloatArray);
+            vgSetf(VG_STROKE_DASH_PHASE, 0.0);
+        } else if (strokeStyle == DashedStroke) {
+            if (!strokeDashArray.size()) {
+                VGfloat vgFloatArray[2] = { 4.0, 3.0 };
+                vgSetfv(VG_STROKE_DASH_PATTERN, 2, vgFloatArray);
+            } else {
+                Vector<VGfloat> vgFloatArray(strokeDashArray.size());
+                for (int i = 0; i < strokeDashArray.size(); ++i)
+                    vgFloatArray[i] = strokeDashArray[i];
+
+                vgSetfv(VG_STROKE_DASH_PATTERN, vgFloatArray.size(), vgFloatArray.data());
+            }
+            vgSetf(VG_STROKE_DASH_PHASE, strokeDashOffset);
+        } else {
+            vgSetfv(VG_STROKE_DASH_PATTERN, 0, 0);
+            vgSetf(VG_STROKE_DASH_PHASE, 0.0);
+        }
+
+        ASSERT_VG_NO_ERROR();
+    }
+
+    inline bool strokeDisabled() const
+    {
+        return (compositeOperation == CompositeSourceOver
+            && (strokeStyle == NoStroke || !strokeColor.alpha()));
+    }
+
+    inline bool fillDisabled() const
+    {
+        return (compositeOperation == CompositeSourceOver && !fillColor.alpha());
+    }
+};
+
+
+PainterOpenVG::PainterOpenVG()
+    : m_state(0)
+    , m_surface(0)
+{
+}
+
+PainterOpenVG::PainterOpenVG(SurfaceOpenVG* surface)
+    : m_state(0)
+    , m_surface(0)
+{
+    ASSERT(surface);
+    begin(surface);
+}
+
+PainterOpenVG::~PainterOpenVG()
+{
+    end();
+}
+
+void PainterOpenVG::begin(SurfaceOpenVG* surface)
+{
+    if (surface == m_surface)
+        return;
+
+    ASSERT(surface);
+    ASSERT(!m_state);
+
+    m_surface = surface;
+
+    m_stateStack.append(new PlatformPainterState());
+    m_state = m_stateStack.last();
+
+    m_surface->setActivePainter(this);
+    m_surface->makeCurrent();
+}
+
+void PainterOpenVG::end()
+{
+    if (!m_surface)
+        return;
+
+    m_surface->setActivePainter(0);
+    m_surface = 0;
+
+    destroyPainterStates();
+}
+
+void PainterOpenVG::destroyPainterStates()
+{
+    PlatformPainterState* state = 0;
+    while (!m_stateStack.isEmpty()) {
+        state = m_stateStack.last();
+        m_stateStack.removeLast();
+        delete state;
+    }
+    m_state = 0;
+}
+
+// Called by friend SurfaceOpenVG, private otherwise.
+void PainterOpenVG::applyState()
+{
+    ASSERT(m_state);
+    m_state->applyState(this);
+}
+
+/**
+ * Copy the current back buffer image onto the surface.
+ *
+ * Call this method when all painting operations have been completed,
+ * otherwise the surface won't visibly change.
+ */
+void PainterOpenVG::blitToSurface()
+{
+    ASSERT(m_state); // implies m_surface
+    m_surface->flush();
+}
+
+TransformationMatrix PainterOpenVG::transformationMatrix() const
+{
+    ASSERT(m_state);
+    return m_state->surfaceTransformationMatrix;
+}
+
+void PainterOpenVG::concatTransformationMatrix(const TransformationMatrix& matrix)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    // We do the multiplication ourself using WebCore's TransformationMatrix rather than
+    // offloading this to VG via vgMultMatrix to keep things simple and so we can maintain
+    // state ourselves.
+    m_state->surfaceTransformationMatrix.multLeft(matrix);
+    m_state->applyTransformationMatrix(this);
+}
+
+void PainterOpenVG::setTransformationMatrix(const TransformationMatrix& matrix)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->surfaceTransformationMatrix = matrix;
+    m_state->applyTransformationMatrix(this);
+}
+
+CompositeOperator PainterOpenVG::compositeOperation() const
+{
+    ASSERT(m_state);
+    return m_state->compositeOperation;
+}
+
+void PainterOpenVG::setCompositeOperation(CompositeOperator op)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->compositeOperation = op;
+    m_state->applyBlending(this);
+}
+
+float PainterOpenVG::opacity() const
+{
+    ASSERT(m_state);
+    return m_state->opacity;
+}
+
+void PainterOpenVG::setOpacity(float opacity)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->opacity = opacity;
+    m_state->applyBlending(this);
+}
+
+float PainterOpenVG::strokeThickness() const
+{
+    ASSERT(m_state);
+    return m_state->strokeThickness;
+}
+
+void PainterOpenVG::setStrokeThickness(float thickness)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeThickness = thickness;
+    vgSetf(VG_STROKE_LINE_WIDTH, thickness);
+    ASSERT_VG_NO_ERROR();
+}
+
+StrokeStyle PainterOpenVG::strokeStyle() const
+{
+    ASSERT(m_state);
+    return m_state->strokeStyle;
+}
+
+void PainterOpenVG::setStrokeStyle(const StrokeStyle& style)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeStyle = style;
+    m_state->applyStrokeStyle();
+}
+
+void PainterOpenVG::setLineDash(const DashArray& dashArray, float dashOffset)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeDashArray = dashArray;
+    m_state->strokeDashOffset = dashOffset;
+    m_state->applyStrokeStyle();
+}
+
+void PainterOpenVG::setLineCap(LineCap lineCap)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeLineCap = lineCap;
+    vgSeti(VG_STROKE_CAP_STYLE, toVGCapStyle(lineCap));
+    ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::setLineJoin(LineJoin lineJoin)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeLineJoin = lineJoin;
+    vgSeti(VG_STROKE_JOIN_STYLE, toVGJoinStyle(lineJoin));
+    ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::setMiterLimit(float miterLimit)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeMiterLimit = miterLimit;
+    vgSetf(VG_STROKE_MITER_LIMIT, miterLimit);
+    ASSERT_VG_NO_ERROR();
+}
+
+Color PainterOpenVG::strokeColor() const
+{
+    ASSERT(m_state);
+    return m_state->strokeColor;
+}
+
+void PainterOpenVG::setStrokeColor(const Color& color)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->strokeColor = color;
+    setVGSolidColor(VG_STROKE_PATH, color);
+}
+
+Color PainterOpenVG::fillColor() const
+{
+    ASSERT(m_state);
+    return m_state->fillColor;
+}
+
+void PainterOpenVG::setFillColor(const Color& color)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->fillColor = color;
+    setVGSolidColor(VG_FILL_PATH, color);
+}
+
+bool PainterOpenVG::antialiasingEnabled() const
+{
+    ASSERT(m_state);
+    return m_state->antialiasingEnabled;
+}
+
+void PainterOpenVG::setAntialiasingEnabled(bool enabled)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    m_state->antialiasingEnabled = enabled;
+
+    if (enabled)
+        vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_FASTER);
+    else
+        vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED);
+}
+
+void PainterOpenVG::scale(const FloatSize& scaleFactors)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    TransformationMatrix matrix = m_state->surfaceTransformationMatrix;
+    matrix.scaleNonUniform(scaleFactors.width(), scaleFactors.height());
+    setTransformationMatrix(matrix);
+}
+
+void PainterOpenVG::rotate(float radians)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    TransformationMatrix matrix = m_state->surfaceTransformationMatrix;
+    matrix.rotate(rad2deg(radians));
+    setTransformationMatrix(matrix);
+}
+
+void PainterOpenVG::translate(float dx, float dy)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    TransformationMatrix matrix = m_state->surfaceTransformationMatrix;
+    matrix.translate(dx, dy);
+    setTransformationMatrix(matrix);
+}
+
+void PainterOpenVG::intersectScissorRect(const FloatRect& rect)
+{
+    // Scissor rectangles are defined by float values, but e.g. painting
+    // something red to a float-clipped rectangle and then painting something
+    // white to the same rectangle will leave some red remnants as it is
+    // rendered to full pixels in between. Also, some OpenVG implementations
+    // are likely to clip to integer coordinates anyways because of the above
+    // effect. So considering the above (and confirming through tests) the
+    // visual result is better if we clip to the enclosing integer rectangle
+    // rather than the exact float rectangle for scissoring.
+    if (m_state->scissoringEnabled)
+        m_state->scissorRect.intersect(FloatRect(enclosingIntRect(rect)));
+    else {
+        m_state->scissoringEnabled = true;
+        m_state->scissorRect = FloatRect(enclosingIntRect(rect));
+    }
+
+    m_state->applyScissorRect();
+}
+
+void PainterOpenVG::intersectClipRect(const FloatRect& rect)
+{
+    ASSERT(m_state);
+    m_surface->makeCurrent();
+
+    if (m_state->surfaceTransformationMatrix.isIdentity()) {
+        // No transformation required, skip all the complex stuff.
+        intersectScissorRect(rect);
+        return;
+    }
+
+    // Check if the actual destination rectangle is still rectilinear (can be
+    // represented as FloatRect) so we could apply scissoring instead of
+    // (potentially more expensive) path clipping. Note that scissoring is not
+    // subject to transformations, so we need to do the transformation to
+    // surface coordinates by ourselves.
+    FloatQuad effectiveScissorQuad =
+        m_state->surfaceTransformationMatrix.mapQuad(FloatQuad(rect));
+
+    if (effectiveScissorQuad.isRectilinear())
+        intersectScissorRect(effectiveScissorQuad.boundingBox());
+    else {
+        // The transformed scissorRect cannot be represented as FloatRect
+        // anymore, so we need to perform masking instead. Not yet implemented.
+        notImplemented();
+    }
+}
+
+void PainterOpenVG::drawRect(const FloatRect& rect, VGbitfield specifiedPaintModes)
+{
+    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();
+
+    VGPath path = vgCreatePath(
+        VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F,
+        1.0 /* scale */, 0.0 /* bias */,
+        5 /* expected number of segments */,
+        5 /* expected number of total coordinates */,
+        VG_PATH_CAPABILITY_APPEND_TO
+    );
+    ASSERT_VG_NO_ERROR();
+
+    if (vguRect(path, rect.x(), rect.y(), rect.width(), rect.height()) == VGU_NO_ERROR) {
+        vgDrawPath(path, paintModes);
+        ASSERT_VG_NO_ERROR();
+    }
+
+    vgDestroyPath(path);
+    ASSERT_VG_NO_ERROR();
+}
+
+void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode)
+{
+    ASSERT(m_state);
+
+    // If the underlying context/surface was switched away by someone without
+    // telling us, it might not correspond to the one assigned to this painter.
+    // Switch back so we can save the state properly. (Should happen rarely.)
+    // Use DontSaveOrApplyPainterState mode in order to avoid recursion.
+    m_surface->makeCurrent(SurfaceOpenVG::DontSaveOrApplyPainterState);
+
+    if (saveMode == PainterOpenVG::CreateNewState) {
+        PlatformPainterState* state = new PlatformPainterState(*m_state);
+        m_stateStack.append(state);
+        m_state = m_stateStack.last();
+    } else { // if (saveMode == PainterOpenVG::CreateNewStateWithPaintStateOnly) {
+        PlatformPainterState* state = new PlatformPainterState();
+        state->copyPaintState(m_state);
+        m_stateStack.append(state);
+        m_state = m_stateStack.last();
+    }
+}
+
+void PainterOpenVG::restore()
+{
+    ASSERT(m_stateStack.size() >= 2);
+    m_surface->makeCurrent(SurfaceOpenVG::DontApplyPainterState);
+
+    PlatformPainterState* state = m_stateStack.last();
+    m_stateStack.removeLast();
+    delete state;
+
+    m_state = m_stateStack.last();
+    m_state->applyState(this);
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/PainterOpenVG.h b/WebCore/platform/graphics/openvg/PainterOpenVG.h
new file mode 100644
index 0000000..38cdfad
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/PainterOpenVG.h
@@ -0,0 +1,116 @@
+/*
+ * 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 PainterOpenVG_h
+#define PainterOpenVG_h
+
+#include "Color.h"
+#include "GraphicsContext.h"
+
+#include <openvg.h>
+
+#include <wtf/Noncopyable.h>
+#include <wtf/Platform.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FloatPoint;
+class FloatRect;
+class IntRect;
+class IntSize;
+class SurfaceOpenVG;
+class TransformationMatrix;
+
+struct PlatformPainterState;
+
+class PainterOpenVG : public Noncopyable {
+public:
+    friend class SurfaceOpenVG;
+    friend struct PlatformPainterState;
+
+    enum SaveMode {
+        CreateNewState,
+        CreateNewStateWithPaintStateOnly // internal usage only, do not use outside PainterOpenVG
+    };
+
+    PainterOpenVG();
+    PainterOpenVG(SurfaceOpenVG*);
+    ~PainterOpenVG();
+
+    void begin(SurfaceOpenVG*);
+    void end();
+
+    TransformationMatrix transformationMatrix() const;
+    void setTransformationMatrix(const TransformationMatrix&);
+    void concatTransformationMatrix(const TransformationMatrix&);
+
+    CompositeOperator compositeOperation() const;
+    void setCompositeOperation(CompositeOperator);
+    float opacity() const;
+    void setOpacity(float);
+
+    float strokeThickness() const;
+    void setStrokeThickness(float);
+    StrokeStyle strokeStyle() const;
+    void setStrokeStyle(const StrokeStyle&);
+
+    void setLineDash(const DashArray&, float dashOffset);
+    void setLineCap(LineCap);
+    void setLineJoin(LineJoin);
+    void setMiterLimit(float);
+
+    Color strokeColor() const;
+    void setStrokeColor(const Color&);
+
+    Color fillColor() const;
+    void setFillColor(const Color&);
+
+    bool antialiasingEnabled() const;
+    void setAntialiasingEnabled(bool);
+
+    void drawRect(const FloatRect&, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
+
+    void scale(const FloatSize& scaleFactors);
+    void rotate(float radians);
+    void translate(float dx, float dy);
+
+    void intersectClipRect(const FloatRect&);
+
+    void save(PainterOpenVG::SaveMode saveMode = CreateNewState);
+    void restore();
+
+    SurfaceOpenVG* surface() { return m_surface; }
+    void blitToSurface();
+
+private:
+    void destroyPainterStates();
+    void applyState();
+
+    void intersectScissorRect(const FloatRect&);
+
+private:
+    Vector<PlatformPainterState*> m_stateStack;
+    PlatformPainterState* m_state;
+    SurfaceOpenVG* m_surface;
+};
+
+}
+
+#endif
diff --git a/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp b/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
index dcb2709..9539f2c 100644
--- a/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/SurfaceOpenVG.cpp
@@ -29,10 +29,11 @@
 #endif
 
 #include <wtf/Assertions.h>
-#include <wtf/UnusedParam.h>
 
 namespace WebCore {
 
+PainterOpenVG* SurfaceOpenVG::s_currentPainter = 0;
+
 SurfaceOpenVG* SurfaceOpenVG::currentSurface()
 {
 #if PLATFORM(EGL)
@@ -45,7 +46,8 @@ SurfaceOpenVG* SurfaceOpenVG::currentSurface()
 
 #if PLATFORM(EGL)
 SurfaceOpenVG::SurfaceOpenVG(const IntSize& size, const EGLDisplay& display, EGLConfig* confPtr, EGLint* errorCode)
-    : m_eglDisplay(display)
+    : m_activePainter(0)
+    , m_eglDisplay(display)
     , m_eglSurface(EGL_NO_SURFACE)
     , m_eglContext(EGL_NO_CONTEXT)
 {
@@ -63,7 +65,8 @@ SurfaceOpenVG::SurfaceOpenVG(const IntSize& size, const EGLDisplay& display, EGL
 }
 
 SurfaceOpenVG::SurfaceOpenVG(EGLNativeWindowType window, const EGLDisplay& display, EGLConfig* confPtr)
-    : m_eglDisplay(display)
+    : m_activePainter(0)
+    , m_eglDisplay(display)
     , m_eglSurface(EGL_NO_SURFACE)
     , m_eglContext(EGL_NO_CONTEXT)
 {
@@ -84,7 +87,8 @@ SurfaceOpenVG::SurfaceOpenVG(EGLNativeWindowType window, const EGLDisplay& displ
 // arguments and EGLDisplayOpenVG basically implements the constructor
 // by itself.
 SurfaceOpenVG::SurfaceOpenVG()
-    : m_eglDisplay(EGL_NO_DISPLAY)
+    : m_activePainter(0)
+    , m_eglDisplay(EGL_NO_DISPLAY)
     , m_eglSurface(EGL_NO_SURFACE)
     , m_eglContext(EGL_NO_CONTEXT)
 {
@@ -96,6 +100,9 @@ SurfaceOpenVG::~SurfaceOpenVG()
     if (!isValid())
         return;
 
+    if (m_activePainter && this == m_activePainter->baseSurface())
+        m_activePainter->end();
+
 #if PLATFORM(EGL)
     EGLDisplayOpenVG::forDisplay(m_eglDisplay)->destroySurface(m_eglSurface);
     EGLDisplayOpenVG::unregisterPlatformSurface(this);
@@ -168,10 +175,15 @@ void SurfaceOpenVG::makeCurrent(MakeCurrentMode mode)
     if (currentSurface != m_eglSurface) {
         eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
         ASSERT_EGL_NO_ERROR();
+        s_currentPainter = 0;
     }
-#else
-    UNUSED_PARAM(mode);
 #endif
+
+    if (m_activePainter && mode == ApplyPainterStateOnSurfaceSwitch
+        && s_currentPainter != m_activePainter) {
+        m_activePainter->applyState();
+        s_currentPainter = m_activePainter;
+    }
 }
 
 void SurfaceOpenVG::makeCompatibleCurrent()
@@ -184,10 +196,15 @@ void SurfaceOpenVG::makeCompatibleCurrent()
     EGLSurface currentSurface = eglGetCurrentSurface(EGL_DRAW);
     ASSERT_EGL_NO_ERROR();
 
-    if (currentSurface != m_eglSurface
-        && !EGLDisplayOpenVG::forDisplay(m_eglDisplay)->surfacesCompatible(currentSurface, m_eglSurface)) {
+    if (currentSurface == m_eglSurface) {
+        if (m_activePainter && s_currentPainter != m_activePainter) {
+            m_activePainter->applyState();
+            s_currentPainter = m_activePainter;
+        }
+    } else if (!EGLDisplayOpenVG::forDisplay(m_eglDisplay)->surfacesCompatible(currentSurface, m_eglSurface)) {
         eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
         ASSERT_EGL_NO_ERROR();
+        s_currentPainter = 0;
     }
     // else: surfaces compatible, no need to switch contexts
 #endif
@@ -203,4 +220,24 @@ void SurfaceOpenVG::flush()
 #endif
 }
 
+void SurfaceOpenVG::setActivePainter(PainterOpenVG* painter)
+{
+    ASSERT(isValid());
+
+    // If painter is non-zero, we want to make sure there was no previous painter set.
+    ASSERT(!painter || !m_activePainter);
+
+    // Make sure a disabled painter isn't marked as global current painter anymore.
+    if (!painter && s_currentPainter == m_activePainter)
+        s_currentPainter = 0;
+
+    m_activePainter = painter;
+}
+
+PainterOpenVG* SurfaceOpenVG::activePainter()
+{
+    ASSERT(isValid());
+    return m_activePainter;
+}
+
 }
diff --git a/WebCore/platform/graphics/openvg/SurfaceOpenVG.h b/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
index 751c143..dc288dd 100644
--- a/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
+++ b/WebCore/platform/graphics/openvg/SurfaceOpenVG.h
@@ -32,6 +32,7 @@ namespace WebCore {
 #if PLATFORM(EGL)
 class EGLDisplayOpenVG;
 #endif
+class PainterOpenVG;
 class IntSize;
 
 /**
@@ -44,6 +45,11 @@ class IntSize;
  */
 class SurfaceOpenVG : public Noncopyable {
 public:
+    enum MakeCurrentMode {
+        ApplyPainterStateOnSurfaceSwitch,
+        DontApplyPainterState,
+    };
+
     static SurfaceOpenVG* currentSurface();
 
 #if PLATFORM(EGL)
@@ -90,7 +96,7 @@ public:
      * Make the associated GL/EGL context the current one, so that subsequent
      * OpenVG commands apply to it.
      */
-    void makeCurrent();
+    void makeCurrent(MakeCurrentMode mode = ApplyPainterStateOnSurfaceSwitch);
 
     /**
      * Make a surface/context combination current that is "compatible"
@@ -110,7 +116,13 @@ public:
      */
     void flush();
 
+    void setActivePainter(PainterOpenVG*);
+    PainterOpenVG* activePainter();
+
 private:
+    PainterOpenVG* m_activePainter;
+    static PainterOpenVG* s_currentPainter; // global currently active painter
+
 #if PLATFORM(EGL)
     SurfaceOpenVG(); // for EGLDisplayOpenVG
 
diff --git a/WebCore/platform/graphics/openvg/VGUtils.cpp b/WebCore/platform/graphics/openvg/VGUtils.cpp
new file mode 100644
index 0000000..72ba5b2
--- /dev/null
+++ b/WebCore/platform/graphics/openvg/VGUtils.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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 "VGUtils.h"
+
+#include "FloatRect.h"
+#include "TransformationMatrix.h"
+
+namespace WebCore {
+
+VGMatrix::VGMatrix(const VGfloat data[9])
+{
+    m_data[0] = data[0];
+    m_data[1] = data[1];
+    m_data[2] = data[2];
+    m_data[3] = data[3];
+    m_data[4] = data[4];
+    m_data[5] = data[5];
+    m_data[6] = data[6];
+    m_data[7] = data[7];
+    m_data[8] = data[8];
+}
+
+VGMatrix::VGMatrix(const TransformationMatrix& matrix)
+{
+    m_data[0] = matrix.m11();
+    m_data[1] = matrix.m12();
+    m_data[2] = matrix.m14();
+    m_data[3] = matrix.m21();
+    m_data[4] = matrix.m22();
+    m_data[5] = matrix.m24();
+    m_data[6] = matrix.m41();
+    m_data[7] = matrix.m42();
+    m_data[8] = matrix.m44();
+}
+
+VGMatrix::operator TransformationMatrix() const
+{
+    TransformationMatrix matrix;
+    matrix.setM11(m_data[0]);
+    matrix.setM12(m_data[1]);
+    matrix.setM14(m_data[2]);
+    matrix.setM21(m_data[3]);
+    matrix.setM22(m_data[4]);
+    matrix.setM24(m_data[5]);
+    matrix.setM41(m_data[6]);
+    matrix.setM42(m_data[7]);
+    matrix.setM44(m_data[8]);
+    return matrix;
+}
+
+TransformationMatrix::operator VGMatrix() const
+{
+    return VGMatrix(*this);
+}
+
+VGRect::VGRect(const VGfloat data[4])
+{
+    m_data[0] = data[0];
+    m_data[1] = data[1];
+    m_data[2] = data[2];
+    m_data[3] = data[3];
+}
+
+VGRect::VGRect(const FloatRect& rect)
+{
+    m_data[0] = rect.x();
+    m_data[1] = rect.y();
+    m_data[2] = rect.width();
+    m_data[3] = rect.height();
+}
+
+VGRect::operator FloatRect() const
+{
+    return FloatRect(m_data[0], m_data[1], m_data[2], m_data[3]);
+}
+
+FloatRect::operator VGRect() const
+{
+    return VGRect(*this);
+}
+
+}
diff --git a/WebCore/platform/graphics/openvg/VGUtils.h b/WebCore/platform/graphics/openvg/VGUtils.h
index 8276d71..083c15a 100644
--- a/WebCore/platform/graphics/openvg/VGUtils.h
+++ b/WebCore/platform/graphics/openvg/VGUtils.h
@@ -56,4 +56,32 @@ static inline const char* toVGErrorConstant(VGErrorCode error)
 } while (0)
 #endif
 
+
+namespace WebCore {
+
+class FloatRect;
+class TransformationMatrix;
+
+class VGMatrix {
+public:
+    VGMatrix(const VGfloat data[9]);
+    VGMatrix(const TransformationMatrix&);
+    const VGfloat* toVGfloat() const { return m_data; }
+    operator TransformationMatrix() const;
+private:
+    VGfloat m_data[9];
+};
+
+class VGRect {
+public:
+    VGRect(const VGfloat data[4]);
+    VGRect(const FloatRect&);
+    const VGfloat* toVGfloat() const { return m_data; }
+    operator FloatRect() const;
+private:
+    VGfloat m_data[4];
+};
+
+}
+
 #endif
diff --git a/WebCore/platform/graphics/transforms/TransformationMatrix.h b/WebCore/platform/graphics/transforms/TransformationMatrix.h
index cc8c8fa..9e724d5 100644
--- a/WebCore/platform/graphics/transforms/TransformationMatrix.h
+++ b/WebCore/platform/graphics/transforms/TransformationMatrix.h
@@ -35,6 +35,8 @@
 #include <CoreGraphics/CGAffineTransform.h>
 #elif PLATFORM(CAIRO)
 #include <cairo.h>
+#elif PLATFORM(OPENVG)
+#include "VGUtils.h"
 #elif PLATFORM(QT)
 #include <QTransform>
 #elif PLATFORM(SKIA)
@@ -307,6 +309,8 @@ public:
     operator CGAffineTransform() const;
 #elif PLATFORM(CAIRO)
     operator cairo_matrix_t() const;
+#elif PLATFORM(OPENVG)
+    operator VGMatrix() const;
 #elif PLATFORM(QT)
     operator QTransform() const;
 #elif PLATFORM(SKIA)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list