mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 17:22:09 +10:00
Improve speed of rendering of the grid
This commit is contained in:
@@ -34,6 +34,7 @@ import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -119,14 +120,14 @@ public class DrawingManager {
|
||||
|
||||
private List<Area> proximityMarkers = null;
|
||||
|
||||
public DrawingManager(MessageDispatcher<EventType> messageDispatcher, IConfigurationManager<?> configManager) {
|
||||
public DrawingManager(MessageDispatcher<EventType> messageDispatcher,
|
||||
IConfigurationManager<?> configManager) {
|
||||
super();
|
||||
this.messageDispatcher = messageDispatcher;
|
||||
this.configManager = configManager;
|
||||
|
||||
try {
|
||||
this.theme = (Theme) configManager.readObject(IPlugInPort.THEME_KEY,
|
||||
Constants.DEFAULT_THEME);
|
||||
this.theme = (Theme) configManager.readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error loading theme", e);
|
||||
this.theme = Constants.DEFAULT_THEME;
|
||||
@@ -137,10 +138,12 @@ public class DrawingManager {
|
||||
componentAreaMap = new HashMap<IDIYComponent<?>, ComponentArea>();
|
||||
lastDrawnStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
|
||||
String debugComponentAreasStr = System.getProperty(DEBUG_COMPONENT_AREAS);
|
||||
debugComponentAreas = debugComponentAreasStr != null && debugComponentAreasStr.equalsIgnoreCase("true");
|
||||
debugComponentAreas =
|
||||
debugComponentAreasStr != null && debugComponentAreasStr.equalsIgnoreCase("true");
|
||||
|
||||
String debugContinuityAreasStr = System.getProperty(DEBUG_CONTINUITY_AREAS);
|
||||
debugContinuityAreas = debugContinuityAreasStr != null && debugContinuityAreasStr.equalsIgnoreCase("true");
|
||||
debugContinuityAreas =
|
||||
debugContinuityAreasStr != null && debugContinuityAreasStr.equalsIgnoreCase("true");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,10 +164,12 @@ public class DrawingManager {
|
||||
* @param visibleRect
|
||||
* @return
|
||||
*/
|
||||
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project, Set<DrawOption> drawOptions,
|
||||
IComponentFilter filter, Rectangle selectionRect, Collection<IDIYComponent<?>> selectedComponents,
|
||||
Set<IDIYComponent<?>> lockedComponents, Set<IDIYComponent<?>> groupedComponents, List<Point2D> controlPointSlot,
|
||||
List<IDIYComponent<?>> componentSlot, boolean dragInProgress, Double externalZoom, Rectangle2D visibleRect) {
|
||||
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project,
|
||||
Set<DrawOption> drawOptions, IComponentFilter filter, Rectangle selectionRect,
|
||||
Collection<IDIYComponent<?>> selectedComponents, Set<IDIYComponent<?>> lockedComponents,
|
||||
Set<IDIYComponent<?>> groupedComponents, List<Point2D> controlPointSlot,
|
||||
List<IDIYComponent<?>> componentSlot, boolean dragInProgress, Double externalZoom,
|
||||
Rectangle2D visibleRect) {
|
||||
long totalStartTime = System.nanoTime();
|
||||
failedComponents.clear();
|
||||
if (project == null) {
|
||||
@@ -185,94 +190,58 @@ public class DrawingManager {
|
||||
|
||||
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
} else {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
|
||||
}
|
||||
if (configManager.readBoolean(IPlugInPort.HI_QUALITY_RENDER_KEY, false)) {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
|
||||
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
||||
// RenderingHints.VALUE_STROKE_PURE);
|
||||
} else {
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
|
||||
RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
}
|
||||
|
||||
// AffineTransform initialTx = g2d.getTransform();
|
||||
Dimension d = getCanvasDimensions(project, zoom, drawOptions.contains(DrawOption.EXTRA_SPACE));
|
||||
Dimension canvasDimension =
|
||||
getCanvasDimensions(project, zoom, drawOptions.contains(DrawOption.EXTRA_SPACE));
|
||||
|
||||
g2dWrapper.setColor(theme.getBgColor());
|
||||
g2dWrapper.fillRect(0, 0, d.width, d.height);
|
||||
g2d.clip(new Rectangle(new Point(0, 0), d));
|
||||
g2dWrapper.fillRect(0, 0, canvasDimension.width, canvasDimension.height);
|
||||
g2d.clip(new Rectangle(new Point(0, 0), canvasDimension));
|
||||
|
||||
Rectangle2D extraSpaceRect = new Rectangle2D.Double();
|
||||
AffineTransform extraSpaceTx = new AffineTransform();
|
||||
|
||||
// calculate size to be rendered
|
||||
double extraSpace = getExtraSpace(project) * zoom;
|
||||
Dimension dInner = getCanvasDimensions(project, zoom, false);
|
||||
|
||||
GridType gridType = GridType.LINES;
|
||||
if (drawOptions.contains(DrawOption.GRID) && gridType != GridType.NONE) {
|
||||
double zoomStep = project.getGridSpacing().convertToPixels() * zoom;
|
||||
float gridThickness = (float) (1f * (zoom > 1 ? 1 : zoom));
|
||||
if (gridType == GridType.CROSSHAIR) {
|
||||
g2d.setStroke(new BasicStroke(gridThickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f, new float[] {
|
||||
(float) zoomStep / 2, (float) zoomStep / 2}, (float) zoomStep / 4));
|
||||
} else if (gridType == GridType.DOT) {
|
||||
g2d.setStroke(new BasicStroke(gridThickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f, new float[] {
|
||||
1f, (float) zoomStep - 1}, 0f));
|
||||
} else {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchZoomableStroke(gridThickness));
|
||||
}
|
||||
|
||||
g2dWrapper.setColor(theme.getGridColor());
|
||||
for (double i = zoomStep; i < d.width; i += zoomStep) {
|
||||
g2dWrapper.draw(new Line2D.Double(i, 0, i, d.height - 1));
|
||||
}
|
||||
for (double j = zoomStep; j < d.height; j += zoomStep) {
|
||||
g2dWrapper.draw(new Line2D.Double(0, j, d.width - 1, j));
|
||||
}
|
||||
// draw dots if needed
|
||||
if (project.getDotSpacing() > 1 && zoomStep > 8) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchZoomableStroke(gridThickness * 3));
|
||||
g2d.setColor(theme.getDotColor());
|
||||
for (double i = extraSpace + zoomStep * project.getDotSpacing(); i < extraSpace + dInner.width; i += zoomStep * project.getDotSpacing())
|
||||
for (double j = extraSpace + zoomStep * project.getDotSpacing(); j < extraSpace + dInner.height; j += zoomStep * project.getDotSpacing()) {
|
||||
g2d.fillOval((int)Math.round(i - 1), (int)Math.round(j - 1), 3, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle2D extraSpaceRect = null;
|
||||
AffineTransform extraSpaceTx = null;
|
||||
// manage extra space
|
||||
if (drawOptions.contains(DrawOption.EXTRA_SPACE)) {
|
||||
float borderThickness = (float) (3f * (zoom > 1 ? 1 : zoom));
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchStroke(borderThickness, new float[] {borderThickness * 4, borderThickness * 4, }, 0, BasicStroke.CAP_BUTT));
|
||||
g2dWrapper.setColor(theme.getOutlineColor());
|
||||
extraSpaceRect = new Rectangle2D.Double(extraSpace, extraSpace, dInner.getWidth(), dInner.getHeight());
|
||||
g2d.draw(extraSpaceRect);
|
||||
extraSpaceTx = g2d.getTransform();
|
||||
|
||||
// translate to the new (0, 0)
|
||||
g2d.transform(AffineTransform.getTranslateInstance(extraSpace, extraSpace));
|
||||
if (visibleRect != null)
|
||||
visibleRect.setRect(visibleRect.getX() - extraSpace, visibleRect.getY() - extraSpace,
|
||||
visibleRect.getWidth(), visibleRect.getHeight());
|
||||
}
|
||||
drawGrid(project, g2d, zoom, extraSpace, canvasDimension, visibleRect, drawOptions,
|
||||
extraSpaceRect, extraSpaceTx);
|
||||
|
||||
// apply zoom
|
||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||
g2dWrapper.scale(zoom, zoom);
|
||||
if (visibleRect != null)
|
||||
visibleRect.setRect(visibleRect.getX() / zoom, visibleRect.getY() / zoom,
|
||||
visibleRect.getWidth() / zoom, visibleRect.getHeight() / zoom);
|
||||
visibleRect.getWidth() / zoom, visibleRect.getHeight() / zoom);
|
||||
}
|
||||
|
||||
// Composite mainComposite = g2d.getComposite();
|
||||
@@ -282,7 +251,8 @@ public class DrawingManager {
|
||||
// g2dWrapper.resetTx();
|
||||
|
||||
// put components and their states in a map
|
||||
Map<IDIYComponent<?>, ComponentState> componentStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
|
||||
Map<IDIYComponent<?>, ComponentState> componentStateMap =
|
||||
new HashMap<IDIYComponent<?>, ComponentState>();
|
||||
for (IDIYComponent<?> component : project.getComponents()) {
|
||||
ComponentState state = ComponentState.NORMAL;
|
||||
if (drawOptions.contains(DrawOption.SELECTION) && selectedComponents.contains(component)) {
|
||||
@@ -328,12 +298,14 @@ public class DrawingManager {
|
||||
try {
|
||||
|
||||
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) // go through the DrawingCache
|
||||
DrawingCache.Instance.draw(component, g2dWrapper, state, drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, visibleRect);
|
||||
DrawingCache.Instance.draw(component, g2dWrapper, state,
|
||||
drawOptions.contains(DrawOption.OUTLINE_MODE), project, zoom, visibleRect);
|
||||
else // go straight to the wrapper
|
||||
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
||||
|
||||
if (g2dWrapper.isTrackingContinuityArea()) {
|
||||
LOG.info("Component " + component.getName() + " of type " + component.getClass().getName() + " did not stop tracking continuity area.");
|
||||
LOG.info("Component " + component.getName() + " of type "
|
||||
+ component.getClass().getName() + " did not stop tracking continuity area.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing " + component.getName(), e);
|
||||
@@ -374,13 +346,17 @@ public class DrawingManager {
|
||||
continue;
|
||||
VisibilityPolicy visibilityPolicy = component.getControlPointVisibilityPolicy(i);
|
||||
if ((groupedComponents.contains(component)
|
||||
&& (visibilityPolicy == VisibilityPolicy.ALWAYS || (selectedComponents.contains(component) && visibilityPolicy == VisibilityPolicy.WHEN_SELECTED)) || (!groupedComponents
|
||||
.contains(component) && !selectedComponents.contains(component) && component
|
||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
|
||||
&& (visibilityPolicy == VisibilityPolicy.ALWAYS
|
||||
|| (selectedComponents.contains(component)
|
||||
&& visibilityPolicy == VisibilityPolicy.WHEN_SELECTED))
|
||||
|| (!groupedComponents.contains(component)
|
||||
&& !selectedComponents.contains(component)
|
||||
&& component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
|
||||
g2dWrapper.setColor(CONTROL_POINT_COLOR);
|
||||
Point2D controlPoint = component.getControlPoint(i);
|
||||
int pointSize = CONTROL_POINT_SIZE - 2;
|
||||
g2dWrapper.fillOval((int)(controlPoint.getX() - pointSize / 2), (int)(controlPoint.getY() - pointSize / 2), pointSize, pointSize);
|
||||
g2dWrapper.fillOval((int) (controlPoint.getX() - pointSize / 2),
|
||||
(int) (controlPoint.getY() - pointSize / 2), pointSize, pointSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,17 +365,19 @@ public class DrawingManager {
|
||||
for (IDIYComponent<?> component : selectedComponents) {
|
||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||
if (!groupedComponents.contains(component)
|
||||
&& (component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.WHEN_SELECTED || component
|
||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
||||
&& (component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.WHEN_SELECTED
|
||||
|| component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
||||
|
||||
Point2D controlPoint = component.getControlPoint(i);
|
||||
int pointSize = CONTROL_POINT_SIZE;
|
||||
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||
g2dWrapper.fillOval((int)(controlPoint.getX() - pointSize / 2), (int)(controlPoint.getY() - pointSize / 2), pointSize, pointSize);
|
||||
g2dWrapper.fillOval((int) (controlPoint.getX() - pointSize / 2),
|
||||
(int) (controlPoint.getY() - pointSize / 2), pointSize, pointSize);
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||
g2dWrapper.fillOval((int)(controlPoint.getX() - CONTROL_POINT_SIZE / 2 + 1), (int)(controlPoint.getY() - CONTROL_POINT_SIZE / 2
|
||||
+ 1), CONTROL_POINT_SIZE - 2, CONTROL_POINT_SIZE - 2);
|
||||
g2dWrapper.fillOval((int) (controlPoint.getX() - CONTROL_POINT_SIZE / 2 + 1),
|
||||
(int) (controlPoint.getY() - CONTROL_POINT_SIZE / 2 + 1), CONTROL_POINT_SIZE - 2,
|
||||
CONTROL_POINT_SIZE - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,8 +390,8 @@ public class DrawingManager {
|
||||
for (IDIYComponent<?> component : componentSlot) {
|
||||
try {
|
||||
|
||||
component.draw(g2dWrapper, ComponentState.NORMAL, drawOptions.contains(DrawOption.OUTLINE_MODE), project,
|
||||
g2dWrapper);
|
||||
component.draw(g2dWrapper, ComponentState.NORMAL,
|
||||
drawOptions.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing " + component.getName(), e);
|
||||
@@ -428,11 +406,13 @@ public class DrawingManager {
|
||||
for (Point2D point : controlPointSlot) {
|
||||
if (point != null) {
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
||||
g2dWrapper.fillOval((int)(point.getX() - CONTROL_POINT_SIZE / 2), (int)(point.getY() - CONTROL_POINT_SIZE / 2), CONTROL_POINT_SIZE,
|
||||
g2dWrapper.fillOval((int) (point.getX() - CONTROL_POINT_SIZE / 2),
|
||||
(int) (point.getY() - CONTROL_POINT_SIZE / 2), CONTROL_POINT_SIZE,
|
||||
CONTROL_POINT_SIZE);
|
||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||
g2dWrapper.fillOval((int)(point.getX() - CONTROL_POINT_SIZE / 2 + 1), (int)(point.getY() - CONTROL_POINT_SIZE / 2 + 1),
|
||||
CONTROL_POINT_SIZE - 2, CONTROL_POINT_SIZE - 2);
|
||||
g2dWrapper.fillOval((int) (point.getX() - CONTROL_POINT_SIZE / 2 + 1),
|
||||
(int) (point.getY() - CONTROL_POINT_SIZE / 2 + 1), CONTROL_POINT_SIZE - 2,
|
||||
CONTROL_POINT_SIZE - 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,8 +458,7 @@ public class DrawingManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.proximityMarkers != null)
|
||||
{
|
||||
if (this.proximityMarkers != null) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||
g2d.setColor(Color.red);
|
||||
for (Shape s : this.proximityMarkers)
|
||||
@@ -496,7 +475,8 @@ public class DrawingManager {
|
||||
|
||||
// shade extra space
|
||||
if (SHADE_EXTRA_SPACE && extraSpaceRect != null) {
|
||||
Area extraSpaceArea = new Area(new Rectangle2D.Double(0, 0, d.getWidth(), d.getHeight()));
|
||||
Area extraSpaceArea = new Area(
|
||||
new Rectangle2D.Double(0, 0, canvasDimension.getWidth(), canvasDimension.getHeight()));
|
||||
extraSpaceArea.subtract(new Area(extraSpaceRect));
|
||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.05f));
|
||||
g2d.setTransform(extraSpaceTx);
|
||||
@@ -513,13 +493,104 @@ public class DrawingManager {
|
||||
return failedComponents;
|
||||
}
|
||||
|
||||
private double zoomCached = 0;
|
||||
private Dimension canvasDimensionCached;
|
||||
private double extraSpaceCached;
|
||||
private GridType gridTypeCached;
|
||||
private BufferedImage cachedGridImage;
|
||||
|
||||
private void drawGrid(Project project, Graphics2D g2dIn, double zoom, double extraSpace,
|
||||
Dimension canvasDimension, Rectangle2D visibleRect, Set<DrawOption> drawOptions,
|
||||
Rectangle2D extraSpaceRect, AffineTransform extraSpaceTx) {
|
||||
|
||||
GridType gridType = GridType.LINES;
|
||||
|
||||
Dimension innerCanvasDimension = getCanvasDimensions(project, zoom, false);
|
||||
|
||||
// draw from cache
|
||||
if (zoom != zoomCached || !canvasDimension.equals(canvasDimensionCached)
|
||||
|| extraSpace != extraSpaceCached || gridType != gridTypeCached) {
|
||||
try {
|
||||
cachedGridImage = new BufferedImage((int) canvasDimension.getWidth(),
|
||||
(int) canvasDimension.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
// create graphics
|
||||
Graphics2D g2d = cachedGridImage.createGraphics();
|
||||
|
||||
if (drawOptions.contains(DrawOption.GRID) && gridType != GridType.NONE) {
|
||||
double zoomStep = project.getGridSpacing().convertToPixels() * zoom;
|
||||
float gridThickness = (float) (1f * (zoom > 1 ? 1 : zoom));
|
||||
if (gridType == GridType.CROSSHAIR) {
|
||||
g2d.setStroke(new BasicStroke(gridThickness, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_MITER, 10f,
|
||||
new float[] {(float) zoomStep / 2, (float) zoomStep / 2}, (float) zoomStep / 4));
|
||||
} else if (gridType == GridType.DOT) {
|
||||
g2d.setStroke(new BasicStroke(gridThickness, BasicStroke.CAP_BUTT,
|
||||
BasicStroke.JOIN_MITER, 10f, new float[] {1f, (float) zoomStep - 1}, 0f));
|
||||
} else {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchZoomableStroke(gridThickness));
|
||||
}
|
||||
|
||||
g2d.setColor(theme.getGridColor());
|
||||
for (double i = zoomStep; i < canvasDimension.width; i += zoomStep) {
|
||||
g2d.draw(new Line2D.Double(i, 0, i, canvasDimension.height - 1));
|
||||
}
|
||||
for (double j = zoomStep; j < canvasDimension.height; j += zoomStep) {
|
||||
g2d.draw(new Line2D.Double(0, j, canvasDimension.width - 1, j));
|
||||
}
|
||||
// draw dots if needed
|
||||
if (project.getDotSpacing() > 1 && zoomStep > 8) {
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchZoomableStroke(gridThickness * 3));
|
||||
g2d.setColor(theme.getDotColor());
|
||||
for (double i = extraSpace + zoomStep * project.getDotSpacing(); i < extraSpace
|
||||
+ innerCanvasDimension.width; i += zoomStep * project.getDotSpacing())
|
||||
for (double j = extraSpace + zoomStep * project.getDotSpacing(); j < extraSpace
|
||||
+ innerCanvasDimension.height; j += zoomStep * project.getDotSpacing()) {
|
||||
g2d.fillOval((int) Math.round(i - 1), (int) Math.round(j - 1), 3, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
zoomCached = zoom;
|
||||
canvasDimensionCached = (Dimension) canvasDimension.clone();
|
||||
extraSpaceCached = extraSpace;
|
||||
gridTypeCached = gridType;
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedGridImage == null) {
|
||||
LOG.warn("Cached grid image is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
g2dIn.drawImage(cachedGridImage, 0, 0, null);
|
||||
|
||||
// manage extra space
|
||||
if (drawOptions.contains(DrawOption.EXTRA_SPACE)) {
|
||||
float borderThickness = (float) (3f * (zoom > 1 ? 1 : zoom));
|
||||
g2dIn.setStroke(ObjectCache.getInstance().fetchStroke(borderThickness,
|
||||
new float[] {borderThickness * 4, borderThickness * 4,}, 0, BasicStroke.CAP_BUTT));
|
||||
g2dIn.setColor(theme.getOutlineColor());
|
||||
extraSpaceRect.setRect(new Rectangle2D.Double(extraSpace, extraSpace,
|
||||
innerCanvasDimension.getWidth(), innerCanvasDimension.getHeight()));
|
||||
g2dIn.draw(extraSpaceRect);
|
||||
extraSpaceTx.setTransform(g2dIn.getTransform());
|
||||
|
||||
// translate to the new (0, 0)
|
||||
g2dIn.transform(AffineTransform.getTranslateInstance(extraSpace, extraSpace));
|
||||
if (visibleRect != null)
|
||||
visibleRect.setRect(visibleRect.getX() - extraSpace, visibleRect.getY() - extraSpace,
|
||||
visibleRect.getWidth(), visibleRect.getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
public void logStats() {
|
||||
// log render time stats periodically
|
||||
if (System.currentTimeMillis() - lastStatsReportedTime > statReportFrequencyMs) {
|
||||
lastStatsReportedTime = System.currentTimeMillis();
|
||||
String mapAsString = renderStatsByType.entrySet().stream().sorted((e1, e2) -> -Long.compare(e1.getValue().getNanoTime(), e2.getValue().getNanoTime()))
|
||||
.map(e -> e.toString())
|
||||
.collect(Collectors.joining("; ", "{", "}"));
|
||||
String mapAsString = renderStatsByType.entrySet().stream()
|
||||
.sorted(
|
||||
(e1, e2) -> -Long.compare(e1.getValue().getNanoTime(), e2.getValue().getNanoTime()))
|
||||
.map(e -> e.toString()).collect(Collectors.joining("; ", "{", "}"));
|
||||
LOG.debug("Render stats: " + mapAsString);
|
||||
LOG.debug("Page stats: " + totalStats.toAvgString());
|
||||
DrawingCache.Instance.logStats();
|
||||
@@ -573,10 +644,12 @@ public class DrawingManager {
|
||||
double width = project.getWidth().convertToPixels();
|
||||
double height = project.getHeight().convertToPixels();
|
||||
double targetExtraSpace = EXTRA_SPACE * Math.max(width, height);
|
||||
return CalcUtils.roundToGrid(targetExtraSpace, project.getGridSpacing().scale(project.getDotSpacing()));
|
||||
return CalcUtils.roundToGrid(targetExtraSpace,
|
||||
project.getGridSpacing().scale(project.getDotSpacing()));
|
||||
}
|
||||
|
||||
public Dimension getCanvasDimensions(Project project, Double zoomLevel, boolean includeExtraSpace) {
|
||||
public Dimension getCanvasDimensions(Project project, Double zoomLevel,
|
||||
boolean includeExtraSpace) {
|
||||
double width = project.getWidth().convertToPixels();
|
||||
double height = project.getHeight().convertToPixels();
|
||||
|
||||
@@ -632,7 +705,7 @@ public class DrawingManager {
|
||||
if (c instanceof IContinuity) {
|
||||
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
||||
for (int j = i + 1; j < c.getControlPointCount(); j++)
|
||||
if (((IContinuity)c).arePointsConnected(i, j))
|
||||
if (((IContinuity) c).arePointsConnected(i, j))
|
||||
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
|
||||
}
|
||||
|
||||
@@ -661,10 +734,10 @@ public class DrawingManager {
|
||||
List<Area> areas = new ArrayList<Area>();
|
||||
for (int i = 0; i < preliminaryAreas.size(); i++) {
|
||||
Area a = preliminaryAreas.get(i);
|
||||
if (checkBreakout.get(i))
|
||||
areas.addAll(AreaUtils.tryAreaBreakout(a));
|
||||
else
|
||||
areas.add(a);
|
||||
if (checkBreakout.get(i))
|
||||
areas.addAll(AreaUtils.tryAreaBreakout(a));
|
||||
else
|
||||
areas.add(a);
|
||||
}
|
||||
|
||||
CalcUtils.expandConnections(connections);
|
||||
@@ -676,8 +749,10 @@ public class DrawingManager {
|
||||
|
||||
public List<Area> getContinuityAreaProximity(Project project, float threshold) {
|
||||
List<Area> continuityAreas = getContinuityAreas(project);
|
||||
Stroke s = ObjectCache.getInstance().fetchBasicStroke(threshold - 1); // value eyeballed for approx good results
|
||||
List<Area> expanded = continuityAreas.parallelStream().map((a) -> new Area(s.createStrokedShape(a))).collect(Collectors.toList());
|
||||
Stroke s = ObjectCache.getInstance().fetchBasicStroke(threshold - 1); // value eyeballed for
|
||||
// approx good results
|
||||
List<Area> expanded = continuityAreas.parallelStream()
|
||||
.map((a) -> new Area(s.createStrokedShape(a))).collect(Collectors.toList());
|
||||
List<Area> intersections = new ArrayList<Area>();
|
||||
for (int i = 0; i < expanded.size() - 1; i++) {
|
||||
for (int j = i + 1; j < expanded.size(); j++) {
|
||||
@@ -696,14 +771,17 @@ public class DrawingManager {
|
||||
for (Area a : intersections) {
|
||||
Rectangle2D bounds2d = a.getBounds2D();
|
||||
if (bounds2d.getWidth() < minSize)
|
||||
bounds2d = new Rectangle2D.Double(bounds2d.getCenterX() - minSize / 2, bounds2d.getY(), minSize, bounds2d.getHeight());
|
||||
bounds2d = new Rectangle2D.Double(bounds2d.getCenterX() - minSize / 2, bounds2d.getY(),
|
||||
minSize, bounds2d.getHeight());
|
||||
if (bounds2d.getHeight() < minSize)
|
||||
bounds2d = new Rectangle2D.Double(bounds2d.getX(), bounds2d.getCenterY() - minSize / 2, bounds2d.getWidth(), minSize);
|
||||
bounds2d = new Rectangle2D.Double(bounds2d.getX(), bounds2d.getCenterY() - minSize / 2,
|
||||
bounds2d.getWidth(), minSize);
|
||||
|
||||
shapes.add(new Area(new Ellipse2D.Double(bounds2d.getX(), bounds2d.getY(), bounds2d.getWidth(), bounds2d.getHeight())));
|
||||
shapes.add(new Area(new Ellipse2D.Double(bounds2d.getX(), bounds2d.getY(),
|
||||
bounds2d.getWidth(), bounds2d.getHeight())));
|
||||
}
|
||||
|
||||
//AreaUtils.crunchAreas(shapes, null);
|
||||
// AreaUtils.crunchAreas(shapes, null);
|
||||
|
||||
this.proximityMarkers = shapes;
|
||||
|
||||
|
||||
@@ -3801,5 +3801,21 @@
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
<org.diylc.appframework.update.Version>
|
||||
<versionNumber>
|
||||
<major>4</major>
|
||||
<minor>22</minor>
|
||||
<build>3</build>
|
||||
</versionNumber>
|
||||
<releaseDate>2022-03-18 00:00:00.000 CET</releaseDate>
|
||||
<name></name>
|
||||
<changes>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
<description>Improved rendering performance</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
</changes>
|
||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||
</org.diylc.appframework.update.Version>
|
||||
</a>
|
||||
</java.util.Arrays_-ArrayList>
|
||||
|
||||
Binary file not shown.
@@ -23,10 +23,8 @@ import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
@@ -259,14 +257,26 @@ public abstract class AbstractGuitarPickup extends AbstractLabeledComponent<Stri
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Area area = new Area();
|
||||
Shape[] body = getBody();
|
||||
int margin = 20;
|
||||
for (Shape a : body)
|
||||
if (a != null)
|
||||
area.add(new Area(a));
|
||||
Rectangle2D bounds = area.getBounds2D();
|
||||
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
|
||||
double minX = 0;
|
||||
double minY = 0;
|
||||
double maxX = 0;
|
||||
double maxY = 0;
|
||||
for (Shape a : body) {
|
||||
if (a != null) {
|
||||
Rectangle2D bounds2d = a.getBounds2D();
|
||||
if (bounds2d.getMinX() < minX)
|
||||
minX = bounds2d.getMinX();
|
||||
if (bounds2d.getMinY() < minY)
|
||||
minY = bounds2d.getMinY();
|
||||
if (bounds2d.getMaxX() > maxX)
|
||||
maxX = bounds2d.getMaxX();
|
||||
if (bounds2d.getMaxY() > maxY)
|
||||
maxY = bounds2d.getMaxY();
|
||||
}
|
||||
}
|
||||
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
|
||||
}
|
||||
|
||||
public enum Polarity {
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.awt.Composite;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
@@ -477,14 +478,26 @@ public class PotentiometerPanel extends AbstractPotentiometer {
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Area area = new Area();
|
||||
Area[] body = getBody();
|
||||
Shape[] body = getBody();
|
||||
int margin = 20;
|
||||
for (Area a : body)
|
||||
if (a != null)
|
||||
area.add(a);
|
||||
Rectangle2D bounds = area.getBounds2D();
|
||||
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
|
||||
double minX = 0;
|
||||
double minY = 0;
|
||||
double maxX = 0;
|
||||
double maxY = 0;
|
||||
for (Shape a : body) {
|
||||
if (a != null) {
|
||||
Rectangle2D bounds2d = a.getBounds2D();
|
||||
if (bounds2d.getMinX() < minX)
|
||||
minX = bounds2d.getMinX();
|
||||
if (bounds2d.getMinY() < minY)
|
||||
minY = bounds2d.getMinY();
|
||||
if (bounds2d.getMaxX() > maxX)
|
||||
maxX = bounds2d.getMaxX();
|
||||
if (bounds2d.getMaxY() > maxY)
|
||||
maxY = bounds2d.getMaxY();
|
||||
}
|
||||
}
|
||||
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.awt.FontMetrics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
@@ -367,13 +368,25 @@ public class TransistorTO3 extends AbstractLabeledComponent<String> {
|
||||
|
||||
@Override
|
||||
public Rectangle2D getCachingBounds() {
|
||||
Area area = new Area();
|
||||
Area[] body = getBody();
|
||||
Shape[] body = getBody();
|
||||
int margin = 20;
|
||||
for (Area a : body)
|
||||
if (a != null)
|
||||
area.add(a);
|
||||
Rectangle2D bounds = area.getBounds2D();
|
||||
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
|
||||
double minX = 0;
|
||||
double minY = 0;
|
||||
double maxX = 0;
|
||||
double maxY = 0;
|
||||
for (Shape a : body) {
|
||||
if (a != null) {
|
||||
Rectangle2D bounds2d = a.getBounds2D();
|
||||
if (bounds2d.getMinX() < minX)
|
||||
minX = bounds2d.getMinX();
|
||||
if (bounds2d.getMinY() < minY)
|
||||
minY = bounds2d.getMinY();
|
||||
if (bounds2d.getMaxX() > maxX)
|
||||
maxX = bounds2d.getMaxX();
|
||||
if (bounds2d.getMaxY() > maxY)
|
||||
maxY = bounds2d.getMaxY();
|
||||
}
|
||||
}
|
||||
return new Rectangle2D.Double(minX - margin, minY - margin, maxX - minX + 2 * margin, maxY - minY + 2 * margin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.diylc.RegressionTestRunner"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="diylc-swing"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value=""C:\Users\bancika\Documents\GitHub\diy-layout-creator\diylc-regression-data" TEST travelcaster3"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value=""C:\Users\bancika\Documents\GitHub\diy-layout-creator\diylc-regression-data" TEST diy-fever"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="diylc-swing"/>
|
||||
</launchConfiguration>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user