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

android only, drawing upside down, zoomed up bitmaps #2557

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

android only, drawing upside down, zoomed up bitmaps #2557

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

Comments

@ddyer0
Copy link
Contributor

ddyer0 commented Sep 23, 2018

package dtest.boardspace;
//
// This version demonstrates a crash "after a while" drawing upside down
// zoomed up bitmaps.  This is used in the real world when implementing
// pinch-zoom on inverted screens.
//
// first, draw a test pattern into a scratch image, display the test pattern,
// then display a portion of the test pattern, upside down, inside a rectangle
// on the actual window.  On IOS and the simulator, this loop runs indefinitely
// on android devices, it runs "for a while" then crashes.  Overall behavior
// suggests a resource exhaustion problem.
//
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.Image;
import com.codename1.ui.layouts.BorderLayout;

import java.util.Random;


public class Dtest  {
	
    /**
     * Draw an image from/to particular rectangles with rescaling.  Note that
     * this uses left,top,right,bottomt coordinates rather than left,top,width,height 
     * @param gc	the gc to be written to
     * @param im	the image to be written from
     * @param dx	dest left
     * @param dy	dest top
     * @param dx2 dest right
     * @param dy2 dest bottom
     * @param fx  source left
     * @param fy  source top
     * @param fx2 source right
     * @param fy2 source bottom
     * @param c   the image observer (not used in codename1) 
     */
    public static void drawImage(Graphics gc,Image im,
			int dx,int dy,int dx2,int dy2,
			int fx,int fy,int fx2,int fy2
			)
{	if(gc!=null)
	{	int w = dx2-dx;
		int h = dy2-dy;
		int sw = fx2-fx;
		int sh = fy2-fy;
		int imw = im.getWidth();
		int imh = im.getHeight();
		double xscale = w/(double)sw;
		double yscale = h/(double)sh;
	   	int[]clip = gc.getClip();

		if(clip!=null && (clip instanceof int[]) && (clip.length>=4))
		{
	   	gc.clipRect(dx,dy,w,h);			// combine with proper clipping region
	   	//gc.setClip(dx,dy,w,h);		// runs wild, can write anywhere!
	   	int finx = dx-(int)(fx*xscale);
	   	int finy = dy-(int)(fy*yscale);
	   	int finw = (int)(imw*xscale);
	   	int finh = (int)(imh*yscale);
	   	gc.drawImage(im,finx,finy,finw,finh);
	   	gc.setClip(clip);
		}

	}
}	
 
    private Form current;
    @SuppressWarnings("unused")
	private Resources theme;
    private Image background;
    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();
            	if(background==null)
            	{
            		background = Image.createImage(getWidth(),getHeight());
            		Graphics bg = background.getGraphics();
            		bg.setColor(0x4f4f4f);
            		bg.fillRect(0, 0, w,h);
            		int xstep = w/10;
            		int ystep = h/10;
            		bg.setColor(0xffff);
            		for(int j=0;j<10;j++)
        			{
         				bg.drawLine(xstep*j,0,xstep*j,h);
        			}
            		for(int i=0;i<10;i++)
            		{
           				bg.drawLine(0, ystep*i,w,ystep*i);
           				for(int j=0;j<10;j++)
            			{
             				bg.drawString(""+i+" "+j,xstep*i+xstep/2,ystep*i+ystep/2);
            			}
            		}
            	}
            	g.setClip(0,0,w,h);
           		g.drawImage(background, 0, 0);
               	//drawImage(g,chip,-loops,-loops,w+loops,h+loops,0,0,chip.getWidth(),chip.getHeight());
            	//g.translate(150, 150);
            	float ang = (float)(Math.PI);
               	int b = Math.min(w, h)/3;
            	int x = loops%b;
            	int y = x-x/2;
               	g.setColor(0);
            	g.drawRect(x,y,w-x*2,h-y*2);
            	g.rotate(ang,getAbsoluteX()+w/2,getAbsoluteY()+h/2);
            	drawImage(g,background,x,y,w-x,h-y,
            				2*x,2*y,w-2*x-1,h-2*y-1);
             	g.rotate(-ang,getAbsoluteX()+w/2,getAbsoluteY()+h/2);
            	g.drawString("Loop "+loops, 100, 100);
            	loops++;
            
            	repaint();
            }
            
        });
        hi.show();
        
    }

    public void stop() {
        current = Display.getInstance().getCurrent();
    }
    
    public void destroy() {
    }
    
static int pass =0;
public void testRandom(Graphics g,int x,int y)
{   pass ++;
    g.drawString("Pass "+pass,x,y);
    y+=20;
    { Random r = new Random(63546);
      for(int i=0;i<3;i++) 
        { String val = ""+r.nextLong();
          g.drawString(val,x,y);
          y+=20;
        }
    }
    y+=20;
    { Random r2 = new Random(63546);
    for(int i=0;i<3;i++) 
    { String val = ""+r2.nextLong();
      g.drawString(val,x,y);
      y+=20;
    }
    }
	}


}
@codenameone codenameone added this to the Version 6.0 milestone Sep 24, 2018
@shannah
Copy link
Collaborator

shannah commented Sep 24, 2018

Also in this issue. repaint() inside paint() seems like a bad idea. can this be reproduced without doing that?

@ddyer0
Copy link
Contributor Author

ddyer0 commented Sep 24, 2018

likewise, repaint just triggers another paint request, it doesn't actually do anything. remove the
repaint() and add
java''''
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();

''''
after hi.show()

shannah added a commit that referenced this issue Sep 25, 2018
…when a component in the view heirarchy sets a transform and doesn't clean up afterward. This fixes issue #2557

It is possible that this papers over other issues with Android related to clipping and transforms - but it fixes this test case.
@shannah shannah closed this as completed Sep 25, 2018
@ddyer0
Copy link
Contributor Author

ddyer0 commented Sep 25, 2018

I don't see the matchup between this fix and the test code. The comments refer to
"not cleaning up" but the code here does unrotate after the rotation and drawing.

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