Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

graphics rotation interacts incorrectly with clipping #2567

Closed
ddyer0 opened this issue Sep 28, 2018 · 3 comments
Closed

graphics rotation interacts incorrectly with clipping #2567

ddyer0 opened this issue Sep 28, 2018 · 3 comments
Assignees
Milestone

Comments

@ddyer0
Copy link
Contributor

ddyer0 commented Sep 28, 2018

combining clipping regions with graphics rotation doesn't work correctly. I believe
the simulator behavior is correct. IOS initially is also correct, but curiously, if you then
rotate the orientation, subsequent calls to paint produce incorrect results. Android
never works right.

package dtest.boardspace;
// 
// this version shows that g.rotate interacts badly with clipping
//
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.ui.Graphics;
import com.codename1.ui.layouts.BorderLayout;

public class Dtest {

private Form current;
@SuppressWarnings("unused")
private Resources theme;

public void init(Object context) {
    theme = UIManager.initFirstTheme("/theme");
    // Pro only feature, uncomment if you have a pro subscription
    // Log.bindCrashProtection(true);
}
int loops = 0;
public void start() {
    if(current != null){
        current.show();
        return;
    }
    Form hi = new Form("Hi >>0 World");
     current = hi;
    hi.setLayout(new BorderLayout());
    hi.addComponent(BorderLayout.CENTER, new Label("Hi Overlay World 2") {

        @Override
        public void paint(Graphics g) {
        	//g.resetAffine();
         	int w = getWidth();
        	int h = getHeight();
        	float ang = (float)(Math.PI);
        	
         	g.setColor(0x8f8f9f7f);
        	g.fillRect(0,0,w,h);

        	g.setColor(0xff);
        	int [] original_clip = g.getClip();
        	
        	// clip
        	g.clipRect(100, 100, 100, 100);
        	g.fillRect(0,0,w,h);
        	g.setColor(0);
        	g.setClip(original_clip);
        	g.drawString("clip only",110,150);
        	
        	// clip first, then rotate
        	g.rotate(ang,w/2,h/2);
        	g.setColor(0xff00);
        	g.clipRect(100,200,100,100);
        	g.fillRect(0, 0,w,h);
        	g.setColor(0);
        	g.setClip(original_clip);
        	g.drawString("clip,rotate",110,250);
        	g.rotate(-ang,w/2,h/2);
  
        	// rotate first, then clip
           	// clip first, then rotate
         	g.rotate(ang,w/2,h/2);
        	g.clipRect(100,300,100,100);
        	g.setColor(0xff0000);
        	g.fillRect(0, 0,w,h);
        	g.setColor(0);
        	g.setClip(original_clip);
        	g.drawString("rotate,clip",110,350);
        	g.rotate(-ang,w/2,h/2);
   
   
        	loops++;
        
        }
        
    });
    hi.show();
	Runnable rr = new Runnable (){ 
		public void run() {
			System.out.println("running");
		while(true) 
		{ 
		  hi.repaint();
		  try {
			  Thread.sleep(1); 
			  }
		  
		  catch (InterruptedException e) {};
		}}};
	new Thread(rr).start();
}
public void stop() {
    current = Display.getInstance().getCurrent();
}

public void destroy() {
}
}

This is a sample from the simulator
cliptest

this is the same program, on android
screenshot_2018-09-28-12-18-34

this the same result on IOS, launching the test program in portrait mode
them rotating to horizontal mode.
img_0118

@codenameone codenameone added this to the Version 6.0 milestone Sep 29, 2018
shannah added a commit that referenced this issue Oct 2, 2018
…incorrect results. This fixes some issues with rotation and clipping on Android, in particular, #2567.

The test case provided in that issue now works correctly in the simulator, iOS, and android.  It still fails on Javascript - and haven't tested on UWP yet.  Work on those is still in progress.
Note: As part of this fix, I changed the behaviour of Graphics.rotate(angle, x, y) so that the x, y coordinates are relative to the context's current translateX and translateY values (i.e. translateX, and translateY will be added to these values before calling the internal transform's rotation.  While this may possibly be a breaking change, this is the 'right' way for it to work and is consistent with all other methods in Graphics.
@shannah shannah closed this as completed Oct 3, 2018
@ddyer0
Copy link
Contributor Author

ddyer0 commented Oct 3, 2018

Thanks. I had noticed that I had to include +getAbsoluteX() in the center calculation, so will
remove that.

@ddyer0
Copy link
Contributor Author

ddyer0 commented Oct 5, 2018

Please reopen this. The initial behavior is correct, but if you switch orientation
between portrait and landscape, the colored rectangles are clipped away, incorrectly.
This behaves the same on IOS and Android.

@shannah shannah reopened this Oct 10, 2018
@shannah
Copy link
Collaborator

shannah commented Oct 25, 2018

@ddyer0 Note: I have reverted the behaviour of rotate() to use absolute coordinates to preserve backward compatibility. I have introduced a new rotateRadians() method that rotates on a pivot that takes into account the current translation.

1bea7d1

This will be part of the next server update. Sorry for the inconvenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants