Re: [whatwg] proposed canvas 2d API additions

2009-04-30 Thread Ian Hickson
On Sat, 28 Feb 2009, JustFillBug wrote:
 On 2006-04-26, Ian Hickson i...@hixie.ch wrote:
  On Mon, 24 Apr 2006, Vladimir Vukicevic wrote:
  
   Assuming nobody has any problem with:
  
  boolean isPointInPath(in float x, in float y);
  
   ...then I'll add that to the spec when you reply to this mail.
  
  Sure, isPointInPath sounds fine.
 
  Added.
 
  We can always add isPointInStrokedPath if we ever want to bother with 
  that (which is where the ...Fill bit came from in my API, because the 
  region covered by a stroked path and that covered by a filled path are 
  different, even though testing for a hit against a filled region would 
  by far be the common case).
 
  We can also call the other one isPointOnPath(), if we want to keep the 
  method names reasonably short. I'm not sure we'll ever need to add it, 
  though. Getting people to click on a line is generally silly.
 
 We do have a need of isPointOnPath() for editing Bezier lines 
 interactively (on a font editing interface). When people want to add a 
 new point on an already existing curve, we have to know if the click is 
 on path. besides, we need double click on the curve to pickup the whole 
 path and then drag on the line to move the whole path.
 
 So I dig up a 2006 post...
 
 Of course it's hard to get people click on a line precisely. But we can 
 check isPointOnPath for an 5x5 square instead to make the operation 
 easier.
 
 Doing point on curve in javascript is painful. And since checking 
 isPointInPath() already need to detect the on edge case, this shouldn't 
 be too much a burdern on the browser developers.
 
 So please conside add the isPointOnPath() call to the function.

On Sat, 28 Feb 2009, Philip Taylor wrote:
 
 (Or maybe we could add a convertStrokeToPath() function, which replaces 
 the current path with a path representing the outline of what you'd get 
 if you stroked the current path, and then use isPointInPath on it.)

I haven't added either of these yet, because, as Philip pointed out in a 
part of his e-mail that I haven't quoted above, there are workarounds that 
can be done to approximate the results.

I expect that when we introduce explicit Path objects we will include 
features like convertStrokeToPath() and so forth which will make this far 
easier to do.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2009-03-02 Thread Kristof Zelechovski
Philip's demonstration of how to handle detection of pointing at the curve
is miserably wrong.  His curve is not typographically correct (bounding
box!).  The detection should be in based on of precomputed regions rather
than flattening.  This all can be done in script library, of course, but the
library would have to rely on mathematical techniques that the graphic
designer need not understand.  And the region information could be cached
on-demand when it is first needed.  I think it would be better to build the
thing into the browser.
See my solution at http://www.2a.pl/~ne01026/bzr.htm (VML + VBScript
required).
Chris






Re: [whatwg] proposed canvas 2d API additions

2009-03-02 Thread Ian Hickson
On Mon, 2 Mar 2009, Kristof Zelechovski wrote:

 [...]

I would like to remind everyone that communication on this list is 
expected to be cordial, pleasant, and cooperative.

After multiple warnings, I've taken the rare step of banning Kristof's 
e-mail address from the mailing list for a week. It will be restored on 
Monday, March 9th.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2009-02-28 Thread JustFillBug
On 2006-04-26, Ian Hickson i...@hixie.ch wrote:
 On Mon, 24 Apr 2006, Vladimir Vukicevic wrote:
 
  Assuming nobody has any problem with:
 
 boolean isPointInPath(in float x, in float y);
 
  ...then I'll add that to the spec when you reply to this mail.
 
 Sure, isPointInPath sounds fine.

 Added.

 We can always add isPointInStrokedPath if we ever want to bother with 
 that (which is where the ...Fill bit came from in my API, because the 
 region covered by a stroked path and that covered by a filled path are 
 different, even though testing for a hit against a filled region would 
 by far be the common case).

 We can also call the other one isPointOnPath(), if we want to keep the 
 method names reasonably short. I'm not sure we'll ever need to add it, 
 though. Getting people to click on a line is generally silly.


We do have a need of isPointOnPath() for editing Bezier lines
interactively (on a font editing interface). When people want to add a
new point on an already existing curve, we have to know if the click is
on path. besides, we need double click on the curve to pickup the whole
path and then drag on the line to move the whole path.

So I dig up a 2006 post...

Of course it's hard to get people click on a line precisely. But we can
check isPointOnPath for an 5x5 square instead to make the operation easier.

Doing point on curve in javascript is painful. And since checking
isPointInPath() already need to detect the on edge case, this shouldn't
be too much a burdern on the browser developers.

So please conside add the isPointOnPath() call to the function.




