<div><span class="Apple-style-span" style="font-family: Verdana; font-size: 13px; "><div><div>I've talked with some other folks on WebKit (Maciej and Oliver) about having a canvas that is available to workers. They suggested some nice modifications to make it an offscreen canvas, which may be used in the Document or in a Worker.</div>
<div><br></div><div>Proposal:</div><div>Introduce an OffscreenCanvas which may be created from a Document or a Worker context.</div></div><div><font face="'courier new', monospace"><br></font></div><div><span style="border-collapse: collapse; "><div>
<font face="'courier new', monospace">interface OffscreenCanvas {</font></div><div><span style="border-collapse: collapse; "><div class="im"><div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> attribute unsigned long width;</font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> attribute unsigned long height;</font></div></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> DOMString toDataURL (in optional DOMString type, in any... args);</font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> object getContext(in DOMString contextId); </font></div></div><div style="margin-top: 0px; margin-bottom: 0px; ">
<span style="border-collapse: separate; "><font face="'courier new', monospace">};</font></span></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"><span style="border-collapse: separate; "><br>
</span></font></div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><font face="arial, helvetica, sans-serif"><br></font></span></div><div style="margin-top: 0px; margin-bottom: 0px; ">
<span style="border-collapse: separate; "><font face="arial, helvetica, sans-serif">When it is created in the Worker context, </font><span style="border-collapse: collapse; "><font face="arial, helvetica, sans-serif">OffscreenCanvas.</font><span style="border-collapse: separate; "><font face="arial, helvetica, sans-serif">getContext("2d") returns a CanvasWorkerContext2D. In the Document context, it returns a CanvasRenderingContext2D.</font></span></span></span></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><span style="border-collapse: collapse; "><span style="border-collapse: separate; "><font face="arial, helvetica, sans-serif"><br>
</font></span></span></span></div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><font face="arial, helvetica, sans-serif">The base class for both CanvasWorkerContext2D and CanvasRenderingContext2D is CanvasContext2D. CanvasContext2D is just like a CanvasRenderingContext2D except for omitting the font methods and any method which uses HTML elements. It does have some replacement methods for createPattern/drawImage which take an OffscreenCanvas. The canvas object attribute is either a HTMLCanvasElement or an OffscreenCanvas depending on what the canvas context came from.</font></span></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><font face="'courier new', monospace"><br></font></span></div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><font face="'courier new', monospace">interface CanvasContext2D<span style="font-family: arial; "> {</span></font></span></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><font face="'courier new', monospace"> readonly attribute object canvas;</font></span></div><span style="border-collapse: separate; font-family: Verdana; font-size: 13px; "><div style="margin-top: 0px; margin-bottom: 0px; ">
<font face="'Courier New'"><br></font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'"><div style="margin-top: 0px; margin-bottom: 0px; "> void save();</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void restore();</div><div style="margin-top: 0px; margin-bottom: 0px; "><br></div><div style="margin-top: 0px; margin-bottom: 0px; "> void scale(in float sx, in float sy);</div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; ">
void rotate(in float angle);</div></div><div style="margin-top: 0px; margin-bottom: 0px; "> void translate(in float tx, in float ty);</div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; ">
void transform(in float m11, in float m12, in float m21, in float m22, in float dx, in float dy);</div><div style="margin-top: 0px; margin-bottom: 0px; "> void setTransform(in float m11, in float m12, in float m21, in float m22, in float dx, in float dy);</div>
<div style="margin-top: 0px; margin-bottom: 0px; "><br></div></div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute float globalAlpha;</div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute [ConvertNullToNullString] DOMString globalCompositeOperation;</div>
<div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "><br></div><div style="margin-top: 0px; margin-bottom: 0px; "> CanvasGradient createLinearGradient(in float x0, in float y0, in float x1, in float y1)</div>
</div><div style="margin-top: 0px; margin-bottom: 0px; "> raises (DOMException);</div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "> CanvasGradient createRadialGradient(in float x0, in float y0, in float r0, in float x1, in float y1, in float r1)</div>
</div><div style="margin-top: 0px; margin-bottom: 0px; "> raises (DOMException);</div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="font-family: Verdana; "><div style="margin-top: 0px; margin-bottom: 0px; ">
<font face="'Courier New'"> CanvasPattern createPattern(in <span style="font-family: 'courier new', monospace; font-size: small; border-collapse: collapse; ">OffscreenCanvas</span> image, in DOMString repetition);</font></div>
<div><font face="'Courier New'"><br></font></div></span></div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute float lineWidth;</div><div style="margin-top: 0px; margin-bottom: 0px; ">
attribute [ConvertNullToNullString] DOMString lineCap;</div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute [ConvertNullToNullString] DOMString lineJoin;</div><div style="margin-top: 0px; margin-bottom: 0px; ">
attribute float miterLimit;</div><div style="margin-top: 0px; margin-bottom: 0px; "><br></div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute float shadowOffsetX;</div><div style="margin-top: 0px; margin-bottom: 0px; ">
attribute float shadowOffsetY;</div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute float shadowBlur;</div><div style="margin-top: 0px; margin-bottom: 0px; "> attribute [ConvertNullToNullString] DOMString shadowColor;</div>
<div style="margin-top: 0px; margin-bottom: 0px; "><br></div><div style="margin-top: 0px; margin-bottom: 0px; "> void clearRect(in float x, in float y, in float width, in float height);</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void fillRect(in float x, in float y, in float width, in float height);</div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "> void strokeRect(in float x, in float y, in float w, in float h);</div>
<div style="margin-top: 0px; margin-bottom: 0px; "><br></div></div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "> void beginPath();</div><div style="margin-top: 0px; margin-bottom: 0px; "> void closePath();</div>
<div style="margin-top: 0px; margin-bottom: 0px; "> void moveTo(in float x, in float y);</div><div style="margin-top: 0px; margin-bottom: 0px; "> void lineTo(in float x, in float y);</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void quadraticCurveTo(in float cpx, in float cpy, in float x, in float y);</div><div style="margin-top: 0px; margin-bottom: 0px; "> void bezierCurveTo(in float cp1x, in float cp1y, in float cp2x, in float cp2y, in float x, in float y);</div>
<div style="margin-top: 0px; margin-bottom: 0px; "> void arcTo(in float x1, in float y1, in float x2, in float y2, in float radius);</div></div><div style="margin-top: 0px; margin-bottom: 0px; "> void rect(in float x, in float y, in float width, in float height);</div>
<div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "> void arc(in float x, in float y, in float radius, in float startAngle, in float endAngle, in boolean anticlockwise);</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void fill();</div><div style="margin-top: 0px; margin-bottom: 0px; "> void stroke();</div><div style="margin-top: 0px; margin-bottom: 0px; "> void clip();</div><div style="margin-top: 0px; margin-bottom: 0px; ">
boolean isPointInPath(in float x, in float y);</div><div style="margin-top: 0px; margin-bottom: 0px; "><br></div></div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="font-family: 'courier new', monospace; font-size: small; "><div style="margin-top: 0px; margin-bottom: 0px; ">
void drawImage(in <span style="border-collapse: collapse; ">OffscreenCanvas</span> image, in float dx, in float dy, in optional float dw, in optional float dh);</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void drawImage(in <span style="border-collapse: collapse; ">OffscreenCanvas</span> image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);</div><div><br></div>
</span></div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "> // pixel manipulation</div><div style="margin-top: 0px; margin-bottom: 0px; "> ImageData createImageData(in float sw, in float sh)</div>
</div><div style="margin-top: 0px; margin-bottom: 0px; "> raises (DOMException);</div><div class="im"><div style="margin-top: 0px; margin-bottom: 0px; "> ImageData getImageData(in float sx, in float sy, in float sw, in float sh)</div>
</div><div style="margin-top: 0px; margin-bottom: 0px; "> raises(DOMException);</div><div style="margin-top: 0px; margin-bottom: 0px; "> void putImageData(in ImageData imagedata, in float dx, in float dy, in optional float dirtyX, in optional float dirtyY, in optional float dirtyWidth, in optional float dirtyHeight]);</div>
</font></div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="font-family: 'Courier New'; ">};</span></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'"><br></font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'">interface <span style="font-family: 'courier new', monospace; font-size: small; ">CanvasWorkerContext2D : CanvasContext2D {</span></font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'"><span style="font-family: 'courier new', monospace; font-size: small; ">};</span></font></div><div style="margin-top: 0px; margin-bottom: 0px; ">
<font face="'Courier New'"><span style="font-family: 'courier new', monospace; font-size: small; "><br></span></font></div><div style="margin-top: 0px; margin-bottom: 0px; "><span style="font-family: 'courier new', monospace; font-size: small; ">interface CanvasRenderingContext2D <span style="font-family: arial; ">: <span style="font-family: 'courier new', monospace; ">CanvasContext2D <span style="font-family: arial; ">{</span></span></span></span></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'"><span style="font-family: 'courier new', monospace; font-size: small; "><span style="font-family: arial; "><div style="margin-top: 0px; margin-bottom: 0px; ">
<font face="'courier new', monospace"><div style="margin-top: 0px; margin-bottom: 0px; "> CanvasPattern createPattern(in HTMLImageElement image, in DOMString repetition);</div><div style="margin-top: 0px; margin-bottom: 0px; ">
CanvasPattern createPattern(in HTMLCanvasElement image, in DOMString repetition);</div><div style="margin-top: 0px; margin-bottom: 0px; "> CanvasPattern createPattern(in HTMLVideoElement image, in DOMString repetition);</div>
<div><br></div></font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> // focus management</font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> boolean drawFocusRing(in Element element, in float xCaret, in float yCaret, in optional boolean canDrawCustom);</font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"><br></font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> // text</font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"><span style="font-family: 'Courier New'; font-size: 13px; "> </span><span style="font-family: 'Courier New'; "> </span> attribute DOMString font;</font></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"><span style="font-family: 'Courier New'; "> </span> attribute DOMString textAlign;</font></div><div style="margin-top: 0px; margin-bottom: 0px; ">
<font face="'courier new', monospace"><span style="font-family: 'Courier New'; "> </span> attribute DOMString textBaseline;</font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> void fillText(</font><span style="line-height: 21px; white-space: pre-wrap; "><font face="'courier new', monospace">in DOMString text, in float x, in float y, in optional float maxWidth</font><span style="line-height: normal; white-space: normal; "><font face="'courier new', monospace">);</font></span></span></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> void strokeText(</font><span style="line-height: 21px; white-space: pre-wrap; "><font face="'courier new', monospace">in DOMString text, in float x, in float y, in optional float maxWidth</font><span style="line-height: normal; white-space: normal; "><font face="'courier new', monospace">);</font></span></span></div>
<div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"> TextMetrics measureText(in DOMString text);</font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"><br>
</font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'courier new', monospace"><div style="margin-top: 0px; margin-bottom: 0px; "> // drawing images</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void drawImage(in HTMLImageElement image, in float dx, in float dy, in optional float dw, in float dh);</div><div style="margin-top: 0px; margin-bottom: 0px; "> void drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);</div>
<div style="margin-top: 0px; margin-bottom: 0px; "> void drawImage(in HTMLVideoElement image, in float dx, in float dy, in optional float dw, in optional float dh);</div><div style="margin-top: 0px; margin-bottom: 0px; ">
void drawImage(in HTMLVideoElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);</div></font></div></span></span></font></div><span style="font-family: 'courier new', monospace; font-size: small; "><div style="margin-top: 0px; margin-bottom: 0px; ">
</div></span><div style="margin-top: 0px; margin-bottom: 0px; "><span style="font-size: small; "><font face="'courier new', monospace"><div style="margin-top: 0px; margin-bottom: 0px; "> void drawImage(in HTMLCanvasElement image, in float dx, in float dy, in optional float dw, in float dh);</div>
<div style="margin-top: 0px; margin-bottom: 0px; "> void drawImage(in HTMLCanvasElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);</div></font></span></div>
<span style="font-family: arial; font-size: small; "><div><span style="border-collapse: collapse; "><div><span style="border-collapse: collapse; "><div style="margin-top: 0px; margin-bottom: 0px; "><span style="border-collapse: separate; "><font face="'courier new', monospace"><span style="font-family: arial; "><br>
</span></font></span></div></span></div></span></div><font face="'courier new', monospace"></font></span><font face="'courier new', monospace"></font><font face="'courier new', monospace"></font><div style="margin-top: 0px; margin-bottom: 0px; ">
<span style="font-size: small; "><font face="'courier new', monospace">};</font></span></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'"><span style="font-family: 'courier new', monospace; font-size: small; "><span style="font-family: arial; "><br>
</span></span></font></div><div style="margin-top: 0px; margin-bottom: 0px; "><font face="'Courier New'"><span style="font-family: 'courier new', monospace; font-size: small; "><span style="font-family: arial; "><div>
Questions and comments are welcome.</div><div><br></div><div>Note that something similar did come up in December and this proposal avoids doing any text related items in the offscreen canvas which was a concern brought up by Robert O'Callahan at the time (<a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-December/024478.html">http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-December/024478.html</a>).</div>
<div><br></div><div>Dave</div><div><br></div></span></span></font></div></span></span></div></span></div></span></div>