Implement Canvas element in the Qt port.
authorzack <zack@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 May 2007 13:53:52 +0000 (13:53 +0000)
committerzack <zack@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 May 2007 13:53:52 +0000 (13:53 +0000)
Implementation of Context2D was completely missing in the
Qt port. This commit adds bigger parts of it.
r=Lars

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@21517 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/html/CanvasRenderingContext2D.cpp
WebCore/html/CanvasStyle.cpp
WebCore/html/HTMLCanvasElement.cpp
WebCore/html/HTMLCanvasElement.h

index c011fd54658d51c202cfde4af152a95210336f35..9cc07724ae4119799b20554a224d9323d1ecd727 100644 (file)
@@ -1,3 +1,15 @@
+2007-05-16  Zack Rusin  <zrusin@trolltech.com>
+
+        Reviewed by Lars.
+
+        Implement bigger parts of the Canvas element in the
+        Qt port. Gradients and patterns are missing.
+
+        * WebCore/html/CanvasRenderingContext2D.cpp:
+        * WebCore/html/CanvasStyle.cpp:
+        * WebCore/html/HTMLCanvasElement.cpp:
+        * WebCore/html/HTMLCanvasElement:
+
 2007-05-16  Zack Rusin  <zrusin@trolltech.com>
 
         Reviewed by Lars
index da2d6b17da6ff9d98679e00878c7d22e523a6b98..06c58ded443b47195179a0108c813454908a123d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2007 Trolltech ASA
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "cssparser.h"
 #include <wtf/MathExtras.h>
 
+#if PLATFORM(QT)
+#include <QPainter>
+#include <QPixmap>
+#include <QPainterPath>
+#endif
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -445,6 +452,17 @@ void CanvasRenderingContext2D::fill()
             applyFillPattern();
         CGContextFillPath(c->platformContext());
     }
+#elif PLATFORM(QT)
+    QPainterPath* path = state().m_path.platformPath();
+    QPainter* p = static_cast<QPainter*>(c->platformContext());
+    willDraw(path->controlPointRect());
+    if (state().m_fillStyle->gradient()) {
+        fprintf(stderr, "FIXME: CanvasRenderingContext2D::fill\n");
+    } else {
+        if (state().m_fillStyle->pattern())
+            applyFillPattern();
+        p->fillPath(*path, p->brush());
+    }
 #endif
 }
 
@@ -476,6 +494,17 @@ void CanvasRenderingContext2D::stroke()
             applyStrokePattern();
         CGContextStrokePath(c->platformContext());
     }
+#elif PLATFORM(QT)
+    QPainterPath* path = state().m_path.platformPath();
+    QPainter* p = static_cast<QPainter*>(c->platformContext());
+    willDraw(path->controlPointRect());
+    if (state().m_strokeStyle->gradient()) {
+        fprintf(stderr, "FIXME: CanvasRenderingContext2D::stroke\n");
+    } else {
+        if (state().m_strokeStyle->pattern())
+            applyStrokePattern();
+        p->strokePath(*path, p->pen());
+    }
 #endif
 
     if (m_canvas && m_canvas->document()->frame() && m_canvas->document()->frame()->settings()->usesDashboardBackwardCompatibilityMode())
@@ -534,6 +563,17 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
             applyFillPattern();
         CGContextFillRect(c->platformContext(), rect);
     }
+#elif PLATFORM(QT)
+    QRectF rect(x, y, width, height);
+    willDraw(rect);
+    QPainter* p = static_cast<QPainter*>(c->platformContext());
+    if (state().m_fillStyle->gradient()) {
+        fprintf(stderr, "FIXME: Canvas gradients\n");
+    } else {
+        if (state().m_fillStyle->pattern())
+            applyFillPattern();
+        p->fillRect(rect, p->brush());
+    }
 #endif
 }
 
@@ -852,6 +892,13 @@ void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatR
     }
 
     CGImageRelease(platformImage);
+#elif PLATFORM(QT)
+    QPixmap px = canvas->createPlatformImage();
+    if (px.isNull())
+        return;
+    willDraw(dstRect);
+    QPainter* painter = static_cast<QPainter*>(c->platformContext());
+    painter->drawPixmap(dstRect, px, srcRect);
 #endif
 }
 
@@ -926,9 +973,10 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElem
     PassRefPtr<CanvasPattern> pattern = new CanvasPattern(image, repeatX, repeatY);
     CGImageRelease(image);
     return pattern;
-#else
-    return 0;
+#elif PLATFORM(QT)
+    fprintf(stderr, "FIXME: CanvasRenderingContext2D::createPattern patterns not implemented\n");
 #endif
+    return 0;
 }
 
 void CanvasRenderingContext2D::willDraw(const FloatRect& r)
@@ -975,6 +1023,8 @@ void CanvasRenderingContext2D::applyStrokePattern()
     CGPatternRelease(platformPattern);
 
     state().m_strokeStylePatternTransform = m;