Re: [whatwg] proposed canvas 2d API additions

2009-02-28 Thread Philip Taylor
On Sat, Feb 28, 2009 at 8:38 PM, JustFillBug mozbug...@yahoo.com.au wrote:
 On 2006-04-26, Ian Hickson i...@hixie.ch wrote:
 On Mon, 24 Apr 2006, Vladimir Vukicevic wrote:

 We can always add isPointInStrokedPath if we ever want to bother with
 that (which is where the ...Fill bit came from in my API, because the
 region covered by a stroked path and that covered by a filled path are
 different, even though testing for a hit against a filled region would
 by far be the common case).

 We can also call the other one isPointOnPath(), if we want to keep the
 method names reasonably short. I'm not sure we'll ever need to add it,
 though. Getting people to click on a line is generally silly.

(Or maybe we could add a convertStrokeToPath() function, which
replaces the current path with a path representing the outline of what
you'd get if you stroked the current path, and then use isPointInPath
on it.)

 We do have a need of isPointOnPath() for editing Bezier lines
 interactively (on a font editing interface). [...]

 Doing point on curve in javascript is painful. And since checking
 isPointInPath() already need to detect the on edge case, this shouldn't
 be too much a burdern on the browser developers.

 So please conside add the isPointOnPath() call to the function.

What makes it painful? If you're only using Beziers, it doesn't seem
too hard to approximate the curves as line segments and then calculate
distances from that.
http://philip.html5.org/demos/canvas/bezier-approx.html is fairly
straightforward (and a much more accurate version shouldn't be much
more complex) and can detect when your mouse is near a curve. (But if
this is a common problem, it would indeed be nicer if the canvas API
provided the functionality instead of forcing you to reimplement it.)

-- 
Philip Taylor
exc...@gmail.com


Re: [whatwg] proposed canvas 2d API additions

2006-08-29 Thread Anne van Kesteren

On Fri, 19 May 2006 17:34:04 +0200, Ian Hickson [EMAIL PROTECTED] wrote:

One other problem I had with it was that the colors are restricted to 8
bit. That may potentially lead to data loss but I guess it's not a major
concern yet.


This is already the case in other aspects of the API, I think.


As you pointed out some to me, not for percentage rgb color values.


--
Anne van Kesteren
http://annevankesteren.nl/
http://www.opera.com/



Re: [whatwg] proposed canvas 2d API additions

2006-08-29 Thread Ian Hickson
On Tue, 29 Aug 2006, Anne van Kesteren wrote:
 On Fri, 19 May 2006 17:34:04 +0200, Ian Hickson [EMAIL PROTECTED] wrote:
   One other problem I had with it was that the colors are restricted to 8
   bit. That may potentially lead to data loss but I guess it's not a major
   concern yet.
  
  This is already the case in other aspects of the API, I think.
 
 As you pointed out some to me, not for percentage rgb color values.

I don't recall what this thread was about. Was there a change you wanted 
made to the spec?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-05-19 Thread Ian Hickson
On Tue, 9 May 2006, Ric Hardacre wrote:
 
 i absolutely agree that pixels should be treated as atomic units. if a 
 canvas pixel space is initialized as a 1x1 square then there is only one 
 (visible) coordinate you could possibly access: (0,0)

Canvas' coordinate space is not quantised. The arguments are all floats, 
not ints.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-05-16 Thread Vladimir Vukicevic

On 4/26/06, Ian Hickson [EMAIL PROTECTED] wrote:

   ImageData getImageData(in float x, in float y, in float w, in float h);
   void drawImageData(in float x, in float y, in ImageData d);


I'm about to implement this as suggested; however, I'd call the second
function here putImageData instead of drawImageData; draw implies
an actual drawing operation, similar to drawImage, that would be
affected by (at least) the current compositing operator.  What's
actually happening is a direct replacement of the pixel data in the
given region, so that could be confusing.  (If someone does want the
operator to be involved they can use an offscreen canvas to call
putImageData on and drawImage that in.)

   - Vlad


Re: [whatwg] proposed canvas 2d API additions

2006-05-09 Thread Anne van Kesteren

Quoting Vladimir Vukicevic [EMAIL PROTECTED]:

I agree that they shouldn't be affected by the CTM, but I disagree that
they should be integers. e.g. in cases like:

  HTML  CSS
  canvas height=1 width=1 canvas { height: 100%; width: 100%; }
  /canvas

...where the JS then uses the coordinate space 0..1,0..1 the author might
want to grab the top corner by grabbing the 0,0,0.25,0.25 rect.


