Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-15 Thread Denis Lila
uts (but not at the
> >>>> same
> >>>>>> time).
> >>>>>> This could no longer be supported with this approach.
> >>>>>> The way I did it has none of these weaknesses.
> >>>>>>
> >>>>>> 2. As for algorithms for the circle approximation, I considered
> 2:
> >>>>>> a. Compute the control points using the constraints that
> >>>>>> B(1/3)=A(a+t/3)
> >>>>>> and B(2/3) = A(a+2t/3) (i.e. make the arc and the bezier curve
> >>>>>> coincide at 2
> >>>>>> evenly spaced points in the arc). This didn't work very well:
> some
> >>>> of
> >>>>>> the end
> >>>>>> caps looked more like triangles.
> >>>>>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This
> worked
> >>>>>> better, but
> >>>>>> still not good enough.
> >>>>>>
> >>>>>> If anyone knows of any better ways to compute the control
> points,
> >>>>>> please let
> >>>>>> me know.
> >>>>>>
> >>>>>> I'm sorry for the length of this. I tried to make it shorter.
> >>>>>>
> >>>>>> Thank you very much,
> >>>>>> Denis.
> >>>>>>
> >>>>>>
> >>>>>> - "Jim Graham"  wrote:
> >>>>>>
> >>>>>>> Hi Denis,
> >>>>>>>
> >>>>>>> Consider the case of using BasicStroke.createStrokedShape(). 
> How
> >>>> do
> >>>>>>> you
> >>>>>>> know how many pixels the resulting path will occupy?  You
> can't
> >>>>>> reduce
> >>>>>>> to concrete samples if you don't know the transform.
> >>>>>>>
> >>>>>>> So, for rendering, then you may be correct.  But for cases
> where
> >>>> the
> >>>>>>> path is being asked for then beziers are the only responsible
> >>>>>>> solution...
> >>>>>>>
> >>>>>>> ...jim
> >>>>>>>
> >>>>>>> Denis Lila wrote:
> >>>>>>>> Hello Jim.
> >>>>>>>>
> >>>>>>>> I thought about checking the output and changing the
> behaviour
> >>>>>>>> depending on whether the output is a PC2D or a LineSink, but
> I
> >>>>>>> didn't
> >>>>>>>> implement it because I thought the point was to get rid of
> the
> >>>>>>> sampling
> >>>>>>>> at this stage. However, if performance is the issue, then I
> >>>> guess
> >>>>>>> I'll
> >>>>>>>> start working on it.
> >>>>>>>>
> >>>>>>>> Although, I wonder whether it is really worth it. I think
> most
> >>>>>> lines
> >>>>>>> drawn
> >>>>>>>> won't be wider than about 5 pixels, which means that the
> current
> >>>>>> way
> >>>>>>> will
> >>>>>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier
> quarter
> >>>>>>> circles will
> >>>>>>>> require 12 coordinates. In terms of storage, there isn't
> much
> >>>>>>> difference, and
> >>>>>>>> for lines of width 4 or smaller the current method is more
> >>>>>>> efficient.
> >>>>>>>> I'm also guessing that it's harder for the rasterizer to
> deal
> >>>> with
> >>>>>>> bezier
> >>>>>>>> curves than with straight lines, so is it possible that
> >>>> replacing
> >>>>>>> the
> >>>>>>>> 3.14*lineWidth/2 lines generated by the current method with
> 2
> >>>>>> bezier
> >>>>>>>> quarter circles isn't worth it (for small lineWidths)?
> >>>>>>>>
> >>>>>>>> Thanks,
> >>>>>>>> Denis.
> >>>&g

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-13 Thread Jim Graham
straight lines, so is it possible that

replacing

the

3.14*lineWidth/2 lines generated by the current method with 2

bezier

quarter circles isn't worth it (for small lineWidths)?

Thanks,
Denis.

- "Jim Graham"  wrote:


Sigh - that makes sense.  One issue is that the resulting paths

it

generates are much more "verbose" than they need to be.  This

would

generally mean that it takes far more storage than it would

otherwise

need - and it means that if the result needs to be transformed

then

it

would take many more computations to transform each segment

than

the

bezier.

So, perhaps it would be worth having it check the type of the

output

and
do either a bezier or a bunch of lines depending on if it is a

PC2D

or

a
LineSink?

Also, it isn't really that difficult to for Renderer to include

its

own
Cubic/Quadratic flattening code, but it might involve more
calculations
than the round-cap code since it would have to be written for
arbitrary
beziers whereas if you know it is a quarter circle then it is

easier