+#elif PLATFORM(QT)
+    fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyStrokePattern\n");
 #endif
     state().m_appliedStrokePattern = true;
 }
@@ -1009,6 +1059,8 @@ void CanvasRenderingContext2D::applyFillPattern()
     CGPatternRelease(platformPattern);
 
     state().m_fillStylePatternTransform = m;
+#elif PLATFORM(QT)
+    fprintf(stderr, "FIXME: CanvasRenderingContext2D::applyStrokePattern\n");
 #endif
     state().m_appliedFillPattern = true;
 }
index 92b917f1ec77f091e4dc6a619d8418ded988825a..acb8e85c9ef444f090e4655b647810183af35bc5 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2007 Trolltech ASA
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "cssparser.h"
 #include <wtf/PassRefPtr.h>
 
+#if PLATFORM(QT)
+#include <QPainter>
+#include <QBrush>
+#include <QPen>
+#include <QColor>
+#endif
+
 namespace WebCore {
 
 CanvasStyle::CanvasStyle(const String& color)
@@ -78,6 +86,9 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
 {
     if (!context)
         return;
+#if PLATFORM(QT)
+    QPainter* p = static_cast<QPainter*>(context->platformContext());
+#endif
     switch (m_type) {
         case ColorString: {
             RGBA32 color = CSSParser::parseColor(m_color);
@@ -88,6 +99,8 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
                 ((color >> 8) & 0xFF) / 255.0,
                 (color & 0xFF) / 255.0,
                 ((color >> 24) & 0xFF) / 255.0);
+#elif PLATFORM(QT)
+            p->setPen(QPen(QColor(QRgb(color))));
 #endif
             break;
         }
@@ -100,27 +113,45 @@ void CanvasStyle::applyStrokeColor(GraphicsContext* context)
                 ((color >> 8) & 0xFF) / 255.0,
                 (color & 0xFF) / 255.0,
                 m_alpha);
+#elif PLATFORM(QT)
+            QColor clr = QColor(QRgb(color));
+            clr.setAlphaF(m_alpha);
+            p->setPen(clr);
 #endif
             break;
         }
-        case GrayLevel:
+        case GrayLevel: {
             // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
             CGContextSetGrayStrokeColor(context->platformContext(), m_grayLevel, m_alpha);
+#elif PLATFORM(QT)
+            QColor clr;
+            clr.setRgbF(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha);
+            p->setPen(clr);
 #endif
             break;
-        case RGBA:
+        }
+        case RGBA: {
             // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
             CGContextSetRGBStrokeColor(context->platformContext(), m_red, m_green, m_blue, m_alpha);
+#elif PLATFORM(QT)
+            QColor clr; clr.setRgbF(m_red, m_green, m_blue, m_alpha);
+            p->setPen(clr);
 #endif
             break;
-        case CMYKA:
+        }
+        case CMYKA: {
             // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
             CGContextSetCMYKStrokeColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
+#elif PLATFORM(QT)
+            QColor clr;
+            clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
+            p->setPen(clr);
 #endif
             break;
+        }
         case Gradient:
         case ImagePattern:
             break;
@@ -131,6 +162,9 @@ void CanvasStyle::applyFillColor(GraphicsContext* context)
 {
     if (!context)
         return;
+#if PLATFORM(QT)
+    QPainter* p = static_cast<QPainter*>(context->platformContext());
+#endif
     switch (m_type) {
         case ColorString: {
             RGBA32 color = CSSParser::parseColor(m_color);
@@ -141,6 +175,8 @@ void CanvasStyle::applyFillColor(GraphicsContext* context)
                 ((color >> 8) & 0xFF) / 255.0,
                 (color & 0xFF) / 255.0,
                 ((color >> 24) & 0xFF) / 255.0);
+#elif PLATFORM(QT)
+            p->setBrush(QColor(QRgb(color)));
 #endif
             break;
         }
@@ -153,27 +189,44 @@ void CanvasStyle::applyFillColor(GraphicsContext* context)
                 ((color >> 8) & 0xFF) / 255.0,
                 (color & 0xFF) / 255.0,
                 m_alpha);
+#elif PLATFORM(QT)
+            QColor clr = QColor(QRgb(color));
+            clr.setAlphaF(m_alpha);
+            p->setBrush(clr);
 #endif
             break;
         }
-        case GrayLevel:
+        case GrayLevel: {
             // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
             CGContextSetGrayFillColor(context->platformContext(), m_grayLevel, m_alpha);
+#elif PLATFORM(QT)
+            QColor clr; clr.setRgbF(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha);
+            p->setBrush(clr);
 #endif
             break;
-        case RGBA:
+        }
+        case RGBA: {
             // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
             CGContextSetRGBFillColor(context->platformContext(), m_red, m_green, m_blue, m_alpha);
+#elif PLATFORM(QT)
+            QColor clr; clr.setRgbF(m_red, m_green, m_blue, m_alpha);
+            p->setBrush(clr);
 #endif
             break;
-        case CMYKA:
+        }
+        case CMYKA: {
             // FIXME: Do this through platform-independent GraphicsContext API.
 #if PLATFORM(CG)
             CGContextSetCMYKFillColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
+#elif PLATFORM(QT)
+            QColor clr;
+            clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
+            p->setBrush(clr);
 #endif
             break;
+        }
         case Gradient:
         case ImagePattern:
             break;
