Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CodenameOne/src/com/codename1/impl/CodenameOneImplementation.java
Original file line number Diff line number Diff line change
Expand Up @@ -3616,6 +3616,47 @@ public void resetAffine(Object nativeGraphics) {
System.out.println("Affine unsupported");
}

/// Indicates whether the underlying implementation composes
/// `g.translateMatrix(float, float)` onto the impl-side transform matrix.
/// When this returns false `Graphics.translateMatrix` silently falls
/// back to the per-Graphics integer accumulator
/// (`Graphics.translate(int, int)`), so apps don't render at the wrong
/// position on ports that haven't been updated. Ports that DO route
/// `translateMatrix` through the matrix (iOS, JavaSE, Android, modern
/// JavaScript) must override this to return true AND override
/// `#translateMatrix(Object, float, float)`. The legacy / restricted
/// JavaScript builds keep the default false until the matrix path is
/// wired up.
///
/// #### Returns
///
/// true if `translateMatrix` reaches the impl matrix on this port.
public boolean isTranslateMatrixSupported() {
return false;
}

/// Composes a translation onto the impl-side transform matrix -- the
/// matrix-correct counterpart of `Graphics.translate(int, int)`. Pairs
/// with `#scale(Object, float, float)` and `#rotate(Object, float, int, int)`:
/// the new transform is `currentMatrix * T(x, y)` and any subsequent
/// draw applies that composed matrix as a single step (no separate
/// integer accumulator pre-applied before the matrix). Only invoked
/// when `#isTranslateMatrixSupported()` returns true; ports must keep
/// the two in sync.
///
/// #### Parameters
///
/// - `nativeGraphics`: the native graphics object
///
/// - `x`: x-axis translation
///
/// - `y`: y-axis translation
public void translateMatrix(Object nativeGraphics, float x, float y) {
// Default no-op: ports advertise translateMatrix support via
// isTranslateMatrixSupported(); Graphics.translateMatrix never
// reaches this body when that's false.
}

/// Scales the coordinate system using the affine transform
///
/// #### Parameters
Expand Down
61 changes: 61 additions & 0 deletions CodenameOne/src/com/codename1/ui/Graphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,67 @@ public void scale(float x, float y) {
scaleY = y;
}

/// Translates the coordinate system using the affine transform matrix
/// (as opposed to `#translate(int, int)` which uses a per-Graphics
/// integer accumulator). On every port today
/// `isTranslationSupported() == false`, which means `g.translate(int, int)`
/// is added to draw coordinates **before** the impl matrix is applied;
/// a subsequent `g.scale()` or `g.rotate()` therefore multiplies the
/// integer translate too. That's surprising when porting code that came
/// from Java2D / AWT where translate composes into the matrix the same
/// way as scale and rotate.
///
/// `translateMatrix` composes the translation directly onto the impl
/// matrix, exactly like `#scale(float, float)` and `#rotate(float)` do.
/// The result is uniform "post-multiply translate onto the current
/// transform" semantics across iOS / JavaSE / Android / JavaScript --
/// the same code produces the same on-screen position regardless of
/// which port you target or whether you're drawing into a Form's
/// Graphics or a mutable Image's Graphics.
///
/// On ports where `#isTranslateMatrixSupported()` returns false (e.g.
/// the legacy JavaScript port) the call falls back to the integer
/// `#translate(int, int)` so apps don't silently render at the wrong
/// position -- the visual result on those ports matches whatever
/// `translate(int, int)` does there.
///
/// #### Parameters
///
/// - `x`: x-axis translation
///
/// - `y`: y-axis translation
///
/// #### See also
///
/// - `#isTranslateMatrixSupported()`
/// - `#translate(int, int)`
/// - `#scale(float, float)`
/// - `#rotateRadians(float, int, int)`
public void translateMatrix(float x, float y) {
if (impl.isTranslateMatrixSupported()) {
impl.translateMatrix(nativeGraphics, x, y);
} else {
translate((int) x, (int) y);
}
}

