[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

rjw rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:41:59 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 8a2b244cbdae240a783e5730e6ef816f1088add2
Author: rjw <rjw at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed May 26 23:58:25 2004 +0000

    	Part 2 of the new <CANVAS> tag implementation.  This adds the
    	basic machinery and draw operations for the <CANVAS> tag.  Pretty cool.
    
            function drawLine() {
    	    var canvas1 = document.getElementById ("canvas1");
    	    var context = canvas1.getContext("context-2d");
    
    	    context.setStrokeColor ("red");
    	    context.setLineWidth (10);
    	    context.beginPath();
    	    context.moveToPoint (0,0);
    	    context.addLineToPoint (400,400);
    	    context.strokePath();
            }
    
            ...
    
            <canvas id="canvas1" width="400" height="400">
    
    
            Currently supported operations on the 2D context are:
    
            Save, Restore,
            Scale, Rotate, Translate,
            BeginPath, ClosePath,
            SetStrokeColor, SetFillColor, SetLineWidth, SetLineCap, SetLineJoin, SetMiterLimit,
            FillPath, StrokePath,
            MoveToPoint, AddLineToPoint, AddQuadraticCurveToPoint, AddBezierCurveToPoint,
            ClearRect
    
    
    	More to come.
    
            Reviewed by Dave.
    
            * khtml/ecma/kjs_html.cpp:
            (KJS::HTMLElementFunction::tryCall):
            (KJS::Context2DFunction::tryCall):
            (Context2D::tryGet):
            (Context2D::getValueProperty):
            (Context2D::tryPut):
            (Context2D::putValue):
            (Context2D::Context2D):
            (Context2D::~Context2D):
            * khtml/ecma/kjs_html.h:
            (KJS::Context2D::toBoolean):
            (KJS::Context2D::classInfo):
            (KJS::Context2D::):
            * khtml/ecma/kjs_html.lut.h:
            (KJS::):
            * khtml/html/html_canvasimpl.cpp:
            (HTMLCanvasElementImpl::HTMLCanvasElementImpl):
            * khtml/html/htmlparser.cpp:
            (KHTMLParser::getElement):
            * khtml/rendering/render_canvasimage.cpp:
            (RenderCanvasImage::RenderCanvasImage):
            (RenderCanvasImage::~RenderCanvasImage):
            (RenderCanvasImage::createDrawingContext):
            (RenderCanvasImage::drawingContext):
            (RenderCanvasImage::setNeedsImageUpdate):
            (RenderCanvasImage::updateDrawnImage):
            (RenderCanvasImage::drawnImage):
            (RenderCanvasImage::paint):
            (RenderCanvasImage::layout):
            * khtml/rendering/render_canvasimage.h:
            * khtml/rendering/render_image.cpp:
            (RenderImage::paint):
            * khtml/rendering/render_image.h:
            * khtml/rendering/render_replaced.cpp:
            (RenderReplaced::shouldPaint):
            (RenderWidget::paint):
            * kwq/KWQPainter.h:
            * kwq/KWQPainter.mm:
            (QPainter::currentContext):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6693 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 47c7655..33ab11e 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,68 @@
+2004-05-26  Richard Williamson   <rjw at apple.com>
+
+	Part 2 of the new <CANVAS> tag implementation.  This adds the 
+	basic machinery and draw operations for the <CANVAS> tag.  Pretty cool.  
+
+        function drawLine() {
+	    var canvas1 = document.getElementById ("canvas1");
+	    var context = canvas1.getContext("context-2d");
+
+	    context.setStrokeColor ("red");
+	    context.setLineWidth (10);
+	    context.beginPath();
+	    context.moveToPoint (0,0);
+	    context.addLineToPoint (400,400);
+	    context.strokePath();
+        }
+
+        ...
+
+        <canvas id="canvas1" width="400" height="400">
+
+	More to come.
+
+        Reviewed by Dave.
+
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::HTMLElementFunction::tryCall):
+        (KJS::Context2DFunction::tryCall):
+        (Context2D::tryGet):
+        (Context2D::getValueProperty):
+        (Context2D::tryPut):
+        (Context2D::putValue):
+        (Context2D::Context2D):
+        (Context2D::~Context2D):
+        * khtml/ecma/kjs_html.h:
+        (KJS::Context2D::toBoolean):
+        (KJS::Context2D::classInfo):
+        (KJS::Context2D::):
+        * khtml/ecma/kjs_html.lut.h:
+        (KJS::):
+        * khtml/html/html_canvasimpl.cpp:
+        (HTMLCanvasElementImpl::HTMLCanvasElementImpl):
+        * khtml/html/htmlparser.cpp:
+        (KHTMLParser::getElement):
+        * khtml/rendering/render_canvasimage.cpp:
+        (RenderCanvasImage::RenderCanvasImage):
+        (RenderCanvasImage::~RenderCanvasImage):
+        (RenderCanvasImage::createDrawingContext):
+        (RenderCanvasImage::drawingContext):
+        (RenderCanvasImage::setNeedsImageUpdate):
+        (RenderCanvasImage::updateDrawnImage):
+        (RenderCanvasImage::drawnImage):
+        (RenderCanvasImage::paint):
+        (RenderCanvasImage::layout):
+        * khtml/rendering/render_canvasimage.h:
+        * khtml/rendering/render_image.cpp:
+        (RenderImage::paint):
+        * khtml/rendering/render_image.h:
+        * khtml/rendering/render_replaced.cpp:
+        (RenderReplaced::shouldPaint):
+        (RenderWidget::paint):
+        * kwq/KWQPainter.h:
+        * kwq/KWQPainter.mm:
+        (QPainter::currentContext):
+
 2004-05-26  Darin Adler  <darin at apple.com>
 
         - fixed warning that prevents Deployment build from compiling
