[whatwg] Canvas path objects and path transformations
Ian Hickson wrote : [...] Based on the above, I've left the spec as is for now (it's what Opera implements); but I've contact the browser vendors about this and I'm looking into it as we speak. Check the spec for updates to this issue. Thank you, i hope they will agree. :) On Sun, 15 Apr 2007, Stefan Haustein wrote: Anyway, now that you mention it, we really need a way to retrieve the current transform matrix. Like the current point, it is something that already is in the browser's memory, so a function returning an array would be enough. There's still no way to _get_ the transformation matrix, but you can not _set_ the transformation matrix now, which should be of help here. I'm not sure exactly what you mean. Isn't it the purpose of the setTransform method? (http://www.whatwg.org/specs/web-apps/current-work/#settransform, though it doesn't seem implemented by UAs yet). Like ~getLastPointOfPath, it's just allowing to read values that are already in the UA's memory, so it shouldn't be too hard to implement. I know applications can emulate it by overriding the other functions, or keeping track of it by themself, but it means significantly more work in this case. Regards, Jordan Osete
[whatwg] Canvas color serialisation
Ian Hickson wrote : On Mon, 16 Apr 2007, Jordan OSETE wrote: In that case, we could detect if the application tries to set an array to the properties fillStyle or strokeStyle, and if it is the case, then it means that the given application is more recent than the change from string to array, and we can switch to an array-like reading. [...] This seems way, way more complex than necessary. We really want to keep this API as simple as possible. Hm, i have to admit that... It's not clear to me why the author ever needs to read this value. The value, when set, is set by the author's code -- if you need to know what the value is in some more detailed way then just remember what you set it to (e.g. with a wrapper function). It can be done with a wrapper, but it seems overhead, when the UA can just return something easier to read. In that case, why not always return an array, like Philip Taylor suggested? It would allow the user be able to read color values in an easy way, and still keep compatibility with this kind of code : var old = context.fillStyle; context.fillStyle = 'green'; context.fillRect(0,0,100,100); context.fillStyle = old; I don't see many reasons to return strings like #xx or rgba(...) in the first place, but if needed, it's way easier for the application to convert that array[4] to a rgba(...) or #xx string than the other way around. Regards, Jordan Osete
Re: [whatwg] Canvas color serialisation
On Sat, 12 May 2007 10:52:39 +0200, Jordan OSETE [EMAIL PROTECTED] wrote: It can be done with a wrapper, but it seems overhead, when the UA can just return something easier to read. In that case, why not always return an array, like Philip Taylor suggested? This would complicate setting fillStyle and strokeStyle. It's also not clear what the use case is, as I understand it. -- Anne van Kesteren http://annevankesteren.nl/ http://www.opera.com/
Re: [whatwg] Canvas color serialisation
On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: On Sat, 12 May 2007 10:52:39 +0200, Jordan OSETE [EMAIL PROTECTED] wrote: It can be done with a wrapper, but it seems overhead, when the UA can just return something easier to read. In that case, why not always return an array, like Philip Taylor suggested? This would complicate setting fillStyle and strokeStyle. It's also not clear what the use case is, as I understand it. Being able to set colours by a [r,g,b(,a)] array would be slightly useful for anyone computing colours. I've done some code which deals with colours as arrays internally, with a function function array_to_rgba(c) { return 'rgba('+c[0]+','+c[1]+','+c[2]+',1)'; } to get an output format the canvas understands. (If I wanted to be slightly fancier I'd probably have to do function array_to_rgba(c) { return 'rgba(' + Math.floor(c[0]) + ',' + Math.floor(c[1]) + ',' + Math.floor(c[2]) + ',' + (c.length==4 ? c[3]/255 : 1) + ')'; } instead.) As other examples, there's PlotKit at http://projects.liquidx.net/js/browser/plotkit/trunk/PlotKit using MochiKit's Color.toRGBString, and people constructing the strings inline with: rgba(+((c10)?c1:0)+,+((c20)?c2:0)+,+((c30)?c3:0)+,+((max_iteration-c)/max_iteration)+); at http://virtuelvis.com/download/2005/10/mandelbrot/ 'rgba('+(face[i/4]%2==0 ? shade1 : 0)+','+(face[i/4]==1 ? shade1 : 0)+','+(face[i/4]==2 ? 0 : shade1)+',1)' at http://www.abrahamjoffe.com.au/ben/canvascape/ rgb(+rand_red+,+rand_green+,+rand_blue+) at http://dave-webster.com/projects/index.php?page=incs/plasma_demo1 so people do want to set colours from calculated values, and the CSS-colour interface just becomes an inconvenience. But it's only a small inconvenience and is easy to work around, so it may not matter enough to make changes. If arrays were accepted as input, then using arrays as return values would seem to be a logical change - it would still allow people to do 'ctx.fillStyle = ctx.fillStyle' as before, and would make it easier if anybody did want to parse the colours (though I don't know why they would), and would probably simplify the spec a little (since the paragraph about colour return values is a bit long and painful now), and would gain consistency with the output format of getImageData. -- Philip Taylor [EMAIL PROTECTED]
[whatwg] putImageData() and getImageData()
These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. I'm not quite sure what a good solution to this problem would be. -- Anne van Kesteren http://annevankesteren.nl/ http://www.opera.com/
Re: [whatwg] Canvas spec issues
On May 11, 2007, at 4:18 PM, Ian Hickson wrote: On Mon, 26 Mar 2007, Philip Taylor wrote: A couple of points that are unclear and are causing differences between current implementations (which is presumably a bad thing): interface HTMLCanvasElement says attribute long width;. #reflect says If a reflecting DOM attribute is a signed integer type (long) then the content attribute must be parsed according to the rules for parsing signed integers first, which seems to apply in this case. But the canvas section says of width/height, The rules for parsing non- negative integers must be used to obtain their numeric values. Hence, conflict. Also, canvas.width = -1 is acceptable for a signed long, but doesn't make sense here. (After setting that, Firefox gives canvas.width==0, Opera gives 300, Safari gives -1.) Changed to unsigned. If it's unsigned, it's ambiguous what behavior should be when an attempt is made to set the value to a signed value via JavaScript. Should an INDEX_SIZE_ERR exception be raised? Should the value be ignored? I think I ran into this problem with HTMLOptionsCollection length property. -- Darin
Re: [whatwg] putImageData() and getImageData()
On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. Looking for people using getImageData already, I find: http://canvaspaint.org/paint.js - incorrect (though commented out) http://svn.sourceforge.net/viewvc/jsmsx/trunk/msx.js?view=markup - incorrect http://www.thescripts.com/forum/thread521112.html - incorrect http://tech.groups.yahoo.com/group/canvas-developers/files/buttons.html (or maybe http://f1.grp.yahoofs.com/v1/gORFRoOLlxuXtJddXwdSyravD-aFfgNuYoSzjI8vUevuBxus3V1sXs5xckiHKd1osiUpDE_bku-vtGMFPV_M-2JZkLKXTqc/buttons.html) - correct I couldn't find any others doing anything with the ImageData.width/height, but three of those four will break when somebody implements getImageData with imagedata.width != canvas.width. -- Philip Taylor [EMAIL PROTECTED]
Re: [whatwg] Canvas spec issues
On Sat, 12 May 2007 18:21:21 +0200, Darin Adler [EMAIL PROTECTED] wrote: If it's unsigned, it's ambiguous what behavior should be when an attempt is made to set the value to a signed value via JavaScript. Should an INDEX_SIZE_ERR exception be raised? Should the value be ignored? I think I ran into this problem with HTMLOptionsCollection length property. The idea is that this will eventually be clarified by some specification that defines common mappings from pseudo-IDL to ECMAScript. However, there hasn't been much progress on that. I believe INDEX_SIZE_ERR would be correct here, though. -- Anne van Kesteren http://annevankesteren.nl/ http://www.opera.com/
Re: [whatwg] putImageData() and getImageData()
On 12/05/07, Philip Taylor [EMAIL PROTECTED] wrote: On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. Looking for people using getImageData already, I find: [...] three of those four will break when somebody implements getImageData with imagedata.width != canvas.width. It may also be worth noting that it looks (as far as I can tell) like nearly everyone (in those examples and elsewhere) is working from the concept that a 'pixel' in the canvas coordinate space really is an actual pixel with a single colour value, and that fillRect(x, y, 1, 1) will draw one pixel (assuming a sensible transformation matrix and integer coordinates). I believe there's the same problematic assumption when you do img.src = ctx.toDataURL(); ...; ctx.drawImage(img) that pixels are pixels and it's not going to change size, but toDataURL saves each device pixel as an image pixel (though actually that seems unspecified) whereas drawImage draws each image pixel as one canvas pixel. I think it would make much more sense (and be much less error-prone) if canvas acted like a dynamic bitmap img and the browser just scaled up the bitmap before rendering to the screen, rather than optionally using a higher-resolution buffer for all the intermediate drawing. That matches the behaviour when you change the canvas's size with CSS - ... the element can be sized arbitrarily by a style sheet. During rendering, the image is scaled to fit this layout size. It would reduce the quality of the output to some extent, but in the current situation it seems likely that people will write code that simply doesn't work at all when the canvas has more device pixels than expected. Browsers already have to do as-nice-as-possible scaling for static bitmap images on high-res/zoomed displays, so it wouldn't be any worse than that. For people who really do want high quality output and know what they're doing, there could be some way to query the current canvas-display scaling factor (taking account of high-res displays, zoomed pages, CSS scaling, etc) and they can manually change the canvas's width/height to get a 1:1 match between device pixels and canvas pixels. Then they can even update the size of the bitmap every frame, so it continues looking good if the user has zoomed in on the page. Or they could use SVG. -- Philip Taylor [EMAIL PROTECTED]
Re: [whatwg] putImageData() and getImageData()
On Sat, 12 May 2007 17:54:25 +0200, Anne van Kesteren [EMAIL PROTECTED] wrote: These features are nice but I don't think authors will understand that imagedata.height != canvas.height (likewise for width). Authors will just make something that works in their browser and then assume it will work everywhere else. Which would horribly break. Even the more experienced canvas developers playing with these features have already made these mistakes. I'm not quite sure what a good solution to this problem would be. The best way forward would probably be to get rid of canvas device pixels and just make such a pixel map a canvas pixel. This means that getImageData() and putImageData() work similarly to toDataURL() and drawImage(). If people really want high resolution canvas they could just make it high resolution and scale it down for display using CSS. Incidentally such an approach might get us rid of all the floats currently in the API... -- Anne van Kesteren http://annevankesteren.nl/ http://www.opera.com/
Re: [whatwg] putImageData() and getImageData()
On 12/05/07, Anne van Kesteren [EMAIL PROTECTED] wrote: The best way forward would probably be to get rid of canvas device pixels and just make such a pixel map a canvas pixel. This means that getImageData() and putImageData() work similarly to toDataURL() and drawImage(). If people really want high resolution canvas they could just make it high resolution and scale it down for display using CSS. Incidentally such an approach might get us rid of all the floats currently in the API... With those pixels being the same (i.e. a canvas width=100 height=100 will always make the browser create a 100*100*4 byte array to store the data and to work in, regardless of what size it's finally going to be drawn to the screen), then it would be helpful to get rid of floats only in getImageData/putImageData. It's still sensible and useful to e.g. draw rectangles at float coordinates, because of antialiasing - if you do fillStyle='white'; fillRect(0, 0, 0.5, 0.5) so one pixel is 25% covered, then it will be approximated by setting one canvas pixel ( = one canvas device pixel, i.e. 4 bytes in the canvas's backing bitmap) to rgba(255, 255, 255, 0.25). This is how existing browsers handle it, e.g. http://canvex.lazyilluminati.com/misc/subpixel.html - they approximate subpixel rendering by doing antialiasing into a 3x3 bitmap, and then eventually scale the 3x3 bitmap up just before drawing to the screen. (Opera does that final scaling by repeating each pixel, Firefox does it more smoothly with some interpolation, but in both cases the canvas is originally drawing onto a 3x3 pixel bitmap.) This would disallow people from implementing antialiasing via supersampling, e.g. storing 8x8 subpixel values per canvas pixel and then scaling downwards when rendering, because putPixelData(getPixelData()) would require only one colour value to exist for each canvas pixel. But it seems nobody implements it with supersampling now, probably because it uses far too much memory and normal antialiasing is a good enough approximation - I currently think the predictability and simplicity of requiring one storage pixel per canvas pixel is worth that theoretical limitation. (And if somebody wants higher-resolution output, they can still do canvas width=800 height=800 style=width:100px; height:100px.) -- Philip Taylor [EMAIL PROTECTED]