<div>The lack of support for text drawing in the worker context seems like a short sighted mistake. I understand there may be implementation issues in some browsers, but lack of text support feels like a glaring omission spec wise.</div>
<br><div class="gmail_quote">On Mon, Feb 22, 2010 at 11:13 AM, David Levin <span dir="ltr"><<a href="mailto:levin@google.com">levin@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><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><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><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><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><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><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><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><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><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><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><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" target="_blank">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>