This is almost there.  A couple of points about the solution, though:

- If you skip the MOVETO then you need to make sure that you later emit an lsink.moveTo otherwise the lsink object will complain about bad state. If you look in ProcessPath.c you will see that a "skip" boolean is set whenever a moveto is skipped (bad name, I would have called it "movetoSkipped" or something) and that tells the other path cases to turn their point into a moveto if they need to.

- If you never got any path segments because you skipped them all, make sure that calling lsink.close() isn't a problem. Note that if you get a CLOSE as the first thing in the path then it's OK to have lsink.close() throw an exception, but now that you are skipping coordinates, the burden is on you that if you skipped some coordinates, don't call close() in an invalid state because the incoming path state *was* correct - it's your edited path that got mangled down to just a close(), right?

- Finally, we should consider what we should do with "huge" coordinates that aren't infinite. Why reject infinity, but not maxfloat-1? The Ductus and ProcessPath.c pipelines reject all coordinates outside of maxfloat/2 and maxfloat/4 respectively which are huge compared to the range of S15_16, but they aren't infinite. Also, those pipelines can handle huge float values, but values greater than those limits have the potential of being driven to infinity by doing things like "(a+b)/2" where the result will be infinity if a and b are more than inf/2. I'm not sure what the best strategy is for our S15_16 code is, though, in the short term. Perhaps long term we want to have all path processing done in float and only the inner loops done in fract, but we aren't there yet... :-(

                        ...jim

Roman Kennke wrote:
Hi Jim,

I think the shape iterators used in the other pipelines (which should be visible as it was code that we wrote, even if it isn't used for Pisces) took a more flexible approach, testing each segment for NaN and overflow and ignoring individual segments until the shape became finite again. This happens somewhere in the src/share/classes/sun/java2d/pipe classes...

Ah cool. In this case we can implement it quite easily as in the
attached patch. Seems the output is 1:1 the same as with the non-free
JDK6.

/Roman

                        ...jim

Roman Kennke wrote:
Hi again,

3. NotANumberTest: Double.NaN isn't handled gracefully.
The problem here is that the renderer in OpenJDK is originally written
for ME and uses fixed point arithmetic. I can't think of a quick fix,
because shapes are processed by iterating over them, this means, by the
time we hit the NaN, we might already have processed (==rendered) some
of the shape, but your test seems to suggest that you expect nothing to
be rendered in this case. The specification doesn't say anything about
this particular problem (at least I can't find anything). One solution
would be to pre-check all the incoming shapes for NaN or other invalid
values (infinity, etc) and not go into the iteration at all. But this
seems like quite a big overhead to me. We could also make the
floating->fixed conversion to throw an exception, that we would have to
catch higher up in the call tree and rollback what has already been
rendered (which doesn't seem easy either, because in the case of
strokeTo() this lies outside of the pisces renderer).

/Roman

Reply via email to