From 91f3561130f9396d9440228fc522f9d6e7781e0b Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Fri, 17 Jan 2025 19:53:19 +0100 Subject: [PATCH 01/10] Export to PDEZ button --- build/shared/lib/languages/PDE.properties | 1 + java/src/processing/mode/java/JavaEditor.java | 62 ++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/build/shared/lib/languages/PDE.properties b/build/shared/lib/languages/PDE.properties index fb2042f22..66fcf1729 100644 --- a/build/shared/lib/languages/PDE.properties +++ b/build/shared/lib/languages/PDE.properties @@ -25,6 +25,7 @@ menu.file.close = Close menu.file.save = Save menu.file.save_as = Save As... menu.file.export_application = Export Application... +menu.file.export_pdez = Export as PDEZ... menu.file.page_setup = Page Setup menu.file.print = Print... menu.file.preferences = Preferences... diff --git a/java/src/processing/mode/java/JavaEditor.java b/java/src/processing/mode/java/JavaEditor.java index 338a6bd29..416219283 100644 --- a/java/src/processing/mode/java/JavaEditor.java +++ b/java/src/processing/mode/java/JavaEditor.java @@ -28,9 +28,13 @@ import java.awt.event.*; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import javax.swing.*; import javax.swing.event.*; @@ -228,7 +232,17 @@ public class JavaEditor extends Editor { } }); - return buildFileMenu(new JMenuItem[] { exportApplication }); + var exportPDEZ = new JMenuItem(Language.text("menu.file.export_pdez")); + exportPDEZ.addActionListener(e -> { + if (sketch.isUntitled() || sketch.isReadOnly()) { + Messages.showMessage("Save First", "Please first save the sketch."); + } else { + handleExportPDEZ(); + } + }); + + + return buildFileMenu(new JMenuItem[] { exportApplication, exportPDEZ }); } @@ -489,6 +503,52 @@ public class JavaEditor extends Editor { } } + /** + * Handler for File → Export PDEZ + */ + public void handleExportPDEZ() { + if (handleExportCheckModified()) { + var sketch = getSketch(); + var folder = sketch.getFolder().toPath(); + var target = new File(folder + ".pdez").toPath(); + if (Files.exists(target)) { + try { + Platform.deleteFile(target.toFile()); + } catch (IOException e) { + Messages.showError("Export Error", "Could not delete existing file: " + target, e); + } + } + + try (var zs = new ZipOutputStream(Files.newOutputStream(target))) { + Files.walk(folder) + .filter(path -> !Files.isDirectory(path)) + .forEach(path -> { + var zipEntry = new ZipEntry(folder.getParent().relativize(path).toString()); + try { + zs.putNextEntry(zipEntry); + Files.copy(path, zs); + zs.closeEntry(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + if (Desktop.isDesktopSupported()) { + var desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE_FILE_DIR)) { + desktop.browseFileDirectory(target.toFile()); + } else { + try { + desktop.open(target.getParent().toFile()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + } /** * Checks to see if the sketch has been modified, and if so, From 65acbc07417c036f0c804841f5dafef1f80cefda Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Sun, 19 Jan 2025 21:31:20 +0100 Subject: [PATCH 02/10] Update PSurfaceAWT.java --- core/src/processing/awt/PSurfaceAWT.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 06337ba38..4006171b2 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -422,7 +422,9 @@ public class PSurfaceAWT extends PSurfaceNone { //frame.setVisible(true); // re-add native resources } */ - frame.setLayout(null); + // Solves #862 - Grey/White bar on right side of sketches + frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); + frame.pack(); // Need to pass back our new sketchWidth/Height here, because it may have // been overridden by numbers we calculated above if fullScreen and/or From cd9d3fb96fc308d48277b84c2127e6be9798b5a8 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Sun, 19 Jan 2025 21:35:22 +0100 Subject: [PATCH 03/10] Update PSurfaceAWT.java Forgot the import statements --- core/src/processing/awt/PSurfaceAWT.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 4006171b2..074f886a8 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -33,8 +33,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; -import javax.swing.JFrame; -import javax.swing.SwingUtilities; +import javax.swing.*; import processing.core.PApplet; import processing.core.PConstants; From c8a85e3a580475462d27dd042087b940fe760b42 Mon Sep 17 00:00:00 2001 From: Benjamin Fox Date: Sun, 19 Jan 2025 15:38:54 -0500 Subject: [PATCH 04/10] Adding an extension handler to the SVG library to allow linear and radial gradients to export as SVG The extension handler is a copy of https://gist.github.com/msteiger/4509119 by Martin Steiger with minor changes for Processing Several classes and methods in PShapeSVG and PShapeJava2D have been made public or modified to support the export of gradients --- core/src/processing/awt/PShapeJava2D.java | 119 +++++++++- core/src/processing/core/PShapeSVG.java | 5 +- .../svg/GradientExtensionHandler.java | 209 ++++++++++++++++++ .../svg/src/processing/svg/PGraphicsSVG.java | 4 + 4 files changed, 329 insertions(+), 8 deletions(-) create mode 100644 java/libraries/svg/src/processing/svg/GradientExtensionHandler.java diff --git a/core/src/processing/awt/PShapeJava2D.java b/core/src/processing/awt/PShapeJava2D.java index 2b9b968a4..4238ef924 100644 --- a/core/src/processing/awt/PShapeJava2D.java +++ b/core/src/processing/awt/PShapeJava2D.java @@ -33,6 +33,9 @@ import java.awt.image.ColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; +import java.util.Arrays; +import java.awt.Color; + import processing.core.PApplet; import processing.core.PGraphics; import processing.core.PShapeSVG; @@ -96,16 +99,29 @@ public class PShapeJava2D extends PShapeSVG { */ - static class LinearGradientPaint implements Paint { + public static class LinearGradientPaint implements Paint { float x1, y1, x2, y2; float[] offset; int[] color; + Color[] colors; int count; float opacity; + AffineTransform xform; + + public static enum CycleMethod { + NO_CYCLE, + REFLECT, + REPEAT + } + + public static enum ColorSpaceType { + SRGB, + LINEAR_RGB + } public LinearGradientPaint(float x1, float y1, float x2, float y2, float[] offset, int[] color, int count, - float opacity) { + float opacity, AffineTransform xform) { this.x1 = x1; this.y1 = y1; this.x2 = x2; @@ -114,6 +130,13 @@ public class PShapeJava2D extends PShapeSVG { this.color = color; this.count = count; this.opacity = opacity; + this.xform = xform; + + //set an array of type Color + this.colors = new Color[this.color.length]; + for (int i = 0; i < this.color.length; i++) { + this.colors[i] = new Color(this.color[i], true); + } } public PaintContext createContext(ColorModel cm, @@ -125,6 +148,35 @@ public class PShapeJava2D extends PShapeSVG { (float) t2.getX(), (float) t2.getY()); } + public Point2D getStartPoint() { + return new Point2D.Float(this.x1, this.y1); + } + + public Point2D getEndPoint() { + return new Point2D.Float(this.x2, this.y2); + } + + /* MultipleGradientPaint methods... */ + public AffineTransform getTransform() { + return this.xform; + } + + public ColorSpaceType getColorSpace() { + return ColorSpaceType.SRGB; + } + + public CycleMethod getCycleMethod() { + return CycleMethod.NO_CYCLE; + } + + public Color[] getColors() { + return Arrays.copyOf(this.colors, this.colors.length); + } + + public float[] getFractions() { + return Arrays.copyOf(this.offset, this.offset.length); + } + public int getTransparency() { return TRANSLUCENT; // why not.. rather than checking each color } @@ -221,16 +273,29 @@ public class PShapeJava2D extends PShapeSVG { } - static class RadialGradientPaint implements Paint { + public static class RadialGradientPaint implements Paint { float cx, cy, radius; float[] offset; int[] color; + Color[] colors; int count; float opacity; + AffineTransform xform; + + public static enum CycleMethod { + NO_CYCLE, + REFLECT, + REPEAT + } + + public static enum ColorSpaceType { + SRGB, + LINEAR_RGB + } public RadialGradientPaint(float cx, float cy, float radius, float[] offset, int[] color, int count, - float opacity) { + float opacity, AffineTransform xform) { this.cx = cx; this.cy = cy; this.radius = radius; @@ -238,6 +303,13 @@ public class PShapeJava2D extends PShapeSVG { this.color = color; this.count = count; this.opacity = opacity; + this.xform = xform; + + //set an array of type Color + this.colors = new Color[this.color.length]; + for (int i = 0; i < this.color.length; i++) { + this.colors[i] = new Color(this.color[i], true); + } } public PaintContext createContext(ColorModel cm, @@ -246,6 +318,41 @@ public class PShapeJava2D extends PShapeSVG { return new RadialGradientContext(); } + public Point2D getCenterPoint() { + return new Point2D.Double(this.cx, this.cy); + } + + //TODO: investigate how to change a focus point for 0% x of the gradient + //for now default to center x/y + public Point2D getFocusPoint() { + return new Point2D.Double(this.cx, this.cy); + } + + public float getRadius() { + return this.radius; + } + + /* MultipleGradientPaint methods... */ + public AffineTransform getTransform() { + return this.xform; + } + + public ColorSpaceType getColorSpace() { + return ColorSpaceType.SRGB; + } + + public CycleMethod getCycleMethod() { + return CycleMethod.NO_CYCLE; + } + + public Color[] getColors() { + return Arrays.copyOf(this.colors, this.colors.length); + } + + public float[] getFractions() { + return Arrays.copyOf(this.offset, this.offset.length); + } + public int getTransparency() { return TRANSLUCENT; } @@ -305,14 +412,14 @@ public class PShapeJava2D extends PShapeSVG { LinearGradient grad = (LinearGradient) gradient; return new LinearGradientPaint(grad.x1, grad.y1, grad.x2, grad.y2, grad.offset, grad.color, grad.count, - opacity); + opacity, grad.transform); } else if (gradient instanceof RadialGradient) { // System.out.println("creating radial gradient"); RadialGradient grad = (RadialGradient) gradient; return new RadialGradientPaint(grad.cx, grad.cy, grad.r, grad.offset, grad.color, grad.count, - opacity); + opacity, grad.transform); } return null; } diff --git a/core/src/processing/core/PShapeSVG.java b/core/src/processing/core/PShapeSVG.java index a51e94276..f8aa3400f 100644 --- a/core/src/processing/core/PShapeSVG.java +++ b/core/src/processing/core/PShapeSVG.java @@ -1397,7 +1397,8 @@ public class PShapeSVG extends PShape { } - void setColor(String colorText, boolean isFill) { + //making this public allows us to set gradient fills on a PShape + public void setColor(String colorText, boolean isFill) { colorText = colorText.trim(); int opacityMask = fillColor & 0xFF000000; boolean visible = true; @@ -1620,7 +1621,7 @@ public class PShapeSVG extends PShape { static public class Gradient extends PShapeSVG { - AffineTransform transform; + public AffineTransform transform; public float[] offset; public int[] color; diff --git a/java/libraries/svg/src/processing/svg/GradientExtensionHandler.java b/java/libraries/svg/src/processing/svg/GradientExtensionHandler.java new file mode 100644 index 000000000..370adbea9 --- /dev/null +++ b/java/libraries/svg/src/processing/svg/GradientExtensionHandler.java @@ -0,0 +1,209 @@ +package processing.svg; + +import static org.apache.batik.util.SVGConstants.*; + +import processing.awt.PShapeJava2D.LinearGradientPaint; +import processing.awt.PShapeJava2D.RadialGradientPaint; + +import java.awt.Color; +import java.awt.MultipleGradientPaint; +import java.awt.Paint; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; + +import java.util.Objects; + +import org.apache.batik.svggen.DefaultExtensionHandler; +import org.apache.batik.svggen.SVGColor; +import org.apache.batik.svggen.SVGGeneratorContext; +import org.apache.batik.svggen.SVGPaintDescriptor; +import org.w3c.dom.Element; + +/** + * Extension of Batik's {@link DefaultExtensionHandler} which handles different kinds of Paint objects + * based on the extenstion by Martin Steiger https://gist.github.com/msteiger/4509119 + * modified to work with Processing's SVG export library, by Benjamin Fox https://github.com/tracerstar + */ +public class GradientExtensionHandler extends DefaultExtensionHandler { + + @Override + public SVGPaintDescriptor handlePaint(Paint paint, SVGGeneratorContext genCtx) { + + // Handle LinearGradientPaint + if (paint instanceof LinearGradientPaint) { + return getLgpDescriptor((LinearGradientPaint) paint, genCtx); + } + + // Handle RadialGradientPaint + if (paint instanceof RadialGradientPaint) { + return getRgpDescriptor((RadialGradientPaint) paint, genCtx); + } + + return super.handlePaint(paint, genCtx); + } + + private SVGPaintDescriptor getLgpDescriptor(LinearGradientPaint gradient, SVGGeneratorContext genCtx) { + Element gradElem = genCtx.getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_LINEAR_GRADIENT_TAG); + + // Create and set unique XML id + String id = genCtx.getIDGenerator().generateID("gradient"); + gradElem.setAttribute(SVG_ID_ATTRIBUTE, id); + + // Set x,y pairs + Point2D startPt = gradient.getStartPoint(); + gradElem.setAttribute("x1", String.valueOf(startPt.getX())); + gradElem.setAttribute("y1", String.valueOf(startPt.getY())); + + Point2D endPt = gradient.getEndPoint(); + gradElem.setAttribute("x2", String.valueOf(endPt.getX())); + gradElem.setAttribute("y2", String.valueOf(endPt.getY())); + + //TODO: change this to be: addMgpAttributes after refactoring the paint methods + addLgpAttributes(gradElem, genCtx, gradient); + + return new SVGPaintDescriptor("url(#" + id + ")", SVG_OPAQUE_VALUE, gradElem); + } + + private SVGPaintDescriptor getRgpDescriptor(RadialGradientPaint gradient, SVGGeneratorContext genCtx) { + Element gradElem = genCtx.getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_RADIAL_GRADIENT_TAG); + + // Create and set unique XML id + String id = genCtx.getIDGenerator().generateID("gradient"); + gradElem.setAttribute(SVG_ID_ATTRIBUTE, id); + + // Set x,y pairs + Point2D centerPt = gradient.getCenterPoint(); + gradElem.setAttribute("cx", String.valueOf(centerPt.getX())); + gradElem.setAttribute("cy", String.valueOf(centerPt.getY())); + + Point2D focusPt = gradient.getFocusPoint(); + gradElem.setAttribute("fx", String.valueOf(focusPt.getX())); + gradElem.setAttribute("fy", String.valueOf(focusPt.getY())); + + gradElem.setAttribute("r", String.valueOf(gradient.getRadius())); + + //TODO: change this to be: addMgpAttributes after refactoring the paint methods + addRgpAttributes(gradElem, genCtx, gradient); + + return new SVGPaintDescriptor("url(#" + id + ")", SVG_OPAQUE_VALUE, gradElem); + } + + + /* + Being lazy here to duplicate the methods so we don't have to refactor the two gradient paints + to implement java.awt.MultipleGradientPaint + + TODO: make the effort to refactor them to properly implement java.awt.MultipleGradientPaint + */ + private void addLgpAttributes(Element gradElem, SVGGeneratorContext genCtx, LinearGradientPaint gradient) { + gradElem.setAttribute(SVG_GRADIENT_UNITS_ATTRIBUTE, SVG_USER_SPACE_ON_USE_VALUE); + + // Set cycle method + switch (gradient.getCycleMethod()) { + case REFLECT: + gradElem.setAttribute(SVG_SPREAD_METHOD_ATTRIBUTE, SVG_REFLECT_VALUE); + break; + case REPEAT: + gradElem.setAttribute(SVG_SPREAD_METHOD_ATTRIBUTE, SVG_REPEAT_VALUE); + break; + case NO_CYCLE: + default: + gradElem.setAttribute(SVG_SPREAD_METHOD_ATTRIBUTE, SVG_PAD_VALUE); // this is the default + break; + } + + // Set color space + switch (gradient.getColorSpace()) { + case LINEAR_RGB: + gradElem.setAttribute(SVG_COLOR_INTERPOLATION_ATTRIBUTE, SVG_LINEAR_RGB_VALUE); + break; + case SRGB: + default: + gradElem.setAttribute(SVG_COLOR_INTERPOLATION_ATTRIBUTE, SVG_SRGB_VALUE); + break; + } + + // Set transform matrix if not identity + AffineTransform tf = gradient.getTransform(); + if (!Objects.isNull(tf) && !tf.isIdentity()) { + String matrix = "matrix(" + + tf.getScaleX() + " " + tf.getShearX() + " " + tf.getTranslateX() + " " + + tf.getScaleY() + " " + tf.getShearY() + " " + tf.getTranslateY() + ")"; + gradElem.setAttribute(SVG_TRANSFORM_ATTRIBUTE, matrix); + } + + // Convert gradient stops + Color[] colors = gradient.getColors(); + float[] fracs = gradient.getFractions(); + + for (int i = 0; i < colors.length; i++) { + Element stop = genCtx.getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_STOP_TAG); + SVGPaintDescriptor pd = SVGColor.toSVG(colors[i], genCtx); + + stop.setAttribute(SVG_OFFSET_ATTRIBUTE, (int) (fracs[i] * 100.0f) + "%"); + stop.setAttribute(SVG_STOP_COLOR_ATTRIBUTE, pd.getPaintValue()); + + if (colors[i].getAlpha() != 255) { + stop.setAttribute(SVG_STOP_OPACITY_ATTRIBUTE, pd.getOpacityValue()); + } + + gradElem.appendChild(stop); + } + } + + private void addRgpAttributes(Element gradElem, SVGGeneratorContext genCtx, RadialGradientPaint gradient) { + gradElem.setAttribute(SVG_GRADIENT_UNITS_ATTRIBUTE, SVG_USER_SPACE_ON_USE_VALUE); + + // Set cycle method + switch (gradient.getCycleMethod()) { + case REFLECT: + gradElem.setAttribute(SVG_SPREAD_METHOD_ATTRIBUTE, SVG_REFLECT_VALUE); + break; + case REPEAT: + gradElem.setAttribute(SVG_SPREAD_METHOD_ATTRIBUTE, SVG_REPEAT_VALUE); + break; + case NO_CYCLE: + default: + gradElem.setAttribute(SVG_SPREAD_METHOD_ATTRIBUTE, SVG_PAD_VALUE); // this is the default + break; + } + + // Set color space + switch (gradient.getColorSpace()) { + case LINEAR_RGB: + gradElem.setAttribute(SVG_COLOR_INTERPOLATION_ATTRIBUTE, SVG_LINEAR_RGB_VALUE); + break; + case SRGB: + default: + gradElem.setAttribute(SVG_COLOR_INTERPOLATION_ATTRIBUTE, SVG_SRGB_VALUE); + break; + } + + // Set transform matrix if not identity + AffineTransform tf = gradient.getTransform(); + if (!Objects.isNull(tf) && !tf.isIdentity()) { + String matrix = "matrix(" + + tf.getScaleX() + " " + tf.getShearX() + " " + tf.getTranslateX() + " " + + tf.getScaleY() + " " + tf.getShearY() + " " + tf.getTranslateY() + ")"; + gradElem.setAttribute(SVG_TRANSFORM_ATTRIBUTE, matrix); + } + + // Convert gradient stops + Color[] colors = gradient.getColors(); + float[] fracs = gradient.getFractions(); + + for (int i = 0; i < colors.length; i++) { + Element stop = genCtx.getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_STOP_TAG); + SVGPaintDescriptor pd = SVGColor.toSVG(colors[i], genCtx); + + stop.setAttribute(SVG_OFFSET_ATTRIBUTE, (int) (fracs[i] * 100.0f) + "%"); + stop.setAttribute(SVG_STOP_COLOR_ATTRIBUTE, pd.getPaintValue()); + + if (colors[i].getAlpha() != 255) { + stop.setAttribute(SVG_STOP_OPACITY_ATTRIBUTE, pd.getOpacityValue()); + } + + gradElem.appendChild(stop); + } + } +} diff --git a/java/libraries/svg/src/processing/svg/PGraphicsSVG.java b/java/libraries/svg/src/processing/svg/PGraphicsSVG.java index 3b170353b..857f5d93a 100644 --- a/java/libraries/svg/src/processing/svg/PGraphicsSVG.java +++ b/java/libraries/svg/src/processing/svg/PGraphicsSVG.java @@ -87,6 +87,10 @@ public class PGraphicsSVG extends PGraphicsJava2D { g2 = new SVGGraphics2D(document); ((SVGGraphics2D) g2).setSVGCanvasSize(new Dimension(width, height)); + //set the extension handler to allow linear and radial gradients to be exported as svg + GradientExtensionHandler gradH = new GradientExtensionHandler(); + ((SVGGraphics2D) g2).setExtensionHandler(gradH); + // Done with our work, let's check on defaults and the rest //super.beginDraw(); // Can't call super.beginDraw() because it'll nuke our g2 From fc3d87b2661f6068fee3aa046057eecda065f1e4 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Sun, 19 Jan 2025 22:09:57 +0100 Subject: [PATCH 05/10] Different solution for #862 --- core/src/processing/awt/PSurfaceAWT.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 074f886a8..b7e25416b 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -421,9 +421,7 @@ public class PSurfaceAWT extends PSurfaceNone { //frame.setVisible(true); // re-add native resources } */ - // Solves #862 - Grey/White bar on right side of sketches - frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); - frame.pack(); + frame.setLayout(null); // Need to pass back our new sketchWidth/Height here, because it may have // been overridden by numbers we calculated above if fullScreen and/or @@ -1022,6 +1020,9 @@ public class PSurfaceAWT extends PSurfaceNone { //sketch.postWindowMoved(x - currentInsets.left, y - currentInsets.top); sketch.postWindowMoved(x, y); // presumably user wants drawing area } + }else{ + // Solves #862 - Grey/White bar on right side of sketches + setFrameSize(); } } From a9668035009d4574ecde122e76012bd2b5d6477a Mon Sep 17 00:00:00 2001 From: Jim Date: Sun, 19 Jan 2025 17:29:45 -0500 Subject: [PATCH 06/10] fix for #918 --- core/src/processing/core/PApplet.java | 33 +++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index ec16e4291..24c0d5d39 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -9663,7 +9663,7 @@ public class PApplet implements PConstants { // WINDOW METHODS - Map windowEventQueue = new ConcurrentHashMap<>(); + Map windowEventQueue = new ConcurrentHashMap<>(); public void windowTitle(String title) { @@ -9683,8 +9683,7 @@ public class PApplet implements PConstants { * only the notification that the resize has happened. */ public void postWindowResized(int newWidth, int newHeight) { - windowEventQueue.put("w", newWidth); - windowEventQueue.put("h", newHeight); + windowEventQueue.put("wh", new WindowEventValuePairs(newWidth, newHeight)); } @@ -9724,8 +9723,7 @@ public class PApplet implements PConstants { frameMoved(newX, newY); } - windowEventQueue.put("x", newX); - windowEventQueue.put("y", newY); + windowEventQueue.put("xy", new WindowEventValuePairs(newX, newY)); } @@ -9734,21 +9732,28 @@ public class PApplet implements PConstants { private void dequeueWindowEvents() { - if (windowEventQueue.containsKey("x")) { - windowX = windowEventQueue.remove("x"); - windowY = windowEventQueue.remove("y"); + if (windowEventQueue.containsKey("xy")) { + WindowEventValuePairs xy = windowEventQueue.remove("xy"); + windowX = xy.num1; + windowY = xy.num2; windowMoved(); } - if (windowEventQueue.containsKey("w")) { - // these should already match width/height - //windowResized(windowEventQueue.remove("w"), - // windowEventQueue.remove("h")); - windowEventQueue.remove("w"); - windowEventQueue.remove("h"); + if (windowEventQueue.containsKey("wh")) { + WindowEventValuePairs wh = windowEventQueue.remove("wh"); windowResized(); } } + protected class WindowEventValuePairs { + + public int num1; + public int num2; + + public WindowEventValuePairs(int num1, int num2) { + this.num1 = num1; + this.num2 = num2; + } + } /** * Scale the sketch as if it fits this specific width and height. From 20d0c2503e8249940b64fdd789455cf49d78da6d Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Tue, 21 Jan 2025 09:19:38 +0100 Subject: [PATCH 07/10] Fix for #931 Seems like the synchronised was there for an older approach to rendering. Made redundant by the BufferStrategy in 2015. Now it causes issues on windows if you resize the window too quickly --- core/src/processing/awt/PSurfaceAWT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 06337ba38..ad58b8541 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -227,7 +227,7 @@ public class PSurfaceAWT extends PSurfaceNone { } - synchronized protected void render() { + protected void render() { if (canvas.isDisplayable() && graphics.image != null) { if (canvas.getBufferStrategy() == null) { From c6a10fcec663efd1ecf3e04975bbf5ca519634d7 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Tue, 21 Jan 2025 18:52:36 +0100 Subject: [PATCH 08/10] =?UTF-8?q?Updated=20dependency=20locations=20to=20s?= =?UTF-8?q?omewhere=20more=20stable=20=F0=9F=A4=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.xml | 4 ++-- java/libraries/svg/build.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.xml b/app/build.xml index 5ca75a877..0b91c0a14 100644 --- a/app/build.xml +++ b/app/build.xml @@ -4,14 +4,14 @@ - + + value="https://dlcdn.apache.org//ant/binaries/${ant.zip}" /> diff --git a/java/libraries/svg/build.xml b/java/libraries/svg/build.xml index cf82369e8..de0b9e41a 100644 --- a/java/libraries/svg/build.xml +++ b/java/libraries/svg/build.xml @@ -3,7 +3,7 @@ - + @@ -13,7 +13,7 @@ + value="https://dlcdn.apache.org//xmlgraphics/batik/binaries/${batik.zip}" /> From 2eadb50f261954ecb6a6c9b6bc7a424de8a151f7 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Tue, 21 Jan 2025 19:19:30 +0100 Subject: [PATCH 09/10] Update build.yml --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 42faabe60..1ad3e6c5b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -67,7 +67,7 @@ jobs: - name: Setup Ant uses: cedx/setup-ant@v3 - name: Install Certificates for Code Signing - if: ${{ matrix.os_prefix == 'macos' }} + if: ${{ matrix.os_prefix == 'macos' && startsWith(github.repository, 'processing/') }} uses: apple-actions/import-codesign-certs@v3 with: p12-file-base64: ${{ secrets.CERTIFICATES_P12 }} @@ -75,7 +75,7 @@ jobs: - name: Build Release run: ant -noinput -buildfile build/build.xml ${{ matrix.os_prefix }}-dist -Dversion="${{ github.sha }}" env: - PROCESSING_APP_SIGNING: true + PROCESSING_APP_SIGNING: ${{ startsWith(github.repository, 'processing/') }} - name: Add artifact uses: actions/upload-artifact@v4 with: From 2f3ef533cdc55ebe7aee175a5d067fba9c005db5 Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Tue, 21 Jan 2025 19:27:58 +0100 Subject: [PATCH 10/10] Disable signing on preview builds --- .github/workflows/build.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ad3e6c5b..ec986daef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,16 +66,8 @@ jobs: architecture: ${{ matrix.arch }} - name: Setup Ant uses: cedx/setup-ant@v3 - - name: Install Certificates for Code Signing - if: ${{ matrix.os_prefix == 'macos' && startsWith(github.repository, 'processing/') }} - uses: apple-actions/import-codesign-certs@v3 - with: - p12-file-base64: ${{ secrets.CERTIFICATES_P12 }} - p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }} - name: Build Release run: ant -noinput -buildfile build/build.xml ${{ matrix.os_prefix }}-dist -Dversion="${{ github.sha }}" - env: - PROCESSING_APP_SIGNING: ${{ startsWith(github.repository, 'processing/') }} - name: Add artifact uses: actions/upload-artifact@v4 with: