Cannot draw veritical and horizontal lines of 0 width stroke using PPath
Closed this issue · 9 comments
Originally reported on Google Code with ID 221
What steps will reproduce the problem?
1. Use the following code:
PPath line = PPath.createLine(5f, 10f, 5f, 100f);
line.setStroke(new BasicStroke(0));
2. The following code too:
PPath line = new PPath();
line.setStroke(new BasicStroke(0));
line.moveTo(5f, 10f);
line.lineTo(5f, 100f);
What is the expected output? What do you see instead?
A horizontal or vertical line of 1 pixel wide should be drawn in any zoom level. However
the line just can not be seen!
What version of the product are you using? On what operating system?
Piccolo2d.java 1.3.1 is used on java 1.6.0_14-b08, Windows XP SP3.
Reported by v116mo
on 2011-07-23 10:54:06
Shouldn't a BasicStroke(0) yield a stroke that is zero pixels wide? Maybe you need
to create a BasicStroke(1) to get a stroke of 1 pixel wide.
Reported by samrreid
on 2011-07-23 16:35:23
In the Developer's FAQ http://www.piccolo2d.org/learn/dev-faq.html
section "Why is my app so slow?", it states as follows:
"...., If you need to render the strokes, you could try setting the stroke width to
zero, which has the effect of always drawing a one-pixel wide stroke. ...."
And it brings very significant performance improvement using BasicStroke(0).
The bug occurs when either x1 == x2, or y1 == y2 in the case of
PPath.createLine(x1, y1, x2, y2);
Reported by v116mo
on 2011-07-24 03:36:41
I can confirm the bug with my system
* Piccolo2d.java 1.3.1,
* java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.3) (fedora-59.1.10.3.fc15-i386)
OpenJDK Server VM (build 20.0-b11, mixed mode)
* Fedora 15 2.6.40.6-0.fc15.i686
If x1!=x2 or y1!=y2 then a one pixel width line is drawn in every zoom level, for stroke
width zero. Attached is a test program to show the issue.
Reported by funnyacc
on 2011-10-22 16:10:31
- _Attachment: [ZeroWidthStrokeBug.java](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-221/comment-3/ZeroWidthStrokeBug.java)_
Is this a Piccolo2D bug or an AWT one? I don't see any mention of 1-pixel wide stroke
width with BasicStroke(0) in the JDK javadocs.
Reported by heuermh
on 2011-10-26 03:12:51
"If you need to render the strokes, you could try setting the stroke width to zero,
which has the effect of always drawing a one-pixel wide stroke."
This is true for the Win7/Java1.6.27 system I've tested it on, but afaik Piccolo doesn't
have logic that ensures this, so it would be a side effect of what the JDK does. If
the JDK doesn't document this as a contract, then it must be inadvertent or a bug and
not to be relied on.
We might want to remove that comment from the developer faq.
Reported by atdixon
on 2011-11-01 23:28:11
Adding example
$ svn commit -m "Issue 221 ; adding ZeroWidthStrokeBug to examples.issues" .
Committed revision 1169.
Reported by heuermh
on 2012-08-31 16:59:34
Reported by heuermh
on 2012-08-31 20:29:30
- Labels added: Toolkit-Piccolo2D.Java
The attached java examples draws vertical and horizontal lines with BasicStroke(0).
It works correctly. I think the problem is not in java itself.
Reported by v116mo
on 2012-12-09 06:12:21
- _Attachment: [ZeroWidthStroke.java](https://storage.googleapis.com/google-code-attachments/piccolo2d/issue-221/comment-8/ZeroWidthStroke.java)_
In PNode.setBounds(), there is the logic to check line's width and height. With BasickStroke(0), it's width will be 0 for vertical lines, it's height will be 0 for horizontal lines. The bounds is reset to EMPTY, so the horizontal and vertical lines cannot be drawn correctly. If the checking is changed to if (width < 0 || height < 0). The issue is resolved. Hope it helps!
public boolean setBounds(final double x, final double y, final double width, final double height) {
if (bounds.x != x || bounds.y != y || bounds.width != width || bounds.height != height) {
bounds.setRect(x, y, width, height);
if (width < 0 || height < 0) { /* changed to include 0 width/height */
bounds.reset();
}
internalUpdateBounds(x, y, width, height);
invalidatePaint();
signalBoundsChanged();
return true;
}
// Don't put any invalidating code here or else nodes with volatile
// bounds will
// create a soft infinite loop (calling Swing.invokeLater()) when they
// validate
// their bounds.
return false;
}