codenameone / CodenameOne

Cross-platform framework for building truly native mobile apps with Java or Kotlin. Write Once Run Anywhere support for iOS, Android, Desktop & Web.
https://www.codenameone.com/
Other
1.72k stars 408 forks source link

incorrent affine transform on IOS #3037

Open ddyer0 opened 4 years ago

ddyer0 commented 4 years ago

The attached program rotates an arrowhead pointing AWAY from a fixed point near the center of the screen. - on the simulator and on android. However, on IOS it rotates the arrowhead with the point touching a fixed point near the center of the screen.

''''java

package com.boardspace.dtest;

// issue #2555 // this version shows that g.rotate damages the transform after a // few iterations, and that the damage persists across calls to paint // sep 23 2018 // import com.codename1.ui.Display; import com.codename1.ui.Form; import com.codename1.ui.Label; import com.codename1.ui.Stroke; import com.codename1.ui.geom.GeneralPath; import com.codename1.ui.geom.Rectangle; import com.codename1.ui.plaf.UIManager; import com.codename1.ui.util.Resources; import com.codename1.ui.Graphics; import com.codename1.ui.layouts.BorderLayout;

class Polygon { GeneralPath path = new GeneralPath(); public Polygon() { } public void addPoint(int x,int y) { if(path.getCurrentPoint()==null) { path.moveTo(x,y); } else { path.lineTo(x,y); } } public void fill(Graphics g) { g.fillShape(path); } public void frame(Graphics g) { Stroke stroke = new Stroke( 1, Stroke.CAP_BUTT, Stroke.JOIN_ROUND, 1f );

    // Draw the shape
    g.drawShape(path, stroke);

}
public Rectangle getBounds() {
    return(path.getBounds());
}
public boolean contains(int i, int j) { return(path.getBounds().contains(i,j)); }

}

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(); } Form hi = new Form("Hi >>0 World"); current = hi; hi.setLayout(new BorderLayout()); hi.addComponent(BorderLayout.CENTER, new Label("Hi Overlay World 2") { int paints = 0; @Override public void paint(Graphics g) { paints++; Polygon p = new Polygon(); p.addPoint(-100, 0); p.addPoint(0, -100); p.addPoint(100, 0); p.addPoint(-100,0);

        int w = getWidth();
        int h = getHeight();
        g.setColor(0x8f8f9f7f);
        g.fillRect(0,0,w,h);
        g.setColor(0);
        g.drawString("Paint "+paints,100,100);

        g.rotateRadians(((float)Math.PI+paints),w/2,w/4);

        g.setColor(0xffffff);
        g.drawRect(w/2-100, h/2-200, 200, 100);
        g.setColor(0);
        g.translate(w/2, h/2-100);
        p.fill(g);          // triangle should be inscribed in the rectangle    
        g.setColor(0xff00);
        p.frame(g);
        g.translate(-w/2, -(h/2-100));

        g.rotateRadians(-((float)Math.PI+paints),w/2,w/4);
                }

});
hi.show();
Runnable rr = new Runnable (){ 
    public void run() {
        System.out.println("running");
    while(true) 
    { 
      hi.repaint();
      try {
          Thread.sleep(1000); 
          }

      catch (InterruptedException e) {};
    }}};
new Thread(rr).start();

} public void stop() { current = Display.getInstance().getCurrent(); }

public void destroy() { } } ''''

ddyer0 commented 4 years ago

please keep this issue in mind as you look into the other clipping/rotating problem. I have an actual app affected by this, in a way that would be quite difficult to work around.

ddyer0 commented 4 years ago

This is probably part of the same can of worms. Consider these two screen snaps from IOS. The first, correct one, is drawn using to a graphics object derived from image.getGraphics(), the second, incorrect one, is drawn directly to a graphics object supplied to paint(Graphics g) image image

The drawing code in both cases is the same; only the source of the graphics object differs. In this case, the filled, curved lines are drawn using polygons defined by com.codename1.ui.geom.GeneralPath

nickhowes99 commented 1 year ago

I'm also seeing problems with rotation Transforms and only on iOS. Most of the drawing in my app is done via GeneralPaths and some of these have transforms applied (path.transform(...)) which works in the simulator and on Android, but sometimes fails on iOS - typically if there are "too many" transforms used in the various GeneralPaths that are being rendered (where "too many" is not a consistent count). A couple of example screenshots are attached. The first is a pure Java App, the second is CN1 on iOS. The arrow at the bottom middle should be pointing down, but the rotation transform in CN1 failed for some reason. Screenshot 2023-09-13 at 11 01 06 AM IMG_691CF0E4C194-1