<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Feb 22, 2010, at 11:13 AM, David Levin wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><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></span></div></blockquote><div><br></div><div>Comments:</div><div><br></div><div>1) Like others, I would recommend not omitting the text APIs. I can see why they are a bit trickier to implement than the others, but I don't see a fundamental barrier.</div><div><br></div><div>2) I would propose adding createPattern and drawImage overloads that take an OffscreenCanvas. The other overloads would in practice not be usefully callable in the worker case since you couldn't get an image, canvas or video element.</div><div><br></div><div>3) This would leave the only difference between the two interfaces as the drawFocusRing method. This would not be usefully callable in a worker, since there would be no way to get an Element. But it doesn't seem worth it to add an interface just for one method's worth of difference.</div><div><br></div><div>Regards,</div><div>Maciej</div><br><blockquote type="cite"><div><span class="Apple-style-span" style="font-family: Verdana; font-size: 13px; "><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>
</blockquote></div><br></body></html>