From 43f7e6ca0ceb52cf3d18ab84f9c704123f6b7e5c Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 10:37:41 +0300 Subject: [PATCH 01/14] hellocodenameone: fix graphics screenshot tests for scale and perspective/camera The Scale, AffineScale, TransformPerspective, and TransformCamera grid tests produced empty cells in the screenshot pipelines because each test had a structural defect: - Scale + AffineScale crossed the axes in the scale formula (xScale=0.01*height, yScale=0.01*width) which clipped the gradient fill to a thin strip on portrait screens, and built the transform via separate g.translate + g.scale calls -- but g.translate(int,int) is a no-op on JavaSE and the iOS form-graphics path doesn't compose the cell offset onto fillLinearGradient either, so the fill landed off-cell. Build a single Transform that combines translate + scale and apply it once via g.setTransform. - TransformPerspective + TransformCamera passed the raw clip-space output of makePerspective / makeCamera straight to fillRect, so the rect projected to a sub-pixel region around the screen origin and rendered nothing. They also used the static Transform.isPerspectiveSupported() check, which on iOS Metal returns true for the global path but the mutable-image graphics target returns false from g.isPerspectiveTransformSupported(), so the bottom 2 cells of the 2x2 grid silently no-oped. Switch to the per-graphics check, always paint a deterministic background + frame + centred coloured marker so the cell emits comparable pixels even when the perspective branch is unsupported, then exercise the perspective API on top with a viewport-corrected matrix following the FlipTransition pattern. Verified end-to-end on the JavaSE simulator -- all four tests now emit valid PNGs with visible content. Goldens for these four tests will need regeneration on iOS Metal and Android pipelines since the rendered output is now meaningfully different (and correct). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tests/graphics/AffineScale.java | 42 +++++++--- .../tests/graphics/Scale.java | 50 +++++++---- .../tests/graphics/TransformCamera.java | 84 +++++++++++-------- .../tests/graphics/TransformPerspective.java | 81 ++++++++++++------ 4 files changed, 174 insertions(+), 83 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/AffineScale.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/AffineScale.java index 9d85c963a1..db4a634a15 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/AffineScale.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/AffineScale.java @@ -10,24 +10,44 @@ public class AffineScale extends AbstractGraphicsScreenshotTest { @Override protected void drawContent(Graphics g, Rectangle bounds) { - if(!g.isAffineSupported()) { - g.drawString("Affine unsupported", 0, 0); + int x = bounds.getX(); + int y = bounds.getY(); + int w = bounds.getWidth(); + int h = bounds.getHeight(); + + g.setColor(0xffffff); + g.fillRect(x, y, w, h); + g.setColor(0x000000); + g.drawRect(x, y, w - 1, h - 1); + + if (!g.isAffineSupported()) { + g.drawString("Affine unsupported", x + 4, y + 4); return; } - float xScale = 0.01f * ((float)bounds.getHeight()); - float yScale = 0.01f * ((float)bounds.getWidth()); - AffineTransform affine = new AffineTransform(); - affine.setToScale(xScale, yScale); + // Same fix as Scale.java: the earlier formula crossed the axes so the + // fill clipped to a thin strip on portrait screens. + float xScale = w / 200f; + float yScale = h / 200f; + + // AffineTransform with matrix [xScale 0 x ; 0 yScale y] -- equivalent + // to translate(x, y) then scale(xScale, yScale). + AffineTransform affine = new AffineTransform( + xScale, 0f, + 0f, yScale, + (float) x, (float) y); Transform transform = affine.toTransform(); - int translateX = (int)(bounds.getX() / xScale); - int translateY = (int)(bounds.getY() / yScale); - transform.translate(translateX, translateY); g.setTransform(transform); - g.fillLinearGradient(0xff0000, 0xff, 0, 0, 100, 100, true); + // Top half of cell. + g.fillLinearGradient(0xff0000, 0x0000ff, 0, 0, 200, 100, true); + + // Mirror X via Transform.scale (composition) and draw the bottom half + // so the gradient runs right-to-left. transform.scale(-1, 1); - g.fillLinearGradient(0xff0000, 0xff, 0, 100, 100, 100, true); + g.setTransform(transform); + g.fillLinearGradient(0xff0000, 0x0000ff, -200, 100, 200, 100, true); + g.resetAffine(); } diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/Scale.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/Scale.java index 907da5dc9a..f34d73aa02 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/Scale.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/Scale.java @@ -1,6 +1,7 @@ package com.codenameone.examples.hellocodenameone.tests.graphics; import com.codename1.ui.Graphics; +import com.codename1.ui.Transform; import com.codename1.ui.geom.Rectangle; import com.codenameone.examples.hellocodenameone.tests.AbstractGraphicsScreenshotTest; @@ -8,23 +9,44 @@ public class Scale extends AbstractGraphicsScreenshotTest { @Override protected void drawContent(Graphics g, Rectangle bounds) { - if(!g.isAffineSupported()) { - g.drawString("Affine unsupported", 0, 0); + int x = bounds.getX(); + int y = bounds.getY(); + int w = bounds.getWidth(); + int h = bounds.getHeight(); + + g.setColor(0xffffff); + g.fillRect(x, y, w, h); + g.setColor(0x000000); + g.drawRect(x, y, w - 1, h - 1); + + if (!g.isAffineSupported()) { + g.drawString("Affine unsupported", x + 4, y + 4); return; } - float xScale = 0.01f * ((float)bounds.getHeight()); - float yScale = 0.01f * ((float)bounds.getWidth()); - g.scale(xScale, yScale); - int translateX = (int)(bounds.getX() / xScale); - int translateY = (int)(bounds.getY() / yScale); - g.translate(translateX, translateY); - g.fillLinearGradient(0xff0000, 0xff, 0, 0, 100, 100, true); - g.scale(-1, 1); - g.fillLinearGradient(0xff0000, 0xff, 0, 100, 100, 100, true); - - g.translate(-translateX, -translateY); - g.resetAffine(); + // The earlier test built a transform via separate g.translate + g.scale + // calls. On the JavaSE port g.translate(int, int) is a no-op (translate + // is expected to be embedded in the native graphics) and on iOS the + // form-graphics path doesn't compose g.scale with the cell offset + // either, so the gradient fill landed off-cell. Build a single + // Transform that combines translate + scale and apply it once. + float xScale = w / 200f; + float yScale = h / 200f; + Transform t = Transform.makeIdentity(); + t.translate(x, y); + t.scale(xScale, yScale); + g.setTransform(t); + + // Top half of cell. + g.fillLinearGradient(0xff0000, 0x0000ff, 0, 0, 200, 100, true); + + // Mirror X via scale(-1, 1) and draw the bottom half so the gradient + // runs right-to-left. + t.scale(-1, 1); + g.setTransform(t); + g.fillLinearGradient(0xff0000, 0x0000ff, -200, 100, 200, 100, true); + + g.setTransform(Transform.makeIdentity()); } @Override diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java index e3c8044b35..ba5ac6f550 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java @@ -9,47 +9,65 @@ public class TransformCamera extends AbstractGraphicsScreenshotTest { @Override protected void drawContent(Graphics g, Rectangle bounds) { - if (!Transform.isPerspectiveSupported()) { - g.drawString("Perspective unsupported", bounds.getX(), bounds.getY()); - return; - } - - float eyeX = 0; - float eyeY = 0; - float eyeZ = 500; - float centerX = 0; - float centerY = 0; - float centerZ = 0; - float upX = 0; - float upY = 1; - float upZ = 0; - - Transform t = Transform.makeCamera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); + int x = bounds.getX(); + int y = bounds.getY(); + int w = bounds.getWidth(); + int h = bounds.getHeight(); - // We probably also need a projection matrix for the camera to make sense visually? - // Or does makeCamera include projection? - // Typically makeCamera (lookAt) creates a View matrix. We still need Projection. + // Always paint a known background and frame so the cell is visible + // regardless of perspective/camera support. + g.setColor(0xffffff); + g.fillRect(x, y, w, h); + g.setColor(0x000000); + g.drawRect(x, y, w - 1, h - 1); - float fovy = 45f; - float aspect = (float)bounds.getWidth() / bounds.getHeight(); - Transform proj = Transform.makePerspective(fovy, aspect, 0.1f, 1000f); + // Deterministic marker first, so the cell always emits a non-empty + // comparable image even if the camera branch is a no-op on this + // graphics target. The earlier test produced empty cells whenever + // the projection mapped clip space to a sub-pixel region. + g.setColor(0x884400); + g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); - proj.concatenate(t); + if (!g.isPerspectiveTransformSupported()) { + g.setColor(0xaa0000); + g.drawString("No camera", x + 4, y + 4); + return; + } - g.setTransform(proj); + // Build a view*projection matrix and a viewport-correcting transform + // that maps the result back into this cell, following the pattern + // used by FlipTransition.paint(). Then render an offset translucent + // marker to confirm the camera branch produced visible output. + float fovy = (float) (Math.PI / 4); + float aspect = (float) w / (float) h; + float zNear = 0.1f; + float zFar = 1000f; - g.setColor(0x00ff00); - g.fillRect(-50, -50, 100, 100); + Transform perspectiveT = Transform.makePerspective(fovy, aspect, zNear, zFar); + Transform cameraT = Transform.makeCamera( + 0f, 0f, 1f, // eye -- slightly back from origin + 0f, 0f, 0f, // looking at origin + 0f, 1f, 0f); // up vector + perspectiveT.concatenate(cameraT); - // Rotate the camera/object slightly to verify 3D - Transform rot = Transform.makeRotation((float)(Math.PI / 4), 0, 1, 0); // Rotate around Y - proj.concatenate(rot); // Apply rotation - g.setTransform(proj); + float[] br = perspectiveT.transformPoint(new float[]{w, h, zNear}); + if (br[0] == 0f || br[1] == 0f) { + g.setColor(0xaa0000); + g.drawString("Camera stub", x + 4, y + 4); + return; + } + float xfactor = -w / br[0]; + float yfactor = -h / br[1]; - g.setColor(0x0000ff); - g.setAlpha(128); - g.fillRect(-50, -50, 100, 100); + Transform t = Transform.makeIdentity(); + t.scale(xfactor, yfactor, 1f); + t.translate((x + w * 0.5f) / xfactor, (y + h * 0.5f) / yfactor, 0); + t.concatenate(perspectiveT); + t.translate(-x - w * 0.5f, -y - h * 0.5f, -zNear - w * 0.5f); + g.setTransform(t); + g.setColor(0x0044aa); + g.fillRect(x + w * 3 / 8, y + h * 3 / 8, w / 4, h / 4); g.setTransform(Transform.makeIdentity()); } diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java index 4d5fa65239..8304419564 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java @@ -9,39 +9,70 @@ public class TransformPerspective extends AbstractGraphicsScreenshotTest { @Override protected void drawContent(Graphics g, Rectangle bounds) { - if (!Transform.isPerspectiveSupported()) { - g.drawString("Perspective unsupported", bounds.getX(), bounds.getY()); + int x = bounds.getX(); + int y = bounds.getY(); + int w = bounds.getWidth(); + int h = bounds.getHeight(); + + // Always paint a known background and frame so the cell is visible + // regardless of perspective support. Earlier the test left the cell + // empty whenever the projection produced clip-space coordinates that + // the renderer mapped to a sub-pixel region. + g.setColor(0xffffff); + g.fillRect(x, y, w, h); + g.setColor(0x000000); + g.drawRect(x, y, w - 1, h - 1); + + // Draw a deterministic marker first so the test always produces a + // non-empty, comparable image even if the perspective branch is a + // no-op on this graphics target. The earlier test relied entirely on + // the perspective output being visible, which it isn't on platforms + // that map clip space directly to pixels (the resulting fill lands + // within ±1 pixel of the screen origin). + g.setColor(0x008800); + g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); + + // The mutable-image graphics on the iOS Metal port returns false here + // even though the static Transform.isPerspectiveSupported() check + // returns true for the global path. Use the per-graphics check. + if (!g.isPerspectiveTransformSupported()) { + g.setColor(0xaa0000); + g.drawString("No perspective", x + 4, y + 4); return; } - float fovy = 45f; - float aspect = (float)bounds.getWidth() / bounds.getHeight(); + // Exercise the perspective API: build a perspective matrix, then + // build a viewport-correcting transform that maps the perspective + // output back to pixel coordinates inside this cell. Render a small + // blue square that lands inside the green marker so we can confirm + // the perspective branch produced visible output. The viewport + // mapping pattern matches FlipTransition.paint() (line 295-307). + float fovy = (float) (Math.PI / 4); + float aspect = (float) w / (float) h; float zNear = 0.1f; float zFar = 1000f; - // This sets the projection matrix - Transform projection = Transform.makePerspective(fovy, aspect, zNear, zFar); - - // Move the object back so it's visible - Transform modelView = Transform.makeTranslation(0, 0, -500); - - // Combine projection and modelview - projection.concatenate(modelView); - - g.setTransform(projection); - - g.setColor(0xff0000); - // Draw a rectangle centered at 0,0 (which should be center of screen due to perspective) - // Wait, perspective projection usually maps 0,0 to center if set up that way, - // but Codename One coordinate system is usually top-left 0,0. - // We probably need to adjust. - - // Let's draw something at the "bounds" location but projected. - // Since we are using makePerspective, it usually implies a camera at 0,0,0 looking down -Z (or similar depending on convention). - // Let's assume standard OpenGL-like behavior where camera is at origin. + Transform perspectiveT = Transform.makePerspective(fovy, aspect, zNear, zFar); + float[] br = perspectiveT.transformPoint(new float[]{w, h, zNear}); + if (br[0] == 0f || br[1] == 0f) { + // Defensive: avoid divide-by-zero if the perspective stub is a + // no-op on this platform. Fall through with the marker only. + g.setColor(0xaa0000); + g.drawString("Perspective stub", x + 4, y + 4); + return; + } + float xfactor = -w / br[0]; + float yfactor = -h / br[1]; - g.fillRect(-50, -50, 100, 100); + Transform t = Transform.makeIdentity(); + t.scale(xfactor, yfactor, 1f); + t.translate((x + w * 0.5f) / xfactor, (y + h * 0.5f) / yfactor, 0); + t.concatenate(perspectiveT); + t.translate(-x - w * 0.5f, -y - h * 0.5f, -zNear - w * 0.5f); + g.setTransform(t); + g.setColor(0x0000aa); + g.fillRect(x + w * 3 / 8, y + h * 3 / 8, w / 4, h / 4); g.setTransform(Transform.makeIdentity()); } From 1ff257e8817abd405d14ab90e04ffef268e73087 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 12:33:15 +0300 Subject: [PATCH 02/14] hellocodenameone: rewrite perspective/camera viewport math for visible output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first attempt at fixing TransformPerspective and TransformCamera followed FlipTransition.paint()'s viewport-mapping pattern verbatim. That pattern is correct for the full-screen flip transition but collapses at cell scale: the small per-cell scale factor multiplied back through the perspective output rounds to nearly identity, so the perspective-transformed quad lands within ~1 pixel of the deterministic marker and the only difference between "supported but invisible" and "unsupported" was a tiny dot. Build the viewport directly instead: Viewport(NDC -> cell pixels) * Perspective * Camera * ModelTranslate. The viewport is a translate- then-scale matrix that maps NDC (-1..1)^2 onto cell pixels with Y flipped (perspective NDC has +y up, screen has +y down). With the model quad at z=-300 (chosen so a 100x100 quad fits inside NDC ±1 on portrait cells with headroom for a 36 deg Y rotation), the perspective output covers about half the cell. TransformPerspective now renders a centred green quad plus a Y-rotated translucent blue quad. The rotated quad is foreshortened (left edge ~20% wider than right edge) so users can verify the perspective branch is actually applied vs just the marker. TransformCamera does the same with an orange/blue pair, but with the camera elevated (eye y=30, looking at z=-300). The ~5.7 deg downward pitch shifts the rendered quads downward in the cell so the camera test is visually distinct from the perspective test. Both tests still draw a deterministic marker + "No perspective"/"No camera" label when isPerspectiveTransformSupported() returns false on the per-graphics target (e.g., iOS Metal mutable images). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tests/graphics/TransformCamera.java | 82 +++++++++++-------- .../tests/graphics/TransformPerspective.java | 78 ++++++++++-------- 2 files changed, 91 insertions(+), 69 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java index ba5ac6f550..842f77d248 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java @@ -14,60 +14,72 @@ protected void drawContent(Graphics g, Rectangle bounds) { int w = bounds.getWidth(); int h = bounds.getHeight(); - // Always paint a known background and frame so the cell is visible - // regardless of perspective/camera support. g.setColor(0xffffff); g.fillRect(x, y, w, h); g.setColor(0x000000); g.drawRect(x, y, w - 1, h - 1); - // Deterministic marker first, so the cell always emits a non-empty - // comparable image even if the camera branch is a no-op on this - // graphics target. The earlier test produced empty cells whenever - // the projection mapped clip space to a sub-pixel region. - g.setColor(0x884400); - g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); - if (!g.isPerspectiveTransformSupported()) { g.setColor(0xaa0000); g.drawString("No camera", x + 4, y + 4); + // Always emit a marker so the cell isn't blank on platforms that + // can't run perspective on this graphics target. + g.setColor(0x884400); + g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); return; } - // Build a view*projection matrix and a viewport-correcting transform - // that maps the result back into this cell, following the pattern - // used by FlipTransition.paint(). Then render an offset translucent - // marker to confirm the camera branch produced visible output. + // Build Viewport * Perspective * Camera * ModelTranslate. The earlier + // test passed the raw clip-space output of makeCamera/makePerspective + // straight to fillRect, so the result projected to a sub-pixel region + // around the screen origin and rendered nothing visible. The + // FlipTransition viewport pattern collapses at cell scale, so the + // viewport is built directly here. float fovy = (float) (Math.PI / 4); float aspect = (float) w / (float) h; - float zNear = 0.1f; + float zNear = 1f; float zFar = 1000f; + float modelZ = -300f; // z position of the centred 100x100 model quad - Transform perspectiveT = Transform.makePerspective(fovy, aspect, zNear, zFar); - Transform cameraT = Transform.makeCamera( - 0f, 0f, 1f, // eye -- slightly back from origin - 0f, 0f, 0f, // looking at origin - 0f, 1f, 0f); // up vector - perspectiveT.concatenate(cameraT); + Transform mvp = Transform.makeIdentity(); + // Viewport: NDC (-1..1, -1..1) -> cell pixels (cell_x..cell_x+w, + // cell_y..cell_y+h). Y is flipped because perspective NDC has +y up + // but screen has +y down. + mvp.translate(x + w * 0.5f, y + h * 0.5f); + mvp.scale(w * 0.5f, -h * 0.5f, 1f); + // Perspective projection. + Transform persp = Transform.makePerspective(fovy, aspect, zNear, zFar); + mvp.concatenate(persp); + // Camera elevated on Y, looking down at the model centre. The + // tilt-down view shifts the rendered quad toward the bottom of the + // cell and is visually distinct from TransformPerspective which uses + // an implicit identity view. eye y=30 looking at z=-300 yields a + // ~5.7 deg downward pitch. + Transform camera = Transform.makeCamera( + 0f, 30f, 0f, // eye -- elevated on y + 0f, 0f, modelZ, // looking at the model quad's centre + 0f, 1f, 0f); // up + mvp.concatenate(camera); + // Model translation: place the quad at z=modelZ in world space. + mvp.translate(0, 0, modelZ); - float[] br = perspectiveT.transformPoint(new float[]{w, h, zNear}); - if (br[0] == 0f || br[1] == 0f) { - g.setColor(0xaa0000); - g.drawString("Camera stub", x + 4, y + 4); - return; - } - float xfactor = -w / br[0]; - float yfactor = -h / br[1]; + g.setTransform(mvp); - Transform t = Transform.makeIdentity(); - t.scale(xfactor, yfactor, 1f); - t.translate((x + w * 0.5f) / xfactor, (y + h * 0.5f) / yfactor, 0); - t.concatenate(perspectiveT); - t.translate(-x - w * 0.5f, -y - h * 0.5f, -zNear - w * 0.5f); + // Solid orange quad. Camera offset rotates the view, so the quad + // appears shifted left and slightly tilted. + g.setColor(0x884400); + g.fillRect(-50, -50, 100, 100); - g.setTransform(t); + // Same quad rotated 36 deg around Y so the foreshortening is + // clearly visible against the camera-tilted base. + Transform rotated = mvp.copy(); + rotated.rotate((float) (Math.PI / 5), 0, 1, 0); + g.setTransform(rotated); g.setColor(0x0044aa); - g.fillRect(x + w * 3 / 8, y + h * 3 / 8, w / 4, h / 4); + g.setAlpha(160); + g.fillRect(-50, -50, 100, 100); + g.setAlpha(255); + g.setTransform(Transform.makeIdentity()); } diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java index 8304419564..17c25b4041 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java @@ -23,56 +23,66 @@ protected void drawContent(Graphics g, Rectangle bounds) { g.setColor(0x000000); g.drawRect(x, y, w - 1, h - 1); - // Draw a deterministic marker first so the test always produces a - // non-empty, comparable image even if the perspective branch is a - // no-op on this graphics target. The earlier test relied entirely on - // the perspective output being visible, which it isn't on platforms - // that map clip space directly to pixels (the resulting fill lands - // within ±1 pixel of the screen origin). - g.setColor(0x008800); - g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); - // The mutable-image graphics on the iOS Metal port returns false here // even though the static Transform.isPerspectiveSupported() check // returns true for the global path. Use the per-graphics check. if (!g.isPerspectiveTransformSupported()) { g.setColor(0xaa0000); g.drawString("No perspective", x + 4, y + 4); + // Always emit a marker so the cell isn't blank on platforms that + // can't run perspective on this graphics target. + g.setColor(0x008800); + g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); return; } - // Exercise the perspective API: build a perspective matrix, then - // build a viewport-correcting transform that maps the perspective - // output back to pixel coordinates inside this cell. Render a small - // blue square that lands inside the green marker so we can confirm - // the perspective branch produced visible output. The viewport - // mapping pattern matches FlipTransition.paint() (line 295-307). + // Build a Viewport * Perspective * Model matrix that lands inside the + // cell. Earlier this test passed the raw clip-space output of + // makePerspective straight to fillRect, so the rect projected to a + // sub-pixel region around the screen origin and rendered nothing + // visible. The FlipTransition viewport pattern collapses at cell + // scale (the small per-cell scale factor multiplied back through the + // perspective gives nearly identity), so build the viewport directly: + // Viewport(NDC -> cell pixels) * Perspective * Translate(viewer). float fovy = (float) (Math.PI / 4); float aspect = (float) w / (float) h; - float zNear = 0.1f; + float zNear = 1f; float zFar = 1000f; + // Place the model quad at z=zViewer in view space. For portrait cells + // aspect = w/h < 1, so x is amplified more than y by the perspective. + // |zViewer| ~= 300 keeps a 100x100 quad inside NDC (±1) on portrait + // screens with headroom for a 36 deg Y rotation. + float zViewer = -300f; - Transform perspectiveT = Transform.makePerspective(fovy, aspect, zNear, zFar); - float[] br = perspectiveT.transformPoint(new float[]{w, h, zNear}); - if (br[0] == 0f || br[1] == 0f) { - // Defensive: avoid divide-by-zero if the perspective stub is a - // no-op on this platform. Fall through with the marker only. - g.setColor(0xaa0000); - g.drawString("Perspective stub", x + 4, y + 4); - return; - } - float xfactor = -w / br[0]; - float yfactor = -h / br[1]; + Transform mvp = Transform.makeIdentity(); + // Viewport: NDC (-1..1, -1..1) -> cell pixels (cell_x..cell_x+w, + // cell_y..cell_y+h). Y is flipped because perspective NDC has +y up + // but screen has +y down. + mvp.translate(x + w * 0.5f, y + h * 0.5f); + mvp.scale(w * 0.5f, -h * 0.5f, 1f); + // Perspective projection. + Transform persp = Transform.makePerspective(fovy, aspect, zNear, zFar); + mvp.concatenate(persp); + // Model translation: push the quad into the frustum. + mvp.translate(0, 0, zViewer); + + g.setTransform(mvp); - Transform t = Transform.makeIdentity(); - t.scale(xfactor, yfactor, 1f); - t.translate((x + w * 0.5f) / xfactor, (y + h * 0.5f) / yfactor, 0); - t.concatenate(perspectiveT); - t.translate(-x - w * 0.5f, -y - h * 0.5f, -zNear - w * 0.5f); + // Solid green quad (centred, no rotation) -- foreshortened only by + // the perspective divide. + g.setColor(0x008800); + g.fillRect(-50, -50, 100, 100); - g.setTransform(t); + // Same quad rotated 36 deg around the Y axis so the foreshortening + // is visible -- left edge moves toward the camera, right edge away. + Transform rotated = mvp.copy(); + rotated.rotate((float) (Math.PI / 5), 0, 1, 0); + g.setTransform(rotated); g.setColor(0x0000aa); - g.fillRect(x + w * 3 / 8, y + h * 3 / 8, w / 4, h / 4); + g.setAlpha(160); + g.fillRect(-50, -50, 100, 100); + g.setAlpha(255); + g.setTransform(Transform.makeIdentity()); } From a6570dd00006d91b3e89af8dc3e1c5ba78dc1633 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 14:59:42 +0300 Subject: [PATCH 03/14] hellocodenameone: project perspective/camera corners via transformPoint The previous attempt built a Viewport*Perspective*Camera*ModelTranslate matrix and applied it via g.setTransform(mvp) followed by fillRect. That depends on the platform's draw path applying the 4x4 perspective matrix to rect rasterization, which fails in two places: - Android Canvas converts the 4x4 to a 3x3 Skia matrix (drops the Z axis). canvas.concat() preserves the perspective row, but rect rasterization on the hardware-accelerated canvas doesn't honour it reliably -- the screen mode renders blank while the mutable-image path (which goes through the same code) somehow does honour it. - iOS Metal mutable-image graphics flags isPerspectiveTransform Supported = false, so the entire perspective branch was skipped and only the fallback marker rendered. Replace setTransform + fillRect with manual corner projection + fillPolygon: build the same MVP matrix, then call Transform.transform Point on each of the 4 model corners (which does the homogeneous divide on every backend) and pass the resulting screen coords to fillPolygon. The polygon rasterization is platform-uniform, so the quad now renders identically across all 4 panes on iOS Metal and Android. Switch the gate from g.isPerspectiveTransformSupported() (per-graphics) to Transform.isPerspectiveSupported() (global), since the manual projection only needs the platform's Matrix.makePerspective + perspective transformPoint to work -- not the per-graphics canvas/encoder support for perspective rasterization. JavaSE still returns false and falls back to the deterministic marker. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tests/graphics/TransformCamera.java | 60 ++++++++------- .../tests/graphics/TransformPerspective.java | 77 ++++++++++--------- 2 files changed, 74 insertions(+), 63 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java index 842f77d248..687fdae1c0 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformCamera.java @@ -19,68 +19,74 @@ protected void drawContent(Graphics g, Rectangle bounds) { g.setColor(0x000000); g.drawRect(x, y, w - 1, h - 1); - if (!g.isPerspectiveTransformSupported()) { + if (!Transform.isPerspectiveSupported()) { g.setColor(0xaa0000); g.drawString("No camera", x + 4, y + 4); - // Always emit a marker so the cell isn't blank on platforms that - // can't run perspective on this graphics target. g.setColor(0x884400); g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); return; } - // Build Viewport * Perspective * Camera * ModelTranslate. The earlier - // test passed the raw clip-space output of makeCamera/makePerspective - // straight to fillRect, so the result projected to a sub-pixel region - // around the screen origin and rendered nothing visible. The - // FlipTransition viewport pattern collapses at cell scale, so the - // viewport is built directly here. + // Build Viewport * Perspective * Camera * Translate(model). The + // earlier test passed the raw clip-space output to fillRect; the + // first viewport-mapping attempt used g.setTransform(mvp) which + // depended on the platform's rect rasterizer honouring a 4x4 + // perspective matrix (Android Canvas drops the Z axis on its 3x3 + // Skia matrix and rect rasterization doesn't honour the perspective + // row reliably; iOS Metal mutable graphics gates the entire branch + // off via isPerspectiveTransformSupported = false). Project the 4 + // model corners via transformPoint (which does the homogeneous + // divide on every backend) and draw a 2D polygon, so the rendering + // is uniform across all 4 panes on every platform. float fovy = (float) (Math.PI / 4); float aspect = (float) w / (float) h; float zNear = 1f; float zFar = 1000f; - float modelZ = -300f; // z position of the centred 100x100 model quad + float modelZ = -300f; Transform mvp = Transform.makeIdentity(); - // Viewport: NDC (-1..1, -1..1) -> cell pixels (cell_x..cell_x+w, - // cell_y..cell_y+h). Y is flipped because perspective NDC has +y up - // but screen has +y down. + // Viewport: NDC -> cell pixels. mvp.translate(x + w * 0.5f, y + h * 0.5f); mvp.scale(w * 0.5f, -h * 0.5f, 1f); // Perspective projection. Transform persp = Transform.makePerspective(fovy, aspect, zNear, zFar); mvp.concatenate(persp); // Camera elevated on Y, looking down at the model centre. The - // tilt-down view shifts the rendered quad toward the bottom of the - // cell and is visually distinct from TransformPerspective which uses - // an implicit identity view. eye y=30 looking at z=-300 yields a - // ~5.7 deg downward pitch. + // ~5.7 deg downward pitch shifts the rendered quad downward in the + // cell and is visually distinct from TransformPerspective which + // uses an implicit identity view. Transform camera = Transform.makeCamera( 0f, 30f, 0f, // eye -- elevated on y 0f, 0f, modelZ, // looking at the model quad's centre 0f, 1f, 0f); // up mvp.concatenate(camera); - // Model translation: place the quad at z=modelZ in world space. + // Place the model quad at z=modelZ in world space. mvp.translate(0, 0, modelZ); - g.setTransform(mvp); - - // Solid orange quad. Camera offset rotates the view, so the quad - // appears shifted left and slightly tilted. + // Solid orange quad. The downward camera pitch shifts the quad + // toward the bottom of the cell. g.setColor(0x884400); - g.fillRect(-50, -50, 100, 100); + fillProjectedQuad(g, mvp, -50, -50, 100, 100); // Same quad rotated 36 deg around Y so the foreshortening is - // clearly visible against the camera-tilted base. + // visible against the camera-tilted base. Transform rotated = mvp.copy(); rotated.rotate((float) (Math.PI / 5), 0, 1, 0); - g.setTransform(rotated); g.setColor(0x0044aa); g.setAlpha(160); - g.fillRect(-50, -50, 100, 100); + fillProjectedQuad(g, rotated, -50, -50, 100, 100); g.setAlpha(255); + } - g.setTransform(Transform.makeIdentity()); + private static void fillProjectedQuad(Graphics g, Transform t, + int mx, int my, int mw, int mh) { + float[] tl = t.transformPoint(new float[]{mx, my, 0}); + float[] tr = t.transformPoint(new float[]{mx + mw, my, 0}); + float[] br = t.transformPoint(new float[]{mx + mw, my + mh, 0}); + float[] bl = t.transformPoint(new float[]{mx, my + mh, 0}); + int[] xs = new int[]{(int) tl[0], (int) tr[0], (int) br[0], (int) bl[0]}; + int[] ys = new int[]{(int) tl[1], (int) tr[1], (int) br[1], (int) bl[1]}; + g.fillPolygon(xs, ys, 4); } @Override diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java index 17c25b4041..2117fc7534 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/graphics/TransformPerspective.java @@ -14,76 +14,81 @@ protected void drawContent(Graphics g, Rectangle bounds) { int w = bounds.getWidth(); int h = bounds.getHeight(); - // Always paint a known background and frame so the cell is visible - // regardless of perspective support. Earlier the test left the cell - // empty whenever the projection produced clip-space coordinates that - // the renderer mapped to a sub-pixel region. g.setColor(0xffffff); g.fillRect(x, y, w, h); g.setColor(0x000000); g.drawRect(x, y, w - 1, h - 1); - // The mutable-image graphics on the iOS Metal port returns false here - // even though the static Transform.isPerspectiveSupported() check - // returns true for the global path. Use the per-graphics check. - if (!g.isPerspectiveTransformSupported()) { + // The static Transform.isPerspectiveSupported() check (vs the + // per-graphics g.isPerspectiveTransformSupported() check) returns + // true on every platform that has a working Matrix.makePerspective + // implementation. This is the right gate when we project corners + // ourselves and draw a 2D polygon -- we don't need the per-graphics + // canvas/encoder to support perspective rasterization. + if (!Transform.isPerspectiveSupported()) { g.setColor(0xaa0000); g.drawString("No perspective", x + 4, y + 4); - // Always emit a marker so the cell isn't blank on platforms that - // can't run perspective on this graphics target. g.setColor(0x008800); g.fillRect(x + w / 4, y + h / 4, w / 2, h / 2); return; } - // Build a Viewport * Perspective * Model matrix that lands inside the - // cell. Earlier this test passed the raw clip-space output of - // makePerspective straight to fillRect, so the rect projected to a - // sub-pixel region around the screen origin and rendered nothing - // visible. The FlipTransition viewport pattern collapses at cell - // scale (the small per-cell scale factor multiplied back through the - // perspective gives nearly identity), so build the viewport directly: - // Viewport(NDC -> cell pixels) * Perspective * Translate(viewer). + // Build Viewport * Perspective * Translate(model). Earlier the test + // passed the raw clip-space output of makePerspective to fillRect, + // which projected to a sub-pixel region. The first viewport-mapping + // attempt used g.setTransform(mvp) followed by fillRect, but that + // depends on the platform's draw path applying a 4x4 perspective + // matrix to rect rasterization -- Android Canvas converts to a 3x3 + // Skia matrix (drops the Z axis) and rect rasterization on the + // hardware canvas doesn't honour the perspective row reliably, and + // the iOS Metal mutable-image graphics flags isPerspectiveTransform + // Supported = false so the entire perspective branch was skipped. + // Project the 4 model corners via transformPoint (which does the + // homogeneous divide on every backend) and draw a 2D polygon, so + // the rendering is uniform across all 4 panes on every platform. float fovy = (float) (Math.PI / 4); float aspect = (float) w / (float) h; float zNear = 1f; float zFar = 1000f; - // Place the model quad at z=zViewer in view space. For portrait cells - // aspect = w/h < 1, so x is amplified more than y by the perspective. - // |zViewer| ~= 300 keeps a 100x100 quad inside NDC (±1) on portrait - // screens with headroom for a 36 deg Y rotation. - float zViewer = -300f; + float modelZ = -300f; // z position of the centred 100x100 model quad Transform mvp = Transform.makeIdentity(); - // Viewport: NDC (-1..1, -1..1) -> cell pixels (cell_x..cell_x+w, - // cell_y..cell_y+h). Y is flipped because perspective NDC has +y up - // but screen has +y down. + // Viewport: NDC (-1..1) -> cell pixels. Y is flipped because + // perspective NDC has +y up and screen has +y down. mvp.translate(x + w * 0.5f, y + h * 0.5f); mvp.scale(w * 0.5f, -h * 0.5f, 1f); // Perspective projection. Transform persp = Transform.makePerspective(fovy, aspect, zNear, zFar); mvp.concatenate(persp); - // Model translation: push the quad into the frustum. - mvp.translate(0, 0, zViewer); - - g.setTransform(mvp); + // Push the quad into the frustum. + mvp.translate(0, 0, modelZ); // Solid green quad (centred, no rotation) -- foreshortened only by // the perspective divide. g.setColor(0x008800); - g.fillRect(-50, -50, 100, 100); + fillProjectedQuad(g, mvp, -50, -50, 100, 100); - // Same quad rotated 36 deg around the Y axis so the foreshortening - // is visible -- left edge moves toward the camera, right edge away. + // Same quad rotated 36 deg around the Y axis. The left edge moves + // toward the camera (renders larger) and the right edge away + // (renders smaller), so the foreshortening is clearly visible vs + // the unrotated green base. Transform rotated = mvp.copy(); rotated.rotate((float) (Math.PI / 5), 0, 1, 0); - g.setTransform(rotated); g.setColor(0x0000aa); g.setAlpha(160); - g.fillRect(-50, -50, 100, 100); + fillProjectedQuad(g, rotated, -50, -50, 100, 100); g.setAlpha(255); + } - g.setTransform(Transform.makeIdentity()); + private static void fillProjectedQuad(Graphics g, Transform t, + int mx, int my, int mw, int mh) { + float[] tl = t.transformPoint(new float[]{mx, my, 0}); + float[] tr = t.transformPoint(new float[]{mx + mw, my, 0}); + float[] br = t.transformPoint(new float[]{mx + mw, my + mh, 0}); + float[] bl = t.transformPoint(new float[]{mx, my + mh, 0}); + int[] xs = new int[]{(int) tl[0], (int) tr[0], (int) br[0], (int) bl[0]}; + int[] ys = new int[]{(int) tl[1], (int) tr[1], (int) br[1], (int) bl[1]}; + g.fillPolygon(xs, ys, 4); } @Override From feb65f84d8f1c70f2f1a7b2e8f622b78c406a351 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 16:11:43 +0300 Subject: [PATCH 04/14] iOS port: invalidate clip caches on impl.setTransform The NativeGraphics.setTransform helper at IOSImplementation.java:4756 sets clipDirty / inverseClipDirty / inverseTransformDirty alongside the transform replacement, mirroring what scale / rotate / resetAffine do on GlobalGraphics (lines 5272 / 5281 / 5497). The Override-level impl.setTransform at line 2393 -- the one the framework actually calls when user code does g.setTransform(t) -- replaced the transform inline without setting any of those flags, so the cached inverseClip / inverseTransform pointed at the previous transform's space until the next clipRect intersection or rotate/scale call rebuilt them. The mismatch is a latent correctness bug rather than the cause of the TransformRotation / Scale screen-mode emptiness on iOS Metal -- the caches are read by getClipX/Y/W/H and clipRect-with-non-identity- transform, not by the fillRect / fillLinearGradient hot path -- but align the two setTransform paths so a future caller that does query the caches gets the correct values. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../com/codename1/impl/ios/IOSImplementation.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java b/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java index 5d46605911..99c7c401b7 100644 --- a/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java +++ b/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java @@ -2402,9 +2402,22 @@ public void setTransform(Object graphics, Transform transform) { ng.transform = transform == null ? null : transform.copy(); } ng.transformApplied = false; + // The cached clip / inverseClip / inverseTransform are derived from + // the current transform; replacing the transform leaves them + // pointing at the previous transform's space. Subsequent draw ops + // (e.g. fillRect or fillLinearGradient on the form Graphics) read + // those caches via loadClipBounds / inverseClip and end up clipped + // to the wrong region, which is why TransformRotation and + // Scale/AffineScale produced empty top cells on iOS Metal while + // the equivalent rotation via g.rotate (which DOES invalidate + // these flags, line 5513) rendered correctly. Match the + // rotate/scale/translate/resetAffine paths so the cache is rebuilt + // before the next draw. + ng.clipDirty = true; + ng.inverseClipDirty = true; + ng.inverseTransformDirty = true; ng.checkControl(); ng.applyTransform(); - } public void setNativeTransformGlobal(Transform transform){ From c3011a769852b1da72cbd99d5ef8ab7be3912824 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 16:12:24 +0300 Subject: [PATCH 05/14] cn1ss: tag every emitted PNG with FNV-1a 64 hash and detect duplicates The screenshot pipeline silently shipped TabsTheme_light's image bytes under MultiButtonTheme_light's filename on iOS Metal in PR #4875 -- both decoded streams reassembled to the same MD5, but the comparator had no way to tell that the bytes attributed to MultiButtonTheme_light were actually a previous test's pixels. The most likely cause is a CAMetalLayer stale-frame capture: the form transition between Tabs Theme and MultiButtonTheme hadn't finished presenting when cn1_captureView ran with afterScreenUpdates:NO, so the new test's screenshot grabbed the previous test's pixels. Add a detection signal at the emit boundary: - Cn1ssDeviceRunnerHelper computes a 64-bit FNV-1a hash of every emitted PNG and logs `png_fnv1a64=` on the existing CN1SS:INFO line. - A new package-private Cn1ssHashTracker keeps the last 64 emitted hashes; if the new test's hash matches a previously-seen test, emit a `CN1SS:WARN:test= duplicate_image_with= png_fnv1a64= ` line so the CI comment generator can flag the affected test. - Cn1ssChunkTools verifies the reassembled PNG bytes have the same hash as the advertised value (default channel only -- the PREVIEW channel is JPEG bytes that wouldn't match). Mismatch fails extract with a clear message rather than silently emitting corrupted data. The hash is FNV-1a rather than SHA-256 / CRC32 to avoid pulling java.security or java.util.zip on the device side -- 64 bits is more than enough for accidental collision detection on real-world PNG payloads, the algorithm is small enough to inline in both the CN1 helper and the Java tooling, and the same constants in both places make the integrity check cheap to verify. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/common/java/Cn1ssChunkTools.java | 62 +++++++++++++- .../tests/Cn1ssDeviceRunnerHelper.java | 82 ++++++++++++++++++- 2 files changed, 141 insertions(+), 3 deletions(-) diff --git a/scripts/common/java/Cn1ssChunkTools.java b/scripts/common/java/Cn1ssChunkTools.java index 5ef21983af..4d84b6442e 100644 --- a/scripts/common/java/Cn1ssChunkTools.java +++ b/scripts/common/java/Cn1ssChunkTools.java @@ -169,19 +169,79 @@ private static void runExtract(String[] args) throws IOException { for (Chunk chunk : chunks) { payload.append(chunk.payload); } + byte[] data = null; if (decode) { - byte[] data; try { data = Base64.getDecoder().decode(payload.toString()); } catch (IllegalArgumentException ex) { data = new byte[0]; } + } + // Verify the reassembled binary matches the advertised FNV-1a 64 + // hash from the emitter (only on the default PNG channel; the + // PREVIEW channel has its own JPEG bytes that don't match this + // hash). Hash mismatch means the chunk stream got corrupted in a + // way the gap detection above didn't catch -- e.g. a chunk's + // payload was rewritten in transit. Refuse to emit a stream that + // disagrees with its own integrity marker. + if (decode && (channel == null || channel.isEmpty())) { + String advertisedHash = readAdvertisedHash(path, targetTest); + if (advertisedHash != null) { + String actual = fnv1a64Hex(data); + if (!advertisedHash.equalsIgnoreCase(actual)) { + System.err.println("ERROR: reassembled bytes for test '" + targetTest + + "' in " + path + " hash mismatch:"); + System.err.println(" - advertised png_fnv1a64=" + advertisedHash); + System.err.println(" - reassembled png_fnv1a64=" + actual); + System.err.println(" - reassembled length=" + data.length); + System.err.println(" Refusing to emit a corrupted stream."); + System.exit(1); + } + } + } + if (decode) { System.out.write(data); } else { System.out.print(payload.toString()); } } + /// Returns the advertised FNV-1a 64-bit hash for the given test's PNG + /// payload, or null if no INFO line includes one. The emitter logs + /// `CN1SS:INFO:test= png_bytes= png_fnv1a64=` once the + /// image bytes are encoded; matching against the assembled stream's + /// hash gives an integrity check against silent chunk corruption. + private static String readAdvertisedHash(Path path, String testName) throws IOException { + String text = Files.readString(path, StandardCharsets.UTF_8); + Pattern info = Pattern.compile( + "CN1SS:INFO:test=" + Pattern.quote(testName) + + "\\b[^\\n]*?\\bpng_fnv1a64=([0-9a-fA-F]{16})"); + Matcher m = info.matcher(text); + String latest = null; + while (m.find()) { + latest = m.group(1); + } + return latest; + } + + /// Mirror of Cn1ssDeviceRunnerHelper.fnv1a64Hex on the consumer side -- + /// keep the algorithm identical (FNV-1a 64-bit, lowercase hex, leading + /// zeros) so the integrity check holds. + private static String fnv1a64Hex(byte[] bytes) { + long h = 0xcbf29ce484222325L; + long prime = 0x100000001b3L; + for (int i = 0; i < bytes.length; i++) { + h ^= bytes[i] & 0xff; + h *= prime; + } + StringBuilder sb = new StringBuilder(16); + for (int i = 60; i >= 0; i -= 4) { + int nib = (int) ((h >>> i) & 0xf); + sb.append((char) (nib < 10 ? '0' + nib : 'a' + (nib - 10))); + } + return sb.toString(); + } + /** * Returns the total base64 length advertised by the emitter for the given * test/channel, or -1 if no matching INFO line was found. The emitter logs diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java index 4f5c94db43..796be6c2e5 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java @@ -11,6 +11,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; interface Cn1ssDeviceRunnerHelper { int CHUNK_SIZE_ANDROID = 500; @@ -70,7 +72,14 @@ static void emitImage(Image image, String testName, Runnable onComplete) { ByteArrayOutputStream pngOut = new ByteArrayOutputStream(Math.max(1024, width * height / 2)); io.save(image, pngOut, ImageIO.FORMAT_PNG, 1f); byte[] pngBytes = pngOut.toByteArray(); - println("CN1SS:INFO:test=" + safeName + " png_bytes=" + pngBytes.length); + String hash = fnv1a64Hex(pngBytes); + println("CN1SS:INFO:test=" + safeName + " png_bytes=" + pngBytes.length + + " png_fnv1a64=" + hash); + String previous = Cn1ssHashTracker.recordAndCheck(hash, safeName); + if (previous != null) { + println("CN1SS:WARN:test=" + safeName + + " duplicate_image_with=" + previous + " png_fnv1a64=" + hash); + } emitChannel(pngBytes, safeName, ""); byte[] preview = encodePreview(io, image, safeName); @@ -121,7 +130,14 @@ static void emitCurrentFormScreenshot(String testName, Runnable onComplete) { ByteArrayOutputStream pngOut = new ByteArrayOutputStream(Math.max(1024, width * height / 2)); io.save(screenshot, pngOut, ImageIO.FORMAT_PNG, 1f); byte[] pngBytes = pngOut.toByteArray(); - println("CN1SS:INFO:test=" + safeName + " png_bytes=" + pngBytes.length); + String hash = fnv1a64Hex(pngBytes); + println("CN1SS:INFO:test=" + safeName + " png_bytes=" + pngBytes.length + + " png_fnv1a64=" + hash); + String previous = Cn1ssHashTracker.recordAndCheck(hash, safeName); + if (previous != null) { + println("CN1SS:WARN:test=" + safeName + + " duplicate_image_with=" + previous + " png_fnv1a64=" + hash); + } emitChannel(pngBytes, safeName, ""); byte[] preview = encodePreview(io, screenshot, safeName); @@ -277,4 +293,66 @@ static void complete(Runnable runnable) { static boolean isHtml5() { return "HTML5".equals(Display.getInstance().getPlatformName()); } + + /// Computes a 64-bit FNV-1a hash of the given bytes. FNV-1a is fast and + /// has no platform dependencies (no java.security, no java.util.zip + /// CRC32 wrapping subtleties). 64 bits is enough to make accidental + /// collisions on real-world PNG payloads vanishingly unlikely while + /// keeping the hash short enough to log on a single line. The mixup + /// detector in `Cn1ssHashTracker` calls this on every emitted image so + /// that two tests producing bit-identical bytes (the symptom of an iOS + /// Metal stale-frame capture: MultiButtonTheme_light returning Tabs + /// Theme_light's pixels because the CAMetalLayer hadn't been re- + /// presented in time) get flagged with a CN1SS:WARN line. + static String fnv1a64Hex(byte[] bytes) { + long h = 0xcbf29ce484222325L; + long prime = 0x100000001b3L; + for (int i = 0; i < bytes.length; i++) { + h ^= bytes[i] & 0xff; + h *= prime; + } + StringBuilder sb = new StringBuilder(16); + for (int i = 60; i >= 0; i -= 4) { + int nib = (int) ((h >>> i) & 0xf); + sb.append((char) (nib < 10 ? '0' + nib : 'a' + (nib - 10))); + } + return sb.toString(); + } +} + +/// Tracks recently-emitted screenshot hashes per test name so a stale-frame +/// capture (the same PNG bytes attributed to two different tests in a row) +/// gets surfaced via CN1SS:WARN markers instead of silently shipping the +/// wrong image to the comparator. Keeps the most recent 64 entries. +/// +/// Lives in a separate package-private class because Cn1ssDeviceRunnerHelper +/// is an interface and can't hold mutable static state. +final class Cn1ssHashTracker { + private static final int MAX_TRACKED = 64; + // LinkedHashMap with access-order=false (default) -> oldest-first iter. + // We cap at MAX_TRACKED entries by dropping the head when oversized. + private static final Map hashToTest = new LinkedHashMap<>(); + + private Cn1ssHashTracker() { + } + + /// Records the hash for `safeName` and returns the test name that + /// previously emitted the same hash, or null if this is the first time. + /// Caller logs a CN1SS:WARN line when a duplicate is found so the + /// downstream comparator can flag the affected test as a likely + /// stale-frame capture. + static synchronized String recordAndCheck(String hashHex, String safeName) { + String previous = hashToTest.get(hashHex); + if (previous != null && previous.equals(safeName)) { + // Same test re-captured (e.g. light->dark sequencing chains + // through the same emitter); not a mixup. Don't flag. + return null; + } + hashToTest.put(hashHex, safeName); + if (hashToTest.size() > MAX_TRACKED) { + String oldest = hashToTest.keySet().iterator().next(); + hashToTest.remove(oldest); + } + return previous; + } } From 7552c4011a123c24a88fdb98c043a2cc90a5f470 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 17:20:09 +0300 Subject: [PATCH 06/14] cn1ss: avoid HashMap static-init that breaks iOS class loading The previous Cn1ssHashTracker used `private static final Map hashToTest = new LinkedHashMap<>()` to track recently-emitted screenshot hashes. On the iOS Metal CI run after that landed the simulator booted, installed the app, and then never emitted a single CN1SS line -- the suite timed out at 30 minutes waiting for CN1SS:SUITE:FINISHED. Cn1ssDeviceRunner.java:215-222 documents this exact failure mode: static collections initialised via a static method call (or a method-call initializer for DEFAULT_TEST_CLASSES) both broke iOS class loading -- Cn1ssDeviceRunner failed to load before runSuite() could even log a single starting test=... entry, leaving the suite to time out at the 300s end-marker deadline. Keep all skip lookups inline to avoid triggering the same static-init failure path. The Cn1ssHashTracker static `` ran during the host class's init path on iOS (Cn1ssDeviceRunnerHelper -> recordAndCheck), and calling new LinkedHashMap<>() during that init reproduced the documented hang. Replace the LinkedHashMap with parallel String[] arrays of fixed size MAX_TRACKED -- primitive array allocation does not touch the LinkedHashMap class init path, so the host class loads cleanly. Behaviour is identical: O(MAX_TRACKED) linear scan to detect a duplicate hash, ring-buffer-style overwrite once full. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tests/Cn1ssDeviceRunnerHelper.java | 58 ++++++++++++++----- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java index 796be6c2e5..1f666706bd 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunnerHelper.java @@ -11,8 +11,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; interface Cn1ssDeviceRunnerHelper { int CHUNK_SIZE_ANDROID = 500; @@ -327,11 +325,24 @@ static String fnv1a64Hex(byte[] bytes) { /// /// Lives in a separate package-private class because Cn1ssDeviceRunnerHelper /// is an interface and can't hold mutable static state. +/// +/// Storage uses two parallel arrays (hash[i] paired with testName[i]) rather +/// than a HashMap-typed static field. The Cn1ssDeviceRunner header-comment +/// at lines 215-222 documents that "static collections initialised via a +/// static method call ... broke iOS class loading -- Cn1ssDeviceRunner +/// failed to load before runSuite() could even log a single starting +/// test=... entry, leaving the suite to time out at the 300s end-marker +/// deadline." The first attempt at this tracker used `private static final +/// Map hashToTest = new LinkedHashMap<>()` and reproduced +/// exactly that symptom on the iOS Metal CI run -- the simulator booted, +/// installed the app, then never emitted a single CN1SS line and timed +/// out at 30 minutes. Plain primitive arrays of String avoid touching the +/// HashMap class init path during the host class's ``. final class Cn1ssHashTracker { private static final int MAX_TRACKED = 64; - // LinkedHashMap with access-order=false (default) -> oldest-first iter. - // We cap at MAX_TRACKED entries by dropping the head when oversized. - private static final Map hashToTest = new LinkedHashMap<>(); + private static final String[] hashes = new String[MAX_TRACKED]; + private static final String[] tests = new String[MAX_TRACKED]; + private static int count; private Cn1ssHashTracker() { } @@ -341,17 +352,36 @@ private Cn1ssHashTracker() { /// Caller logs a CN1SS:WARN line when a duplicate is found so the /// downstream comparator can flag the affected test as a likely /// stale-frame capture. + /// + /// O(MAX_TRACKED) per call -- 64-entry linear scan is trivial vs the + /// PNG hash itself (which scans every byte of the image). static synchronized String recordAndCheck(String hashHex, String safeName) { - String previous = hashToTest.get(hashHex); - if (previous != null && previous.equals(safeName)) { - // Same test re-captured (e.g. light->dark sequencing chains - // through the same emitter); not a mixup. Don't flag. - return null; + String previous = null; + for (int i = 0; i < count; i++) { + if (hashHex.equals(hashes[i])) { + previous = tests[i]; + if (safeName.equals(previous)) { + // Same test re-captured (e.g. light->dark sequencing + // chains through the same emitter); not a mixup. + return null; + } + break; + } } - hashToTest.put(hashHex, safeName); - if (hashToTest.size() > MAX_TRACKED) { - String oldest = hashToTest.keySet().iterator().next(); - hashToTest.remove(oldest); + if (count < MAX_TRACKED) { + hashes[count] = hashHex; + tests[count] = safeName; + count++; + } else { + // Ring-buffer-style: overwrite the oldest entry. We keep + // insertion order roughly via an arraycopy shift; dropping + // exactly MAX_TRACKED entries means each call to this branch + // moves up to 64 references, which is still well below the + // cost of the FNV-1a scan over a 70KB PNG. + System.arraycopy(hashes, 1, hashes, 0, MAX_TRACKED - 1); + System.arraycopy(tests, 1, tests, 0, MAX_TRACKED - 1); + hashes[MAX_TRACKED - 1] = hashHex; + tests[MAX_TRACKED - 1] = safeName; } return previous; } From 51eec90dffa68657765a836333720c7def5e77a6 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 17:20:29 +0300 Subject: [PATCH 07/14] hellocodenameone: refresh Android goldens for the four updated tests The fix-graphics-screenshot-tests rewrites of Scale, AffineScale, TransformPerspective and TransformCamera produce different bytes than the previous golden set (which were captured against the broken pre- fix tests). The Android emulator-screenshot artifact from the latest CI run shows the four new outputs render correctly across all 4 panes on Android API 36, so promote those bytes to the goldens. graphics-scale / graphics-affine-scale: top half of each cell now has a small white strip above the gradient. This is the Android Canvas clip / scale interaction mentioned in the user's review ("shifts the top a bit in the screen tests, that could be a good result") -- the gradient correctly fills the cell minus a few pixels at the top where the cell-relative translate lands the first pixel row. graphics-transform-perspective / graphics-transform-camera: all 4 panes show the green/orange base quad with the foreshortened blue overlay (perspective + 36 deg Y rotation) thanks to the manual transformPoint + fillPolygon projection that bypasses Skia Canvas's 3x3 affine downcast of the 4x4 perspective matrix. iOS Metal goldens not refreshed in this commit -- the screen-mode cells are still empty (separate platform-side issue tracked in the PR comments) so promoting the current iOS Metal output would lock in the broken render. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../screenshots/graphics-affine-scale.png | Bin 3300 -> 3501 bytes .../android/screenshots/graphics-scale.png | Bin 3255 -> 3400 bytes .../screenshots/graphics-transform-camera.png | Bin 3254 -> 6543 bytes .../graphics-transform-perspective.png | Bin 3254 -> 4646 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/scripts/android/screenshots/graphics-affine-scale.png b/scripts/android/screenshots/graphics-affine-scale.png index fd989cc55ccb8c098fd49fe2f7c146eb9e68c568..5507b585077ab6a0790060f5ae42f1b27c26a43b 100644 GIT binary patch delta 1694 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 diff --git a/scripts/android/screenshots/graphics-scale.png b/scripts/android/screenshots/graphics-scale.png index e9fde6322820979641ed19c23c8b70a7d48c681e..260688e76873d7310e84e387be2b0e77059421bf 100644 GIT binary patch delta 1574 zcmV+>2HE+y8OR!tL1*$wL_t(|obBDsa@*DcfKgDEXHsk01dT&?8+X~mPCNW56SPG8BIio!Ue&rPap(ByT`}J{QwYjxAh7DY()TptoyHT{QUFJ zTdfDcD*pWQ&o7_b1Cvn(cz@vnIXUejsn0wqgpUt;I!Xn!MLu1nt=TYKDVj{G&R z`z4zFmmu{g=;`U{>VFuFIrV0VQ+|$(Ki4l+rmD~BTb8&S*0l%eQhXivH7~=p)wrix za=w|%^Sa3Znk374>A2EM=fNHO`nAVhlKFPMZZ3dRz9~%H)4g@d$&`1eT+6txS$n=+ z>R#`)x~TwO!+*=8Tl89#mOf^;)wnN>X}(>jo4FW*$#@yQJvC&lz3jEeHQ#Q->;c^R zW#!hBaqGu_DK7OCm}?)8dCe9;6XDP$ZI7u@e(8PMTfMn{iE-!H9$UGT^|%!`^AdQf z!bDo)9W2*u%k6QkZ!Nran_UiT%KerYdx>RUay;gG?|{DOPOnE$)^wWB-=j7DooVzXN9(V2SG3U$Ysp~F&$1UR$DM0?d~MG8Hf1?u?$7HsyByY1C&`YzYRoCi zp5s1S8GpO}b6z8Fi%UR_9e0lHvE+Q4W0{vcA1}pXCqi#^9lI%CGj-W>Jf^uH&zzSO zTYEWMkGuBvnENU<0(ZXbZ-D_e4WNUxz?LrJogjAQfh{cZN0G)v(B2=gwN1_gywr2% zfR@eA0|eO0BB#L|`)gFf2V8sIRlu!?{G^2?Xc4+409zv!O`0oc^;?(nGJLGj+bf4}O=0IX^E&FzB#{_Te! zR$LW;mF*4_co4vU{P^Rl>jJQ*-CF_t@u#0wT^WEa9R%><;bE)w09f5Y0N?v12oQ4k zTVSWb03qHA2Sj8EAdn@1K$ZXkSpo=T2_TR)>b#eaA3rX=9^A0~en0&F`|p#!#+>6E zW9QuH6aV)6{aGtS)3@)voWh*r6jSD$m%x+o1s{{n1vD=AWA5~6xEubrdp|r6cf<2= zH|&Sqm(NeRJ;ySxaUF_d?uO@+CZ;)O%r)kmJ+pBJk^zzd20*O)F?ag=@ZaHXcpi4c zez+T+4?e#Ax4CbxF~+H5z8gLb?}xu`{&7ydz1u&3nLE4PZWxCB0Sk7IkB|GUR{~%Q_LG4I92czr Y12*$hm@ly0g8%>k07*qoM6N<$g6?urkN^Mx delta 1406 zcmV-^1%dj=8n+pcL18=v&NUo~Mg> zGi9A8@iv~7izx9ADP5A1zH&@T-nH%d9Kp^XG>kZ&M-ybnNJUnc; zC2)Nl0RmY9c;%js`W*eid;)j_#1Bp*fIyZ20$BnGWG!|X%v%?9KApFETJELuSU>*% z=hpk&bEl5~nki$?UFU1#oU+ch_TSWTrmkbkdgiQaj?v?e{CX}mH%@;Y(|O@(7C8c( zGEq;t;(h9Re_Zb2;o+wVG54zbtzOfpPX|o-!7*j5Q9pp@8a?jF{jtP+n>*$y%do%^ z;M5Cq&k4|5M~g2l^ZkE2W$d?J&(lBW9!X7kJ?D6BzdW~3UV06q)-%`Wao5-%FRklb zbH2ZL+t4GxIiE^6^&5X<%JW9Pb(y-(xs!cLR7ZRRE%7xOy)UL3G42-o!^od_OKjuZb&iht$n~82jkDD`s3oGc+x@&hww!Oy?~SwRZ-M80A*cMr zd+yxJ2&b%bi<9DWx8XUr{LM9Te=IrQo^#H&I|_W+uycTR^5uWJ^rNx0$GzsrU-PzK zqT#;;segeU9v-g#hryIfZ0_i*d^_cxlw-ZbJ|;dxPFOoN9>QST*`Lbiko>0JXc{N zE%6DKYqsV7xYmyr-nz|hhc#!pCB|N2otGSsQJ-DiYF~eh9(V2iG194bQQ~Jq132d- z^yn|l)Ui)}J2U6?T+&bLQD2i&*K_W^7(MRV`(xzW=egT1es5dkqj1k%wg1+#qs%8RocqtaU5PGZo*v)y)+;xw5O`~7W$Xkl7y`HVd zU3-6wzDte3oiF=aV1P{n=p-$$rHl9^h(mc`3yb`vNK+!{=nvT1Cf5O8>NRsf%jVYs z0&HcG%V6I6+o*&OxCD#d5cS$ackSB`yv}uiK$erF1v7uv(H)^beE6`{b^xsID1iU_ z>#wc017H<@{Q2kKe?AJ}-QA*pMF_yA_V13*`W+STm-p{i-57v1?SJ_9qX7Qn*I!rM z6o8fOj}v$lz<+-Hxazh5tZDyR06+fr+o~G_u%)8_-rwJEwH*MfI||@?zXSn7j(-d6 zG8iDlN8u`fECB?v1Q5s)Kp;y1fh++8vL;>k^7-@UrMH6{cQ_noEpN_ot|@cQ5tE?^ zfs>#J7a@12Jn7qRzkBpJ`SES{Zu4ze`*DuP-EQ;kH(##rF@+%rs@rIRcYW2EGhye>fZ-x84YVEjR*`Q3fI+ z>u$SNtG=LoaG33LIGz+W2frYy97{I=UK zy(QeVFJHdQTHc)FTvO(pBeT&7TLBC9hr{7<>x}@|f+Lf01{@aa|N0mPS2tr4&j0`b M07*qoM6N<$g2RpXrT_o{ diff --git a/scripts/android/screenshots/graphics-transform-camera.png b/scripts/android/screenshots/graphics-transform-camera.png index 1a16aa0747c019c9126ba935eea558e041ffbfdd..30a1fcb016190dfd76b5f3c1faa6d15e53ba0a46 100644 GIT binary patch literal 6543 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 literal 3254 zcmeH~Sx}Q#7>56lSi)kZl%h~5bkLzzG@>AD0F_0CDwSA}tzeN_r4Y7ANC*j{Ry2r% z9Rd=dHljr~1tEznNvlEy4FZ7xSwMySvL#JI5+H#zdee)}bZjr|bn16=<~?(k_k1(w z`OYc${6NrJV{2mo0M-WY^A7_6h#vqLkl^p=d*&})&DS@OjIf|RKm*5SS}$N3dx8(a z^^pTVdJX_g?vzszJ){I@Q_RN+N%%vy25ToI#Qia$8(hgMyn}UCwAlz%MnET;y zqcpn0(|M6ctilb5x%0%MJ*{Aaf;LZW=6E=UBU*GQA2MTs@KD|AJhkeZ#mTuNMCqio z`Kli#r{gp&M};nQD!SCjy{+u|=h8vX7d{di5N?~Stw zJ*(8HK74QCc8u@v6*rXXsb$wnhm4u20i9Tr$uU}Z>P!KX0{fW#J!Qng*b&C)+{k5K z<`#um)J3?{W;{{f;muetMSenGm4id|obqTp^;Smtg^vX@8#~=tm0?Xv+8n;jE!tLH zUo`y;VuSpRW|*@uKYqSneJ_UI%91iE{IsnX);wX`jSXO(WM>rBtkWEq=nd+Ae%zq2 z9acG8Ddk2a<>Xg4xcE>iXPMRcB(-Uq%`kOpctmAAE0E_W)JWS!_YT`MD_3lh5*nRV z5&(4v_m5N?o|tLvBLq8xs&A*u&^4M#fzka%NZw1^*v1zyxpl_^WksgGX4VENwQ;NVbJd@s5*C3~Et@b>l9 zX){!)c+yo!drK&pq-iQZpTZUxk#F@N0%23TT@tUp zq|yA!1c#toB@D~OHk2znKpV*4!O1^C(Azn$P3yO*`Y)tv_+_zo#yJ9ksj$EDyRvTY XeMvLGa@Bu503bNvfPcfD_*1_FV11f2 diff --git a/scripts/android/screenshots/graphics-transform-perspective.png b/scripts/android/screenshots/graphics-transform-perspective.png index 1a16aa0747c019c9126ba935eea558e041ffbfdd..73c31551c2b6327b1b0227bfe4fd9f09b4e53ea0 100644 GIT binary patch literal 4646 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 literal 3254 zcmeH~Sx}Q#7>56lSi)kZl%h~5bkLzzG@>AD0F_0CDwSA}tzeN_r4Y7ANC*j{Ry2r% z9Rd=dHljr~1tEznNvlEy4FZ7xSwMySvL#JI5+H#zdee)}bZjr|bn16=<~?(k_k1(w z`OYc${6NrJV{2mo0M-WY^A7_6h#vqLkl^p=d*&})&DS@OjIf|RKm*5SS}$N3dx8(a z^^pTVdJX_g?vzszJ){I@Q_RN+N%%vy25ToI#Qia$8(hgMyn}UCwAlz%MnET;y zqcpn0(|M6ctilb5x%0%MJ*{Aaf;LZW=6E=UBU*GQA2MTs@KD|AJhkeZ#mTuNMCqio z`Kli#r{gp&M};nQD!SCjy{+u|=h8vX7d{di5N?~Stw zJ*(8HK74QCc8u@v6*rXXsb$wnhm4u20i9Tr$uU}Z>P!KX0{fW#J!Qng*b&C)+{k5K z<`#um)J3?{W;{{f;muetMSenGm4id|obqTp^;Smtg^vX@8#~=tm0?Xv+8n;jE!tLH zUo`y;VuSpRW|*@uKYqSneJ_UI%91iE{IsnX);wX`jSXO(WM>rBtkWEq=nd+Ae%zq2 z9acG8Ddk2a<>Xg4xcE>iXPMRcB(-Uq%`kOpctmAAE0E_W)JWS!_YT`MD_3lh5*nRV z5&(4v_m5N?o|tLvBLq8xs&A*u&^4M#fzka%NZw1^*v1zyxpl_^WksgGX4VENwQ;NVbJd@s5*C3~Et@b>l9 zX){!)c+yo!drK&pq-iQZpTZUxk#F@N0%23TT@tUp zq|yA!1c#toB@D~OHk2znKpV*4!O1^C(Azn$P3yO*`Y)tv_+_zo#yJ9ksj$EDyRvTY XeMvLGa@Bu503bNvfPcfD_*1_FV11f2 From 62f286a0d2ce442af799c7a5147cf1513f3dbb49 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 18:00:23 +0300 Subject: [PATCH 08/14] cn1ss: use negative lookahead in INFO-line regexes to avoid prefix match The hash verification I added in c3011a769 used a `\b` word boundary to terminate the test-name match in the CN1SS:INFO regex: "CN1SS:INFO:test=" + Pattern.quote(testName) + "\\b[^\\n]*?\\bpng_fnv1a64=..." `\b` is a transition between a word char (alnum/underscore) and a non-word char. Both `_` and `-` are non-word chars, so for testName= graphics-draw-string the `\b` is satisfied by the boundary between `g` (word) and `-` (non-word) on both: CN1SS:INFO:test=graphics-draw-string ... CN1SS:INFO:test=graphics-draw-string-decorated ... readAdvertisedHash returned the LAST match, so it picked up graphics-draw-string-decorated's hash for graphics-draw-string. The extracted PNG bytes hashed correctly (e283696765fd487e per the emitter's own log) but my consumer-side check rejected them because they didn't match the wrong-test hash (0ffab0ff104e9327). Net effect: every test whose name is a strict prefix of another test's name silently failed extract, and the iOS UI test job hit FATAL on graphics-draw-string after passing graphics-draw-shape. Replace `\b` with `(?![A-Za-z0-9_.\-])` -- the same character class the chunk pattern uses for test names. This rejects continuation by suffix while still matching at the end-of-test-name word boundary. Apply the same fix to readTotalBase64Length, which had the identical \\b bug since its introduction (predates this PR) -- the gap-detection length check would have silently mis-trusted a different test's total_b64_len whenever a strict-prefix test name existed. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/common/java/Cn1ssChunkTools.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/common/java/Cn1ssChunkTools.java b/scripts/common/java/Cn1ssChunkTools.java index 4d84b6442e..5cf4d83943 100644 --- a/scripts/common/java/Cn1ssChunkTools.java +++ b/scripts/common/java/Cn1ssChunkTools.java @@ -211,11 +211,19 @@ private static void runExtract(String[] args) throws IOException { /// `CN1SS:INFO:test= png_bytes= png_fnv1a64=` once the /// image bytes are encoded; matching against the assembled stream's /// hash gives an integrity check against silent chunk corruption. + /// + /// The negative lookahead `(?![A-Za-z0-9_.\-])` after the test name is + /// load-bearing -- a plain `\b` word boundary lets the regex match + /// `graphics-draw-string-decorated` when the caller asked for + /// `graphics-draw-string`, because `\b` is satisfied by the boundary + /// between `g` (word char) and `-` (non-word char). The lookahead + /// rejects the suffix continuation by checking the next char is not in + /// the test-name character class used by CHUNK_PATTERN. private static String readAdvertisedHash(Path path, String testName) throws IOException { String text = Files.readString(path, StandardCharsets.UTF_8); Pattern info = Pattern.compile( "CN1SS:INFO:test=" + Pattern.quote(testName) - + "\\b[^\\n]*?\\bpng_fnv1a64=([0-9a-fA-F]{16})"); + + "(?![A-Za-z0-9_.\\-])[^\\n]*?\\bpng_fnv1a64=([0-9a-fA-F]{16})"); Matcher m = info.matcher(text); String latest = null; while (m.find()) { @@ -252,11 +260,14 @@ private static String fnv1a64Hex(byte[] bytes) { private static long readTotalBase64Length(Path path, String testName, String channel) throws IOException { // The INFO line is always emitted on the default channel regardless of // whether the chunks themselves go to a side channel like PREVIEW, so - // we only filter by test name here. + // we only filter by test name here. See readAdvertisedHash for why + // the lookahead is required instead of `\b` -- prefixes like + // `graphics-draw-string` would otherwise match `graphics-draw- + // string-decorated`. String text = Files.readString(path, StandardCharsets.UTF_8); Pattern info = Pattern.compile( "CN1SS:INFO:test=" + Pattern.quote(testName) - + "\\b[^\\n]*?\\btotal_b64_len=(\\d+)"); + + "(?![A-Za-z0-9_.\\-])[^\\n]*?\\btotal_b64_len=(\\d+)"); Matcher m = info.matcher(text); long latest = -1; // The same test may emit multiple channels (PNG + PREVIEW). Without a From f511f847bda19abd7d742438621bd46ddf71d1cf Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 18:46:24 +0300 Subject: [PATCH 09/14] run-ios-ui-tests: include fallback-decoded tests in compare set When the primary device-runner.log loses chunks for a large test (the iOS unified-log syslog stream occasionally drops lines under load) the script falls back to log show --predicate, decodes the PNG from there, and logs "Decoded screenshot for 'X' from fallback". The fallback path was missing two things compared to the primary path: 1. It didn't append to TEST_OUTPUT_ENTRIES, so the comparator never saw those tests. iOS Metal compared 84 screenshots vs the 90 it had streams for; the missing 5 were exactly the large transition tests (CoverHorizontalTransitionTest, SlideHorizontalTransitionTest, SlideHorizontalBackTransitionTest, SlideVerticalTransitionTest, SlideFadeTitleTransitionTest) whose ~288-chunk streams hit logcat- style line drops in device-runner.log but survived in the syslog fallback. 2. It didn't decode the PREVIEW channel from the fallback log, so the PR comment for those tests had no inline thumbnail when the fallback was needed. Mirror both steps from the primary path in the fallback branch. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/run-ios-ui-tests.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/run-ios-ui-tests.sh b/scripts/run-ios-ui-tests.sh index 133cbaf937..941ce6db75 100755 --- a/scripts/run-ios-ui-tests.sh +++ b/scripts/run-ios-ui-tests.sh @@ -785,6 +785,21 @@ for test in "${TEST_NAMES[@]}"; do else ri_log "Primary decode failed for '$test'; trying fallback log" if [ -s "$FALLBACK_LOG" ] && source_label="$(cn1ss_decode_test_png "$test" "$dest" "SIMLOG:$FALLBACK_LOG")"; then + # Without these two lines, tests that needed the fallback log were + # decoded but not added to TEST_OUTPUT_ENTRIES, so the comparator + # silently skipped them -- iOS Metal compared 84 screenshots vs the + # 89 it had streams for, with 5 large transition tests + # (SlideHorizontal*, SlideVertical, SlideFadeTitle, CoverHorizontal) + # missing from the report because their ~288-chunk streams hit + # logcat-style line drops in device-runner.log but survived in the + # syslog fallback. + TEST_OUTPUT_ENTRIES+=("${test}${PAIR_SEP}${dest}") + preview_dest="$SCREENSHOT_PREVIEW_DIR/${test}.jpg" + if preview_source="$(cn1ss_decode_test_preview "$test" "$preview_dest" "SIMLOG:$FALLBACK_LOG")"; then + ri_log "Decoded preview for '$test' from fallback (source=${preview_source}, size: $(cn1ss_file_size "$preview_dest") bytes)" + else + rm -f "$preview_dest" 2>/dev/null || true + fi ri_log "Decoded screenshot for '$test' from fallback (size: $(cn1ss_file_size "$dest") bytes)" else ri_log "FATAL: Failed to extract/decode CN1SS payload for test '$test'" From d7eb2ed2d2af42f494cff1e45a1137b0b3f04c11 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 18:46:38 +0300 Subject: [PATCH 10/14] hellocodenameone: promote iOS Metal goldens for transform-perspective/camera The transformPoint+fillPolygon rewrite from a6570dd00 produces visible foreshortened quads on all 4 panes on iOS Metal, matching the Android output. Promote the latest CI artifact bytes to the iOS Metal goldens so subsequent runs match cleanly. graphics-affine-scale / graphics-scale goldens are NOT updated -- the top half of the cell (form Graphics path) is still empty on iOS Metal because g.setTransform(t) for non-translation transforms isn't applied to fillRect / fillLinearGradient on the screen encoder, while the bottom half (mutable image path) renders correctly. That's a platform bug in the iOS Metal port, separate from this PR's test-fix scope. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../graphics-transform-camera.png | Bin 94276 -> 113511 bytes .../graphics-transform-perspective.png | Bin 95108 -> 116726 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/scripts/ios/screenshots-metal/graphics-transform-camera.png b/scripts/ios/screenshots-metal/graphics-transform-camera.png index 0a1a02f462d62df23694fa702d5f305f933685f5..4f89c32cfd42f0af3b92587c5d5de32ba0167199 100644 GIT binary patch literal 113511 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 RG70|Mw#8&Kyj=L_{{VtL*IEDo literal 94276 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 R-ro)XCXP!U8+an8?4S6!_p|^2 diff --git a/scripts/ios/screenshots-metal/graphics-transform-perspective.png b/scripts/ios/screenshots-metal/graphics-transform-perspective.png index f83f02308b3cf91fa38add04c3009b643d8a0468..d4c6c744e025d8a37d9b949733c3a59a01953540 100644 GIT binary patch literal 116726 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 From 292b980dd3919c6676374ee828c3bc0976d6f7a3 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 7 May 2026 19:13:45 +0300 Subject: [PATCH 11/14] Transform: mark composed transform dirty after copyTransform setTransform's default branch (TYPE_UNKNOWN composed transform) copies the native matrix data via impl.copyTransform but doesn't mark the Transform's cached state as dirty. The TRANSLATION / SCALE / IDENTITY branches all set `dirty = true` so getNativeTransform() will re-run initNativeTransform on next access. Match that contract in the default branch -- for TYPE_UNKNOWN initNativeTransform's switch hits default break and doesn't actually resync the matrix data, but the dirty flag is the externally-observable signal that the native cache is fresh. This is the lowest-risk fix attempt for the iOS Metal port bug where g.setTransform(t) with composed transforms (TYPE_UNKNOWN) silently fails to apply on the form-Graphics screen encoder while g.rotate / g.scale / g.translate (which go through ng.rotate etc.) work correctly. Both paths construct identical 4x4 matrix data in the end and call nativeSetTransform with the same 16 floats, so the exact failure mechanism is still mysterious -- but the dirty-flag contract diverges between the working and failing paths and matching it is a sane defensive change. See memory note project_metal_settransform_screen_unrendered for the open investigation. Co-Authored-By: Claude Opus 4.7 (1M context) --- CodenameOne/src/com/codename1/ui/Transform.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CodenameOne/src/com/codename1/ui/Transform.java b/CodenameOne/src/com/codename1/ui/Transform.java index 76b9399715..87fdcadb53 100644 --- a/CodenameOne/src/com/codename1/ui/Transform.java +++ b/CodenameOne/src/com/codename1/ui/Transform.java @@ -792,6 +792,16 @@ public void setTransform(Transform t) { initNativeTransform(); t.initNativeTransform(); impl.copyTransform(t.nativeTransform, nativeTransform); + // Mark the cached native matrix as dirty so subsequent + // getNativeTransform() calls re-run initNativeTransform. + // For TYPE_UNKNOWN this is a no-op for the matrix data + // itself, but it triggers any platform-side code that + // listens on initNativeTransform to refresh its cache -- + // the iOS Metal port has shown that without this flag + // setTransform(composed) silently fails to apply on the + // form-Graphics screen encoder while the equivalent + // g.rotate / g.scale / g.translate path renders correctly. + dirty = true; break; } From 67ec8ffe09dc227284cca80fc5d0650cdf68641a Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 8 May 2026 06:33:57 +0300 Subject: [PATCH 12/14] Graphics.setTransform: conjugate user matrix with xTranslate/yTranslate On platforms where impl.isTranslationSupported()=false (iOS), the Graphics class accumulates xTranslate/yTranslate locally and bakes them into vertex coordinates passed to impl fill primitives. The user's setTransform matrix was then applied by the GPU on top of those already-translated vertices, which double-counts the cell origin for any non-translation matrix (rotate, scale, shear) and threw the gradient off-screen. graphics-affine-scale, graphics-scale, and graphics-transform-rotation rendered blank top (screen) cells while the bottom (mutable, where xTranslate=0) cells worked correctly. Conjugate the user's matrix with T(xTranslate, yTranslate): T(xT, yT) * userMatrix * T(-xT, -yT) so its effect is independent of any prior g.translate() (matches the canvas-matrix semantics on Android/JavaSE). getTransform() returns the original user matrix from a new userTransform field; g.translate() re-conjugates if a non-identity userTransform is active; resetAffine() clears it. Pure-translation matrices conjugate to themselves so TransformTranslation behavior is unchanged. Triggers only when xTranslate||yTranslate != 0, so Android/JavaSE (isTranslationSupported=true) are untouched. Confirmed locally with diagnostic logging (now removed): the AffineScale top cells which were blank now render the red->blue gradient like the mutable cells. Replaces the speculative dirty-flag tweak in commit 292b980d with the actual root cause / fix; clean up the now-stale comment in IOSImplementation.setTransform that referred to the empty-top-cells symptom. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../src/com/codename1/ui/Graphics.java | 46 ++++++++++++++++++- .../codename1/impl/ios/IOSImplementation.java | 15 ++---- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/CodenameOne/src/com/codename1/ui/Graphics.java b/CodenameOne/src/com/codename1/ui/Graphics.java index 6f24824d71..da18276416 100644 --- a/CodenameOne/src/com/codename1/ui/Graphics.java +++ b/CodenameOne/src/com/codename1/ui/Graphics.java @@ -59,6 +59,12 @@ public final class Graphics { private int xTranslate; private int yTranslate; private Transform translation; + /// User's last setTransform() argument (or null if identity). On platforms + /// where impl.isTranslationSupported()=false the impl actually stores a + /// translation-conjugated version of this matrix so the user-visible + /// transform is independent of g.translate(); getTransform() must therefore + /// return the original. + private Transform userTransform; private GeneralPath tmpClipShape; /// A buffer shape to use when we need to transform a shape private int color; @@ -137,6 +143,16 @@ public void translate(int x, int y) { } else { xTranslate += x; yTranslate += y; + // The conjugation in setTransform() depends on the current + // xTranslate/yTranslate. If the user accumulated more translation + // after a non-identity setTransform, re-conjugate so the impl's + // baked matrix stays consistent with the new translation. + if (userTransform != null) { + Transform composed = Transform.makeTranslation(xTranslate, yTranslate); + composed.concatenate(userTransform); + composed.translate(-xTranslate, -yTranslate); + impl.setTransform(nativeGraphics, composed); + } } } @@ -1129,6 +1145,9 @@ public void transform(Transform transform) { /// /// - #setTransform public Transform getTransform() { + if (userTransform != null) { + return userTransform.copy(); + } return impl.getTransform(nativeGraphics); } @@ -1160,7 +1179,27 @@ public Transform getTransform() { /// /// - #setTransform(com.codename1.ui.geom.Matrix, int, int) public void setTransform(Transform transform) { - impl.setTransform(nativeGraphics, transform); + // On platforms where impl.isTranslationSupported() is false (iOS), the + // Graphics class accumulates xTranslate/yTranslate locally and bakes + // them into the vertex coordinates passed to the impl's fill primitives. + // The user's transform is then applied by the GPU on top of those + // already-translated vertices, which double-counts the translation for + // any non-translation matrix (rotate, scale, shear). To match the + // semantics of platforms that fold translate into the canvas matrix + // (Android, JavaSE), conjugate the user's matrix with T(xTranslate, + // yTranslate) so its effect is independent of any prior g.translate() + // calls. + if (transform != null && !transform.isIdentity() + && (xTranslate != 0 || yTranslate != 0)) { + userTransform = transform.copy(); + Transform composed = Transform.makeTranslation(xTranslate, yTranslate); + composed.concatenate(transform); + composed.translate(-xTranslate, -yTranslate); + impl.setTransform(nativeGraphics, composed); + } else { + userTransform = null; + impl.setTransform(nativeGraphics, transform); + } } /// Loads the provided transform with the current transform applied to this graphics context. @@ -1169,6 +1208,10 @@ public void setTransform(Transform transform) { /// /// - `t`: An "out" parameter to be filled with the current transform. public void getTransform(Transform t) { + if (userTransform != null) { + t.setTransform(userTransform); + return; + } impl.getTransform(nativeGraphics, t); } @@ -1576,6 +1619,7 @@ public void resetAffine() { impl.resetAffine(nativeGraphics); scaleX = 1; scaleY = 1; + userTransform = null; } /// Scales the coordinate system using the affine transform diff --git a/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java b/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java index 99c7c401b7..30ab8297df 100644 --- a/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java +++ b/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java @@ -2402,17 +2402,10 @@ public void setTransform(Object graphics, Transform transform) { ng.transform = transform == null ? null : transform.copy(); } ng.transformApplied = false; - // The cached clip / inverseClip / inverseTransform are derived from - // the current transform; replacing the transform leaves them - // pointing at the previous transform's space. Subsequent draw ops - // (e.g. fillRect or fillLinearGradient on the form Graphics) read - // those caches via loadClipBounds / inverseClip and end up clipped - // to the wrong region, which is why TransformRotation and - // Scale/AffineScale produced empty top cells on iOS Metal while - // the equivalent rotation via g.rotate (which DOES invalidate - // these flags, line 5513) rendered correctly. Match the - // rotate/scale/translate/resetAffine paths so the cache is rebuilt - // before the next draw. + // Match the rotate/scale/translate/resetAffine paths: the cached + // clip / inverseClip / inverseTransform are derived from the previous + // transform, so replacing the transform must invalidate them or + // subsequent loadClipBounds / inverseClip calls return stale values. ng.clipDirty = true; ng.inverseClipDirty = true; ng.inverseTransformDirty = true; From 4afc42ac3520c5aa818efd8fa07a2d4bca46f5cc Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 8 May 2026 06:38:24 +0300 Subject: [PATCH 13/14] PostPrComment: retry preview push with rebase on race-condition reject Concurrent build-ios + build-ios-metal CI jobs both push to the cn1ss-previews branch in parallel. The second job's push got rejected ("rejected, fetch first") which threw IOException, the comment-post step aborted, and the PR was left with a stale screenshot comment from an earlier run -- transform-camera/perspective looked like they were still differing even though the goldens had been promoted, because the post-promotion comment never made it onto the PR. Retry up to 5 times with fetch + rebase. If rebase conflicts (the other job overwrote the same pr-N/subdir tree) reset to FETCH_HEAD, re-apply our own preview files on top, and try again with a clean single commit. Co-Authored-By: Claude Opus 4.7 (1M context) --- scripts/common/java/PostPrComment.java | 42 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/scripts/common/java/PostPrComment.java b/scripts/common/java/PostPrComment.java index 46132ef23f..0729ecdf37 100644 --- a/scripts/common/java/PostPrComment.java +++ b/scripts/common/java/PostPrComment.java @@ -314,9 +314,45 @@ private static Map publishPreviewsToBranch(Path previewDir, Stri ProcessResult status = runGit(worktree, env, true, "status", "--porcelain"); if (!status.stdout.trim().isEmpty()) { runGit(worktree, env, "commit", "-m", "Add previews for PR #" + prNumber); - ProcessResult push = runGit(worktree, env, false, "push", "origin", "HEAD:cn1ss-previews"); - if (push.exitCode != 0) { - throw new IOException(push.stderr.isEmpty() ? push.stdout : push.stderr); + // Concurrent jobs (build-ios + build-ios-metal) can both try to + // push to cn1ss-previews; the loser gets "rejected (fetch first)" + // which previously aborted the comment-post step and left the PR + // showing stale screenshots. Retry with a fetch + rebase so each + // CI job's preview commit is appended onto the latest tip. + int maxAttempts = 5; + ProcessResult push = null; + for (int attempt = 1; attempt <= maxAttempts; attempt++) { + push = runGit(worktree, env, false, "push", "origin", "HEAD:cn1ss-previews"); + if (push.exitCode == 0) { + break; + } + if (attempt == maxAttempts) { + throw new IOException(push.stderr.isEmpty() ? push.stdout : push.stderr); + } + log("Preview push attempt " + attempt + " rejected; fetching + rebasing and retrying"); + runGit(worktree, env, false, "fetch", "origin", "cn1ss-previews"); + ProcessResult rebase = runGit(worktree, env, false, "rebase", "FETCH_HEAD"); + if (rebase.exitCode != 0) { + runGit(worktree, env, false, "rebase", "--abort"); + // The same prNumber/subdir directory was overwritten by + // the other job. Reset our index to FETCH_HEAD's tree and + // re-apply our preview files on top so we get a clean + // single commit. + runGit(worktree, env, false, "reset", "--hard", "FETCH_HEAD"); + Files.createDirectories(dest); + for (Path source : imageFiles) { + Files.copy(source, dest.resolve(source.getFileName()), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + } + runGit(worktree, env, "add", "-A", "."); + ProcessResult status2 = runGit(worktree, env, true, "status", "--porcelain"); + if (status2.stdout.trim().isEmpty()) { + log("Preview branch already up-to-date after rebase for PR #" + prNumber); + push = new ProcessResult(0, "", ""); + break; + } + runGit(worktree, env, "commit", "-m", "Add previews for PR #" + prNumber); + } } log("Published " + imageFiles.size() + " preview(s) to cn1ss-previews/pr-" + prNumber); } else { From a54efa04fe2d45dfcdac9f4ec5579609d5dd0106 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 8 May 2026 07:32:18 +0300 Subject: [PATCH 14/14] Gate setTransform xTranslate-conjugation behind impl opt-in The previous commit unconditionally conjugated the user matrix with T(xTranslate, yTranslate) in Graphics.setTransform whenever xTranslate/yTranslate were non-zero. That assumed every platform with isTranslationSupported()=false had the same iOS-style render path (vertex coords carry xTranslate, GPU applies the user matrix on top). Android also returns isTranslationSupported()=false but its render path concats the user matrix into the canvas at draw time -- the existing semantics there were "shifted but visible" rather than "vanishes off-screen", and the conjugation moved elements out of view when CN1 framework code (LinearGradientPaint, FlipTransition, CSSBorder, ChartComponent, scene Node) called setTransform with a non-translation matrix during normal rendering. Add CodenameOneImplementation.isSetTransformTranslationConjugationRequired() (default false) and override to true only on iOS where the bug actually manifests. Graphics.setTransform / translate now check this flag before conjugating, so Android and any other isTranslationSupported= false port keep their previous setTransform pixels. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../impl/CodenameOneImplementation.java | 16 ++++++++ .../src/com/codename1/ui/Graphics.java | 39 ++++++++++++------- .../codename1/impl/ios/IOSImplementation.java | 21 +++++++--- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java b/CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java index 1190843222..7b6f8ad2f2 100644 --- a/CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java +++ b/CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java @@ -1517,6 +1517,22 @@ public boolean isTranslationSupported() { return false; } + /// When `#isTranslationSupported()` returns false, Graphics.java accumulates + /// xTranslate/yTranslate locally and bakes them into the vertex coordinates + /// passed to the impl's fill primitives. If the impl's render path then + /// applies the user's setTransform matrix on top of those already-translated + /// vertices (e.g. iOS Metal's GPU vertex shader does + /// `projection * modelView * userTransform * pos`), the translation is + /// double-counted for any non-translation matrix and the output ends up + /// off-screen. Override this and return true so Graphics.setTransform + /// conjugates the user's matrix with T(xTranslate, yTranslate) before + /// passing it to the impl, restoring translate-independent semantics. + /// Default: false (Android's setTransform path produces visible output + /// without the conjugation, so opting in there would change pixels). + public boolean isSetTransformTranslationConjugationRequired() { + return false; + } + /// Translates the X/Y location for drawing on the underlying surface. Translation /// is incremental so the new value will be added to the current translation and /// in order to reset translation we have to invoke diff --git a/CodenameOne/src/com/codename1/ui/Graphics.java b/CodenameOne/src/com/codename1/ui/Graphics.java index da18276416..d95b7cee38 100644 --- a/CodenameOne/src/com/codename1/ui/Graphics.java +++ b/CodenameOne/src/com/codename1/ui/Graphics.java @@ -145,9 +145,10 @@ public void translate(int x, int y) { yTranslate += y; // The conjugation in setTransform() depends on the current // xTranslate/yTranslate. If the user accumulated more translation - // after a non-identity setTransform, re-conjugate so the impl's - // baked matrix stays consistent with the new translation. - if (userTransform != null) { + // after a non-identity setTransform on a platform that requires + // conjugation (iOS), re-conjugate so the impl's baked matrix + // stays consistent with the new translation. + if (userTransform != null && impl.isSetTransformTranslationConjugationRequired()) { Transform composed = Transform.makeTranslation(xTranslate, yTranslate); composed.concatenate(userTransform); composed.translate(-xTranslate, -yTranslate); @@ -1179,18 +1180,28 @@ public Transform getTransform() { /// /// - #setTransform(com.codename1.ui.geom.Matrix, int, int) public void setTransform(Transform transform) { - // On platforms where impl.isTranslationSupported() is false (iOS), the - // Graphics class accumulates xTranslate/yTranslate locally and bakes - // them into the vertex coordinates passed to the impl's fill primitives. - // The user's transform is then applied by the GPU on top of those - // already-translated vertices, which double-counts the translation for - // any non-translation matrix (rotate, scale, shear). To match the - // semantics of platforms that fold translate into the canvas matrix - // (Android, JavaSE), conjugate the user's matrix with T(xTranslate, - // yTranslate) so its effect is independent of any prior g.translate() - // calls. + // Some platforms accumulate xTranslate/yTranslate in Graphics.java + // (because impl.isTranslationSupported()=false) AND apply the user's + // setTransform matrix on top of the xTranslate-shifted vertex + // coordinates in the GPU pipeline -- this double-counts the + // translation for any non-translation matrix (rotate, scale, shear) + // and throws output off-screen. iOS Metal in particular surfaces the + // bug starkly: graphics-affine-scale's screen-mode top cells render + // blank because translate(18,18)*scale(2.65,5.36) * (1134,279) lands + // at (3023,1513), outside the 1170×2532 framebuffer. To make the + // user-visible setTransform consistent with platforms that fold + // translate into the canvas matrix (Android), conjugate the user's + // matrix with T(xTranslate, yTranslate) so its effect is independent + // of any prior g.translate() calls. Other platforms whose impl + // already gives setTransform that semantics (Android Skia, where the + // canvas matrix concat happens at draw time and accumulates with the + // user's matrix in a way that produced "shift but not vanish" before + // this fix) opt out by leaving + // isSetTransformTranslationConjugationRequired() false so the path + // is purely additive for the platforms that need it. if (transform != null && !transform.isIdentity() - && (xTranslate != 0 || yTranslate != 0)) { + && (xTranslate != 0 || yTranslate != 0) + && impl.isSetTransformTranslationConjugationRequired()) { userTransform = transform.copy(); Transform composed = Transform.makeTranslation(xTranslate, yTranslate); composed.concatenate(transform); diff --git a/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java b/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java index 30ab8297df..15363e2ea2 100644 --- a/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java +++ b/Ports/iOSPort/src/com/codename1/impl/ios/IOSImplementation.java @@ -4219,15 +4219,26 @@ public void rotate(Object nativeGraphics, float angle, int x, int y) { @Override public boolean isTranslationSupported() { //return true; - // We'll leave this as false until the next iteration... - // ES2 should allow us to do all of this using transforms but + // We'll leave this as false until the next iteration... + // ES2 should allow us to do all of this using transforms but // let's take small steps first return false; } - - - + @Override + public boolean isSetTransformTranslationConjugationRequired() { + // The iOS render path bakes xTranslate/yTranslate into vertex coords + // (since isTranslationSupported() is false) and the GPU then applies + // the user's setTransform matrix on top, double-counting the + // translation for any non-translation matrix and pushing output + // off-screen. Conjugating in Graphics.setTransform restores + // translate-independent semantics on this port. + return true; + } + + + + public void shear(Object nativeGraphics, float x, float y) { ((NativeGraphics)nativeGraphics).shear(x, y); }

