From f107fe79d9b3ff55967cd979f2db505cb98af86c Mon Sep 17 00:00:00 2001 From: hneemann Date: Wed, 10 Aug 2016 23:33:42 +0200 Subject: [PATCH] speed up of drawing --- .../digital/draw/elements/VisualElement.java | 23 ++-- .../digital/draw/graphics/GraphicSwing.java | 110 ++++++++++-------- .../gui/components/CircuitComponent.java | 4 +- 3 files changed, 80 insertions(+), 57 deletions(-) diff --git a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java index c0141c67e..555d42026 100644 --- a/src/main/java/de/neemann/digital/draw/elements/VisualElement.java +++ b/src/main/java/de/neemann/digital/draw/elements/VisualElement.java @@ -29,6 +29,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { private transient InteractorInterface interactor; private transient Element element; private transient ShapeFactory shapeFactory; + private transient Transform transform; private final String elementName; private final ElementAttributes elementAttributes; @@ -43,7 +44,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { public VisualElement(String elementName) { this.elementName = elementName; elementAttributes = new ElementAttributes(); - pos = new Vector(0, 0); + setPos(new Vector(0, 0)); } /** @@ -54,7 +55,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { public VisualElement(VisualElement proto) { this.elementName = proto.elementName; this.elementAttributes = new ElementAttributes(proto.elementAttributes); - this.pos = new Vector(proto.pos); + setPos(new Vector(proto.pos)); } /** @@ -91,6 +92,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { public VisualElement setPos(Vector pos) { this.pos = pos; minMax = null; + transform=null; return this; } @@ -167,11 +169,14 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { } private Transform createTransform() { - int rotate = getRotate(); - if (rotate == 0) - return v -> v.add(pos); - else - return new TransformRotate(pos, rotate); + if (transform==null) { + int rotate = getRotate(); + if (rotate == 0) + transform = v -> v.add(pos); + else + transform = new TransformRotate(pos, rotate); + } + return transform; } /** @@ -188,8 +193,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { @Override public void move(Vector delta) { - pos = pos.add(delta); - minMax = null; + setPos(pos.add(delta)); } /** @@ -303,6 +307,7 @@ public class VisualElement implements Drawable, Moveable, AttributeListener { @Override public void attributeChanged(Key key) { shape = null; + transform=null; } @Override diff --git a/src/main/java/de/neemann/digital/draw/graphics/GraphicSwing.java b/src/main/java/de/neemann/digital/draw/graphics/GraphicSwing.java index 017df3424..925db3d3f 100644 --- a/src/main/java/de/neemann/digital/draw/graphics/GraphicSwing.java +++ b/src/main/java/de/neemann/digital/draw/graphics/GraphicSwing.java @@ -15,6 +15,8 @@ import static de.neemann.digital.core.element.ElementAttributes.cleanLabel; public class GraphicSwing implements Graphic { private final Graphics2D gr; + private final int minFontSize; + private int pixelSize; private Style lastStyle; /** @@ -23,7 +25,19 @@ public class GraphicSwing implements Graphic { * @param gr the {@link Graphics2D} instave to use. */ public GraphicSwing(Graphics2D gr) { + this(gr, 1); + } + + /** + * Creates a new instance + * + * @param gr the {@link Graphics2D} instave to use. + * @param pixelSize the size of one pixel + */ + public GraphicSwing(Graphics2D gr, int pixelSize) { this.gr = gr; + this.pixelSize = pixelSize; + this.minFontSize = pixelSize * 3; gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } @@ -59,13 +73,15 @@ public class GraphicSwing implements Graphic { @Override public void drawCircle(Vector p1, Vector p2, Style style) { - applyStyle(style); - Vector p = Vector.min(p1, p2); Vector w = Vector.width(p1, p2); - if (style.isFilled()) - gr.fillOval(p.x - 1, p.y - 1, w.x + 2, w.y + 2); - else - gr.drawOval(p.x, p.y, w.x, w.y); + if (w.x > pixelSize || w.y > pixelSize) { + applyStyle(style); + Vector p = Vector.min(p1, p2); + if (style.isFilled()) + gr.fillOval(p.x - 1, p.y - 1, w.x + 2, w.y + 2); + else + gr.drawOval(p.x, p.y, w.x, w.y); + } } private void applyStyle(Style style) { @@ -79,51 +95,51 @@ public class GraphicSwing implements Graphic { @Override public void drawText(Vector p1, Vector p2, String text, Orientation orientation, Style style) { - if (text == null || text.length() == 0) return; + applyStyle(style); // sets also font size! + int height = gr.getFontMetrics().getHeight(); + if (height > minFontSize) { + if (text == null || text.length() == 0) return; - //GraphicMinMax.approxTextSize(this, p1, p2, text, orientation, style); + //GraphicMinMax.approxTextSize(this, p1, p2, text, orientation, style); - text = cleanLabel(text); + text = cleanLabel(text); - boolean rotateText = false; - if (p1.y == p2.y) { // 0 and 180 deg - if (p1.x > p2.x) // 180 - orientation = orientation.rot(2); - } else { - if (p1.y < p2.y) // 270 - orientation = orientation.rot(2); - else // 90 - orientation = orientation.rot(0); - rotateText = true; + boolean rotateText = false; + if (p1.y == p2.y) { // 0 and 180 deg + if (p1.x > p2.x) // 180 + orientation = orientation.rot(2); + } else { + if (p1.y < p2.y) // 270 + orientation = orientation.rot(2); + else // 90 + orientation = orientation.rot(0); + rotateText = true; + } + + AffineTransform old = null; + if (rotateText) { + old = gr.getTransform(); + gr.translate(p1.x, p1.y); + gr.rotate(-Math.PI / 2); + gr.translate(-p1.x, -p1.y); + } + + int xoff = 0; + if (orientation.getX() != 0) { + int width = gr.getFontMetrics().stringWidth(text); + xoff -= width * orientation.getX() / 2; + } + + int yoff = 0; + if (orientation.getY() != 0) { + yoff += height * orientation.getY() / 3; + } + + gr.drawString(text, p1.x + xoff, p1.y + yoff); + + if (rotateText) + gr.setTransform(old); } - - AffineTransform old = null; - if (rotateText) { - old = gr.getTransform(); - gr.translate(p1.x, p1.y); - gr.rotate(-Math.PI / 2); - gr.translate(-p1.x, -p1.y); - } - - - applyStyle(style); - int xoff = 0; - if (orientation.getX() != 0) { - int width = gr.getFontMetrics().stringWidth(text); - xoff -= width * orientation.getX() / 2; - } - - int yoff = 0; - if (orientation.getY() != 0) { - int height = gr.getFontMetrics().getHeight(); - yoff += height * orientation.getY() / 3; - } - - gr.drawString(text, p1.x + xoff, p1.y + yoff); - - if (rotateText) - gr.setTransform(old); - } } diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java index 8974416b2..d6e7c0d55 100644 --- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java +++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java @@ -337,8 +337,10 @@ public class CircuitComponent extends JComponent { AffineTransform oldTrans = gr2.getTransform(); gr2.transform(transform); - GraphicSwing gr = new GraphicSwing(gr2); + GraphicSwing gr = new GraphicSwing(gr2, (int) (2 / transform.getScaleX())); +// long time = System.currentTimeMillis(); circuit.drawTo(gr, highLighted, modelSync); +// System.out.println(System.currentTimeMillis()-time); // -agentlib:hprof=cpu=samples activeMouseController.drawTo(gr); gr2.setTransform(oldTrans);