Community
Participate
Working Groups
After applying a 45-degree rotation to a GC drawLine() and drawPath() will not work. Other drawing operations after that will not work either. This can be reproduced by changing the rotation angle in org.eclipse.swt.snippets.Snippet10 to -45. Also when setting to angle to -45.5f the path will be drawn but translated by about 40 pixels. I tried SWT 3.4.1 and 3.5M3. I'm on Ubuntu Linux 8.04. GTK-Version: 2.12.9, Cairo-Version: 1.6.0.
This works for me on my machine (Fedora core 5), gtk 2.8 and cairo 1.0 I also tested with gtk 2.12.10 + cairo 1.4 maybe this problem only happens on cairo 1.6 ? bog, do you have cairo 1.6 installed, can you try it for us ?
It doesn't work on macosx 10.5.6 with SWT 3.4.2 either. But It worked under SWT 3.3. I found a way for this to work. If you set the GC data state mak to DRAW_OFFSET (1 << 9) after applying rotation (where it's deleted) but before drawing, it works smoothly.
Created attachment 133345 [details] Codes to compare working and non working solution Sample where I draw some figures with different rotations. First, I do nothing special and it doesn't work : we can see that the fillpolygon works great and not the drawpolygon. It's the with drawLine and others, but it's more visual with drawPolygon. Next, I draw the same but I set the GC data state mask to DRAW_OFFSET and it works. We can see that the problem exists everywhere but mostly around 45°.
Created attachment 133346 [details] Image where we can see working and non working drawing Sample where I draw some figures with different rotations. First, I do nothing special and it doesn't work : we can see that the fillpolygon works great and not the drawpolygon. It's the with drawLine and others, but it's more visual with drawPolygon. Next, I draw the same but I set the GC data state mask to DRAW_OFFSET and it works. We can see that the problem exists everywhere but mostly around 45°.
Changing this to all platforms, as it also happens in Cocoa and Carbon, and Felipe verified it's on Win32 also.
I can still reproduce this on Mac Cocoa using Eclipse/SWT 3.7.1 by means of Snippet 10. When can we expect to have this investigated?
Created attachment 214841 [details] Demonstrates rotate problem, and use of line attributes to fix I am attaching another program to demonstrate the problem. This shows two Canvases that draw a rotating rectangle (use the buttons to rotate them). On the left, the rectangle draws correctly, but the one on the right demonstrates the offset problem. The Canvas on the left uses the DRAW_OFFSET mask to correct the problem. However, I have discovered that it can also be corrected by setting the line attributes on the GC. In the attached code, you can uncomment the line: // e.gc.setLineAttributes(new LineAttributes(1, SWT.CAP_FLAT, SWT.JOIN_MITER)); and you will then see that the rectangle on the right now also rotates correctly. This was tested on Ubuntu/GTK+/Cairo.
Really this is terrible. It means we cannot successfully paint even simple enough graphics in SWT. And it's still not fixed for 5 years. And by the way, magic constant trick (1 << 9) seems not working on Windows, as it have another value (1 << 14). Also, trick with setting line attirubutes is not always working, as line can still disappear when setting some transformation _scale_ value both with 45 degree rotation.
My current workaround for this bug is to call the setLineAttributes() method before performing drawing operations. It is not as to the point as the other workarounds, but you do not have to differentiate between platforms: calling setLineAttributes() fixes the behavior for me under windows and linux. (Mac not tested yet, but I believe it works there, too.)
The problem lies in the checkGC method starting from if ((state & DRAW_OFFSET) != 0) { ... } The method tries to calculate the scaling by passing the point 1,1 through the current transformation. If the transformation matrix is only a scaling operation, that calculation might work. However if there is a rotation involved, the scaling is clearly wrong. There are two cases that need to distinguished. 1) The transformation is uniform meaning x,y are equally scaled. In such a situation Pythagoras is a simple solution to the problem. 2) The transformation is non-uniform meaning x,y are scaled with different factors the solution is a Eigenvalue decomposition where the Eigenvalues form the scaling factors. This should be the solution for 1): double lengthOfInitalVector = Math.sqrt(Math.pow(point.X, 2)+Math.pow(point.Y, 2)); double lengthOfTransformedVector = Math.sqrt(Math.pow(point.X, 2)+Math.pow(point.Y, 2)); float length = (float)(lengthOfTransformedVector/lengthOfInitalVector);float scaling = length;
Fix available and provided for bug #335769.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.