[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