Bug 253670 - Line and Path not drawn when 45-degree rotation is applied
Summary: Line and Path not drawn when 45-degree rotation is applied
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4.1   Edit
Hardware: PC All
: P3 normal with 3 votes (vote)
Target Milestone: ---   Edit
Assignee: Bogdan Gheorghe CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks: 351038 417600
  Show dependency tree
 
Reported: 2008-11-04 06:03 EST by Elfi Heck CLA
Modified: 2020-04-25 17:02 EDT (History)
11 users (show)

See Also:


Attachments
Codes to compare working and non working solution (4.37 KB, text/plain)
2009-04-27 08:51 EDT, Vincent Raman CLA
no flags Details
Image where we can see working and non working drawing (74.98 KB, image/jpeg)
2009-04-27 08:52 EDT, Vincent Raman CLA
no flags Details
Demonstrates rotate problem, and use of line attributes to fix (3.74 KB, text/x-java)
2012-04-30 17:43 EDT, Colin Sharples CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Elfi Heck CLA 2008-11-04 06:03:04 EST
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.
Comment 1 Felipe Heidrich CLA 2008-11-20 14:34:01 EST
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 ?
Comment 2 Vincent Raman CLA 2009-04-27 08:46:26 EDT
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.

Comment 3 Vincent Raman CLA 2009-04-27 08:51:33 EDT
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°.
Comment 4 Vincent Raman CLA 2009-04-27 08:52:24 EDT
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°.
Comment 5 Scott Kovatch CLA 2011-01-31 15:16:42 EST
Changing this to all platforms, as it also happens in Cocoa and Carbon, and Felipe verified it's on Win32 also.
Comment 6 Alexander Nyßen CLA 2011-10-17 17:15:12 EDT
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?
Comment 7 Colin Sharples CLA 2012-04-30 17:43:10 EDT
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.
Comment 8 Roman Dawydkin CLA 2013-06-18 01:10:46 EDT
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.
Comment 9 Matthias Wienand CLA 2013-09-19 08:15:54 EDT
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.)
Comment 10 Jens Kuebler CLA 2015-05-12 03:31:57 EDT
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;
Comment 11 B. Djoudi CLA 2017-10-03 18:03:49 EDT
Fix available and provided for bug #335769.
Comment 12 Eclipse Genie CLA 2020-04-25 17:02:47 EDT
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.