/// Checks whether `#translateMatrix(float, float)` composes through the
/// impl matrix on this port (the matrix-correct mode) versus falling
/// back to the integer `#translate(int, int)` accumulator. Use this to
/// gate code that needs matrix-correct translation semantics.
///
/// #### Returns
///
/// true if `translateMatrix` reaches the impl matrix; false on ports
/// where it falls back to the integer accumulator.
///
/// #### See also
///
/// - `#translateMatrix(float, float)`
public boolean isTranslateMatrixSupported() {
return impl.isTranslateMatrixSupported();
}

/// Rotates the coordinate system around a radian angle using the affine transform
///
/// #### Parameters
Expand Down
11 changes: 11 additions & 0 deletions Ports/Android/src/com/codename1/impl/android/AndroidGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,17 @@ public void scale(float x, float y) {

}

public void translateMatrix(float x, float y) {
// Composes T(x, y) onto the impl-side matrix, exactly like scale.
// Lets Graphics.translateMatrix produce matrix-correct translation
// semantics on Android -- see Graphics.translateMatrix javadoc for
// why this is a separate API from translate(int, int).
getTransform().translate(x, y);
transformDirty = true;
inverseTransformDirty = true;
clipFresh = false;
}

public void rotate(float angle) {
getTransform().rotate(angle, 0, 0);
transformDirty = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5483,6 +5483,16 @@ public void rotate(Object nativeGraphics, float angle, int x, int y) {
((AndroidGraphics) nativeGraphics).rotate(angle, x, y);
}

@Override
public boolean isTranslateMatrixSupported() {
return true;
}

@Override
public void translateMatrix(Object nativeGraphics, float x, float y) {
((AndroidGraphics) nativeGraphics).translateMatrix(x, y);
}

public void shear(Object nativeGraphics, float x, float y) {
}

Expand Down
15 changes: 15 additions & 0 deletions Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -10572,6 +10572,21 @@ public void scale(Object nativeGraphics, float x, float y) {
setTransform(nativeGraphics, tf);
}

@Override
public boolean isTranslateMatrixSupported() {
// JavaSE composes translateMatrix onto the Graphics2D AffineTransform
// the same way it does for scale/rotate (via getTransform / setTransform).
return true;
}

@Override
public void translateMatrix(Object nativeGraphics, float x, float y) {
checkEDT();
com.codename1.ui.Transform tf = getTransform(nativeGraphics);
tf.translate(x, y);
setTransform(nativeGraphics, tf);
}

public void rotate(Object nativeGraphics, float angle) {
/*
checkEDT();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,19 @@ public void scale(double sx, double sy) {
setTransform(Transform.makeScale((float)sx, (float)sy));
}
}

public void translateMatrix(double tx, double ty) {
// Compose T(x, y) onto the impl-side matrix, mirroring scale/rotate.
// Lets Graphics.translateMatrix produce matrix-correct semantics on
// HTML5; see Graphics.translateMatrix javadoc.
if (transform != null) {
transform.translate((float)tx, (float)ty);
setTransformChanged();
applyTransform();
} else {
setTransform(Transform.makeTranslation((float)tx, (float)ty));
}
}

public void drawImage(Object img, int x, int y, int w, int h) {
imageTransformRenderAdapter.drawImage((NativeImage)img, x, y, w, h);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5991,6 +5991,16 @@ public void scale(Object nativeGraphics, float x, float y) {
((HTML5Graphics)nativeGraphics).scale(x, y);
}

@Override
public boolean isTranslateMatrixSupported() {
return true;
}

@Override
public void translateMatrix(Object nativeGraphics, float x, float y) {
((HTML5Graphics)nativeGraphics).translateMatrix(x, y);
}

@Override
public boolean isAffineSupported() {
return true;
Expand Down
Loading
Loading