to
know how far to subdivide...  :-(

...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it

would

have to implement a curveTo method, which means Stroker should
start implementing PathConsumer2D and instead of using a

LineSink

output it would have to use a PathConsumer2D output (either

that,

or

LineSink should include a curveTo method, but then there won't

really

be any difference between a LineSink and a PathConsumer2D. By

the

way,

LineSink doesn't have any implemented methods, so why is it an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape

method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because

the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I

am

not

very

familiar with Bezier curves, but it doesn't seem easy enough

to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the

size

of the cap?  Why not generate a pair of bezier quarter-circles

and

let

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying

affine

transformation set on the graphics object and one tries to draw

a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line

length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like

a

triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the

number

of

points on the pen. The approximation is crude, but it is

simple,

faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if

the

original line width was 100, but g2d.scale(0.1,0.1) was set,

then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-13 Thread Jim Graham
't really that difficult to for Renderer to include

its

own
Cubic/Quadratic flattening code, but it might involve more
calculations
than the round-cap code since it would have to be written for
arbitrary
beziers whereas if you know it is a quarter circle then it is

easier

to
know how far to subdivide...  :-(

...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it

would

have to implement a curveTo method, which means Stroker should
start implementing PathConsumer2D and instead of using a

LineSink

output it would have to use a PathConsumer2D output (either

that,

or

LineSink should include a curveTo method, but then there won't

really

be any difference between a LineSink and a PathConsumer2D. By

the

way,

LineSink doesn't have any implemented methods, so why is it an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape

method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because

the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I

am

not

very

familiar with Bezier curves, but it doesn't seem easy enough

to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the

size

of the cap?  Why not generate a pair of bezier quarter-circles

and

let

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying

affine

transformation set on the graphics object and one tries to draw

a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line

length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like

a

triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the

number

of

points on the pen. The approximation is crude, but it is

simple,

faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if

the

original line width was 100, but g2d.scale(0.1,0.1) was set,

then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-13 Thread Jim Graham
 have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it

would

have to implement a curveTo method, which means Stroker should
start implementing PathConsumer2D and instead of using a

LineSink

output it would have to use a PathConsumer2D output (either

that,

or

LineSink should include a curveTo method, but then there won't

really

be any difference between a LineSink and a PathConsumer2D. By

the

way,

LineSink doesn't have any implemented methods, so why is it an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape

method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because

the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I

am

not

very

familiar with Bezier curves, but it doesn't seem easy enough

to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the

size

of the cap?  Why not generate a pair of bezier quarter-circles

and

let

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying

affine

transformation set on the graphics object and one tries to draw

a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line

length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like

a

triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the

number

of

points on the pen. The approximation is crude, but it is

simple,

faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if

the

original line width was 100, but g2d.scale(0.1,0.1) was set,

then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-13 Thread Jim Graham
here isn't much

difference, and

for lines of width 4 or smaller the current method is more

efficient.

I'm also guessing that it's harder for the rasterizer to deal

with

bezier

curves than with straight lines, so is it possible that

replacing

the

3.14*lineWidth/2 lines generated by the current method with 2

bezier

quarter circles isn't worth it (for small lineWidths)?

Thanks,
Denis.

- "Jim Graham"  wrote:


Sigh - that makes sense.  One issue is that the resulting

paths

it

generates are much more "verbose" than they need to be.  This

would

generally mean that it takes far more storage than it would

otherwise

need - and it means that if the result needs to be transformed

then

it

would take many more computations to transform each segment

than

the

bezier.

So, perhaps it would be worth having it check the type of the

output

and
do either a bezier or a bunch of lines depending on if it is a

PC2D

or

a
LineSink?

Also, it isn't really that difficult to for Renderer to

include

its

own
Cubic/Quadratic flattening code, but it might involve more
calculations
than the round-cap code since it would have to be written for
arbitrary
beziers whereas if you know it is a quarter circle then it is

easier

to
know how far to subdivide...  :-(

 ...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it

would

have to implement a curveTo method, which means Stroker

should

start implementing PathConsumer2D and instead of using a

LineSink

output it would have to use a PathConsumer2D output (either

that,

or

LineSink should include a curveTo method, but then there

won't

really

be any difference between a LineSink and a PathConsumer2D. By

the

way,

LineSink doesn't have any implemented methods, so why is it

an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape

method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output

objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because

the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the

x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would

have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I

am

not

very

familiar with Bezier curves, but it doesn't seem easy enough

to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham"
To: "Denis Lila"
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps

on

scaled lines.

I don't understand - why do we generate sample points based

on

the

size

of the cap?  Why not generate a pair of bezier

quarter-circles

and

let

the rasterizer deal with sampling?

 ...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying

affine

transformation set on the graphics object and one tries to draw

a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array

that

contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line

length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would

be

computed (pi*untransformedLineWidth), so the end cap looks like

a

triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the

number

of

points on the pen. The approximation is crude, but it is

simple,

faster than alternatives
(http://en.wikip

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-12 Thread Denis Lila
 on whether the output is a PC2D or a LineSink, but I
> >>> didn't
> >>>> implement it because I thought the point was to get rid of the
> >>> sampling
> >>>> at this stage. However, if performance is the issue, then I
> guess
> >>> I'll
> >>>> start working on it.
> >>>>
> >>>> Although, I wonder whether it is really worth it. I think most
> >> lines
> >>> drawn
> >>>> won't be wider than about 5 pixels, which means that the current
> >> way
> >>> will
> >>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter
> >>> circles will
> >>>> require 12 coordinates. In terms of storage, there isn't much
> >>> difference, and
> >>>> for lines of width 4 or smaller the current method is more
> >>> efficient.
> >>>> I'm also guessing that it's harder for the rasterizer to deal
> with
> >>> bezier
> >>>> curves than with straight lines, so is it possible that
> replacing
> >>> the
> >>>> 3.14*lineWidth/2 lines generated by the current method with 2
> >> bezier
> >>>> quarter circles isn't worth it (for small lineWidths)?
> >>>>
> >>>> Thanks,
> >>>> Denis.
> >>>>
> >>>> - "Jim Graham"  wrote:
> >>>>
> >>>>> Sigh - that makes sense.  One issue is that the resulting paths
> >> it
> >>>>> generates are much more "verbose" than they need to be.  This
> >> would
> >>>>> generally mean that it takes far more storage than it would
> >>> otherwise
> >>>>> need - and it means that if the result needs to be transformed
> >> then
> >>> it
> >>>>> would take many more computations to transform each segment
> than
> >>> the
> >>>>> bezier.
> >>>>>
> >>>>> So, perhaps it would be worth having it check the type of the
> >>> output
> >>>>> and
> >>>>> do either a bezier or a bunch of lines depending on if it is a
> >> PC2D
> >>> or
> >>>>> a
> >>>>> LineSink?
> >>>>>
> >>>>> Also, it isn't really that difficult to for Renderer to include
> >>> its
> >>>>> own
> >>>>> Cubic/Quadratic flattening code, but it might involve more
> >>>>> calculations
> >>>>> than the round-cap code since it would have to be written for
> >>>>> arbitrary
> >>>>> beziers whereas if you know it is a quarter circle then it is
> >>> easier
> >>>>> to
> >>>>> know how far to subdivide...  :-(
> >>>>>
> >>>>> ...jim
> >>>>>
> >>>>> Denis Lila wrote:
> >>>>>> So, I have been thinking about this, and I can't see a good
> >>>>>> way to do it that wouldn't involve heavy changes to Pisces.
> >>>>>>
> >>>>>> In order for Stroker to generate Bezier quarter circles, it
> >> would
> >>>>>> have to implement a curveTo method, which means Stroker should
> >>>>>> start implementing PathConsumer2D and instead of using a
> >> LineSink
> >>>>>> output it would have to use a PathConsumer2D output (either
> >> that,
> >>>>> or
> >>>>>> LineSink should include a curveTo method, but then there won't
> >>>>> really
> >>>>>> be any difference between a LineSink and a PathConsumer2D. By
> >> the
> >>>>> way,
> >>>>>> LineSink doesn't have any implemented methods, so why is it an
> >>>>> abstract
> >>>>>> class as opposed to an interface?)
> >>>>>>
> >>>>>> Stroker is used in 3 ways:
> >>>>>> 1. As an implementation of BasicStroke's createStrokedShape
> >>> method.
> >>>>> This
> >>>>>> uses a Path2D object as output.
> >>>>>> 2. As a way of feeding a PathConsumer2D without calling
> >>>>> createStrokedShape
> >>>>>> to generate an intermediate Sh

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-12 Thread Denis Lila
t;> evenly spaced points in the arc). This didn't work very well: some
> of
> >>> the end
> >>> caps looked more like triangles.
> >>> b. Let B(1/2) = A(a+t/2), and B'(1/2) = A'(a+t/2). This
> worked
> >>> better, but
> >>> still not good enough.
> >>>
> >>> If anyone knows of any better ways to compute the control points,
> >>> please let
> >>> me know.
> >>>
> >>> I'm sorry for the length of this. I tried to make it shorter.
> >>>
> >>> Thank you very much,
> >>> Denis.
> >>>
> >>>
> >>> - "Jim Graham"  wrote:
> >>>
> >>>> Hi Denis,
> >>>>
> >>>> Consider the case of using BasicStroke.createStrokedShape().  How
> do
> >>>> you
> >>>> know how many pixels the resulting path will occupy?  You can't
> >>> reduce
> >>>> to concrete samples if you don't know the transform.
> >>>>
> >>>> So, for rendering, then you may be correct.  But for cases where
> the
> >>>> path is being asked for then beziers are the only responsible
> >>>> solution...
> >>>>
> >>>> ...jim
> >>>>
> >>>> Denis Lila wrote:
> >>>>> Hello Jim.
> >>>>>
> >>>>> I thought about checking the output and changing the behaviour
> >>>>> depending on whether the output is a PC2D or a LineSink, but I
> >>>> didn't
> >>>>> implement it because I thought the point was to get rid of the
> >>>> sampling
> >>>>> at this stage. However, if performance is the issue, then I
> guess
> >>>> I'll
> >>>>> start working on it.
> >>>>>
> >>>>> Although, I wonder whether it is really worth it. I think most
> >>> lines
> >>>> drawn
> >>>>> won't be wider than about 5 pixels, which means that the
> current
> >>> way
> >>>> will
> >>>>> emit about 7 lines, so that's 14 coordinates. 2 bezier quarter
> >>>> circles will
> >>>>> require 12 coordinates. In terms of storage, there isn't much
> >>>> difference, and
> >>>>> for lines of width 4 or smaller the current method is more
> >>>> efficient.
> >>>>> I'm also guessing that it's harder for the rasterizer to deal
> with
> >>>> bezier
> >>>>> curves than with straight lines, so is it possible that
> replacing
> >>>> the
> >>>>> 3.14*lineWidth/2 lines generated by the current method with 2
> >>> bezier
> >>>>> quarter circles isn't worth it (for small lineWidths)?
> >>>>>
> >>>>> Thanks,
> >>>>> Denis.
> >>>>>
> >>>>> - "Jim Graham"  wrote:
> >>>>>
> >>>>>> Sigh - that makes sense.  One issue is that the resulting
> paths
> >>> it
> >>>>>> generates are much more "verbose" than they need to be.  This
> >>> would
> >>>>>> generally mean that it takes far more storage than it would
> >>>> otherwise
> >>>>>> need - and it means that if the result needs to be transformed
> >>> then
> >>>> it
> >>>>>> would take many more computations to transform each segment
> than
> >>>> the
> >>>>>> bezier.
> >>>>>>
> >>>>>> So, perhaps it would be worth having it check the type of the
> >>>> output
> >>>>>> and
> >>>>>> do either a bezier or a bunch of lines depending on if it is a
> >>> PC2D
> >>>> or
> >>>>>> a
> >>>>>> LineSink?
> >>>>>>
> >>>>>> Also, it isn't really that difficult to for Renderer to
> include
> >>>> its
> >>>>>> own
> >>>>>> Cubic/Quadratic flattening code, but it might involve more
> >>>>>> calculations
> >>>>>> than the round-cap code since it would have to be written for
> >>>>>> arbitrary
> >>>>

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-09 Thread Jim Graham
eeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am

not

very

familiar with Bezier curves, but it doesn't seem easy enough to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the

size

of the cap?  Why not generate a pair of bezier quarter-circles

and

let

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine

transformation set on the graphics object and one tries to draw a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like a
triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the number

of

points on the pen. The approximation is crude, but it is simple,
faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if the
original line width was 100, but g2d.scale(0.1,0.1) was set, then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-09 Thread Jim Graham
y, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am

not

very

familiar with Bezier curves, but it doesn't seem easy enough to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the

size

of the cap?  Why not generate a pair of bezier quarter-circles

and

let

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine

transformation set on the graphics object and one tries to draw a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like a
triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the number

of

points on the pen. The approximation is crude, but it is simple,
faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if the
original line width was 100, but g2d.scale(0.1,0.1) was set, then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-09 Thread Jim Graham
. This worked
better, but
still not good enough.

If anyone knows of any better ways to compute the control points,
please let
me know.

I'm sorry for the length of this. I tried to make it shorter.

Thank you very much,
Denis.


- "Jim Graham"  wrote:


Hi Denis,

Consider the case of using BasicStroke.createStrokedShape().  How do
you
know how many pixels the resulting path will occupy?  You can't

reduce

to concrete samples if you don't know the transform.

So, for rendering, then you may be correct.  But for cases where the
path is being asked for then beziers are the only responsible
solution...

...jim

Denis Lila wrote:

Hello Jim.

I thought about checking the output and changing the behaviour
depending on whether the output is a PC2D or a LineSink, but I

didn't

implement it because I thought the point was to get rid of the

sampling

at this stage. However, if performance is the issue, then I guess

I'll

start working on it.

Although, I wonder whether it is really worth it. I think most

lines

drawn

won't be wider than about 5 pixels, which means that the current

way

will

emit about 7 lines, so that's 14 coordinates. 2 bezier quarter

circles will

require 12 coordinates. In terms of storage, there isn't much

difference, and

for lines of width 4 or smaller the current method is more

efficient.

I'm also guessing that it's harder for the rasterizer to deal with

bezier

curves than with straight lines, so is it possible that replacing

the

3.14*lineWidth/2 lines generated by the current method with 2

bezier

quarter circles isn't worth it (for small lineWidths)?

Thanks,
Denis.

- "Jim Graham"  wrote:


Sigh - that makes sense.  One issue is that the resulting paths

it

generates are much more "verbose" than they need to be.  This

would

generally mean that it takes far more storage than it would

otherwise

need - and it means that if the result needs to be transformed

then

it

would take many more computations to transform each segment than

the

bezier.

So, perhaps it would be worth having it check the type of the

output

and
do either a bezier or a bunch of lines depending on if it is a

PC2D

or

a
LineSink?

Also, it isn't really that difficult to for Renderer to include

its

own
Cubic/Quadratic flattening code, but it might involve more
calculations
than the round-cap code since it would have to be written for
arbitrary
beziers whereas if you know it is a quarter circle then it is

easier

to
know how far to subdivide...  :-(

...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it

would

have to implement a curveTo method, which means Stroker should
start implementing PathConsumer2D and instead of using a

LineSink

output it would have to use a PathConsumer2D output (either

that,

or

LineSink should include a curveTo method, but then there won't

really

be any difference between a LineSink and a PathConsumer2D. By

the

way,

LineSink doesn't have any implemented methods, so why is it an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape

method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am

not

very

familiar with Bezier curves, but it doesn't seem easy enough to

justify

fixing such a small bug.

----- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I do

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-09 Thread Denis Lila
; > >>> LineSink should include a curveTo method, but then there won't
> > >> really
> > >>> be any difference between a LineSink and a PathConsumer2D. By
> the
> > >> way,
> > >>> LineSink doesn't have any implemented methods, so why is it an
> > >> abstract
> > >>> class as opposed to an interface?)
> > >>>
> > >>> Stroker is used in 3 ways:
> > >>> 1. As an implementation of BasicStroke's createStrokedShape
> > method.
> > >> This
> > >>> uses a Path2D object as output.
> > >>> 2. As a way of feeding a PathConsumer2D without calling
> > >> createStrokedShape
> > >>> to generate an intermediate Shape. This uses a PathConsumer2D
> > >> output.
> > >>> 3. As a way of feeding lines to a Renderer object, which
> > generates
> > >> alpha
> > >>> tiles used for anti-aliasing that are fed to a cache and
> > extracted
> > >> as needed
> > >>> by an AATileGenerator. Obviously, Stroker's output here is a
> > >> Renderer.
> > >>> 1 and 2 aren't problems, because the underlying output objects
> > >> support
> > >>> Bezier curves. 3, however, doesn't, and it seems like
> implementing
> > a
> > >>> curveTo method for Renderer would be very difficult because the
> > way
> > >> it
> > >>> generates alpha tiles is by scanning the drawn edges with
> > >> horizontal
> > >>> scan lines, and for each scan line finding the x-intersections
> of
> > >> the scan
> > >>> lines and the edges. Then it determines the alpha values (I'm
> not
> > >> too sure
> > >>> how it does this).
> > >>> In order to implement Bezier curves in Renderer, we would have
> to
> > >> have
> > >>> a quick way of computing, for each scan line, all its
> > intersections
> > >> with
> > >>> however many Bezier curves are being drawn.
> > >>>
> > >>> I haven't given much thought to how this could be done, as I am
> > not
> > >> very
> > >>> familiar with Bezier curves, but it doesn't seem easy enough to
> > >> justify
> > >>> fixing such a small bug.
> > >>>
> > >>> - Original Message -
> > >>> From: "Jim Graham" 
> > >>> To: "Denis Lila" 
> > >>> Cc: 2d-dev@openjdk.java.net
> > >>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada
> > >> Eastern
> > >>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on
> > >> scaled lines.
> > >>> I don't understand - why do we generate sample points based on
> > the
> > >> size
> > >>> of the cap?  Why not generate a pair of bezier quarter-circles
> > and
> > >> let
> > >>> the rasterizer deal with sampling?
> > >>>
> > >>> ...jim
> > >>>
> > >>> Denis Lila wrote:
> > >>>> Hello.
> > >>>>
> > >>>> I think I have a fix for this bug:
> > >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506
> > >>>>
> > >>>> Basically, the problem is that if there is a magnifying affine
> > >> transformation set on the graphics object and one tries to draw a
> > line
> > >> with small thickness and round end caps, the end caps appear
> > jagged.
> > >> This is because the computation of the length of the array that
> > >> contains the points on the "pen" with which the decoration is
> > drawn
> > >> does not take into account the size of the pen after the
> > magnification
> > >> of the affine transformation. So, for example, if the line length
> > was
> > >> set to 1, and the transformation was a scaling by 10, the
> > resulting
> > >> pen would have a diameter of 10, but only 3 pen points would be
> > >> computed (pi*untransformedLineWidth), so the end cap looks like a
> > >> triangle.
> > >>>> My fix computes an approximation of the circumference of the
> > >> transformed pen (which is an ellipse) and uses that as the number
> > of
> > >> points on the pen. The approximation is crude, but it is simple,
> > >> faster than alternatives
> > >> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can
> > say
> > >> from observations that it works fairly well.
> > >>>> There is also icing on the cake, in the form of slight
> > improvements
> > >> in performance when the scaling is a zooming out. Example: if the
> > >> original line width was 100, but g2d.scale(0.1,0.1) was set, then
> > the
> > >> resulting line would have a width of 10, so only ~31 points are
> > >> necessary for the decoration to look like a circle, but without
> > this
> > >> patch, about 314 points are computed (and a line is emitted to
> > each
> > >> one of them).
> > >>>> I appreciate any feedback.
> > >>>>
> > >>>> Regards,
> > >>>> Denis Lila.
> > >>>>


Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-07 Thread Jim Graham
mediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like

implementing

a

curveTo method for Renderer would be very difficult because the

way

it

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections

of

the scan

lines and the edges. Then it determines the alpha values (I'm

not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have

to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am

not

very

familiar with Bezier curves, but it doesn't seem easy enough to

justify

fixing such a small bug.

- Original Message -----
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the

size

of the cap?  Why not generate a pair of bezier quarter-circles

and

let

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine

transformation set on the graphics object and one tries to draw a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like a
triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the number

of

points on the pen. The approximation is crude, but it is simple,
faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if the
original line width was 100, but g2d.scale(0.1,0.1) was set, then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-07 Thread Jim Graham
r
to 
know how far to subdivide...  :-(


...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it would
have to implement a curveTo method, which means Stroker should 
start implementing PathConsumer2D and instead of using a LineSink

output it would have to use a PathConsumer2D output (either that,

or

LineSink should include a curveTo method, but then there won't

really

be any difference between a LineSink and a PathConsumer2D. By the

way,

LineSink doesn't have any implemented methods, so why is it an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape

method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which

generates

alpha

tiles used for anti-aliasing that are fed to a cache and

extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like implementing

a

curveTo method for Renderer would be very difficult because the

way
it 

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections of

the scan

lines and the edges. Then it determines the alpha values (I'm not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have to

have

a quick way of computing, for each scan line, all its

intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am

not

very

familiar with Bezier curves, but it doesn't seem easy enough to

justify

fixing such a small bug.

----- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on

the
size 

of the cap?  Why not generate a pair of bezier quarter-circles

and
let 

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine

transformation set on the graphics object and one tries to draw a

line

with small thickness and round end caps, the end caps appear

jagged.

This is because the computation of the length of the array that
contains the points on the "pen" with which the decoration is

drawn

does not take into account the size of the pen after the

magnification

of the affine transformation. So, for example, if the line length

was

set to 1, and the transformation was a scaling by 10, the

resulting

pen would have a diameter of 10, but only 3 pen points would be
computed (pi*untransformedLineWidth), so the end cap looks like a
triangle.

My fix computes an approximation of the circumference of the

transformed pen (which is an ellipse) and uses that as the number

of

points on the pen. The approximation is crude, but it is simple,
faster than alternatives
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can

say

from observations that it works fairly well.

There is also icing on the cake, in the form of slight

improvements

in performance when the scaling is a zooming out. Example: if the
original line width was 100, but g2d.scale(0.1,0.1) was set, then

the

resulting line would have a width of 10, so only ~31 points are
necessary for the decoration to look like a circle, but without

this

patch, about 314 points are computed (and a line is emitted to

each

one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-07-02 Thread Denis Lila
don't know the transform.
> 
> So, for rendering, then you may be correct.  But for cases where the 
> path is being asked for then beziers are the only responsible
> solution...
> 
>   ...jim
> 
> Denis Lila wrote:
> > Hello Jim.
> > 
> > I thought about checking the output and changing the behaviour 
> > depending on whether the output is a PC2D or a LineSink, but I
> didn't
> > implement it because I thought the point was to get rid of the
> sampling
> > at this stage. However, if performance is the issue, then I guess
> I'll
> > start working on it.
> > 
> > Although, I wonder whether it is really worth it. I think most lines
> drawn
> > won't be wider than about 5 pixels, which means that the current way
> will
> > emit about 7 lines, so that's 14 coordinates. 2 bezier quarter
> circles will
> > require 12 coordinates. In terms of storage, there isn't much
> difference, and
> > for lines of width 4 or smaller the current method is more
> efficient.
> > 
> > I'm also guessing that it's harder for the rasterizer to deal with
> bezier
> > curves than with straight lines, so is it possible that replacing
> the 
> > 3.14*lineWidth/2 lines generated by the current method with 2 bezier
> 
> > quarter circles isn't worth it (for small lineWidths)?
> > 
> > Thanks,
> > Denis.
> > 
> > - "Jim Graham"  wrote:
> > 
> >> Sigh - that makes sense.  One issue is that the resulting paths it
> 
> >> generates are much more "verbose" than they need to be.  This would
> 
> >> generally mean that it takes far more storage than it would
> otherwise
> >>
> >> need - and it means that if the result needs to be transformed then
> it
> >>
> >> would take many more computations to transform each segment than
> the
> >> bezier.
> >>
> >> So, perhaps it would be worth having it check the type of the
> output
> >> and 
> >> do either a bezier or a bunch of lines depending on if it is a PC2D
> or
> >> a 
> >> LineSink?
> >>
> >> Also, it isn't really that difficult to for Renderer to include
> its
> >> own 
> >> Cubic/Quadratic flattening code, but it might involve more
> >> calculations 
> >> than the round-cap code since it would have to be written for
> >> arbitrary 
> >> beziers whereas if you know it is a quarter circle then it is
> easier
> >> to 
> >> know how far to subdivide...  :-(
> >>
> >>...jim
> >>
> >> Denis Lila wrote:
> >>> So, I have been thinking about this, and I can't see a good
> >>> way to do it that wouldn't involve heavy changes to Pisces.
> >>>
> >>> In order for Stroker to generate Bezier quarter circles, it would
> >>> have to implement a curveTo method, which means Stroker should 
> >>> start implementing PathConsumer2D and instead of using a LineSink
> >>> output it would have to use a PathConsumer2D output (either that,
> >> or
> >>> LineSink should include a curveTo method, but then there won't
> >> really
> >>> be any difference between a LineSink and a PathConsumer2D. By the
> >> way,
> >>> LineSink doesn't have any implemented methods, so why is it an
> >> abstract
> >>> class as opposed to an interface?)
> >>>
> >>> Stroker is used in 3 ways:
> >>> 1. As an implementation of BasicStroke's createStrokedShape
> method.
> >> This
> >>> uses a Path2D object as output.
> >>> 2. As a way of feeding a PathConsumer2D without calling
> >> createStrokedShape
> >>> to generate an intermediate Shape. This uses a PathConsumer2D
> >> output.
> >>> 3. As a way of feeding lines to a Renderer object, which
> generates
> >> alpha
> >>> tiles used for anti-aliasing that are fed to a cache and
> extracted
> >> as needed
> >>> by an AATileGenerator. Obviously, Stroker's output here is a
> >> Renderer.
> >>> 1 and 2 aren't problems, because the underlying output objects
> >> support
> >>> Bezier curves. 3, however, doesn't, and it seems like implementing
> a
> >>> curveTo method for Renderer would be very difficult because the
> way
> >> it 
> >>> generates alpha tiles is by scanning the d

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-22 Thread Denis Lila
now how far to subdivide...  :-(
> > >>
> > >>  ...jim
> > >>
> > >> Denis Lila wrote:
> > >>> So, I have been thinking about this, and I can't see a good
> > >>> way to do it that wouldn't involve heavy changes to Pisces.
> > >>>
> > >>> In order for Stroker to generate Bezier quarter circles, it
> would
> > >>> have to implement a curveTo method, which means Stroker should
> > >>> start implementing PathConsumer2D and instead of using a
> LineSink
> > >>> output it would have to use a PathConsumer2D output (either
> that,
> > >> or
> > >>> LineSink should include a curveTo method, but then there won't
> > >> really
> > >>> be any difference between a LineSink and a PathConsumer2D. By
> the
> > >> way,
> > >>> LineSink doesn't have any implemented methods, so why is it an
> > >> abstract
> > >>> class as opposed to an interface?)
> > >>>
> > >>> Stroker is used in 3 ways:
> > >>> 1. As an implementation of BasicStroke's createStrokedShape
> > method.
> > >> This
> > >>> uses a Path2D object as output.
> > >>> 2. As a way of feeding a PathConsumer2D without calling
> > >> createStrokedShape
> > >>> to generate an intermediate Shape. This uses a PathConsumer2D
> > >> output.
> > >>> 3. As a way of feeding lines to a Renderer object, which
> > generates
> > >> alpha
> > >>> tiles used for anti-aliasing that are fed to a cache and
> > extracted
> > >> as needed
> > >>> by an AATileGenerator. Obviously, Stroker's output here is a
> > >> Renderer.
> > >>> 1 and 2 aren't problems, because the underlying output objects
> > >> support
> > >>> Bezier curves. 3, however, doesn't, and it seems like
> implementing
> > a
> > >>> curveTo method for Renderer would be very difficult because the
> > way
> > >> it
> > >>> generates alpha tiles is by scanning the drawn edges with
> > >> horizontal
> > >>> scan lines, and for each scan line finding the x-intersections
> of
> > >> the scan
> > >>> lines and the edges. Then it determines the alpha values (I'm
> not
> > >> too sure
> > >>> how it does this).
> > >>> In order to implement Bezier curves in Renderer, we would have
> to
> > >> have
> > >>> a quick way of computing, for each scan line, all its
> > intersections
> > >> with
> > >>> however many Bezier curves are being drawn.
> > >>>
> > >>> I haven't given much thought to how this could be done, as I am
> > not
> > >> very
> > >>> familiar with Bezier curves, but it doesn't seem easy enough to
> > >> justify
> > >>> fixing such a small bug.
> > >>>
> > >>> - Original Message -
> > >>> From: "Jim Graham" 
> > >>> To: "Denis Lila" 
> > >>> Cc: 2d-dev@openjdk.java.net
> > >>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada
> > >> Eastern
> > >>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on
> > >> scaled lines.
> > >>> I don't understand - why do we generate sample points based on
> > the
> > >> size
> > >>> of the cap?  Why not generate a pair of bezier quarter-circles
> > and
> > >> let
> > >>> the rasterizer deal with sampling?
> > >>>
> > >>> ...jim
> > >>>
> > >>> Denis Lila wrote:
> > >>>> Hello.
> > >>>>
> > >>>> I think I have a fix for this bug:
> > >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506
> > >>>>
> > >>>> Basically, the problem is that if there is a magnifying affine
> > >> transformation set on the graphics object and one tries to draw a
> > line
> > >> with small thickness and round end caps, the end caps appear
> > jagged.
> > >> This is because the computation of the length of the array that
> > >> contains the points on the "pen" with which the decoration is
> > drawn
> > >> does not take into account the size of the pen after the
> > magnification
> > >> of the affine transformation. So, for example, if the line length
> > was
> > >> set to 1, and the transformation was a scaling by 10, the
> > resulting
> > >> pen would have a diameter of 10, but only 3 pen points would be
> > >> computed (pi*untransformedLineWidth), so the end cap looks like a
> > >> triangle.
> > >>>> My fix computes an approximation of the circumference of the
> > >> transformed pen (which is an ellipse) and uses that as the number
> > of
> > >> points on the pen. The approximation is crude, but it is simple,
> > >> faster than alternatives
> > >> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can
> > say
> > >> from observations that it works fairly well.
> > >>>> There is also icing on the cake, in the form of slight
> > improvements
> > >> in performance when the scaling is a zooming out. Example: if the
> > >> original line width was 100, but g2d.scale(0.1,0.1) was set, then
> > the
> > >> resulting line would have a width of 10, so only ~31 points are
> > >> necessary for the decoration to look like a circle, but without
> > this
> > >> patch, about 314 points are computed (and a line is emitted to
> > each
> > >> one of them).
> > >>>> I appreciate any feedback.
> > >>>>
> > >>>> Regards,
> > >>>> Denis Lila.
> > >>>>


Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-22 Thread Denis Lila
od, but then there won't
> >> really
> >>> be any difference between a LineSink and a PathConsumer2D. By the
> >> way,
> >>> LineSink doesn't have any implemented methods, so why is it an
> >> abstract
> >>> class as opposed to an interface?)
> >>>
> >>> Stroker is used in 3 ways:
> >>> 1. As an implementation of BasicStroke's createStrokedShape
> method.
> >> This
> >>> uses a Path2D object as output.
> >>> 2. As a way of feeding a PathConsumer2D without calling
> >> createStrokedShape
> >>> to generate an intermediate Shape. This uses a PathConsumer2D
> >> output.
> >>> 3. As a way of feeding lines to a Renderer object, which
> generates
> >> alpha
> >>> tiles used for anti-aliasing that are fed to a cache and
> extracted
> >> as needed
> >>> by an AATileGenerator. Obviously, Stroker's output here is a
> >> Renderer.
> >>> 1 and 2 aren't problems, because the underlying output objects
> >> support
> >>> Bezier curves. 3, however, doesn't, and it seems like implementing
> a
> >>> curveTo method for Renderer would be very difficult because the
> way
> >> it 
> >>> generates alpha tiles is by scanning the drawn edges with
> >> horizontal
> >>> scan lines, and for each scan line finding the x-intersections of
> >> the scan
> >>> lines and the edges. Then it determines the alpha values (I'm not
> >> too sure
> >>> how it does this).
> >>> In order to implement Bezier curves in Renderer, we would have to
> >> have
> >>> a quick way of computing, for each scan line, all its
> intersections
> >> with
> >>> however many Bezier curves are being drawn.
> >>>
> >>> I haven't given much thought to how this could be done, as I am
> not
> >> very
> >>> familiar with Bezier curves, but it doesn't seem easy enough to
> >> justify
> >>> fixing such a small bug.
> >>>
> >>> - Original Message -
> >>> From: "Jim Graham" 
> >>> To: "Denis Lila" 
> >>> Cc: 2d-dev@openjdk.java.net
> >>> Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada
> >> Eastern
> >>> Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on
> >> scaled lines.
> >>> I don't understand - why do we generate sample points based on
> the
> >> size 
> >>> of the cap?  Why not generate a pair of bezier quarter-circles
> and
> >> let 
> >>> the rasterizer deal with sampling?
> >>>
> >>>   ...jim
> >>>
> >>> Denis Lila wrote:
> >>>> Hello.
> >>>>
> >>>> I think I have a fix for this bug:
> >>>> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506
> >>>>
> >>>> Basically, the problem is that if there is a magnifying affine
> >> transformation set on the graphics object and one tries to draw a
> line
> >> with small thickness and round end caps, the end caps appear
> jagged.
> >> This is because the computation of the length of the array that
> >> contains the points on the "pen" with which the decoration is
> drawn
> >> does not take into account the size of the pen after the
> magnification
> >> of the affine transformation. So, for example, if the line length
> was
> >> set to 1, and the transformation was a scaling by 10, the
> resulting
> >> pen would have a diameter of 10, but only 3 pen points would be
> >> computed (pi*untransformedLineWidth), so the end cap looks like a
> >> triangle.
> >>>> My fix computes an approximation of the circumference of the
> >> transformed pen (which is an ellipse) and uses that as the number
> of
> >> points on the pen. The approximation is crude, but it is simple,
> >> faster than alternatives
> >> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can
> say
> >> from observations that it works fairly well.
> >>>> There is also icing on the cake, in the form of slight
> improvements
> >> in performance when the scaling is a zooming out. Example: if the
> >> original line width was 100, but g2d.scale(0.1,0.1) was set, then
> the
> >> resulting line would have a width of 10, so only ~31 points are
> >> necessary for the decoration to look like a circle, but without
> this
> >> patch, about 314 points are computed (and a line is emitted to
> each
> >> one of them).
> >>>> I appreciate any feedback.
> >>>>
> >>>> Regards,
> >>>> Denis Lila.
> >>>>


Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-21 Thread Jim Graham

Hi Denis,

Consider the case of using BasicStroke.createStrokedShape().  How do you 
know how many pixels the resulting path will occupy?  You can't reduce 
to concrete samples if you don't know the transform.


So, for rendering, then you may be correct.  But for cases where the 
path is being asked for then beziers are the only responsible solution...


...jim

Denis Lila wrote:

Hello Jim.

I thought about checking the output and changing the behaviour 
depending on whether the output is a PC2D or a LineSink, but I didn't

implement it because I thought the point was to get rid of the sampling
at this stage. However, if performance is the issue, then I guess I'll
start working on it.

Although, I wonder whether it is really worth it. I think most lines drawn
won't be wider than about 5 pixels, which means that the current way will
emit about 7 lines, so that's 14 coordinates. 2 bezier quarter circles will
require 12 coordinates. In terms of storage, there isn't much difference, and
for lines of width 4 or smaller the current method is more efficient.

I'm also guessing that it's harder for the rasterizer to deal with bezier
curves than with straight lines, so is it possible that replacing the 
3.14*lineWidth/2 lines generated by the current method with 2 bezier 
quarter circles isn't worth it (for small lineWidths)?


Thanks,
Denis.

- "Jim Graham"  wrote:

Sigh - that makes sense.  One issue is that the resulting paths it 
generates are much more "verbose" than they need to be.  This would 
generally mean that it takes far more storage than it would otherwise


need - and it means that if the result needs to be transformed then it

would take many more computations to transform each segment than the
bezier.

So, perhaps it would be worth having it check the type of the output
and 
do either a bezier or a bunch of lines depending on if it is a PC2D or
a 
LineSink?


Also, it isn't really that difficult to for Renderer to include its
own 
Cubic/Quadratic flattening code, but it might involve more
calculations 
than the round-cap code since it would have to be written for
arbitrary 
beziers whereas if you know it is a quarter circle then it is easier
to 
know how far to subdivide...  :-(


...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it would
have to implement a curveTo method, which means Stroker should 
start implementing PathConsumer2D and instead of using a LineSink

output it would have to use a PathConsumer2D output (either that,

or

LineSink should include a curveTo method, but then there won't

really

be any difference between a LineSink and a PathConsumer2D. By the

way,

LineSink doesn't have any implemented methods, so why is it an

abstract

class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape method.

This

uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling

createStrokedShape

to generate an intermediate Shape. This uses a PathConsumer2D

output.

3. As a way of feeding lines to a Renderer object, which generates

alpha

tiles used for anti-aliasing that are fed to a cache and extracted

as needed

by an AATileGenerator. Obviously, Stroker's output here is a

Renderer.

1 and 2 aren't problems, because the underlying output objects

support

Bezier curves. 3, however, doesn't, and it seems like implementing a
curveTo method for Renderer would be very difficult because the way
it 

generates alpha tiles is by scanning the drawn edges with

horizontal

scan lines, and for each scan line finding the x-intersections of

the scan

lines and the edges. Then it determines the alpha values (I'm not

too sure

how it does this).
In order to implement Bezier curves in Renderer, we would have to

have

a quick way of computing, for each scan line, all its intersections

with

however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am not

very

familiar with Bezier curves, but it doesn't seem easy enough to

justify

fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada

Eastern

Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on

scaled lines.

I don't understand - why do we generate sample points based on the
size 

of the cap?  Why not generate a pair of bezier quarter-circles and
let 

the rasterizer deal with sampling?

...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.o

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-21 Thread Denis Lila
Hello Jim.

I thought about checking the output and changing the behaviour 
depending on whether the output is a PC2D or a LineSink, but I didn't
implement it because I thought the point was to get rid of the sampling
at this stage. However, if performance is the issue, then I guess I'll
start working on it.

Although, I wonder whether it is really worth it. I think most lines drawn
won't be wider than about 5 pixels, which means that the current way will
emit about 7 lines, so that's 14 coordinates. 2 bezier quarter circles will
require 12 coordinates. In terms of storage, there isn't much difference, and
for lines of width 4 or smaller the current method is more efficient.

I'm also guessing that it's harder for the rasterizer to deal with bezier
curves than with straight lines, so is it possible that replacing the 
3.14*lineWidth/2 lines generated by the current method with 2 bezier 
quarter circles isn't worth it (for small lineWidths)?

Thanks,
Denis.

- "Jim Graham"  wrote:

> Sigh - that makes sense.  One issue is that the resulting paths it 
> generates are much more "verbose" than they need to be.  This would 
> generally mean that it takes far more storage than it would otherwise
> 
> need - and it means that if the result needs to be transformed then it
> 
> would take many more computations to transform each segment than the
> bezier.
> 
> So, perhaps it would be worth having it check the type of the output
> and 
> do either a bezier or a bunch of lines depending on if it is a PC2D or
> a 
> LineSink?
> 
> Also, it isn't really that difficult to for Renderer to include its
> own 
> Cubic/Quadratic flattening code, but it might involve more
> calculations 
> than the round-cap code since it would have to be written for
> arbitrary 
> beziers whereas if you know it is a quarter circle then it is easier
> to 
> know how far to subdivide...  :-(
> 
>   ...jim
> 
> Denis Lila wrote:
> > So, I have been thinking about this, and I can't see a good
> > way to do it that wouldn't involve heavy changes to Pisces.
> > 
> > In order for Stroker to generate Bezier quarter circles, it would
> > have to implement a curveTo method, which means Stroker should 
> > start implementing PathConsumer2D and instead of using a LineSink
> > output it would have to use a PathConsumer2D output (either that,
> or
> > LineSink should include a curveTo method, but then there won't
> really
> > be any difference between a LineSink and a PathConsumer2D. By the
> way,
> > LineSink doesn't have any implemented methods, so why is it an
> abstract
> > class as opposed to an interface?)
> > 
> > Stroker is used in 3 ways:
> > 1. As an implementation of BasicStroke's createStrokedShape method.
> This
> > uses a Path2D object as output.
> > 2. As a way of feeding a PathConsumer2D without calling
> createStrokedShape
> > to generate an intermediate Shape. This uses a PathConsumer2D
> output.
> > 3. As a way of feeding lines to a Renderer object, which generates
> alpha
> > tiles used for anti-aliasing that are fed to a cache and extracted
> as needed
> > by an AATileGenerator. Obviously, Stroker's output here is a
> Renderer.
> > 
> > 1 and 2 aren't problems, because the underlying output objects
> support
> > Bezier curves. 3, however, doesn't, and it seems like implementing a
> 
> > curveTo method for Renderer would be very difficult because the way
> it 
> > generates alpha tiles is by scanning the drawn edges with
> horizontal
> > scan lines, and for each scan line finding the x-intersections of
> the scan
> > lines and the edges. Then it determines the alpha values (I'm not
> too sure
> > how it does this).
> > In order to implement Bezier curves in Renderer, we would have to
> have
> > a quick way of computing, for each scan line, all its intersections
> with
> > however many Bezier curves are being drawn.
> > 
> > I haven't given much thought to how this could be done, as I am not
> very
> > familiar with Bezier curves, but it doesn't seem easy enough to
> justify
> > fixing such a small bug.
> > 
> > - Original Message -
> > From: "Jim Graham" 
> > To: "Denis Lila" 
> > Cc: 2d-dev@openjdk.java.net
> > Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada
> Eastern
> > Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on
> scaled lines.
> > 
> > I don't understand - why do we generate sample points based on the
> size 
> 

Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-18 Thread Jim Graham
Sigh - that makes sense.  One issue is that the resulting paths it 
generates are much more "verbose" than they need to be.  This would 
generally mean that it takes far more storage than it would otherwise 
need - and it means that if the result needs to be transformed then it 
would take many more computations to transform each segment than the bezier.


So, perhaps it would be worth having it check the type of the output and 
do either a bezier or a bunch of lines depending on if it is a PC2D or a 
LineSink?


Also, it isn't really that difficult to for Renderer to include its own 
Cubic/Quadratic flattening code, but it might involve more calculations 
than the round-cap code since it would have to be written for arbitrary 
beziers whereas if you know it is a quarter circle then it is easier to 
know how far to subdivide...  :-(


...jim

Denis Lila wrote:

So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it would
have to implement a curveTo method, which means Stroker should 
start implementing PathConsumer2D and instead of using a LineSink

output it would have to use a PathConsumer2D output (either that, or
LineSink should include a curveTo method, but then there won't really
be any difference between a LineSink and a PathConsumer2D. By the way,
LineSink doesn't have any implemented methods, so why is it an abstract
class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape method. This
uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling createStrokedShape
to generate an intermediate Shape. This uses a PathConsumer2D output.
3. As a way of feeding lines to a Renderer object, which generates alpha
tiles used for anti-aliasing that are fed to a cache and extracted as needed
by an AATileGenerator. Obviously, Stroker's output here is a Renderer.

1 and 2 aren't problems, because the underlying output objects support
Bezier curves. 3, however, doesn't, and it seems like implementing a 
curveTo method for Renderer would be very difficult because the way it 
generates alpha tiles is by scanning the drawn edges with horizontal

scan lines, and for each scan line finding the x-intersections of the scan
lines and the edges. Then it determines the alpha values (I'm not too sure
how it does this).
In order to implement Bezier curves in Renderer, we would have to have
a quick way of computing, for each scan line, all its intersections with
however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am not very
familiar with Bezier curves, but it doesn't seem easy enough to justify
fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada Eastern
Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

I don't understand - why do we generate sample points based on the size 
of the cap?  Why not generate a pair of bezier quarter-circles and let 
the rasterizer deal with sampling?


...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine transformation set on the 
graphics object and one tries to draw a line with small thickness and round end caps, the 
end caps appear jagged. This is because the computation of the length of the array that 
contains the points on the "pen" with which the decoration is drawn does not 
take into account the size of the pen after the magnification of the affine 
transformation. So, for example, if the line length was set to 1, and the transformation 
was a scaling by 10, the resulting pen would have a diameter of 10, but only 3 pen points 
would be computed (pi*untransformedLineWidth), so the end cap looks like a triangle.

My fix computes an approximation of the circumference of the transformed pen 
(which is an ellipse) and uses that as the number of points on the pen. The 
approximation is crude, but it is simple, faster than alternatives 
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can say from 
observations that it works fairly well.

There is also icing on the cake, in the form of slight improvements in 
performance when the scaling is a zooming out. Example: if the original line 
width was 100, but g2d.scale(0.1,0.1) was set, then the resulting line would 
have a width of 10, so only ~31 points are necessary for the decoration to look 
like a circle, but without this patch, about 314 points are computed (and a 
line is emitted to each one of them).

I appreciate any feedback.

Regards,
Denis Lila.



Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-17 Thread Denis Lila
So, I have been thinking about this, and I can't see a good
way to do it that wouldn't involve heavy changes to Pisces.

In order for Stroker to generate Bezier quarter circles, it would
have to implement a curveTo method, which means Stroker should 
start implementing PathConsumer2D and instead of using a LineSink
output it would have to use a PathConsumer2D output (either that, or
LineSink should include a curveTo method, but then there won't really
be any difference between a LineSink and a PathConsumer2D. By the way,
LineSink doesn't have any implemented methods, so why is it an abstract
class as opposed to an interface?)

Stroker is used in 3 ways:
1. As an implementation of BasicStroke's createStrokedShape method. This
uses a Path2D object as output.
2. As a way of feeding a PathConsumer2D without calling createStrokedShape
to generate an intermediate Shape. This uses a PathConsumer2D output.
3. As a way of feeding lines to a Renderer object, which generates alpha
tiles used for anti-aliasing that are fed to a cache and extracted as needed
by an AATileGenerator. Obviously, Stroker's output here is a Renderer.

1 and 2 aren't problems, because the underlying output objects support
Bezier curves. 3, however, doesn't, and it seems like implementing a 
curveTo method for Renderer would be very difficult because the way it 
generates alpha tiles is by scanning the drawn edges with horizontal
scan lines, and for each scan line finding the x-intersections of the scan
lines and the edges. Then it determines the alpha values (I'm not too sure
how it does this).
In order to implement Bezier curves in Renderer, we would have to have
a quick way of computing, for each scan line, all its intersections with
however many Bezier curves are being drawn.

I haven't given much thought to how this could be done, as I am not very
familiar with Bezier curves, but it doesn't seem easy enough to justify
fixing such a small bug.

- Original Message -
From: "Jim Graham" 
To: "Denis Lila" 
Cc: 2d-dev@openjdk.java.net
Sent: Wednesday, June 9, 2010 7:42:33 PM GMT -05:00 US/Canada Eastern
Subject: Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

I don't understand - why do we generate sample points based on the size 
of the cap?  Why not generate a pair of bezier quarter-circles and let 
the rasterizer deal with sampling?

...jim

Denis Lila wrote:
> Hello.
> 
> I think I have a fix for this bug:
> http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506
> 
> Basically, the problem is that if there is a magnifying affine transformation 
> set on the graphics object and one tries to draw a line with small thickness 
> and round end caps, the end caps appear jagged. This is because the 
> computation of the length of the array that contains the points on the "pen" 
> with which the decoration is drawn does not take into account the size of the 
> pen after the magnification of the affine transformation. So, for example, if 
> the line length was set to 1, and the transformation was a scaling by 10, the 
> resulting pen would have a diameter of 10, but only 3 pen points would be 
> computed (pi*untransformedLineWidth), so the end cap looks like a triangle.
> 
> My fix computes an approximation of the circumference of the transformed pen 
> (which is an ellipse) and uses that as the number of points on the pen. The 
> approximation is crude, but it is simple, faster than alternatives 
> (http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can say from 
> observations that it works fairly well.
> 
> There is also icing on the cake, in the form of slight improvements in 
> performance when the scaling is a zooming out. Example: if the original line 
> width was 100, but g2d.scale(0.1,0.1) was set, then the resulting line would 
> have a width of 10, so only ~31 points are necessary for the decoration to 
> look like a circle, but without this patch, about 314 points are computed 
> (and a line is emitted to each one of them).
> 
> I appreciate any feedback.
> 
> Regards,
> Denis Lila.
> 


Re: [OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-09 Thread Jim Graham
I don't understand - why do we generate sample points based on the size 
of the cap?  Why not generate a pair of bezier quarter-circles and let 
the rasterizer deal with sampling?


...jim

Denis Lila wrote:

Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine transformation set on the 
graphics object and one tries to draw a line with small thickness and round end caps, the 
end caps appear jagged. This is because the computation of the length of the array that 
contains the points on the "pen" with which the decoration is drawn does not 
take into account the size of the pen after the magnification of the affine 
transformation. So, for example, if the line length was set to 1, and the transformation 
was a scaling by 10, the resulting pen would have a diameter of 10, but only 3 pen points 
would be computed (pi*untransformedLineWidth), so the end cap looks like a triangle.

My fix computes an approximation of the circumference of the transformed pen 
(which is an ellipse) and uses that as the number of points on the pen. The 
approximation is crude, but it is simple, faster than alternatives 
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can say from 
observations that it works fairly well.

There is also icing on the cake, in the form of slight improvements in 
performance when the scaling is a zooming out. Example: if the original line 
width was 100, but g2d.scale(0.1,0.1) was set, then the resulting line would 
have a width of 10, so only ~31 points are necessary for the decoration to look 
like a circle, but without this patch, about 314 points are computed (and a 
line is emitted to each one of them).

I appreciate any feedback.

Regards,
Denis Lila.



[OpenJDK 2D-Dev] Fix for drawing round endcaps on scaled lines.

2010-06-09 Thread Denis Lila
Hello.

I think I have a fix for this bug:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

Basically, the problem is that if there is a magnifying affine transformation 
set on the graphics object and one tries to draw a line with small thickness 
and round end caps, the end caps appear jagged. This is because the computation 
of the length of the array that contains the points on the "pen" with which the 
decoration is drawn does not take into account the size of the pen after the 
magnification of the affine transformation. So, for example, if the line length 
was set to 1, and the transformation was a scaling by 10, the resulting pen 
would have a diameter of 10, but only 3 pen points would be computed 
(pi*untransformedLineWidth), so the end cap looks like a triangle.

My fix computes an approximation of the circumference of the transformed pen 
(which is an ellipse) and uses that as the number of points on the pen. The 
approximation is crude, but it is simple, faster than alternatives 
(http://en.wikipedia.org/wiki/Ellipse#Circumference), and I can say from 
observations that it works fairly well.

There is also icing on the cake, in the form of slight improvements in 
performance when the scaling is a zooming out. Example: if the original line 
width was 100, but g2d.scale(0.1,0.1) was set, then the resulting line would 
have a width of 10, so only ~31 points are necessary for the decoration to look 
like a circle, but without this patch, about 314 points are computed (and a 
line is emitted to each one of them).

I appreciate any feedback.

Regards,
Denis Lila.exporting patch:
# HG changeset patch
# User Denis Lila 
# Date 1276110761 14400
# Node ID 5cc40c7f2678d320519013b58af6808a0516cd68
# Parent  4d55419ce99e749da5037fa4d8247117f1a5cc2e
Fixed bug http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=506

diff --git a/src/share/classes/sun/java2d/pisces/Stroker.java b/src/share/classes/sun/java2d/pisces/Stroker.java
--- a/src/share/classes/sun/java2d/pisces/Stroker.java
+++ b/src/share/classes/sun/java2d/pisces/Stroker.java
@@ -209,7 +209,34 @@
 this.miterLimitSq = (long)(limitSq*65536.0*65536.0);
 }
 
-this.numPenSegments = (int)(3.14159f*lineWidth/65536.0f);
+// The pen is a circle mapped through the linear transformation
+// this.transform; therefore, we must calculate the circumference
+// of the mapped pen, not the pen. If we calculate the
+// circumference of the pen without taking into account this.transform
+// the round end caps will look jagged. However, the way I calculate
+// the circumference of the mapped pen is just a crude approximation, so
+// if anyone reading this knows how to better compute the circumference 
+// of ellipses, please fix it.
+
+// So, we map the points (1,0), (0,1), (-1,0), and (0,-1) through
+// the transformation. The results are (m00,m10), (m01,m11), 
+// (-m00,-m01), and (-m01,-m11). We simply calculate the lengths of
+// the mapped horizontal and vertical diameters, scale them by the
+// actual radius of the circle (i.e. lineWidth / 2), calculate the 
+// circumference of a circle whose diameter is the greater of those
+// two, and pretend this calculation is a good enough approximation
+// to the circumference of the mapped circle.
+double dx1 = 2*dm00;
+double dy1 = 2*dm10;
+double dx2 = 2*dm01;
+double dy2 = 2*dm11;
+double radius = lineWidth / (2 * 65536.0);
+// The diameters:
+double mappedD1 = radius * java.lang.Math.sqrt(dx1*dx1 + dy1*dy1);
+double mappedD2 = radius * java.lang.Math.sqrt(dx2*dx2 + dy2*dy2);
+double mappedD = (mappedD1 < mappedD2) ? mappedD2 : mappedD1;
+
+this.numPenSegments = (int) (3.14159 * mappedD);
 if (pen_dx == null || pen_dx.length < numPenSegments) {
 this.pen_dx = new int[numPenSegments];
 this.pen_dy = new int[numPenSegments];