So, I really don't like this -- we need to nail down space the
getPixels/setPixels coordinates should be in.  I still think that they
should always be in the canvas space, no matter how many pixels they
refer to in the rendered content or in the device space.  Note that in
your example, the canvas can still be a 1x1 pixel canvas (and, I
believe, will be in all current implementations) -- that one pixel
will just cover the entire page.


That is what Ian is saying. He's saying it's a 1x1 pixel canvas just  
that within that 1x1 pixel there could be different subpixels with  
different colors you could try to get using floating points instead of  
integers.



--
Anne van Kesteren
http://annevankesteren.nl/



Re: [whatwg] proposed canvas 2d API additions

2006-05-08 Thread Anne van Kesteren

Quoting Ian Hickson [EMAIL PROTECTED]:

How about:

   interface ImageData {
 readonly attribute long int width;
 readonly attribute long int height;
 readonly attribute Array data;
   }


I saw you added this API and noted that you haven't addressed security  
yet. Basically the same security considerations as for toDataURL()  
should apply. I suggest adding that somewhere.


One other problem I had with it was that the colors are restricted to  
8 bit. That may potentially lead to data loss but I guess it's not a  
major concern yet.



--
Anne van Kesteren
http://annevankesteren.nl/



Re: [whatwg] proposed canvas 2d API additions

2006-05-05 Thread Ian Hickson
On Fri, 28 Apr 2006, Arve Bersvendsen wrote:
 
 I would suggest that we do not use floats for the color values.  While 
 the choice of floats versus integers hardly matters on the desktop, it 
 is a big deal on mobile devices, where you (often) may find that there 
 is no FPU, so any floating point operations are performed entirely in 
 software.  The performance implication of this is huge, and we should 
 not sacrifice performance for theoretical perfection.

This seems like a valid argument.


On Fri, 28 Apr 2006, Vladimir Vukicevic wrote:
  
  How about:
  
 interface ImageData {
   readonly attribute long int width;
   readonly attribute long int height;
   readonly attribute Array data;
 }
 
 I have a nagging feeling that this is a bad idea, but I can't explain 
 why, because I do like the idea.  If we do this, let's advance it a bit:

I'd rather keep it as simple as possible in the first version.


  readonly attribute string format; /* only rgba is valid for now */
 
 format would specify the type of data that is in data; only rgba would 
 be valid for now, but we this gives us a way to extend that later on.

We can always extend it in the next version by adding format, there's no 
reason to add it now that I can see. In fact we might (on the long run) 
want to add it to the context instead of the ImageData object, e.g. to 
make the entire API use CMYK or 16 bit RGBA instead of 8bit RGBA like 
today. I think until we have clear requirements on the issue we should 
just avoid adding features to handle it.


 ImageData createImageData(in string format, in string width, in string
 height, in Array data);
 
 for creating ImageData out of an arbitrary set of generated data (e.g. 
 evaluating some function, drawing the results).  This would be 
 especially needed because you can't assign to data in an ImageData 
 structure (since you have it readonly); can only change the values of 
 its members.

You could always create an arbitrarily sized ImageData structure by 
creating a blank canvas and using getPixels on that canvas. This would 
let you initialise the array to white, transparent black, or whatever is 
necessary.


 ImageData getImageData(in float x, in float y, in float w, in float h);
 void drawImageData(in float x, in float y, in ImageData d);
 
 I would keep x/y/w/h as integers, and explicitly specify that they're 
 not affected by the CTM.  If they are, you can't guarantee a lossless 
 round-trip (since if you shift over by half a pixel you have to do lots 
 of resampling, etc.).

I agree that they shouldn't be affected by the CTM, but I disagree that 
they should be integers. e.g. in cases like:

   HTML  CSS
   canvas height=1 width=1 canvas { height: 100%; width: 100%; }
   /canvas

...where the JS then uses the coordinate space 0..1,0..1 the author might 
want to grab the top corner by grabbing the 0,0,0.25,0.25 rect.


On Thu, 4 May 2006, Vladimir Vukicevic wrote:

  interface ImageData {
readonly attribute long int width;
readonly attribute long int height;
readonly attribute Array data;
  }
 
 Actually, let's step back a second; this may be massive
 overengineering.  What if we simply had:
 
readonly attribute float deviceScaling;
 
 on the 2D context, which would give the scaling factor between
 canvas-space pixels (that is, the space that the canvas width/height
 attributes are in) and device-space pixels (the pixels of the actual
 backing store).  So if canvas width=200 height=200/ was
 represented with a 300x300 backing store, deviceScaling would be 1.5;
 if 400x400, it would be 2.0.  (If necessary, we can have
 deviceScalingX, deviceScalingY.)

You'd still need the object if you wanted to extend it in some other way, 
e.g. with your suggested format attribute. Your proposal basically just 
moves two attributes from that object to the canvas, and the author now 
has to keep track of the height and width separately all the time when he 
passes the array around to mutate it.


 Also... should the RGBA data be returned with premultiplied alpha or 
 not?  Premultiplied tends to be better for the math, non-premultiplied 
 tends to be easier to understand.  (That is, 50% opaque green is 
 (0,255,0,128) if non-premultiplied, or (0,128,0,128) if premultiplied.)

For consistency with the rest of the API I'd say non-premultiplied, but I 
have no strong opinion on this.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-05-04 Thread Vladimir Vukicevic

On 4/28/06, Vladimir Vukicevic [EMAIL PROTECTED] wrote:

interface ImageData {
  readonly attribute string format; /* only rgba is valid for now */
  readonly attribute long int width;
  readonly attribute long int height;
  readonly attribute Array data;
}


Actually, let's step back a second; this may be massive
overengineering.  What if we simply had:

   readonly attribute float deviceScaling;

on the 2D context, which would give the scaling factor between
canvas-space pixels (that is, the space that the canvas width/height
attributes are in) and device-space pixels (the pixels of the actual
backing store).  So if canvas width=200 height=200/ was
represented with a 300x300 backing store, deviceScaling would be 1.5;
if 400x400, it would be 2.0.  (If necessary, we can have
deviceScalingX, deviceScalingY.)

Then getPixels is defined to take parameters in canvas pixel space,
and returns the ARGB array in device space; if you ask for a 50x50
region, you'll get back 100x100x4 samples, with a deviceScaling of
2.0.  putPixels would take coordinates in canvas pixel space again,
but would take the appropriate device-pixel-sized ARGB array.  This
becomes tricky with non-integer deviceScaling; that is, if a 2x2
region becomes a 3x3 region with a deviceScaling of 1.5, what do you
return when you're asked for x=1 y=1 w=1 h=1?  I'd say that you end up
resampling and shifting over your 3x3 device space backing store by .5
pixels so that the region would start on a device pixel boundary. 
This would obviously not be a clean round-trip, but the spec can

inform authors how to ensure a clean round trip (only request regions
where your x/y * deviceScaling are integers).

This removes the need for a separate ImageData object and all the
extra gunk necessary there, but still maintains full resolution
independence.  Any thoughts on this?

  - Vlad


Re: [whatwg] proposed canvas 2d API additions

2006-04-28 Thread Vladimir Vukicevic

On 4/26/06, Ian Hickson [EMAIL PROTECTED] wrote:

On Mon, 24 Apr 2006, Vladimir Vukicevic wrote:

 The use case that I'm thinking of is essentially:

 pixels = c.getPixels(x, y, width, height);
 /* manipulate pixels here */
 c.putPixels(pixels, x, y, width, height);

 That is, direct pixel manipulation, for performing some operation that
 can't be done using the context API.

Ok. That is helpful, because there have been several use cases thrown
about and it wasn't clear to me which use case we actually cared about.

It seems to me that a critical requirement of the use case you describe is
that the result of the following script:

   pixels = c.getPixels(x, y, width, height);
   /* do nothing here */
   c.putPixels(pixels, x, y, width, height);

...be a (possibly expensive) no-op. That is, you should not lose image
data -- the above should not corrupt your picture. This means the pixel
data returned must be native resolution data.

How about:

   interface ImageData {
 readonly attribute long int width;
 readonly attribute long int height;
 readonly attribute Array data;
   }


I have a nagging feeling that this is a bad idea, but I can't explain
why, because I do like the idea.  If we do this, let's advance it a
bit:

interface ImageData {
 readonly attribute string format; /* only rgba is valid for now */
 readonly attribute long int width;
 readonly attribute long int height;
 readonly attribute Array data;
}

format would specify the type of data that is in data; only rgba
would be valid for now, but we this gives us a way to extend that
later on.

and also add:

ImageData createImageData(in string format, in string width, in string
height, in Array data);

for creating ImageData out of an arbitrary set of generated data
(e.g. evaluating some function, drawing the results).  This would be
especially needed because you can't assign to data in an ImageData
structure (since you have it readonly); can only change the values of
its members.


   ImageData getImageData(in float x, in float y, in float w, in float h);
   void drawImageData(in float x, in float y, in ImageData d);


I would keep x/y/w/h as integers, and explicitly specify that they're
not affected by the CTM.  If they are, you can't guarantee a lossless
round-trip (since if you shift over by half a pixel you have to do
lots of resampling, etc.).

  - Vlad


Re: [whatwg] proposed canvas 2d API additions

