Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
59ac249
Add build-time SVG transcoder with SMIL animation support
shai-almog May 25, 2026
c5622bc
Drop reflective SVGRegistry probe to keep ParparVM iOS build alive
shai-almog May 25, 2026
425ef14
Satisfy PMD: braces on every control statement, one decl per line
shai-almog May 25, 2026
f501ea5
Remove unrelated files accidentally staged via git add -A
shai-almog May 25, 2026
98124d8
Use MathUtil.acos so CLDC11 / iOS port still build
shai-almog May 25, 2026
78a33ce
Strip non-ASCII characters from all new sources
shai-almog May 25, 2026
773b01f
Address review: AnimationTime clock, real scaled(), DPI sizing, ui pa…
shai-almog May 26, 2026
3cdfe9a
Register SVG screenshot tests in Cn1ssDeviceRunner so they actually run
shai-almog May 26, 2026
98942c5
Shape-clip gradient fills; convert animated SVG test to 6-frame grid
shai-almog May 26, 2026
7b369c8
Enable antialiasing and animate opacity on transcoded SVGs
shai-almog May 26, 2026
57bfc13
SVG transcoder full stack: CSS-driven, registry-wired, dev guide
shai-almog May 26, 2026
4108c18
Add cn1-svg-width / cn1-svg-height for cross-DPI millimeter sizing
shai-almog May 26, 2026
9526dc1
SVG: seamless install, fail-fast dimensions, text rendering, accurate…
shai-almog May 26, 2026
e6f87a2
SVG: broader hellocodenameone fixtures + initializr skill update
shai-almog May 26, 2026
044df6b
SVG: clip-path / mask support via shape clipping
shai-almog May 26, 2026
2409bf3
Add clipped_badge.svg fixture + SVGClipPath model file
shai-almog May 26, 2026
eddd88a
Fix Vale lints in SVG transcoder dev guide
shai-almog May 26, 2026
db0e3dd
Install transcoded SVGs from the per-platform Stub before init()
shai-almog May 26, 2026
cc7f246
Broaden SVG transcoder unit coverage
shai-almog May 26, 2026
aa5e4fa
PMD LogicInversion: use mm <= 0f || NaN instead of !(mm > 0f)
shai-almog May 26, 2026
844255a
Fix SVG screenshot test: grid layout + drawString for Metal
shai-almog May 26, 2026
59ded09
Fix SVG text + gradient rendering on iOS Metal and Android
shai-almog May 26, 2026
de95317
Revert SVG Metal workarounds; document Metal bugs in test + dev guide
shai-almog May 26, 2026
f8e1b4e
Fix stale Quick Start + Troubleshooting copy in SVG dev guide
shai-almog May 26, 2026
317784b
Add SVG screenshot goldens for Android, iOS legacy, iOS Metal
shai-almog May 26, 2026
81e4fef
Fix Vale lint warnings in SVG-Transcoder.asciidoc
shai-almog May 26, 2026
2e68077
Skip SVGRegistry emission when project has no SVGs; load it generically
shai-almog May 27, 2026
6be96eb
Drop 'silently' adverb flagged by Vale in SVG dev guide
shai-almog May 27, 2026
f21e57c
Skip SVG screenshot tests on JS port at the per-test level
shai-almog May 27, 2026
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
581 changes: 581 additions & 0 deletions CodenameOne/src/com/codename1/ui/GeneratedSVGImage.java

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions CodenameOne/src/com/codename1/ui/SVGScaledView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*/
package com.codename1.ui;

/// Lightweight scaled view returned by [GeneratedSVGImage#scaled(int, int)].
/// Reports the caller-supplied width and height from [#getWidth] / [#getHeight]
/// so component layout sees the correct size, while delegating all rendering
/// (and animation state) to the source SVG.
final class SVGScaledView extends Image {

private final GeneratedSVGImage source;
private final int width;
private final int height;

SVGScaledView(GeneratedSVGImage source, int width, int height) {
super(null);
if (width < 1 || height < 1) {
throw new IllegalArgumentException(
"scaled() requires positive dimensions; got width=" + width
+ " height=" + height);
}
this.source = source;
this.width = width;
this.height = height;
}

@Override
public int getWidth() {
return width;
}

@Override
public int getHeight() {
return height;
}

@Override
public boolean isAnimation() {
return source.isAnimation();
}

@Override
public boolean animate() {
return source.animate();
}

@Override
protected void drawImage(Graphics g, Object nativeGraphics, int x, int y) {
source.drawImage(g, nativeGraphics, x, y, width, height);
}

@Override
protected void drawImage(Graphics g, Object nativeGraphics, int x, int y, int w, int h) {
// Honor the requested draw size rather than our reported size; the
// surrounding component may stretch us inside a different rectangle.
source.drawImage(g, nativeGraphics, x, y, w, h);
}

@Override
public Image scaled(int width, int height) {
return new SVGScaledView(source, width, height);
}
}
1 change: 1 addition & 0 deletions CodenameOne/src/com/codename1/ui/util/MutableResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Image createImage(DataInputStream input) throws IOException {
}
}

@Override
public void setImage(String name, Image value) {
if (value instanceof Timeline) {
throw new UnsupportedOperationException("Timeline resources are not supported in MutableResource");
Expand Down
53 changes: 53 additions & 0 deletions CodenameOne/src/com/codename1/ui/util/Resources.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ public class Resources {
private static int lastLoadedDPI;
private static boolean runtimeMultiImages;
private static boolean failOnMissingTruetype = true;

/// Global image registry populated by the build-time SVG transcoder. Keyed
/// by the source filename ("home.svg") and also under the filename stem
/// ("home") so CSS-style `url(home.svg)` references and direct
/// `getImage("home")` calls both resolve to the same instance.
private static final Map<String, Image> generatedImages = new HashMap<String, Image>();
/// Hashtable containing the mapping between element types and their names in the
/// resource hashtable
private final HashMap<String, Byte> resourceTypes = new HashMap<String, Byte>();
Expand Down Expand Up @@ -880,9 +886,56 @@ public boolean isImage(String name) {
///
/// cached image instance
public Image getImage(String id) {
// The generated-image registry wins over the local resources map
// so the build-time SVG transcoder's installGlobal() call -- run
// from the per-port wiring (JavaSEPort.init reflectively, or the
// iOS / Android Stub emitted by IPhoneBuilder / AndroidGradleBuilder
// when the project contains SVGs) -- overrides the 1x1 PNG
// placeholder the CSS compiler stored under the same name.
Image gen;
synchronized (generatedImages) {
gen = generatedImages.get(id);
}
if (gen != null) {
return gen;
}
return (Image) resources.get(id);
}

/// Install an [Image] into this resources bundle under the given name so a
/// subsequent [#getImage(String)] returns it. Used by the build-time SVG
/// transcoder registry to inject generated images alongside the resources
/// loaded from the `.res` file.
public void setImage(String id, Image image) {
if (id == null || image == null) {
return;
}
resources.put(id, image);
resourceTypes.put(id, Byte.valueOf(MAGIC_IMAGE));
}

/// Add an [Image] to the global registry consulted by every
/// [#getImage(String)] call as a fallback. Intended for the
/// auto-generated `com.codename1.generated.svg.SVGRegistry` produced by
/// the SVG transcoder mojo -- application code should not normally call
/// this directly.
///
/// Registers the image both under the supplied `id` and (if `id` ends with
/// `.svg`) under the bare filename stem so a CSS reference like
/// `url(home.svg)` and a code reference like `getImage("home")` both
/// resolve to the same instance.
public static void registerGeneratedImage(String id, Image image) {
if (id == null || image == null) {
return;
}
synchronized (generatedImages) {
generatedImages.put(id, image);
if (id.endsWith(".svg")) {
generatedImages.put(id.substring(0, id.length() - 4), image);
}
}
}

/// Returns the data resource from the file
///
/// #### Parameters
Expand Down
4 changes: 4 additions & 0 deletions Ports/JavaSE/src/com/codename1/impl/javase/Executor.java
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ public void run() {
@Override
public void run() {
try {
// JavaSEPort.init() already loads
// com.codename1.generated.svg.SVGRegistry reflectively
// when it's on the classpath, so no per-Executor
// install is needed here.
m.invoke(app, new Object[]{null});
Method start = c.getMethod("start", new Class[0]);
if(start.getExceptionTypes() != null && start.getExceptionTypes().length > 0) {
Expand Down
26 changes: 26 additions & 0 deletions Ports/JavaSE/src/com/codename1/impl/javase/JavaSEPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -6605,11 +6605,37 @@ private void loadSkinFile(String f, JFrame frm) {
}
}

/** Reflectively run the build-time SVG transcoder's registry if the
* current classpath contains one. Lets desktop / simulator runs pick
* up transcoded SVGs without the per-platform Stub needing an explicit
* call -- the Stub call is omitted on JavaSE because the user's
* ${mainName}Stub doesn't know at template-expansion time whether the
* project ships any SVGs. Apps without an SVG registry are unaffected. */
private static boolean svgRegistryInstalled;
private static void installGeneratedSvgRegistry() {
if (svgRegistryInstalled) {
return;
}
try {
Class<?> r = Class.forName("com.codename1.generated.svg.SVGRegistry");
r.getMethod("installGlobal").invoke(null);
} catch (ClassNotFoundException noSvgs) {
// Project ships no SVGs -- skip silently.
} catch (Throwable t) {
// Don't take init() down if the registry blows up; surface it
// but let the app keep running so missing SVGs don't blank the
// whole UI.
t.printStackTrace();
}
svgRegistryInstalled = true;
}

/**
* @inheritDoc
*/
public void init(Object m) {
inInit = true;
installGeneratedSvgRegistry();

/* File updater = new File(System.getProperty("user.home") + File.separator + ".codenameone" + File.separator + "UpdateCodenameOne.jar");
if(!updater.exists()) {
Expand Down
Loading
Loading