index 31926763bd6deace23734ef040d5b532d10cf8fc..2842958cae8319100de4becef0d288825888a8fa 100644 (file)
 #include "Page.h"
 #include "RenderHTMLCanvas.h"
 #include "Settings.h"
+
+#if PLATFORM(QT)
+#include <QPainter>
+#include <QPixmap>
+#endif
+
 #include <math.h>
 
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -58,6 +65,9 @@ HTMLCanvasElement::HTMLCanvasElement(Document* doc)
     , m_size(defaultWidth, defaultHeight)
     , m_createdDrawingContext(false)
     , m_data(0)
+#if PLATFORM(QT)
+    , m_painter(0)
+#endif
     , m_drawingContext(0)
 {
 }
@@ -66,7 +76,12 @@ HTMLCanvasElement::~HTMLCanvasElement()
 {
     if (m_2DContext)
         m_2DContext->detachCanvas();
+#if PLATFORM(CG)
     fastFree(m_data);
+#elif PLATFORM(QT)
+    delete m_painter;
+    delete m_data;
+#endif
     delete m_drawingContext;
 }
 
@@ -150,7 +165,12 @@ void HTMLCanvasElement::reset()
 
     bool hadDrawingContext = m_createdDrawingContext;
     m_createdDrawingContext = false;
+#if PLATFORM(QT)
     fastFree(m_data);
+#elif PLATFORM(QT)
+    delete m_painter;
+    delete m_data;
+#endif
     m_data = 0;
     delete m_drawingContext;
     m_drawingContext = 0;
@@ -173,6 +193,12 @@ void HTMLCanvasElement::paint(GraphicsContext* p, const IntRect& r)
         CGContextDrawImage(p->platformContext(), p->roundToDevicePixels(r), image);
         CGImageRelease(image);
     }
+#elif PLATFORM(QT)
+    if (m_data) {
+        if (m_painter->isActive())
+            m_painter->end();
+        static_cast<QPainter*>(p->platformContext())->drawPixmap(r, *m_data);
+    }
 #endif
 }
 
@@ -198,7 +224,11 @@ void HTMLCanvasElement::createDrawingContext() const
     size_t bytesPerRow = w * 4;
     if (bytesPerRow / 4 != w) // check for overflow
         return;
+#if PLATFORM(CG)
     m_data = fastCalloc(h, bytesPerRow);
+#elif PLATFORM(QT)
+    m_data = new QPixmap(w, h);
+#endif
     if (!m_data)
         return;
 #if PLATFORM(CG)
@@ -208,6 +238,10 @@ void HTMLCanvasElement::createDrawingContext() const
     CGColorSpaceRelease(colorSpace);
     m_drawingContext = new GraphicsContext(bitmapContext);
     CGContextRelease(bitmapContext);
+#elif PLATFORM(QT)
+    m_data->fill(Qt::white);
+    m_painter = new QPainter(m_data);
+    m_drawingContext = new GraphicsContext(m_painter);
 #endif
 }
 
@@ -234,6 +268,13 @@ CGImageRef HTMLCanvasElement::createPlatformImage() const
     
     return CGBitmapContextCreateImage(contextRef);
 }
+#elif PLATFORM(QT)
+QPixmap HTMLCanvasElement::createPlatformImage() const
+{
+    if (m_data)
+        return *m_data;
+    return QPixmap();
+}
 
 #endif
 
index 4d4b63ea434dcddc8e3f8d5ca45ae6094d623f22..8bb722bd787b4f3c064593bb5693529bc42c320b 100644 (file)
@@ -33,6 +33,9 @@
 // FIXME: CG-specific parts need to move to the platform directory.
 typedef struct CGContext* CGContextRef;
 typedef struct CGImage* CGImageRef;
+#elif PLATFORM(QT)
+class QPixmap;
+class QPainter;
 #endif
 
 namespace WebCore {
@@ -70,6 +73,8 @@ public:
 
 #if PLATFORM(CG)
     CGImageRef createPlatformImage() const;
+#elif PLATFORM(QT)
+    QPixmap createPlatformImage() const;
 #endif
 
 private:
@@ -85,7 +90,12 @@ private:
     // if we ever drew any images outside the domain, so we can disable toDataURL.
 
     mutable bool m_createdDrawingContext;
+#if PLATFORM(CG)
     mutable void* m_data;
+#elif PLATFORM(QT)
+    mutable QPixmap* m_data;
+    mutable QPainter* m_painter;
+#endif
     mutable GraphicsContext* m_drawingContext;
 };