2006-04-26 Thread Ian Hickson
On Mon, 24 Apr 2006, Vladimir Vukicevic wrote:
 
 The use case that I'm thinking of is essentially:
 
 pixels = c.getPixels(x, y, width, height);
 /* manipulate pixels here */
 c.putPixels(pixels, x, y, width, height);
 
 That is, direct pixel manipulation, for performing some operation that
 can't be done using the context API.

Ok. That is helpful, because there have been several use cases thrown 
about and it wasn't clear to me which use case we actually cared about.

It seems to me that a critical requirement of the use case you describe is 
that the result of the following script:

   pixels = c.getPixels(x, y, width, height);
   /* do nothing here */
   c.putPixels(pixels, x, y, width, height);

...be a (possibly expensive) no-op. That is, you should not lose image 
data -- the above should not corrupt your picture. This means the pixel 
data returned must be native resolution data.

How about:

   interface ImageData {
 readonly attribute long int width;
 readonly attribute long int height;
 readonly attribute Array data;
   }

   ImageData getImageData(in float x, in float y, in float w, in float h);
   void drawImageData(in float x, in float y, in ImageData d);

...where getImageData() returns an object implementing the ImageData 
interface which contains the actual pixel data for the backing store of 
the canvas, with the width and height attributes giving the number of 
actual data pixels returned? The array would contain, as in your proposal, 
4*width*height values, giving the R, G, B, and A components of each pixel 
in the image, row by row.

In the ECMAScript binding we could make the ImageData object have the 
data field as its default so it could be dereferenced directly as if the 
ImageData object itself were the array.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-04-26 Thread Ian Hickson
On Mon, 24 Apr 2006, Vladimir Vukicevic wrote:
 
  Assuming nobody has any problem with:
 
 boolean isPointInPath(in float x, in float y);
 
  ...then I'll add that to the spec when you reply to this mail.
 
 Sure, isPointInPath sounds fine.

Added.

 We can always add isPointInStrokedPath if we ever want to bother with 
 that (which is where the ...Fill bit came from in my API, because the 
 region covered by a stroked path and that covered by a filled path are 
 different, even though testing for a hit against a filled region would 
 by far be the common case).

We can also call the other one isPointOnPath(), if we want to keep the 
method names reasonably short. I'm not sure we'll ever need to add it, 
though. Getting people to click on a line is generally silly.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-04-26 Thread Ian Hickson
On Sat, 22 Apr 2006, Sjoerd Visscher wrote:
 Ian Hickson wrote:
  On Sat, 22 Apr 2006, Sjoerd Visscher wrote:
I understand what you are proposing. What I don't understand is what
colour should be returned when the many device pixels represented by the
given coordinate space pixel have different colors.
   The weighted average of the colors in the square the size of 1 by 1 canvas
   pixels.
  
  ...in fact, that won't work. It would mean that this, which should be a
  no-op:
  
 c.putPixels(c.getPixels(x, y, width, height), x, y, width, height);
  
  ...will end up down-sampling the bitmap, which seems like it would break the
  main use case for this API.
 
 If this is the main use case, then putPixels is just drawImage, and 
 getPixels should be called copyCanvas, with the 4 arguments just setting 
 a clip region.

Vlad suggested the use case was sightly more complex, basically:

   c.putPixels(manipulate(c.getPixels(...)), ...);


 The main use case of calculating the color of a (pixel-)square whould be 
 the eye drop tool.

You could manually do this using the API I suggested earlier today, FWIW, 
including handling transparency in special ways.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-04-26 Thread Ian Hickson
On Sun, 23 Apr 2006, Maciej Stachowiak wrote:

 1) Add a call to allow copying a rect from one canvas to another. You 
 may want to be able to control the compositing mode for this. Then you 
 can use an offscreen canvas to store a bitmap for later drawing into 
 your visible canvas. If this involves a change of size the 
 implementation has the opportunity to apply intelligent scaling.

We already have this.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-04-24 Thread Arve Bersvendsen

[ Ian Hickson ]

I don't understand how these are supposed to work when the underlying
bitmap's device pixel space does not map 1:1 to the coordinate space.


[ Vladimir Vukicevic ]

I'm not sure what you mean -- the coordinates here are explicit canvas
pixels, and they specifically ignore the current canvas transform.
So, given
 canvas width=100 height=200/canvas

the coordinates would be 0..99, 0..199.


Without expressing any other opinion at the moment, I'd just like to  
clarify how Opera's implementation of getPixel/setPixel currently follows  
the coordinate space, as Vlad is suggesting here, disregarding any  
translation and rotation. Given the following script snippet:


  gc =  
document.getElementsByTagName('canvas')[0].getContext('opera-2dgame');

  for ( var y = 50; y  100; y++){
for (var x = 50; x  100; x++){
  gc.setPixel(x,y,blue);
}
  }