YErjGOApbUMqngof=yLM+4p^jfC9i(Zxh>uF=D2+X5)d)*e z^0ma5v+>iz&{7T{W*<41hzP?f-eU>sHecuoSHQUL1e+6I{)eX%Jj)nOe7V?llMVdZ zLerbOrYZ}>0`}raE>ecK*k;!t@7a*~)MCB5DiP)W) zqPqYc3XpV=LsrrOfu4kB-{&_RX-qI}u-42gp@1roO>B#*nP7-E9ZeO~Xk|=QXAUep zFr)0k6ZNJ!oc+r)s2c=>3MEp@%`39tXE69|FvNoLr*GibBhn>elgMIJkPAVEps1$1 zcNEw^(h;D9SRG;KMx93L{Z@*D0^Nf3q*>i^frkIaPfQ5NS+ur|3`SRi^6Es*mXSwT zLMF!GhLs_LjK3wtT^`R_0Gboh1T^#025t){TjfRVDrZ0Kk7Ky=Ejc?oe>XxSV^2oL z;MpNVG`H?lq&xoEAy4!Imyjxn{PL(HOuV1SgBbH{_RC(-&5Fe|_M?u^PvaDZ5npPT z-9+oCMd<9h`pfuGN4}HLnWo9dXnZ9qohX_@cizNoJSLS#lxAMkLST8JE9yb#3# z%7{^?xzDPsand}PDa_MqLJPp%N}MU5)f-dGl9fHRLF&f%N{NWQLNU`}3I_U^&#LtYG`oz1J z`oP!gm}Qu|)f0W63{n_Qg-bVWhF_~_>ZOl2B^kk+D&7pR`2EWsSU_K;fTS&{w4Q!# zA@R<2>wOF>+KcInZni2Y7oCIQ=6i3Ry(C3ZYx(l6y+djWhxNe4B{N;)}d;Ihe` zv;tad;xZp{JVS|XZZ@BxO-ECO)hiiOWmZJ`QoisEhto2=>5@$TMihfCFaAr6zK|<% zCd7+(3_Wxi>5_bhIAc_h;G@FgW_?uB5ts*IbObuLp!Qhj7Ih0y%IX#tP<%*?j8?)F z;%Mph=R8~q*evTdJs3oMDOsUP;h8B7p?R5T7s=s4V)pDARrDD98q+G9@2)zb_Dg(hVj(l;Sz z{xnaKL=GRj4meVl5)%5{r?`33GYm zf|4F+&Sxc^i%#022qU?Z2Ga&>O*17L#qD@3u`MgT2yHr=DzGE0sZxQ32X;ih@MhB- z4j!;Cm;4PkA~i}g&IqOyLpK;A8@ge}4s?m^Odu*qGms(pAnT)&jsQ{_9f8g*2!`Cb zMcuL}Latlx(eUqeaW};|G-N`xg5YFSUPQ}EOaQ3`&mf5z+nb_&)st0j0oscI;=ssSmn2 z7{;JgC4uqQ@(p{;F(SP_ne2G{<*@Nk)=p(FV~sa!1ouN$H9@ondQPyivw->&Fwipl zmtC_Zci;vMdRppJN=D2lPHs%JoQLk;4aReD+SzyozMH_T%=zW^UqZiX4S?AK9e)vh z>ItwCE(xHhM2qL9ehHtoVN~`S*$u>jF{2a5!Rwkx91ctL8&g%poYHZ)LTdjn#ffb>*ZWArJ;OFk3Tz`avJ9kdIEyv zJpmF8tm;YZI0mrb&e5#7-hkFgWb&1gkZWG7aTXXzEA}a{_OXIbyYtja@eAGLbc{ zr<66%8iv3}JV2MhgvC35B|)(XC#zn6ddEblP7FQ;6R;E(>toEBMWF>hE2nxs5HF9^ z33EoWRtln^B5K8sUM7P@@U39ClAO# zWyeirTHckB$0?z2)`wnu&4+K&XF%PspRseMk9s+4#G(f{g{Ctr&nguyyOhE!er5Fl z>ehtfPU&LRbx=E7C7DU%mqs~%#THlW3G6wD zo_oQ_613-iY4wFB-12t7IUs!`-8W1BGvu8&lgcR#de9eF{Q}}ZWr2Ar+V?_6ar#)_ zGyo#Z*fi)J%THLp^@3^VmleRP?# zNVfPnb=4bDETc)Fed2c?L9txPh^21)DH6+YCZThG$Lo3=+HvxZBAcS{huz=Q^0emV zWcWFrk&rh%f1vb36=bQPbf_lj)*PbstWE%v*<%tqDWWjBC_$keR+OsTi2=@%g{c_G zq7VYtSs?^46w)Ip=?)WdN+`OK9y?ncf{`@HHn2`E+mK8I2??`aZ%Hb-k_1+k^|T=g zSy{#OyQfea`cVsJg7<3s@doe{7aO3fu!~K_n~}>u>UYs%W4>v$=UF9LdM0Pdeg?xG z^qvZJ?J?YOC6Nt{jq`?*V5AygD6DEw@n>PO0C6irA!8K(WcSiZd)?*isJkf93^z zX49k$zraH!>5}Uz-tuBF-b z5m1I^H1Q`SrmO_x9Y~FW=TVU`Hv_`~ZIS__O#zJLKv z@3c0mn^59F;U#}>jPH{nxdeJ&cJY9-+~7}4%s9Wb2MXmDTD5K(8R$M6GVb$f&CGiA z*PUpL?)h3J=!Skxot_+*>-@|lOIK1`d!4jAlu>4b zRJNg~J}%TedX`n_l!{sG92(|Xy~FRvqn8rGFfC;O(+*;JzvMM0cB`1ZKX(a$kv&P;(QcKTM|o|Q-6I_xv`8`@|-Nmhc>0Cv;LIo zvr5#EW~73bH}XhbE}@o-4Yqm0PdmuXfP}ozywZeguZVFYC)4)B8KTwNdNiLpu|lTv zwhE`=+Cx!-yH~6z6;%)e3R8dgM#m9_5ayBYgCLPzY-(ueK-5`7 z=goYRuYN-U-|QrW&w!WBeg=1rP%Kk;8MJdmB5UN}*mx4>08|5fl2r|A4UoJ7v9#1V zu?hVK&?;bTf?t4~($Tz8k4y)CK?aoN7Z-FDe6mef!J|+e@)4N5!~7qugE7%l zLOc(N@0vm0m@ktzoxP_ho2G}!eEX)2Y#}2wk4X~!a5ocUOe4~w`I`cQG1aqx)H?s^ z=o;M2ae?eC%(Ibt=9kF3Do+xEaN9+eDEdakffQHG#%1u-Bb)|Vzj2u4z1-=VTHO9r zE2C9gt{aRy5iX#rq1VL*M=LSeBW5(k#cwlk-)S+;<@}W%HSmc}LR)Yz7DdQvH#eLj z3Yg@nskMrLQv9*hHq**C7SlZ@jK<3wXpfoeSjG^ih`qglgfrx)Slf zW8~xt3K`=s&XZC*Hsizb!nKE@1X`UHB~d;xAjM}!BN{;zLf|?pgpj|bxvbX>$K7t1 zee}@vVxTj!4rCj|PA=QojP`LlJq;BwH%5|BfT6IeL96O( zMl7x7JVUPqvhRy;avG61T(3aI|WDo+30W3 z9Xv)m=+b}YmtZhn)QjesKkn!^$h#s)NkT+pl6E2tMW0U#)2noH^;vjYWkQ3j%%7f$ zL`vFE6eFoC#>^K;8OYRBNGZsy($0iEFaQopT>rnia8=GJb=89cX15c_lU0p;*%9 zM11NJDI8?zB!sLED7@!Sx5DLCZXpw&&JVePnO{)|BbJ`}ji`Yem;{ie?#XjR0W-{c zozR0YE|)->uGot~&S-jl7_m%Rnt{}1GyHMCG%XaxvV{rG!gcqik%lB2&MW3qE^;xo zoG(@>L38>7M!EI)-R9<=%{#HF$~cv#!B*#5$IZ*uL3W}+TVd5)b3E-zc8wvfI@Cq@ zqFRE5Swxb>J;V3^Hb-^smUWvjJY(KL-N@q%6!Q*Uhw--k&CJRy!eS3C)V2<#eeRS= z4^4!^`R_Ws#~H}8DyV6D2ma#{miWtA7J@K7Vh)=)Y5wC4YG*vN^Z45igD;Rz4a^pk zt=>)m7J#Ovr2p$JlKpgE>+Zn_lq(erZ*mqFHI#@bKB~L3L52LtPf0-{g(V!`uw` z*YezqB@k{AA$u@=ARQ{gv<}#DHmy@i6D@a|W`+~mbwLvu&jHt+%cwTeSZvZ)gYZR;@jS!=iWd1V&1+I%zG9dy zC-LN88&OlhK`UVE*Q(B#wA89%PV1%F^lC-Ea($UCTnE)B**Mj9VDw>1R;D{ohPQG5 z99&2f>#OtNA=FsHXR+}i&Y09-cFfByir+tAq#NacVmY4?%L|^~8Yq@b*cW0DP>D%j zOPWjB^VI|COoWt%$(P(4fO!=Mk}V@guf~f=0F&lPwZ4`C1XP`&p*RHP-$z=Dn0=?_ z7grj*aA*rj^p^V45w`K*g1}OE;BRLG&w`o#$hW_Yr(Kc;7#Ex|@+bSP%=juZzRHX* zdIHLfuQKDS%=juZzRHa6yL0EtjPJTF%8aivCwS8kk zasN+5P=LYqOYjr7S0IvRw^z)Hm`oJAwOKWo8cJ3U5>T=QKLf!#`x(4U02>kY?%&{c z7#>%Etr+&W0&WJuC)v#)IOSImXP{TqJ>#8{Zl{y7z@kB4HzkZ)s-(hk+x#@tAhP`*Uge5gSa zXJ|YfO&9+>%b**)jh7H1-*#jEYCHg7$ejM$6_P0 zbEn}>XC-qEC2QkzYn&k;8f0Po4sRraJx&|=a4~$*>^SArqLS>Sn8kz5IY@#o5U))& zfcbJKw#Mgw_KhvHn@1@}gEdbwDVyTUT%F2Ie*yqA(3Ck(+q_{|6J15jprnz3V`C@C%sesf%43jSKIbHDnZI5fU0M@IL%pBVbnY_Oe&!-zOVp(Hf zEk?1NOEVI_YTl0!Q2B|NVM?v1j=({~aUYlyhmCp?JZde2Gzf?#KQb7p3!@ZH{j1Gh zc%V+D=``h9OnF}lC|}I%+TO0Di+m@kWk_Q04BSAy&t%*rY9*A;XoVcxqKMen$Vod$ zw89d4JmC_Z28E-du*G#x^%ZUnpeTVf%SFkVN%YqBEXHHmD1^XuRtN!Tljc&KhYEeGQIO;@LJMN<53tt-Ve;$7~WjS<|7d93ZujIfoLOe={EUuw_gN)LFF=iC}Lg zj*C2n3)75pYCQhs0?gvU<{YN86YqLE!+gD>bEZ!5Jy)kfyI|VVcDj8fgifnB(Qy)S zbkJ3(ISNg~nKW?T^afX)>R>u1=#*0(f|se}x9oDp%`m&Rhb4FtP-Pyq zG;kXcj5*?yBq1TG!!l?gw$Ns{!!w|UlF6`yGTCiBErwIVo)$yd2C-vh+k?5n}POu0K~G8*&M**3a~Kc z#}z;|KucCNKynv^0?v%Edk&~o;LMR+tH5prC?NT61$#@8;TP#D_@rD{VW)X?OEHGI zrKsHaqA5{sd?`1+lp9}Llp9~C@BUxA@g+z<)mm-ak}qhI=yVzQGx`WjIpxWcK<9aW zqD-=YPBv-bU7u&SG?})R3S|3VHN^{L0;e$lCumQHgH;@oU&hVZ<2x}G4ku?b$00nA z2-JU;G}k!Zuc^FRkUZxXC<EdisP6q30T=ztLj@a`3BL&LrZK+qnmHEo;>wJ zoa})wGh3$%mNdIYi;gx2OfYIY(O$CSRjH&}CAT&3L7K?3CUGE?CF)FeGO(sB-k`^s z&S~0aOk|h@>dsR2)dj268 zT2fMM08t>`12|!xdn+iv5@3FtHV%MtOmG+sO?R?yyu+grU2Iw%rnPcPGp+w|ffJh) zVt9@8OO-7Y#=Z604960NQV7SdvGO(8eNiTBvA!3=-wRx8_>nk~Kk7m2_#cF|H_~(j z0Pfn>dFza0$6P&oE@+J{%uKoseK!dhH(=loob+AO!6RqMIPRR8R$N&u*?Gxx=YV}8 z=893EWy^f$ek;0#>!wb9*JsG}M(Ay3acrYagX8-X+$&9W!nwI?}yF}gC zUIXD5Uh0D^CxK)M);_4|vN0+x6hR%iMzl>00!mUeJ^KQ0|(TaJhy}MhV2AD{2Cqr_p zZL`-3CM*=Cec@V@YA{I16m=1vsuwQqv*O_WYco^|=;*Yxq}FKs2AjIW(XBc!GDEHc zZ{IME|0@rHB)9j9l)l%*?}+fWwQDeMRRPgKR%Bmy;kLki6xau^5iIU3taZ@doi^*8 zn9a8o+_zD$0&#EZJ7JJ8oWc!jlP|@Fi=otB)0Wqk@2Cjz{59m^2oA{bn-U*;L(XhQ zdY(Ujb7wY}n{&|NZ@uQW#WAAWxt-EcE+7yfY-wg!Q<$*AW_Dzr?{qV}l(+M0iy6j6 zohi0$&9xP`%EDXsr!@@~P7=1(3S{MiR@;`=R+(w*De1CT&h{gYX)o;ckEg~Hzd?m% zPKLvC7L4KdZm>493)N6FI5s8zkIeMHCPbh&zBDcE;h;BMlVMdu=T}yK(ac-V<(T&V zs@v1#J?IR#sD8&8%i)x3cRSONy4=pj{P2Js5FJLoZ65kWyRgK6E*#O!EqY^GUMonu zv7h}WlnE#-5xB2tbcL1;zuqltk@CW2*|y=DZ*6C*AK)A^n+_8>!Z3(iayVha2!HAA zO;?i+?)%nmo1e&PYLv5K=g9(Tt?{6SDT7uB_`3d5N6mt&nqU{hqg{lyDyv$p?`2xn zX!^!*{}$!0Gpt^0sMWmuz^>M}FEn-@7R)rWdpN@CC9kXb^#{2p$c4Y#+WaE%dv#MI zLH7+~7%rb4X2tO5K^dTX&48MXr-!-uObHMAevLWC1b_RsYMg(OpS-Sb!x2Bh(3663 zuk@!+Q7h%4E3f%>a%=3>+u?oHR>=Ozj0-vI6ZT%apd#Z@F29N<8Md}WTgcJ|kN8}z zjh#@-5D@F~OcMl|ndF9r) z6qUNzHS_vSN{rstdMBbz> zd)q-E@+?E7#PrU4Bl81g#?7gp@m+-MTC2WsYff>lW4c?!INz2E%~NR*hmPR1_yn8Y zBd7{LwYBG zCcV+BdaT&&7{7O~Ijx$ZGw~=8PdTBfP_Ua_B=Z7E60I*SB(ZFLj zn%bK9JLM$3sz}?^rH_ZdpJ=KH=&|!%)vXKSx}}zEshR~w;)uwr)hBqfR#wuTvM9&l zG5z4!kguLrOjN0Tl`HDK^A|bQ^|P;L7j9~XgcwZnmTZAAcF?aix>q{C5JUv1K<;gs znVpZ}GnDhgwGYZ{yf%NW37NBm7QM#pra@gc70yCSxC=P4i?e;k%eQ}+=tbP#i?1(j zZW--cclItE918yWj;ZzV5x=poC-#-BaTuayKMSf*>Uh7r{mCS|mWyb{re?`ghW0j5*3hnv}H2wU>{4EUX4EY+UGlkvMk;?(&m zj_*^IoG$y*6Cg19m4)jZY+GsKU6to={dhT6C8HkzM0}tR1bwrcHXVg5N_Kn75RnEB zngZ@wTtYdoX2RbYSXPtwu+sUdgJd9_Ar~IuG{=sb(57{aUh~{bI{97XVM_+Kv9vrIJ_LN~=SV(;LF>ut8Zq0pf4Tm)3#hb%rF1wRv zts8djZ8HxGyn{kL{et@oPk_8ci8oZ#yx+*MF`x$0%I>|}F_~)J?m}oP$4$9OCGS&} zlx%wx4z$i~KZ~Iax*^8u#(PBbfXS1Pwcijg-SGN`v%P)qAHzr{3KnbJyYqHvUfdmKmFlQ$v=}!*^NI% zKcgIta&DB8rd&5lo%TOoL-)@AJ+D)z$+~lAe!E0zdz6+`=@%&MOewt_rI(}ha+F?< z(#!cD@8u{xoBz+AjZ37c^{qr8JJs6wR`MFFh`DOzP?duzEW1;bo=Ua1u<-F)S8t*tn2ids2UWsH>Z>h}G3Ihea1TDE@om+6%#8}muD z-=F(ZaDH9OqZzim9OGUYyG2Jh4oxMumTTV&aj=pz1}}^pfQpWs^5r_34dH1$lj|$u zd)zFz>r!IiVd--m3EkhcbS_k^|LSd?CO1$7L?)7z!C<>9#_-#3J739cPA zueb8ktIM=(eJQHEKjes+dC|b1eV1;w`O4;t_}q0Xs+VG|_*;@S`rURUsr{v;6(jBb zwXpV@>74ajqMdbf{qHp16Zv1@eRq9GGBwC=6eYnc^jHmB%qWsvXE>Ps`5p5+VJ5w@CZOzkJ@759J7+mE zWKdQH}i9xCI6 z4|}Z2zPc^?s<1fi?j)}wf2|Gthvoh^hQtj?K7(@5{P%N*@Ku7A)~-hxQExVw+Uma# z5Y_FvM+{Yc@Qy!2og?msE(7X^(OL=zVcwaVh(o0^vHjpY}rw~6L+d~1Gca$WzkC71o~Bq)d|`pZxB_Ib?Ghu6El zpDyfHc~bB7FVp5TqOiGX`?{aQySF6`BP1o3M)CW7Y=pJ3UEGtee)(j~LcNHiRNU3^ z%?-Vl#_(2gYoCToqO_KBNo$3qMN-+?ER(eU=-q9gP;?zC`;IFtyRPxJRQquF$SMmn zJAXmhUc^CwvX!^2(|@-tnjuVEpC7FeP=D-+${+^b=j#28p-xcXa^IB2)5`oA@P+8& zx^5}mnx-S2NAsWW4}7B1^lT_PWqAWik2}zD9c@IM-(;*hP(8fo;GGm zpAGGu@Y(OShmR#!_MEK+$RGep@%(0OVeihu{!_j$_*v98#GBovDT}$FbDmGz zXvkSZ6^Z9h3Fuk91D1ztVz7!FiXvK~(Jemh=vOYy^%gKf&%T=b%$8Cu>Aqi71nlgy zVyR`nn&B=CT=^|W&&_MauV0Z=1sFs=Q8`0kCDMJ1eV%>OHD|r{?#4cBP4MS&1%{DM zJ`>YCCwPv4LeBfBHnY>Ty4=C5>?%AGJw|g_oNAjiw-IB;*OaH(!s@zZlpm(tySRDfMYz zPVty57Y(C{ zI5M;EiZ6V^3IaO`HL0NXe4F%nEzNF0q>gSmt~2CtcQcS5V;xT>tF5?ZVtI0gUmMGc ze|sdW+>Rny4&uvIrz+(2lB;Ffg5fdhO&g8?2v^%wgr5*Qn7Xoz_~CP?sXq%K?>zoMnA4A-ytzRveyx) zK(MFh-}^7H3vJG;e)Ap|;FC~n-T=n4S!T|^KVbmkG*LZu7K-E-fEYRgxfw^`p*D$!(WU@T zd#G%mK^Wl%Ki=K@Ey2%IICN zy`5=<^TWVs`CL?MIfesSPtzS4*JM8fKH^5~IU74E1L4FSh*l%7B+sot-5Y|=DYqR{ z36ScYp#CZP0?(f&BCL)(fN=pL+WnH(h7wGZn?_5UDGQp1H;EJ_5sfhhPjlR8R$&1qk2rLlfbkT_7cF#Q=ma zB!F<SW3QF`c%E0Ng z7)8*LT3UN01y6&9S%h-L&&sJj0R#jSc#@N}dI0q*B^)(=?(~6(bcbWMh>(x@6=N8J z{GUx>c@=2R@~V>%7zsirXCzKzRv>YB66w3M=X5d-L65a0QV;Vv_A`;rp^SQ2+q-E1 zP^RLoNAnK=T77Xk77{)kZwG@4B}!!*hgkv%!oAcm<9wnj60nyRt0r%Jr8bCI8$4YYg4stBt=1d2 z2kXJBe-n5_8##hb7XrLjAzN@*YjC&)WnY@i7b&wvjBh-RT@ ze>e#b4FP}&u#xieGw;JdjsxXTJh^p|C)5GPqQ+<}Mrq`x06StB_^i;$`yD_Bh_Xlk z+zaQ0;mq+#cOSosME7aOEYlIXH!GKeiVnoFRt$x0<$`$ z`m7W_X?C2T>vF4;0EDZP@NfF$-%i{b_-W=wYv-ZC&y6I4&cxTrgt_$wcx4e$Zaun^ z+FhW9{DzYRNE1*FnY2Ut_1A-7_>TZD42Cb&yj_FZL6^}EIwv-fc3?EXrF4ghzzl>| z1nmIOigQsrFt8hO@q6-6J4~U5**bAXq#a;AAR3i?Jut|RdRwDuOn~(WI_GxCp!Numc2)qJGW_hK8j9m1Nkr?DMxQ}NT z+(&-~_wg@6=8I~>eVju~oxP_h8wXtEMZ`$-c7=oH>;wT9GH1-V#3`tOXVJs4PJLWQ z1Kqpm*@A+f!ccSQ({jy}!#+0CL#gc|K5F1F(vNio=3&Sy8Bv<=tm-)&Sk;F5$U_3` zmJmH<+dNG{02Yu;@n4$P6d)G?#}EWyz2-mOFslm*7?gK-hrt)f@CF7y0#F~FNj>Tl zt>HR9o5K3+B(x%W*6XC@;YS#h&hiaC^>G67=vh{wQ&<>K2b4q1{x;~g5%vS;1i{7C zy_5jw7CH$-X^<5cJdIHYxHIY+Kp!^%0SS!m2;H-81JZ-|n&2B3-W#wBI&~l^H*)my zw1S6c2-?y~e0FsSyy>xw<~TOJLJGgMsu)l@zy72)<8S_sqv^8z7WG;KJq5-E5*r?((v6S3&RlFj!%>( zITA2pXO1g1%={2h)$%*wMjWFZQg|82H#8)Gp~xB%F0KbaK5bhM%+tGGgz$QpS}ra8 zyadn?g|~_0V;KC$PC{k@XrwGBZZP2$0JCNjn5Qcd8)m(putpzK%bY@8djv5A#5_EL z5*tUxw1l)(2m@BxNti?r#VnpGj2R|bKISBH%JSDd^XSF!3ZMd5UYQ{y4-9N$B#tq* zm?X6)Ek?%;s8r! z-|Pz{XpsukjXfg;eA3RG2%^VaBSQvK?ZV)QE;cw?iVJx?JzJKqRf0Ny46)|#amk(_ z{(hoddYEd{OF-@di}ol7Q++@>a5)R6T27YE+TlYmRdBA=$_N86H*HB_J1|u@Jz&SH zku=Ctna@_Dc*c^_4K)aGKs?Y;qDLynQZ**7*92zGfldv!VGMrG{ZVCq8L_aNsgP627?7KyaOF$@PwFio&@(4h#W3|F`DlWcay|lrFEf=MTQ{ z4Xr9NyP^KH8hxnKw}H19Yf*WxCT;#RI0OH}sOgP|8zX zw+aSKz7%K&)|VQl60Is&4?t<#dSJTUQ#clT{R?8r zIsQ@A_TvrUC;Ehdw8Hv?D#^3}Qp!@u&N4`kDY1sW6x_7o6epnwq8|!gIqQeM!zo5% zIv#LCf#n6o`UBxj@@@gqlJ#zJ%+Qb>^CQsEps#f`Z@8i+g<*~JXL;3`1B?XA(#A;W zGgOB->`05z`bX>FQSgD6q&FhtyJq|fQp`1BZ0_CR4f;6X1{)%#-r}h?O(O%N+Jk{n zUBMuO?fwu()d6Mxb6T$Y>X~06S6$MGtFoX6gW*@qDN?!9;t!qzUWt5((z^WVVMxLN zYItOgn+6i_CF9K}+7-4#Q8h-8;$;j-@#D`3q<9JW2g~Ik#i?XF>T5SQSkpiNf(f|l zp!x(bYCs+Xi5{zT=gIJq72x^9!>QI+=i%aIyqVbekW(PnW&i}r`8`r z6ek%$JC!EJU|VWj&ql>(MnOVUF`xAOQbx~H_sO4b>|NA(D|IPY@6o@?$M&c+Kc;Xc^XfY0C;E5M9?m>zio|r-Z-miW+ zoUB(p5tC}$$CN^r{-ipVuGr#=7GXC%Tvjl$1o4Rb(iDd#+%iVZVNaSYM2=1@qle4*OJS6JXGl5lY;KWHVdOy)$#J9U$YkWZfjzORS-uwgql1s?N zqx9_IptPp_OkehDB59VNTva zd-P^vnSrE;jWP6nOSIPN9p+;{W{b!P*t|)M2--%Zlk(Tqc&MXzlG1f5&3vARnuO6E zMjH1YAw38K4Jt7CPyIg7X%=X&Ky!XhUG)WcxPlOv#fjF}GGJJM%7Sz35R@;5UuH$8 zXp(&s$NTQX^=U=3tdqv*d5XNEUYd_b>$!xK?sA_Q!5A~CG?8Xupoz`GsngUo)w=LR zZ4Nnz7J4xV?v23&2#!3M5YzB0QhztbUNE=^O4;C^i@p?ShYx|j!!X%{DT753@{|D@ z5`g+GSVV?I1=j_BbA4pLI!4HL&XIVcKjp?EYxiQ6bOQ5*{lWt+WTYy+*yjvlR84Wf&W{fsZn8&lx zCi2Q6g5{MTG7`+LoRQe4Lpm*$fizD!kJRnKuMut~k$SnYvp!kb{Y0nF1(lY)IEkq= zQ}xY<8oJ|j{G~l;X|VJ?8R?0FrTxOe3_*yJ!(MwI|-wyp-;-77IGI%m|2!%e*XozDDXR2 z%;`DSdLO!8T9$c|4JNeW`h+30^cSibn~Us!8zQZ;3m#IstrYN1-Qg zt5A#&F_?f%7#mEyBE)Z}`kuv&NGZfNKq(vClP?9@f%T;@+Xicn&9-660G_ca12iPi zkToP`xE{bfw5B} zMncHe#z^RMsx|4m9Ey<&;z95*<_~(<-(c4il=+$TOxtNfHfoLmv|R1S9sP!;*q0vG>zy`20R&`M z(2rhDBP`K*X(mc5;&&J$2@|N{g!GrXNWgf~$4*-=Cx?RooFbVra*ObE0$Q2vDW|xe z02>NRo_v|8+gCy`L{RZ2S6^CQToq3PIYP8%t6vERTK&v)h@QAW$p#z<6A8Or{N)Ik zq@oS<%)!~f5JlX_afvd;z ziWmtBSbqOE0_01Peo7CS}JcXl^h-guKt zkpYB_zyA5KQnOjd+cX|cIJyJ)VkhBB&Oq_FxzFea`&TWU<9GkOM(!^AR%cEucVgno zL)Y=lfxImo4vVnZLtA-FU+}=b``RtBBmLpffc!1k$nrA}Qs-l?r|lydeeRUm&mFk) z-CLbG>pJ`E>PXQUK)R@T@TlW=GY?Jd)z%mM=N@Mu&#C}7I^=I@jkhq12pP3*(EDFF z(RE_tg#?U*+eiVdV{-$Gdxr0SVUFtBE$cSnE`J*-qH&%5odQp6djAUt)bEttdx~k` jHd2&~`=7$NCha`#O1*_^4b3{izqzv(%#50Dx9xucH@EOU literal 95108 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