diff --git a/WebCore/khtml/ecma/kjs_html.cpp b/WebCore/khtml/ecma/kjs_html.cpp
index f6cdec7..104dfe4 100644
--- a/WebCore/khtml/ecma/kjs_html.cpp
+++ b/WebCore/khtml/ecma/kjs_html.cpp
@@ -46,11 +46,16 @@
 
 #include "misc/htmltags.h"
 
+#include "rendering/render_canvasimage.h"
 #include "rendering/render_object.h"
 #include "rendering/render_layer.h"
 
 #include <kdebug.h>
 
+#include "qcolor.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+
 
 using namespace KJS;
 
@@ -2136,9 +2141,8 @@ Value KJS::HTMLElementFunction::tryCall(ExecState *exec, Object &thisObj, const
     }
     case ID_CANVAS: {
         if (id == KJS::HTMLElement::GetContext) {
-            if (args.size() == 0 || (args.size() == 1 && args[0].toString(exec).qstring().lower() == "2d-context")) {
-                // FIXME:  Implement canvas.
-                printf ("%s:%d: %s  create 2D context\n", __FILE__, __LINE__, __FUNCTION__);
+            if (args.size() == 0 || (args.size() == 1 && args[0].toString(exec).qstring().lower() == "context-2d")) {
+                return Object(new Context2D(element));
             }
             return Undefined();
         }
@@ -3324,6 +3328,355 @@ Image::~Image()
   if ( onLoadListener ) onLoadListener->deref();
 }
 
+
+////////////////////// Context2D Object ////////////////////////
+
+IMPLEMENT_PROTOFUNC(Context2DFunction)
+
+Value KJS::Context2DFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
+{
+    if (!thisObj.inherits(&Context2D::info)) {
+        Object err = Error::create(exec,TypeError);
+        exec->setException(err);
+        return err;
+    }
+
+    Context2D *contextObject = static_cast<KJS::Context2D *>(thisObj.imp());
+    khtml::RenderCanvasImage *renderer = static_cast<khtml::RenderCanvasImage*>(contextObject->_element->renderer());
+    CGContextRef drawingContext = renderer->drawingContext();
+
+    switch (id) {
+        case Context2D::Save: {
+            if (args.size() != 0) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGContextSaveGState(drawingContext);
+            break;
+        }
+        case Context2D::Restore: {
+            if (args.size() != 0) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGContextRestoreGState(drawingContext);
+            break;
+        }
+        case Context2D::BeginPath: {
+            if (args.size() != 0) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGContextBeginPath(drawingContext);
+            break;
+        }
+        case Context2D::ClosePath: {
+            if (args.size() != 0) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGContextClosePath(drawingContext);
+            break;
+        }
+        case Context2D::SetStrokeColor: {
+            if (args.size() < 1 || args.size() > 2) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            QColor color;
+            if (args.size() > 0)
+                color = QColor(args[0].toString(exec).ascii());
+            float alpha;
+            if (args.size() > 1)
+                alpha = (float)args[1].toNumber(exec);
+            else
+                alpha = 1.;
+            CGContextSetRGBStrokeColor(drawingContext, color.red(), color.green(), color.blue(), alpha);
+            break;
+        }
+        case Context2D::SetFillColor: {
+            if (args.size() < 1 || args.size() > 2) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            QColor color;
+            if (args.size() > 0)
+                color = QColor(args[0].toString(exec).ascii());
+            float alpha;
+            if (args.size() > 1)
+                alpha = (float)args[1].toNumber(exec);
+            else
+                alpha = 1.;
+            CGContextSetRGBFillColor(drawingContext, color.red(), color.green(), color.blue(), alpha);
+            break;
+        }
+        case Context2D::SetLineWidth: {
+            if (args.size() != 1) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float w = (float)args[0].toNumber(exec);
+            CGContextSetLineWidth (drawingContext, w);
+            break;
+        }
+        case Context2D::SetLineCap: {
+            if (args.size() != 1) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGLineCap cap = kCGLineCapButt;
+            QString capString = args[0].toString(exec).qstring().lower();
+            if (capString == "round")
+                cap = kCGLineCapRound;
+            else if (capString == "square")
+                cap = kCGLineCapSquare;
+            CGContextSetLineCap (drawingContext, cap);
+            break;
+        }
+        case Context2D::SetLineJoin: {
+            if (args.size() != 1) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGLineJoin join = kCGLineJoinMiter;
+            QString joinString = args[0].toString(exec).qstring().lower();
+            if (joinString == "round")
+                join = kCGLineJoinRound;
+            else if (joinString == "bevel")
+                join = kCGLineJoinBevel;
+            CGContextSetLineJoin (drawingContext, join);
+            break;
+        }
+        case Context2D::SetMiterLimit: {
+            if (args.size() != 1) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float l = (float)args[0].toNumber(exec);
+            CGContextSetMiterLimit (drawingContext, l);
+            break;
+        }
+        case Context2D::FillPath: {
+            if (args.size() != 0) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGContextFillPath (drawingContext);
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::StrokePath: {
+            if (args.size() != 0) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            CGContextStrokePath (drawingContext);
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::Scale: {
+            if (args.size() != 2) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float sx = (float)args[0].toNumber(exec);
+            float sy = (float)args[1].toNumber(exec);
+            CGContextScaleCTM (drawingContext, sx, sy);
+            break;
+        }
+        case Context2D::Rotate: {
+            if (args.size() != 1) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float angle = (float)args[0].toNumber(exec);
+            CGContextRotateCTM (drawingContext, angle);
+            break;
+        }
+        case Context2D::Translate: {
+            if (args.size() != 2) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float tx = (float)args[0].toNumber(exec);
+            float ty = (float)args[1].toNumber(exec);
+            CGContextTranslateCTM (drawingContext, tx, ty);
+            break;
+        }
+        case Context2D::MoveToPoint: {
+            if (args.size() != 2) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float x = (float)args[0].toNumber(exec);
+            float y = (float)args[1].toNumber(exec);
+            CGContextMoveToPoint (drawingContext, x, y);
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::AddLineToPoint: {
+            if (args.size() != 2) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float x = (float)args[0].toNumber(exec);
+            float y = (float)args[1].toNumber(exec);
+            CGContextAddLineToPoint (drawingContext, x, y);
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::AddQuadraticCurveToPoint: {
+            if (args.size() != 4) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float cpx = (float)args[0].toNumber(exec);
+            float cpy = (float)args[1].toNumber(exec);
+            float x = (float)args[2].toNumber(exec);
+            float y = (float)args[3].toNumber(exec);
+            CGContextAddQuadCurveToPoint (drawingContext, cpx, cpy, x, y);
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::AddBezierCurveToPoint: {
+            if (args.size() != 6) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float cp1x = (float)args[0].toNumber(exec);
+            float cp1y = (float)args[1].toNumber(exec);
+            float cp2x = (float)args[2].toNumber(exec);
+            float cp2y = (float)args[3].toNumber(exec);
+            float x = (float)args[2].toNumber(exec);
+            float y = (float)args[3].toNumber(exec);
+            CGContextAddCurveToPoint (drawingContext, cp1x, cp1y, cp2x, cp2y, x, y);
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::ClearRect: {
+            if (args.size() != 4) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            float x = (float)args[0].toNumber(exec);
+            float y = (float)args[1].toNumber(exec);
+            float w = (float)args[2].toNumber(exec);
+            float h = (float)args[3].toNumber(exec);
+            CGContextClearRect (drawingContext, CGRectMake(x,y,w,h));
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::DrawImage: {
+            if (args.size() != 6) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+        case Context2D::DrawImageFromRect: {
+            if (args.size() != 10) {
+                Object err = Error::create(exec,SyntaxError);
+                exec->setException(err);
+                return err;
+            }
+            renderer->setNeedsImageUpdate();
+            break;
+        }
+    }
+
+    return Undefined();
+}
+
+const ClassInfo KJS::Context2D::info = { "Context2D", 0, &Context2DTable, 0 };
+
+/* Source for Context2DTable. Use "make hashtables" to regenerate.
+ at begin Context2DTable 20
+  save                     Context2D::Save                        DontDelete|Function 0
+  restore                  Context2D::Restore                     DontDelete|Function 0
+  scale                    Context2D::Scale                       DontDelete|Function 2
+  rotate                   Context2D::Rotate                      DontDelete|Function 2
+  translate                Context2D::Translate                   DontDelete|Function 1
+  beginPath                Context2D::BeginPath                   DontDelete|Function 0
+  closePath                Context2D::ClosePath                   DontDelete|Function 0
+  setStrokeColor           Context2D::SetStrokeColor              DontDelete|Function 1
+  setFillColor             Context2D::SetFillColor                DontDelete|Function 1
+  setLineWidth             Context2D::SetLineWidth                DontDelete|Function 1
+  setLineCap               Context2D::SetLineCap                  DontDelete|Function 1
+  setLineJoin              Context2D::SetLineJoin                 DontDelete|Function 1
+  setMiterLimit            Context2D::SetMiterLimit               DontDelete|Function 1
+  fillPath                 Context2D::FillPath                    DontDelete|Function 0
+  strokePath               Context2D::StrokePath                  DontDelete|Function 0
+  moveToPoint              Context2D::MoveToPoint                 DontDelete|Function 2
+  addLineToPoint           Context2D::AddLineToPoint              DontDelete|Function 2
+  addQuadraticCurveToPoint Context2D::AddQuadraticCurveToPoint    DontDelete|Function 4
+  addBezierCurveToPoint    Context2D::AddBezierCurveToPoint       DontDelete|Function 6
+  clearRect                Context2D::ClearRect                   DontDelete|Function 4
+  drawImage                Context2D::DrawImge                    DontDelete|Function 6
+  drawImageFromRect        Context2D::DrawImageFromRect           DontDelete|Function 10
+ at end
+*/
+
+Value Context2D::tryGet(ExecState *exec, const Identifier &propertyName) const
+{
+    const HashTable* table = classInfo()->propHashTable; // get the right hashtable
+    const HashEntry* entry = Lookup::findEntry(table, propertyName);
+    if (entry) {
+        if (entry->attr & Function)
+            return lookupOrCreateFunction<KJS::Context2DFunction>(exec, propertyName, this, entry->value, entry->params, entry->attr);
+        return getValueProperty(exec, entry->value);
+    }
+
+    return DOMObjectLookupGetValue<Context2D,DOMObject>(exec, propertyName, &Context2DTable, this);
+}
+
+Value Context2D::getValueProperty(ExecState *, int token) const
+{
+    return Undefined();
+}
+
+void Context2D::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
+{
+    DOMObjectLookupPut<Context2D,DOMObject>(exec, propertyName, value, attr, &ImageTable, this );
+}
+
+void Context2D::putValue(ExecState *exec, int token, const Value& value, int /*attr*/)
+{
+}
+
+Context2D::Context2D(const DOM::HTMLElement &e)
+  : _element(static_cast<DOM::HTMLElementImpl*>(e.handle()))
+{
+}
+
+Context2D::~Context2D()
+{
+}
+
+////////////////////////////////////////////////////////////////
+                     
+
 Value KJS::getHTMLCollection(ExecState *exec, const DOM::HTMLCollection &c)
 {
   return cacheDOMObject<DOM::HTMLCollection, KJS::HTMLCollection>(exec, c);
diff --git a/WebCore/khtml/ecma/kjs_html.h b/WebCore/khtml/ecma/kjs_html.h
index 6467ff8..eb772de 100644
--- a/WebCore/khtml/ecma/kjs_html.h
+++ b/WebCore/khtml/ecma/kjs_html.h
@@ -234,6 +234,33 @@ namespace KJS {
     JSEventListener *onLoadListener;
   };
 
+  ////////////////////// Context2D Object ////////////////////////
+
+  class Context2D : public DOMObject {
+  public:
+    Context2D(const DOM::HTMLElement &e);
+    ~Context2D();
+    virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const;
+    Value getValueProperty(ExecState *exec, int token) const;
+    virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None);
+    void putValue(ExecState *exec, int token, const Value& value, int /*attr*/);
+    virtual bool toBoolean(ExecState *) const { return true; }
+    virtual const ClassInfo* classInfo() const { return &info; }
+    static const ClassInfo info;
+
+    enum { 
+        Save, Restore,
+        Scale, Rotate, Translate,
+        BeginPath, ClosePath, 
+        SetStrokeColor, SetFillColor, SetLineWidth, SetLineCap, SetLineJoin, SetMiterLimit, 
+        FillPath, StrokePath, 
+        MoveToPoint, AddLineToPoint, AddQuadraticCurveToPoint, AddBezierCurveToPoint,
+        ClearRect,
+        drawImage, drawImageFromRect };
+
+    DOM::HTMLElementImpl *_element;
+  };
+
   Value getHTMLCollection(ExecState *exec, const DOM::HTMLCollection &c);
   Value getSelectHTMLCollection(ExecState *exec, const DOM::HTMLCollection &c, const DOM::HTMLSelectElement &e);
 
diff --git a/WebCore/khtml/ecma/kjs_html.lut.h b/WebCore/khtml/ecma/kjs_html.lut.h
index 02fcb75..cf4319c 100644
--- a/WebCore/khtml/ecma/kjs_html.lut.h
+++ b/WebCore/khtml/ecma/kjs_html.lut.h
@@ -1033,3 +1033,42 @@ const struct HashEntry ImageTableEntries[] = {
 const struct HashTable ImageTable = { 2, 4, ImageTableEntries, 3 };
 
 } // namespace
+
+namespace KJS {
+
+const struct HashEntry Context2DTableEntries[] = {
+   { "scale", Context2D::Scale, DontDelete|Function, 2, &Context2DTableEntries[24] },
+   { "strokePath", Context2D::StrokePath, DontDelete|Function, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { "setLineJoin", Context2D::SetLineJoin, DontDelete|Function, 1, 0 },
+   { 0, 0, 0, 0, 0 },
+   { "addLineToPoint", Context2D::AddLineToPoint, DontDelete|Function, 2, 0 },
+   { 0, 0, 0, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { "save", Context2D::Save, DontDelete|Function, 0, &Context2DTableEntries[21] },
+   { "restore", Context2D::Restore, DontDelete|Function, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { "translate", Context2D::Translate, DontDelete|Function, 1, &Context2DTableEntries[20] },
+   { "rotate", Context2D::Rotate, DontDelete|Function, 2, &Context2DTableEntries[22] },
+   { "setLineWidth", Context2D::SetLineWidth, DontDelete|Function, 1, &Context2DTableEntries[25] },
+   { "addQuadraticCurveToPoint", Context2D::AddQuadraticCurveToPoint, DontDelete|Function, 4, &Context2DTableEntries[29] },
+   { 0, 0, 0, 0, 0 },
+   { 0, 0, 0, 0, 0 },
+   { "beginPath", Context2D::BeginPath, DontDelete|Function, 0, &Context2DTableEntries[23] },
+   { "closePath", Context2D::ClosePath, DontDelete|Function, 0, 0 },
+   { "setStrokeColor", Context2D::SetStrokeColor, DontDelete|Function, 1, 0 },
+   { "setFillColor", Context2D::SetFillColor, DontDelete|Function, 1, 0 },
+   { "setLineCap", Context2D::SetLineCap, DontDelete|Function, 1, &Context2DTableEntries[26] },
+   { "setMiterLimit", Context2D::SetMiterLimit, DontDelete|Function, 1, &Context2DTableEntries[27] },
+   { "fillPath", Context2D::FillPath, DontDelete|Function, 0, &Context2DTableEntries[28] },
+   { "moveToPoint", Context2D::MoveToPoint, DontDelete|Function, 2, 0 },
+   { "addBezierCurveToPoint", Context2D::AddBezierCurveToPoint, DontDelete|Function, 6, 0 },
+   { "clearRect", Context2D::ClearRect, DontDelete|Function, 4, 0 }
+};
+
+const struct HashTable Context2DTable = { 2, 30, Context2DTableEntries, 20 };
+
+} // namespace
diff --git a/WebCore/khtml/html/html_canvasimpl.cpp b/WebCore/khtml/html/html_canvasimpl.cpp
index 73d15e0..2f13a98 100644
--- a/WebCore/khtml/html/html_canvasimpl.cpp
+++ b/WebCore/khtml/html/html_canvasimpl.cpp
@@ -57,7 +57,6 @@ using namespace khtml;
 HTMLCanvasElementImpl::HTMLCanvasElementImpl(DocumentPtr *doc)
     : HTMLImageElementImpl(doc)
 {
-    printf ("%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__);
 }
 
 HTMLCanvasElementImpl::~HTMLCanvasElementImpl()
diff --git a/WebCore/khtml/html/htmlparser.cpp b/WebCore/khtml/html/htmlparser.cpp
index 19323ef..0b1e187 100644
--- a/WebCore/khtml/html/htmlparser.cpp
+++ b/WebCore/khtml/html/htmlparser.cpp
@@ -949,12 +949,10 @@ NodeImpl *KHTMLParser::getElement(Token* t)
         n = new HTMLAnchorElementImpl(document);
         break;
 
-#if APPLE_CHANGES
 // canvas
     case ID_CANVAS:
         n = new HTMLCanvasElementImpl(document);
         break;
-#endif
 
 // images
     case ID_IMG:
diff --git a/WebCore/khtml/rendering/render_canvasimage.cpp b/WebCore/khtml/rendering/render_canvasimage.cpp
index adbf59a..0440676 100644
--- a/WebCore/khtml/rendering/render_canvasimage.cpp
+++ b/WebCore/khtml/rendering/render_canvasimage.cpp
@@ -51,24 +51,192 @@ using namespace khtml;
 // -------------------------------------------------------------------------
 
 RenderCanvasImage::RenderCanvasImage(NodeImpl *_node)
-    : RenderImage(_node)
+    : RenderImage(_node), _drawingContext(0), _drawingContextData(0), _drawnImage(0), _needsImageUpdate(0)
 {
 }
 
 RenderCanvasImage::~RenderCanvasImage()
 {
+    if (_drawingContext) {
+        CFRelease (_drawingContext);
+        _drawingContext = 0;
+    }
+    
+    free (_drawingContextData);
+    _drawingContextData = 0;
+    
+    if (_drawnImage) {
+        CFRelease (_drawnImage);
+        _drawnImage = 0;
+    }
+}
+
+#define BITS_PER_COMPONENT 8
+#define BYTES_PER_ROW(width,bitsPerComponent,numComponents) ((width * bitsPerComponent * numComponents + 7)/8)
+
+void RenderCanvasImage::createDrawingContext()
+{
+    if (_drawingContext) {
+        CFRelease (_drawingContext);
+        _drawingContext = 0;
+    }
+    free (_drawingContextData);
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    size_t numComponents = CGColorSpaceGetNumberOfComponents(colorSpace);
+    size_t bytesPerRow = BYTES_PER_ROW(width(),BITS_PER_COMPONENT,(numComponents+1)); // + 1 for alpha
+    _drawingContextData = malloc(height() * bytesPerRow);
+    _drawingContext = CGBitmapContextCreate(_drawingContextData, width(), height(), BITS_PER_COMPONENT, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
+    
+#ifdef DEBUG_CANVAS_BACKGROUND
+    CGContextSetRGBFillColor(_drawingContext, 1.0, 0., 0., 1.);
+    CGContextFillRect (_drawingContext, CGRectMake (0, 0, width(), height()));
+    CGContextFlush (_drawingContext);
+#endif
+    
+    updateDrawnImage();
+    
+    CFRelease (colorSpace);
+}
+
+CGContextRef RenderCanvasImage::drawingContext()
+{
+    if (!_drawingContext) {
+        document()->updateLayout();
+        createDrawingContext();
+    }
+    
+    return _drawingContext;
+}
+
+CG_EXTERN_C_BEGIN
+CG_EXTERN CGImageRef CGBitmapContextCreateImage(CGContextRef c);
+CG_EXTERN_C_END
+
+void RenderCanvasImage::setNeedsImageUpdate()
+{
+    _needsImageUpdate = true;
+    repaint();
 }
 
 
+void RenderCanvasImage::updateDrawnImage()
+{
+    if (_drawnImage)
+        CFRelease (_drawnImage);
+    CGContextFlush (_drawingContext);
+    _drawnImage = CGBitmapContextCreateImage (_drawingContext);
+}
+
+CGImageRef RenderCanvasImage::drawnImage()
+{
+    return _drawnImage;
+}
+
 void RenderCanvasImage::paint(PaintInfo& i, int _tx, int _ty)
 {
-    printf ("%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__);
+    if (!shouldPaint(i, _tx, _ty))
+        return;
+
+    int x = _tx + m_x;
+    int y = _ty + m_y;
+
+    if (shouldPaintBackgroundOrBorder() && i.phase != PaintActionOutline) 
+        paintBoxDecorations(i, x, y);
+
+    QPainter* p = i.p;
+    
+    if (i.phase == PaintActionOutline && style()->outlineWidth() && style()->visibility() == VISIBLE)
+        paintOutline(p, x, y, width(), height(), style());
+    
+    if (i.phase != PaintActionForeground && i.phase != PaintActionSelection)
+        return;
+
+    bool drawSelectionTint = selectionState() != SelectionNone;
+    if (i.phase == PaintActionSelection) {
+        if (selectionState() == SelectionNone) {
+            return;
+        }
+        drawSelectionTint = false;
+    }
+
+    int cWidth = contentWidth();
+    int cHeight = contentHeight();
+    int leftBorder = borderLeft();
+    int topBorder = borderTop();
+    int leftPad = paddingLeft();
+    int topPad = paddingTop();
+
+    x += leftBorder + leftPad;
+    y += topBorder + topPad;
+    
+    if (_needsImageUpdate) {
+        updateDrawnImage();
+        _needsImageUpdate = false;
+    }
+    
+    if (drawnImage())
+        CGContextDrawImage (p->currentContext(), CGRectMake (x, y, cWidth, cHeight), drawnImage());
+
+    if (drawSelectionTint) {
+        QSize tintSize(cWidth, cHeight);
+
+
+        // Do the calculations to draw selections as tall as the line.
+        // Ignore the passed-in value for _ty.
+        // Use the bottom of the line above as the y position (if there is one, 
+        // otherwise use the top of this renderer's line) and the height of the line as the height. 
+        // This mimics Cocoa.
+        int selectionTop = -1;
+        int selectionHeight = -1;
+        int selectionLeft = -1;
+        int selectionRight = -1;
+        bool extendSelectionToLeft = false;
+        bool extendSelectionToRight = false;
+        if (drawSelectionTint) {
+            InlineBox *box = inlineBox();
+            if (box) {
+                // Get a value for selectionTop that is relative to the containing block.
+                // This value is used for determining left and right offset for the selection, if necessary,
+                // and for calculating the selection height.
+                if (box->root()->prevRootBox())
+                    selectionTop = box->root()->prevRootBox()->bottomOverflow();
+                else
+                    selectionTop = box->root()->topOverflow();
+
+                selectionHeight = box->root()->bottomOverflow() - selectionTop;
+
+                int absx, absy;
+                containingBlock()->absolutePosition(absx, absy);
+
+                if (selectionState() == SelectionInside && box->root()->firstLeafChild() == box) {
+                    extendSelectionToLeft = true;
+                    selectionLeft = absx + containingBlock()->leftOffset(selectionTop);
+                }
+                if (selectionState() == SelectionInside && box->root()->lastLeafChild() == box) {
+                    extendSelectionToRight = true;
+                    selectionRight = absx + containingBlock()->rightOffset(selectionTop);
+                }
+        
+                // Now make the selectionTop an absolute coordinate.
+                selectionTop += absy;
+            }
+        }
+
+        int left = x;
+        int width = tintSize.width();
+        int top = selectionTop >= 0 ? selectionTop : y;
+        int height = selectionHeight >= 0 ? selectionHeight : tintSize.height();
+        QBrush brush(selectionTintColor(p));
+        p->fillRect(left, top, width, height, brush);
+        if (extendSelectionToLeft)
+            p->fillRect(selectionLeft, selectionTop, left - selectionLeft, selectionHeight, brush);
+        if (extendSelectionToRight)
+            p->fillRect(left + width, selectionTop, selectionRight - (left + width), selectionHeight, brush);
+    }
 }
 
 void RenderCanvasImage::layout()
 {
-    printf ("%s:%d: %s\n", __FILE__, __LINE__, __FUNCTION__);
-
     KHTMLAssert(needsLayout());
     KHTMLAssert(minMaxKnown());
 
@@ -76,10 +244,17 @@ void RenderCanvasImage::layout()
     bool checkForRepaint = checkForRepaintDuringLayout();
     if (checkForRepaint)
         oldBounds = getAbsoluteRepaintRect();
+
+    int oldwidth = m_width;
+    int oldheight = m_height;
     
     calcWidth();
     calcHeight();
 
+    if ( m_width != oldwidth || m_height != oldheight ) {
+        createDrawingContext();
+    }
+
     if (checkForRepaint)
         repaintAfterLayoutIfNeeded(oldBounds, oldBounds);
     
diff --git a/WebCore/khtml/rendering/render_canvasimage.h b/WebCore/khtml/rendering/render_canvasimage.h
index eb4c7b1..7f4a91f 100644
--- a/WebCore/khtml/rendering/render_canvasimage.h
+++ b/WebCore/khtml/rendering/render_canvasimage.h
@@ -34,6 +34,8 @@
 #include <qmap.h>
 #include <qpixmap.h>
 
+#include <ApplicationServices/ApplicationServices.h>
+
 namespace khtml {
 
 class DocLoader;
@@ -50,9 +52,24 @@ public:
 
     virtual void layout();
 
+    void setNeedsImageUpdate();
+    
     // don't even think about making this method virtual!
     DOM::HTMLElementImpl* element() const
     { return static_cast<DOM::HTMLElementImpl*>(RenderObject::element()); }
+    
+    void updateDrawnImage();
+    CGContextRef drawingContext();
+    
+private:
+    void createDrawingContext();
+    CGImageRef drawnImage();
+
+    CGContextRef _drawingContext;
+    void *_drawingContextData;
+    CGImageRef _drawnImage;
+    
+    unsigned _needsImageUpdate:1;
 };
 
 
diff --git a/WebCore/khtml/rendering/render_image.cpp b/WebCore/khtml/rendering/render_image.cpp
index f87614b..c757c78 100644
--- a/WebCore/khtml/rendering/render_image.cpp
+++ b/WebCore/khtml/rendering/render_image.cpp
@@ -223,7 +223,10 @@ QColor RenderImage::selectionTintColor(QPainter *p) const
 void RenderImage::paint(PaintInfo& i, int _tx, int _ty)
 {
     if (!shouldPaint(i, _tx, _ty)) return;
-    
+
+    _tx += m_x;
+    _ty += m_y;
+        
     if (shouldPaintBackgroundOrBorder() && i.phase != PaintActionOutline) 
         paintBoxDecorations(i, _tx, _ty);
 
diff --git a/WebCore/khtml/rendering/render_image.h b/WebCore/khtml/rendering/render_image.h
index 7439809..4dd3d0a 100644
--- a/WebCore/khtml/rendering/render_image.h
+++ b/WebCore/khtml/rendering/render_image.h
@@ -84,10 +84,11 @@ public:
     
     DOM::HTMLMapElementImpl* imageMap();
 
+    QColor selectionTintColor(QPainter *p) const;
+
 private:
     bool isWidthSpecified() const;
     bool isHeightSpecified() const;
-    QColor selectionTintColor(QPainter *p) const;
 
     /*
      * Pointer to the image
diff --git a/WebCore/khtml/rendering/render_replaced.cpp b/WebCore/khtml/rendering/render_replaced.cpp
index b2f9699..4e3e8c8 100644
--- a/WebCore/khtml/rendering/render_replaced.cpp
+++ b/WebCore/khtml/rendering/render_replaced.cpp
@@ -63,14 +63,14 @@ bool RenderReplaced::shouldPaint(PaintInfo& i, int& _tx, int& _ty)
     // if we're invisible or haven't received a layout yet, then just bail.
     if (style()->visibility() != VISIBLE || m_y <=  -500000)  return false;
 
-    _tx += m_x;
-    _ty += m_y;
+    int tx = _tx + m_x;
+    int ty = _ty + m_y;
 
     // Early exit if the element touches the edges.
     int os = 2*maximalOutlineSize(i.phase);
-    if ((_tx >= i.r.x() + i.r.width() + os) || (_tx + m_width <= i.r.x() - os))
+    if ((tx >= i.r.x() + i.r.width() + os) || (tx + m_width <= i.r.x() - os))
         return false;
-    if ((_ty >= i.r.y() + i.r.height() + os) || (_ty + m_height <= i.r.y() - os))
+    if ((ty >= i.r.y() + i.r.height() + os) || (ty + m_height <= i.r.y() - os))
         return false;
 
     return true;
@@ -313,6 +313,9 @@ void RenderWidget::paint(PaintInfo& i, int _tx, int _ty)
 {
     if (!shouldPaint(i, _tx, _ty)) return;
 
+    _tx += m_x;
+    _ty += m_y;
+    
     if (shouldPaintBackgroundOrBorder() && i.phase != PaintActionOutline) 
         paintBoxDecorations(i, _tx, _ty);
 
diff --git a/WebCore/kwq/KWQPainter.h b/WebCore/kwq/KWQPainter.h
index d51b4b2..1d5c0c8 100644
--- a/WebCore/kwq/KWQPainter.h
+++ b/WebCore/kwq/KWQPainter.h
@@ -37,6 +37,8 @@
 #include "KWQString.h"
 #include "KWQFontMetrics.h"
 
+#include <ApplicationServices/ApplicationServices.h>
+
 class QFont;
 class QPixmap;
 class QWidget;
@@ -123,6 +125,8 @@ public:
     void clearFocusRing();
     void setDrawsFocusRing(bool flag) { _drawsFocusRing = flag; }
     
+    CGContextRef currentContext();
+    
 private:
     // no copying or assignment
     QPainter(const QPainter &);
diff --git a/WebCore/kwq/KWQPainter.mm b/WebCore/kwq/KWQPainter.mm
index a94a520..bd2f884 100644
--- a/WebCore/kwq/KWQPainter.mm
+++ b/WebCore/kwq/KWQPainter.mm
@@ -693,6 +693,11 @@ bool QPainter::paintingDisabled() const
     return data->state.paintingDisabled;
 }
 
+CGContextRef QPainter::currentContext()
+{
+    return (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);
+}
+
 void QPainter::beginTransparencyLayer(float opacity)
 {
     [NSGraphicsContext saveGraphicsState];

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list