... with this CSS:

  canvas  {
width: 200px;
height: 200px;
border: 1px solid black;
  }

and the following markup:

  canvas width=100 height=100

we fill the bottom-right quadrant of the canvas, with a rectangle that is  
comprised of 100x100 CSS pixels.


--
Arve Bersvendsen, Opera Software ASA


Re: [whatwg] proposed canvas 2d API additions

2006-04-24 Thread Vladimir Vukicevic
Arve's example is how I imagined putPixels working -- basically as a
potential optimization over a bunch of fillRect calls.  Even in the
presence of a higher resolution backing store, this can provide for an
optimization -- load the putPixels data into a bitmap image that's
width*height pixels and draw it to the canvas backing store with the
appropriate resolution scaling.

The use case that I'm thinking of is essentially:

pixels = c.getPixels(x, y, width, height);
/* manipulate pixels here */
c.putPixels(pixels, x, y, width, height);

That is, direct pixel manipulation, for performing some operation that
can't be done using the context API.  An example might be to perform a
desaturate on a region of the canvas to obtain a grayscale region from
a color one.  Any image-type operations (copying a region from one
place to another) should be done using the existing drawImage or other
APIs, with temporary canvases as needed.

Because of this, putPixels will end up losing quality in a
getPixels/putPixels round-trip if the backing store is higher
resolution.  I'm not sure what to do about that; one solution might be
that we specify that a pixel in the canvas backing store must map to
exactly one pixel in canvas-space; that is, that there's always a
cluster of NxN device pixels that correspond to 1 canvas pixel.  We
can then have getPixels return the actual device-resolution pixel
data, along with a resolution multiplier or somesuch.  I don't really
like that, though; I'd much rather leave putPixels as the
fillRect-type optimization, and have getPixels return a simple average
of the color of all the device pixels that compose a single target
pixel.  (Again, as with the putPixels case, this can be optimized by
simply doing a downscaling of the appropriate region of the
higher-resolution backing store into a width*height pixel buffer).

- Vlad

On 4/24/06, Arve Bersvendsen [EMAIL PROTECTED] wrote:
 [ Ian Hickson ]
  I don't understand how these are supposed to work when the underlying
  bitmap's device pixel space does not map 1:1 to the coordinate space.

 [ Vladimir Vukicevic ]
  I'm not sure what you mean -- the coordinates here are explicit canvas
  pixels, and they specifically ignore the current canvas transform.
  So, given
   canvas width=100 height=200/canvas
 
  the coordinates would be 0..99, 0..199.

 Without expressing any other opinion at the moment, I'd just like to
 clarify how Opera's implementation of getPixel/setPixel currently follows
 the coordinate space, as Vlad is suggesting here, disregarding any
 translation and rotation. Given the following script snippet:

gc =
 document.getElementsByTagName('canvas')[0].getContext('opera-2dgame');
for ( var y = 50; y  100; y++){
  for (var x = 50; x  100; x++){
gc.setPixel(x,y,blue);
  }
}

 ... with this CSS:

canvas  {
  width: 200px;
  height: 200px;
  border: 1px solid black;
}

 and the following markup:

canvas width=100 height=100

 we fill the bottom-right quadrant of the canvas, with a rectangle that is
 comprised of 100x100 CSS pixels.

 --
 Arve Bersvendsen, Opera Software ASA




Re: [whatwg] proposed canvas 2d API additions

2006-04-23 Thread Maciej Stachowiak


putPixels is just a cover for drawing a bunch of 1 x 1 rects. And in  
general it won't be much more efficient than that, due to possible  
device scaling. Is drawing a bunch of 1x1 rects a common enough use  
case to be worth it? Seems like it would almost always be better  
solved by drawing an image or using other drawing calls.


getPixels, as others have mentioned, is hard to define sensibly when  
the canvas backing store is higher resolution than the canvas  
coordinate space.


Calling these pixels also seems misleading since they are neither  
device pixels nor CSS px units.


Proposed alternate design:

1) Add a call to allow copying a rect from one canvas to another. You  
may want to be able to control the compositing mode for this. Then  
you can use an offscreen canvas to store a bitmap for later drawing  
into your visible canvas. If this involves a change of size the  
implementation has the opportunity to apply intelligent scaling.


2) Add an averageColorInRect call for the benefit of eyedropper  
type tools.


I'm actually not sure how people intend to use getPixels / putPixels  
so I'm not 100% sure this covers the use cases.


Regards
Maciej



On Apr 21, 2006, at 12:10 PM, Vladimir Vukicevic wrote:


Hi folks,

