performance upgrade

This commit is contained in:
Branislav Stojkovic
2025-03-17 12:05:26 +01:00
parent 44c776194f
commit 2ead5592d8
3 changed files with 78 additions and 36 deletions
@@ -253,6 +253,10 @@
<changeType>NEW_FEATURE</changeType> <changeType>NEW_FEATURE</changeType>
<description>Configurable 'High DPI Rendering' feature which makes the diagram smoother on high-resolution displays but can affect performance</description> <description>Configurable 'High DPI Rendering' feature which makes the diagram smoother on high-resolution displays but can affect performance</description>
</org.diylc.appframework.update.Change> </org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType>
<description>Significantly improved rendering performance</description>
</org.diylc.appframework.update.Change>
<org.diylc.appframework.update.Change> <org.diylc.appframework.update.Change>
<changeType>IMPROVEMENT</changeType> <changeType>IMPROVEMENT</changeType>
<description>Upgraded source code structure to modern standards and introduced Maven</description> <description>Upgraded source code structure to modern standards and introduced Maven</description>
@@ -40,6 +40,7 @@ import org.diylc.awt.ImageUtils;
import org.diylc.common.ObjectCache; import org.diylc.common.ObjectCache;
import org.diylc.common.Orientation; import org.diylc.common.Orientation;
import org.diylc.components.AbstractTransparentComponent; import org.diylc.components.AbstractTransparentComponent;
import org.diylc.components.boards.AbstractBoard;
import org.diylc.components.transform.ImageTransformer; import org.diylc.components.transform.ImageTransformer;
import org.diylc.core.ComponentState; import org.diylc.core.ComponentState;
import org.diylc.core.IDIYComponent; import org.diylc.core.IDIYComponent;
@@ -94,6 +95,8 @@ public class Image extends AbstractTransparentComponent<Void> {
private byte newScale = DEFAULT_SCALE; private byte newScale = DEFAULT_SCALE;
private ImageSizingMode sizingMode = ImageSizingMode.Scale; private ImageSizingMode sizingMode = ImageSizingMode.Scale;
private transient ImageIcon imageIcon;
public Image() { public Image() {
try { try {
data = IOUtils.toByteArray(Image.class.getResourceAsStream("/image.png")); data = IOUtils.toByteArray(Image.class.getResourceAsStream("/image.png"));
@@ -105,6 +108,11 @@ public class Image extends AbstractTransparentComponent<Void> {
@Override @Override
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project, public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
IDrawingObserver drawingObserver) { IDrawingObserver drawingObserver) {
if (!getImageRectangle().intersects(g2d.getClipBounds())) {
return;
}
double scaleX; double scaleX;
double scaleY; double scaleY;
ImageIcon imageIcon = getImage(); ImageIcon imageIcon = getImage();
@@ -199,21 +207,24 @@ public class Image extends AbstractTransparentComponent<Void> {
} }
public ImageIcon getImage() { public ImageIcon getImage() {
if (image != null) { if (imageIcon == null) {
// when loading old files, convert the stored image to byte array and then then discard it, we won't be needing it anymore if (image != null) {
BufferedImage bi = ImageUtils.ToBufferedImage(image.getImage()); // when loading old files, convert the stored image to byte array and then then discard it, we won't be needing it anymore
ByteArrayOutputStream baos = new ByteArrayOutputStream(); BufferedImage bi = ImageUtils.ToBufferedImage(image.getImage());
try { ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "png", baos); try {
// make it official ImageIO.write(bi, "png", baos);
data = baos.toByteArray(); // make it official
} catch (IOException e) { data = baos.toByteArray();
} catch (IOException e) {
}
// don't save back to the file
image = null;
} }
// don't save back to the file
image = null;
}
return new ImageIcon(data); imageIcon = new ImageIcon(data);
}
return imageIcon;
} }
@ByteArrayProperty(binaryType = BinaryType.IMAGE) @ByteArrayProperty(binaryType = BinaryType.IMAGE)
@@ -280,6 +291,27 @@ public class Image extends AbstractTransparentComponent<Void> {
this.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 { public static enum ImageSizingMode {
TwoPoints("Opposing Points"), Scale("Scale"); TwoPoints("Opposing Points"), Scale("Scale");
@@ -338,28 +338,9 @@ public class CanvasPanel extends JComponent implements Autoscroll {
double x = visibleRect.x;// / scaleFactor; double x = visibleRect.x;// / scaleFactor;
double y = visibleRect.y;// / scaleFactor; double y = visibleRect.y;// / scaleFactor;
bufferG2d.translate(-x, -y); bufferG2d.translate(-x, -y);
bufferG2d.setClip(visibleRect);
Set<DrawOption> drawOptions = Set<DrawOption> drawOptions = getDrawOptions();
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);
}
plugInPort.draw(bufferG2d, drawOptions, null, null, scaleFactor, visibleRect); plugInPort.draw(bufferG2d, drawOptions, null, null, scaleFactor, visibleRect);
@@ -389,6 +370,31 @@ public class CanvasPanel extends JComponent implements Autoscroll {
bufferG2d.dispose(); bufferG2d.dispose();
} }
private Set<DrawOption> getDrawOptions() {
Set<DrawOption> 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 @Override
public void update(Graphics g) { public void update(Graphics g) {
paint(g); paint(g);