From 2ead5592d8b7e546511304a1ee873b0c088c7cfb Mon Sep 17 00:00:00 2001 From: Branislav Stojkovic Date: Mon, 17 Mar 2025 12:05:26 +0100 Subject: [PATCH] performance upgrade --- .../diylc-core/src/main/resources/update.xml | 4 ++ .../java/org/diylc/components/misc/Image.java | 62 ++++++++++++++----- .../swing/plugins/canvas/CanvasPanel.java | 48 +++++++------- 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/diylc/diylc-core/src/main/resources/update.xml b/diylc/diylc-core/src/main/resources/update.xml index a0f3286c..3ed8e068 100644 --- a/diylc/diylc-core/src/main/resources/update.xml +++ b/diylc/diylc-core/src/main/resources/update.xml @@ -253,6 +253,10 @@ NEW_FEATURE Configurable 'High DPI Rendering' feature which makes the diagram smoother on high-resolution displays but can affect performance + + IMPROVEMENT + Significantly improved rendering performance + IMPROVEMENT Upgraded source code structure to modern standards and introduced Maven diff --git a/diylc/diylc-library/src/main/java/org/diylc/components/misc/Image.java b/diylc/diylc-library/src/main/java/org/diylc/components/misc/Image.java index 94c9fdc4..1e67dd13 100644 --- a/diylc/diylc-library/src/main/java/org/diylc/components/misc/Image.java +++ b/diylc/diylc-library/src/main/java/org/diylc/components/misc/Image.java @@ -40,6 +40,7 @@ import org.diylc.awt.ImageUtils; import org.diylc.common.ObjectCache; import org.diylc.common.Orientation; import org.diylc.components.AbstractTransparentComponent; +import org.diylc.components.boards.AbstractBoard; import org.diylc.components.transform.ImageTransformer; import org.diylc.core.ComponentState; import org.diylc.core.IDIYComponent; @@ -94,6 +95,8 @@ public class Image extends AbstractTransparentComponent { private byte newScale = DEFAULT_SCALE; private ImageSizingMode sizingMode = ImageSizingMode.Scale; + private transient ImageIcon imageIcon; + public Image() { try { data = IOUtils.toByteArray(Image.class.getResourceAsStream("/image.png")); @@ -105,6 +108,11 @@ public class Image extends AbstractTransparentComponent { @Override public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, IDrawingObserver drawingObserver) { + + if (!getImageRectangle().intersects(g2d.getClipBounds())) { + return; + } + double scaleX; double scaleY; ImageIcon imageIcon = getImage(); @@ -199,21 +207,24 @@ public class Image extends AbstractTransparentComponent { } public ImageIcon getImage() { - if (image != null) { - // when loading old files, convert the stored image to byte array and then then discard it, we won't be needing it anymore - BufferedImage bi = ImageUtils.ToBufferedImage(image.getImage()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - ImageIO.write(bi, "png", baos); - // make it official - data = baos.toByteArray(); - } catch (IOException e) { - } - // don't save back to the file - image = null; - } + if (imageIcon == null) { + if (image != null) { + // when loading old files, convert the stored image to byte array and then then discard it, we won't be needing it anymore + BufferedImage bi = ImageUtils.ToBufferedImage(image.getImage()); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + ImageIO.write(bi, "png", baos); + // make it official + data = baos.toByteArray(); + } catch (IOException e) { + } + // don't save back to the file + image = null; + } - return new ImageIcon(data); + imageIcon = new ImageIcon(data); + } + return imageIcon; } @ByteArrayProperty(binaryType = BinaryType.IMAGE) @@ -279,7 +290,28 @@ public class Image extends AbstractTransparentComponent { public void setOrientation(Orientation orientation) { this.orientation = orientation; } - + + protected Point2D getFinalSecondPoint() { + Point2D finalSecondPoint; + if (getSizingMode() == ImageSizingMode.TwoPoints) { + finalSecondPoint = secondPoint; + } else { + double scale = 1d * getScale() / DEFAULT_SCALE; + ImageIcon iconImage = getImage(); + finalSecondPoint = new Point2D.Double(point.getX() + iconImage.getIconWidth() * scale, + point.getY() + iconImage.getIconHeight() * scale); + } + return finalSecondPoint; + } + + protected Rectangle2D getImageRectangle() { + Point2D finalSecondPoint = getFinalSecondPoint(); + return new Rectangle2D.Double(Math.min(point.getX(), finalSecondPoint.getX()), + Math.min(point.getY(), finalSecondPoint.getY()), + Math.abs(point.getX() - finalSecondPoint.getX()), + Math.abs(point.getY() - finalSecondPoint.getY())); + } + public static enum ImageSizingMode { TwoPoints("Opposing Points"), Scale("Scale"); diff --git a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/canvas/CanvasPanel.java b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/canvas/CanvasPanel.java index cbe90006..011eaa9a 100644 --- a/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/canvas/CanvasPanel.java +++ b/diylc/diylc-swing/src/main/java/org/diylc/swing/plugins/canvas/CanvasPanel.java @@ -338,28 +338,9 @@ public class CanvasPanel extends JComponent implements Autoscroll { double x = visibleRect.x;// / scaleFactor; double y = visibleRect.y;// / scaleFactor; bufferG2d.translate(-x, -y); + bufferG2d.setClip(visibleRect); - Set drawOptions = - EnumSet.of(DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.CONTROL_POINTS); - - if (configManager.readBoolean(IPlugInPort.ANTI_ALIASING_KEY, true)) { - drawOptions.add(DrawOption.ANTIALIASING); - } - if (configManager.readBoolean(IPlugInPort.OUTLINE_KEY, false)) { - drawOptions.add(DrawOption.OUTLINE_MODE); - } - if (configManager.readBoolean(IPlugInPort.SHOW_GRID_KEY, true)) { - drawOptions.add(DrawOption.GRID); - } - if (configManager.readBoolean(IPlugInPort.EXTRA_SPACE_KEY, true)) { - drawOptions.add(DrawOption.EXTRA_SPACE); - } - if (configManager.readBoolean(IPlugInPort.CACHING_ENABLED_KEY, true)) { - drawOptions.add(DrawOption.ENABLE_CACHING); - } - if (configManager.readBoolean(IPlugInPort.LOCKED_ALPHA, true)) { - drawOptions.add(DrawOption.LOCKED_ALPHA); - } + Set drawOptions = getDrawOptions(); plugInPort.draw(bufferG2d, drawOptions, null, null, scaleFactor, visibleRect); @@ -389,6 +370,31 @@ public class CanvasPanel extends JComponent implements Autoscroll { bufferG2d.dispose(); } + private Set getDrawOptions() { + Set drawOptions = + EnumSet.of(DrawOption.SELECTION, DrawOption.ZOOM, DrawOption.CONTROL_POINTS); + + if (configManager.readBoolean(IPlugInPort.ANTI_ALIASING_KEY, true)) { + drawOptions.add(DrawOption.ANTIALIASING); + } + if (configManager.readBoolean(IPlugInPort.OUTLINE_KEY, false)) { + drawOptions.add(DrawOption.OUTLINE_MODE); + } + if (configManager.readBoolean(IPlugInPort.SHOW_GRID_KEY, true)) { + drawOptions.add(DrawOption.GRID); + } + if (configManager.readBoolean(IPlugInPort.EXTRA_SPACE_KEY, true)) { + drawOptions.add(DrawOption.EXTRA_SPACE); + } + if (configManager.readBoolean(IPlugInPort.CACHING_ENABLED_KEY, true)) { + drawOptions.add(DrawOption.ENABLE_CACHING); + } + if (configManager.readBoolean(IPlugInPort.LOCKED_ALPHA, true)) { + drawOptions.add(DrawOption.LOCKED_ALPHA); + } + return drawOptions; + } + @Override public void update(Graphics g) { paint(g);