I'd like to suggest extending the HTML canvas 2d context with a few
additions.  These are variations on some of the methods added to
Opera's opera-2dgame context.  The methods are intended to give
content authors direct pixel access to the canvas, as well as provide
some basic point-in-path testing functionality.

float [] getPixels (in integer x, in integer y, in integer width,
in integer height);

Returns an array of floats representing the color values in the region
of pixels in the canvas whose upper left corner is at (x,y) and which
extends for width,height pixels.  These coordinates are in canvas
pixel space (that is, the same space that the canvas width and height
attributes are specified in).  The color values for each pixel are
returned as 4 floats, each in the range of 0.0 to 1.0, in R,G,B,A
order.  That is, given the paramters (0,0,2,2), the returned array
will be [R00 G00 B00 A00 R10 G10 B10 A10 R01 G01 B01 A01 R11 B11 G11
A11].

Note: we could return the pixels as integers in the range of 0..255,
as 8-bit color is most likely what canvases will be dealing with.
However, using floats allow us to easily extend into a 16-bit
colorspace without any API changes.  In addition, any computation
using these pixels is often done in normalized colors, so the division
by 255 would need to happen anyway.

void putPixels (in float [] pixels, in integer x, in integer y, in
integer width, in integer height);

Does the opposite of getPixels; the given array must be exactly width
* height * 4 elements in length.  The values are to be clamped to
0.0..1.0.

boolean pointInPathFill(in float x, in float y);

pointInPathFill returns true if the given point would be inside the
region filled by the current path, and false otherwise.  The x,y
coordinates are in the current space of the canvas; that is, they are
transformed by the CTM and do not necessarily map directly to pixels.

I'd suggest that these three functions be added directly to the 2d
context; content authors can test for their presence by checking the
function is not null on the 2d context object.  We might want a more
comprehensive way of letting authors test whether particular features
are supported, e.g. shadows, pixel-access, etc, but maybe it's not
necessary.

How's this sound?

- Vlad




Re: [whatwg] proposed canvas 2d API additions

2006-04-22 Thread Sjoerd Visscher

Ian Hickson wrote:

On Sat, 22 Apr 2006, Sjoerd Visscher wrote:
I understand what you are proposing. What I don't understand is what 
colour should be returned when the many device pixels represented by 
the given coordinate space pixel have different colors.
The weighted average of the colors in the square the size of 1 by 1 
canvas pixels.


...in fact, that won't work. It would mean that this, which should be a 
no-op:


   c.putPixels(c.getPixels(x, y, width, height), x, y, width, height);

...will end up down-sampling the bitmap, which seems like it would break 
the main use case for this API.




If this is the main use case, then putPixels is just drawImage, and 
getPixels should be called copyCanvas, with the 4 arguments just setting 
a clip region.


The main use case of calculating the color of a (pixel-)square whould be 
 the eye drop tool.


--
Sjoerd Visscher
http://w3future.com/weblog/


Re: [whatwg] proposed canvas 2d API additions

2006-04-21 Thread Ian Hickson
On Fri, 21 Apr 2006, Vladimir Vukicevic wrote:

 boolean pointInPathFill(in float x, in float y);

This sounds fine to me (though it means you have to spin through creating 
many paths for hit testing, instead of just hanging on to a particular 
path and hit testing a list of paths, which seems silly).


 float [] getPixels (in integer x, in integer y, in integer width,
 in integer height);

 void putPixels (in float [] pixels, in integer x, in integer y, in
 integer width, in integer height);

I don't understand how these are supposed to work when the underlying 
bitmap's device pixel space does not map 1:1 to the coordinate space.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-04-21 Thread Vladimir Vukicevic
On 4/21/06, Ian Hickson [EMAIL PROTECTED] wrote:
 On Fri, 21 Apr 2006, Vladimir Vukicevic wrote:
  boolean pointInPathFill(in float x, in float y);

 This sounds fine to me (though it means you have to spin through creating
 many paths for hit testing, instead of just hanging on to a particular
 path and hit testing a list of paths, which seems silly).

Hm, I'm not sure what you mean -- we have no way of holding on to a
Path as a retained object.  If we did, then you could hit test
through this object; there would be a speedup for some paths, but not
noticable for most, I would think.  Adding support for retained path
objects would be an additional chunk of work, though, and isn't really
necessary.

  float [] getPixels (in integer x, in integer y, in integer width,
  in integer height);
 
  void putPixels (in float [] pixels, in integer x, in integer y, in
  integer width, in integer height);

 I don't understand how these are supposed to work when the underlying
 bitmap's device pixel space does not map 1:1 to the coordinate space.

I'm not sure what you mean -- the coordinates here are explicit canvas
pixels, and they specifically ignore the current canvas transform. 
So, given

  canvas width=100 height=200/canvas

