On 10/10/16 3:23 PM, Phil Race wrote:
That last sentence sounds like the right answer in principle but I don't know
if we'll be unpleasantly surprised
by some consequence of "... that setClip(Shape) and fill(Shape) might disagree
.."
-phil.
As I was thinking more about this last night we have additional issues to
consider.
Our rasterization rules bend a bit under STROKE_CONTROL and they do so differently for AA and non-AA. Really
STROKE_CONTROL was a bandaid for the fact that the suddenly specific rasterization rules we created with the 2D API
didn't necessarily match what developers had been used to and so we'd need some time for them to adjust. In particular,
a common misunderstanding is that "drawLine(X,0,X,h)" would fill in all of the pixels in the X column, but in AA this
would not work right as it would fill half of (coverage-wise 50% blending) the pixels to the right of X and half of the
pixels to the left of X and look fuzzy. Similarly, exact insideness rules meant that even with non-AA and a line width
of 1, technically the outline for that "line" would suggest that the pixels in the column to the left of X would be drawn.
In retrospect, we should have been advising developers to wean themselves off of STROKE_NORMALIZE adjustments from the
release of Java 2, but we dropped that ball. :( To be fair, though, these issues had been common in dealing with other
rendering systems, like Postscript - but how many developers have ever written Postscript code themselves?
Now with JavaFX we no longer have STROKE_CONTROL at all and we honor the strict rasterization rules that Java2D should
be honoring under STROKE_PURE and so developers must learn how to be more selective in how the render things from their
first exposure to FX. So, the ins and outs of dealing with the specific rasterization rules (things like where to
center lines, and manually snapping to pixels because "ints" don't do it pseudo-automatically for you) should be
becoming part of the developer experience with FX. I'm not sure how much that will help in Swing/AWT when Java2D has
had NORMALIZE rules as default for a couple of decades.
The rules for STROKE_NORMALIZE were created so that fills and strokes would match and be non-surprising for both AA and
non-AA modes, but the rules needed were different for the 2 modes. Having different rules was fine because nobody would
expect someone to draw a shape with non-AA and then fill it with AA or vice versa. It is very much expected that the AA
hint would stay the same for both a fill and a draw of a shape.
But, will the AA hint (or even the STROKE hint) stay the same for both the setting of a clip shape and the rendering of
items in it? How often is clip(someShape) followed by draw(sameShape) or fill(sameShape)? Would a developer believe
that the hints would affect the clip and so they would do the clip adjustment first and then set all of their "rendering
hints"? (Note that these are called "RenderingHints", though if I were to come up with a clip-specific hint I would
have no qualms adding it to the bag of hints in the RH class...)
Additionally, for AA rendering, there is no such thing as "setClip(someShape)" and "fill(sameShape)" being identical no
matter how much we predict which rules they may want because clips are inherently non-AA and so the fuzzy pixels along
the boundary of an AA shape will be randomly clipped or included.
When all is said and done I feel (not very strongly) it would be best to have clipping remain unaffected by the biasing
of STROKE hints, but part of that is driven by the fact that I think it can be fixed with a couple of lines of code in
SG2D/LoopPipe...
...jim