the coordinates would be 0..99, 0..199.  Are you referring to the case
where on, say, a very high resolution display the canvas might choose
to create a 200x400 pixel canvas and just present it as 100x200, and
quadruple the physical screen space taken up by each pixel?  If so, it
would still map to the original 100x200 pixels; the fact that each of
those takes up 4 physical device pixels should be transparent to the
user.  That is, we have:

  CSS size (width/height style)   --  canvas size  --  device bitmap size

The API would always operate in terms of canvas size.  Does that make
more sense?

- Vlad


Re: [whatwg] proposed canvas 2d API additions

2006-04-21 Thread Ian Hickson
On Fri, 21 Apr 2006, Vladimir Vukicevic wrote:
 On 4/21/06, Ian Hickson [EMAIL PROTECTED] wrote:
  On Fri, 21 Apr 2006, Vladimir Vukicevic wrote:
  
   boolean pointInPathFill(in float x, in float y);
 
  This sounds fine to me (though it means you have to spin through 
  creating many paths for hit testing, instead of just hanging on to a 
  particular path and hit testing a list of paths, which seems silly).
 
 Hm, I'm not sure what you mean -- we have no way of holding on to a 
 Path as a retained object.  If we did, then you could hit test through 
 this object; there would be a speedup for some paths, but not noticable 
 for most, I would think.  Adding support for retained path objects would 
 be an additional chunk of work, though, and isn't really necessary.

I was suggesting that we may wish to add that code.

Consider a canvas implementation of a board game with many little 
pieces. You get a click and want to find out which piece the click was on. 
With the API above, you basically have to redraw the entire board, except 
instead of calling .fill() on each one, you call .pointInPathFill(). That 
seems painful. Then again, you have the same problem with .fill() in the 
first place, so maybe it's not a big deal.

(Incidentally, I would prefer isPointInPathFill() or isPointInPath() for 
this method name, since it is a test that returns a boolean.)

Assuming nobody has any problem with:

   boolean isPointInPath(in float x, in float y);

...then I'll add that to the spec when you reply to this mail.


   float [] getPixels (in integer x, in integer y, in integer width,
   in integer height);
  
   void putPixels (in float [] pixels, in integer x, in integer y, in
   integer width, in integer height);
 
  I don't understand how these are supposed to work when the underlying
  bitmap's device pixel space does not map 1:1 to the coordinate space.
 
 I'm not sure what you mean -- the coordinates here are explicit canvas 
 pixels, and they specifically ignore the current canvas transform. So, 
 given
 
   canvas width=100 height=200/canvas
 
 the coordinates would be 0..99, 0..199.  Are you referring to the case
 where on, say, a very high resolution display the canvas might choose
 to create a 200x400 pixel canvas and just present it as 100x200, and
 quadruple the physical screen space taken up by each pixel?

Yes, except it doesn't have to be a high-resolution display:

   canvas height=10 width=10/   canvas { height: 100%; width: 100%; }

...should, per spec, work perfectly fine, but each coordinate space unit 
pixel is likely to map to many device pixels, and thus many colors.


 If so, it would still map to the original 100x200 pixels; the fact that 
 each of those takes up 4 physical device pixels should be transparent to 
 the user.  That is, we have:
 
   CSS size (width/height style)   --  canvas size  --  device bitmap size
 
 The API would always operate in terms of canvas size.  Does that make 
 more sense?

I understand what you are proposing. What I don't understand is what 
colour should be returned when the many device pixels represented by the 
given coordinate space pixel have different colors.


Incidentally, what JS type did you mean float[] to map to? A simply Array 
instance?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] proposed canvas 2d API additions

2006-04-21 Thread Sjoerd Visscher
I understand what you are proposing. What I don't understand is what 
colour should be returned when the many device pixels represented by the 
given coordinate space pixel have different colors.


The weighted average of the colors in the square the size of 1 by 1 
canvas pixels.


--
Sjoerd Visscher
http://w3future.com/weblog/


Re: [whatwg] proposed canvas 2d API additions

2006-04-21 Thread Ian Hickson
On Sat, 22 Apr 2006, Sjoerd Visscher wrote:
 
  I understand what you are proposing. What I don't understand is what 
  colour should be returned when the many device pixels represented by 
  the given coordinate space pixel have different colors.
 
 The weighted average of the colors in the square the size of 1 by 1 
 canvas pixels.

...in fact, that won't work. It would mean that this, which should be a 
no-op:

   c.putPixels(c.getPixels(x, y, width, height), x, y, width, height);

...will end up down-sampling the bitmap, which seems like it would break 
the main use case for this API.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'