mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-10 09:12: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.Line2D;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -108,7 +109,7 @@ public class DrawingManager {
|
|||||||
|
|
||||||
private boolean debugComponentAreas;
|
private boolean debugComponentAreas;
|
||||||
private boolean debugContinuityAreas;
|
private boolean debugContinuityAreas;
|
||||||
|
|
||||||
// rendering stats
|
// rendering stats
|
||||||
private Map<String, Counter> renderStatsByType = new HashMap<String, Counter>();
|
private Map<String, Counter> renderStatsByType = new HashMap<String, Counter>();
|
||||||
private long lastStatsReportedTime = System.currentTimeMillis();
|
private long lastStatsReportedTime = System.currentTimeMillis();
|
||||||
@@ -119,28 +120,30 @@ public class DrawingManager {
|
|||||||
|
|
||||||
private List<Area> proximityMarkers = null;
|
private List<Area> proximityMarkers = null;
|
||||||
|
|
||||||
public DrawingManager(MessageDispatcher<EventType> messageDispatcher, IConfigurationManager<?> configManager) {
|
public DrawingManager(MessageDispatcher<EventType> messageDispatcher,
|
||||||
|
IConfigurationManager<?> configManager) {
|
||||||
super();
|
super();
|
||||||
this.messageDispatcher = messageDispatcher;
|
this.messageDispatcher = messageDispatcher;
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.theme = (Theme) configManager.readObject(IPlugInPort.THEME_KEY,
|
this.theme = (Theme) configManager.readObject(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||||
Constants.DEFAULT_THEME);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error loading theme", e);
|
LOG.error("Error loading theme", e);
|
||||||
this.theme = Constants.DEFAULT_THEME;
|
this.theme = Constants.DEFAULT_THEME;
|
||||||
// replace bad value with default
|
// replace bad value with default
|
||||||
configManager.writeValue(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
configManager.writeValue(IPlugInPort.THEME_KEY, Constants.DEFAULT_THEME);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentAreaMap = new HashMap<IDIYComponent<?>, ComponentArea>();
|
componentAreaMap = new HashMap<IDIYComponent<?>, ComponentArea>();
|
||||||
lastDrawnStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
|
lastDrawnStateMap = new HashMap<IDIYComponent<?>, ComponentState>();
|
||||||
String debugComponentAreasStr = System.getProperty(DEBUG_COMPONENT_AREAS);
|
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);
|
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
|
* @param visibleRect
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project, Set<DrawOption> drawOptions,
|
public List<IDIYComponent<?>> drawProject(Graphics2D g2d, Project project,
|
||||||
IComponentFilter filter, Rectangle selectionRect, Collection<IDIYComponent<?>> selectedComponents,
|
Set<DrawOption> drawOptions, IComponentFilter filter, Rectangle selectionRect,
|
||||||
Set<IDIYComponent<?>> lockedComponents, Set<IDIYComponent<?>> groupedComponents, List<Point2D> controlPointSlot,
|
Collection<IDIYComponent<?>> selectedComponents, Set<IDIYComponent<?>> lockedComponents,
|
||||||
List<IDIYComponent<?>> componentSlot, boolean dragInProgress, Double externalZoom, Rectangle2D visibleRect) {
|
Set<IDIYComponent<?>> groupedComponents, List<Point2D> controlPointSlot,
|
||||||
|
List<IDIYComponent<?>> componentSlot, boolean dragInProgress, Double externalZoom,
|
||||||
|
Rectangle2D visibleRect) {
|
||||||
long totalStartTime = System.nanoTime();
|
long totalStartTime = System.nanoTime();
|
||||||
failedComponents.clear();
|
failedComponents.clear();
|
||||||
if (project == null) {
|
if (project == null) {
|
||||||
@@ -185,104 +190,69 @@ public class DrawingManager {
|
|||||||
|
|
||||||
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
|
if (drawOptions.contains(DrawOption.ANTIALIASING)) {
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
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 {
|
} else {
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
|
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)) {
|
if (configManager.readBoolean(IPlugInPort.HI_QUALITY_RENDER_KEY, false)) {
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
|
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
|
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_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
|
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,
|
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
||||||
// RenderingHints.VALUE_STROKE_PURE);
|
// RenderingHints.VALUE_STROKE_PURE);
|
||||||
} else {
|
} else {
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
|
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
|
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_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
|
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();
|
// 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.setColor(theme.getBgColor());
|
||||||
g2dWrapper.fillRect(0, 0, d.width, d.height);
|
g2dWrapper.fillRect(0, 0, canvasDimension.width, canvasDimension.height);
|
||||||
g2d.clip(new Rectangle(new Point(0, 0), d));
|
g2d.clip(new Rectangle(new Point(0, 0), canvasDimension));
|
||||||
|
|
||||||
|
Rectangle2D extraSpaceRect = new Rectangle2D.Double();
|
||||||
|
AffineTransform extraSpaceTx = new AffineTransform();
|
||||||
|
|
||||||
// calculate size to be rendered
|
// calculate size to be rendered
|
||||||
double extraSpace = getExtraSpace(project) * zoom;
|
double extraSpace = getExtraSpace(project) * zoom;
|
||||||
Dimension dInner = getCanvasDimensions(project, zoom, false);
|
|
||||||
|
|
||||||
GridType gridType = GridType.LINES;
|
drawGrid(project, g2d, zoom, extraSpace, canvasDimension, visibleRect, drawOptions,
|
||||||
if (drawOptions.contains(DrawOption.GRID) && gridType != GridType.NONE) {
|
extraSpaceRect, extraSpaceTx);
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply zoom
|
// apply zoom
|
||||||
if (Math.abs(1.0 - zoom) > 1e-4) {
|
if (Math.abs(1.0 - zoom) > 1e-4) {
|
||||||
g2dWrapper.scale(zoom, zoom);
|
g2dWrapper.scale(zoom, zoom);
|
||||||
if (visibleRect != null)
|
if (visibleRect != null)
|
||||||
visibleRect.setRect(visibleRect.getX() / zoom, visibleRect.getY() / zoom,
|
visibleRect.setRect(visibleRect.getX() / zoom, visibleRect.getY() / zoom,
|
||||||
visibleRect.getWidth() / zoom, visibleRect.getHeight() / zoom);
|
visibleRect.getWidth() / zoom, visibleRect.getHeight() / zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Composite mainComposite = g2d.getComposite();
|
// Composite mainComposite = g2d.getComposite();
|
||||||
// Composite alphaComposite =
|
// Composite alphaComposite =
|
||||||
// AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
|
// AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
|
||||||
|
|
||||||
// g2dWrapper.resetTx();
|
// g2dWrapper.resetTx();
|
||||||
|
|
||||||
// put components and their states in a map
|
// 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()) {
|
for (IDIYComponent<?> component : project.getComponents()) {
|
||||||
ComponentState state = ComponentState.NORMAL;
|
ComponentState state = ComponentState.NORMAL;
|
||||||
if (drawOptions.contains(DrawOption.SELECTION) && selectedComponents.contains(component)) {
|
if (drawOptions.contains(DrawOption.SELECTION) && selectedComponents.contains(component)) {
|
||||||
@@ -294,9 +264,9 @@ public class DrawingManager {
|
|||||||
}
|
}
|
||||||
componentStateMap.put(component, state);
|
componentStateMap.put(component, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean outlineMode = drawOptions.contains(DrawOption.OUTLINE_MODE);
|
boolean outlineMode = drawOptions.contains(DrawOption.OUTLINE_MODE);
|
||||||
|
|
||||||
// give the cache a chance to prepare all the components in multiple threads
|
// give the cache a chance to prepare all the components in multiple threads
|
||||||
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) {
|
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) {
|
||||||
DrawingCache.Instance.bulkPrepare(componentStateMap, g2dWrapper, outlineMode, project, zoom);
|
DrawingCache.Instance.bulkPrepare(componentStateMap, g2dWrapper, outlineMode, project, zoom);
|
||||||
@@ -312,7 +282,7 @@ public class DrawingManager {
|
|||||||
// Do not track the area if component is not invalidated and was
|
// Do not track the area if component is not invalidated and was
|
||||||
// drawn in the same state.
|
// drawn in the same state.
|
||||||
boolean trackArea = lastDrawnStateMap.get(component) != state;
|
boolean trackArea = lastDrawnStateMap.get(component) != state;
|
||||||
|
|
||||||
synchronized (g2d) {
|
synchronized (g2d) {
|
||||||
g2dWrapper.startedDrawingComponent();
|
g2dWrapper.startedDrawingComponent();
|
||||||
if (!trackArea) {
|
if (!trackArea) {
|
||||||
@@ -326,14 +296,16 @@ public class DrawingManager {
|
|||||||
// Draw the component through the g2dWrapper.
|
// Draw the component through the g2dWrapper.
|
||||||
long componentStart = System.nanoTime();
|
long componentStart = System.nanoTime();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (drawOptions.contains(DrawOption.ENABLE_CACHING)) // go through the DrawingCache
|
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
|
else // go straight to the wrapper
|
||||||
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
component.draw(g2dWrapper, state, outlineMode, project, g2dWrapper);
|
||||||
|
|
||||||
if (g2dWrapper.isTrackingContinuityArea()) {
|
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) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error drawing " + component.getName(), e);
|
LOG.error("Error drawing " + component.getName(), e);
|
||||||
@@ -349,7 +321,7 @@ public class DrawingManager {
|
|||||||
Counter stats = null;
|
Counter stats = null;
|
||||||
String key = component.getClass().getCanonicalName().replace("org.diylc.components.", "");
|
String key = component.getClass().getCanonicalName().replace("org.diylc.components.", "");
|
||||||
if (renderStatsByType.containsKey(key)) {
|
if (renderStatsByType.containsKey(key)) {
|
||||||
stats = renderStatsByType.get(key);
|
stats = renderStatsByType.get(key);
|
||||||
} else {
|
} else {
|
||||||
stats = new Counter();
|
stats = new Counter();
|
||||||
renderStatsByType.put(key, stats);
|
renderStatsByType.put(key, stats);
|
||||||
@@ -374,13 +346,17 @@ public class DrawingManager {
|
|||||||
continue;
|
continue;
|
||||||
VisibilityPolicy visibilityPolicy = component.getControlPointVisibilityPolicy(i);
|
VisibilityPolicy visibilityPolicy = component.getControlPointVisibilityPolicy(i);
|
||||||
if ((groupedComponents.contains(component)
|
if ((groupedComponents.contains(component)
|
||||||
&& (visibilityPolicy == VisibilityPolicy.ALWAYS || (selectedComponents.contains(component) && visibilityPolicy == VisibilityPolicy.WHEN_SELECTED)) || (!groupedComponents
|
&& (visibilityPolicy == VisibilityPolicy.ALWAYS
|
||||||
.contains(component) && !selectedComponents.contains(component) && component
|
|| (selectedComponents.contains(component)
|
||||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
|
&& visibilityPolicy == VisibilityPolicy.WHEN_SELECTED))
|
||||||
|
|| (!groupedComponents.contains(component)
|
||||||
|
&& !selectedComponents.contains(component)
|
||||||
|
&& component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS))) {
|
||||||
g2dWrapper.setColor(CONTROL_POINT_COLOR);
|
g2dWrapper.setColor(CONTROL_POINT_COLOR);
|
||||||
Point2D controlPoint = component.getControlPoint(i);
|
Point2D controlPoint = component.getControlPoint(i);
|
||||||
int pointSize = CONTROL_POINT_SIZE - 2;
|
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 (IDIYComponent<?> component : selectedComponents) {
|
||||||
for (int i = 0; i < component.getControlPointCount(); i++) {
|
for (int i = 0; i < component.getControlPointCount(); i++) {
|
||||||
if (!groupedComponents.contains(component)
|
if (!groupedComponents.contains(component)
|
||||||
&& (component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.WHEN_SELECTED || component
|
&& (component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.WHEN_SELECTED
|
||||||
.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
|| component.getControlPointVisibilityPolicy(i) == VisibilityPolicy.ALWAYS)) {
|
||||||
|
|
||||||
Point2D controlPoint = component.getControlPoint(i);
|
Point2D controlPoint = component.getControlPoint(i);
|
||||||
int pointSize = CONTROL_POINT_SIZE;
|
int pointSize = CONTROL_POINT_SIZE;
|
||||||
|
|
||||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
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.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||||
g2dWrapper.fillOval((int)(controlPoint.getX() - CONTROL_POINT_SIZE / 2 + 1), (int)(controlPoint.getY() - CONTROL_POINT_SIZE / 2
|
g2dWrapper.fillOval((int) (controlPoint.getX() - CONTROL_POINT_SIZE / 2 + 1),
|
||||||
+ 1), CONTROL_POINT_SIZE - 2, CONTROL_POINT_SIZE - 2);
|
(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) {
|
for (IDIYComponent<?> component : componentSlot) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
component.draw(g2dWrapper, ComponentState.NORMAL, drawOptions.contains(DrawOption.OUTLINE_MODE), project,
|
component.draw(g2dWrapper, ComponentState.NORMAL,
|
||||||
g2dWrapper);
|
drawOptions.contains(DrawOption.OUTLINE_MODE), project, g2dWrapper);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error drawing " + component.getName(), e);
|
LOG.error("Error drawing " + component.getName(), e);
|
||||||
@@ -428,11 +406,13 @@ public class DrawingManager {
|
|||||||
for (Point2D point : controlPointSlot) {
|
for (Point2D point : controlPointSlot) {
|
||||||
if (point != null) {
|
if (point != null) {
|
||||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR.darker());
|
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);
|
CONTROL_POINT_SIZE);
|
||||||
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
g2dWrapper.setColor(SELECTED_CONTROL_POINT_COLOR);
|
||||||
g2dWrapper.fillOval((int)(point.getX() - CONTROL_POINT_SIZE / 2 + 1), (int)(point.getY() - CONTROL_POINT_SIZE / 2 + 1),
|
g2dWrapper.fillOval((int) (point.getX() - CONTROL_POINT_SIZE / 2 + 1),
|
||||||
CONTROL_POINT_SIZE - 2, CONTROL_POINT_SIZE - 2);
|
(int) (point.getY() - CONTROL_POINT_SIZE / 2 + 1), CONTROL_POINT_SIZE - 2,
|
||||||
|
CONTROL_POINT_SIZE - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -477,9 +457,8 @@ public class DrawingManager {
|
|||||||
g2d.draw(a);
|
g2d.draw(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.proximityMarkers != null)
|
if (this.proximityMarkers != null) {
|
||||||
{
|
|
||||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(2));
|
||||||
g2d.setColor(Color.red);
|
g2d.setColor(Color.red);
|
||||||
for (Shape s : this.proximityMarkers)
|
for (Shape s : this.proximityMarkers)
|
||||||
@@ -493,33 +472,125 @@ public class DrawingManager {
|
|||||||
g2d.fill(currentContinuityArea);
|
g2d.fill(currentContinuityArea);
|
||||||
g2d.setComposite(oldComposite);
|
g2d.setComposite(oldComposite);
|
||||||
}
|
}
|
||||||
|
|
||||||
// shade extra space
|
// shade extra space
|
||||||
if (SHADE_EXTRA_SPACE && extraSpaceRect != null) {
|
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));
|
extraSpaceArea.subtract(new Area(extraSpaceRect));
|
||||||
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.05f));
|
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.05f));
|
||||||
g2d.setTransform(extraSpaceTx);
|
g2d.setTransform(extraSpaceTx);
|
||||||
g2d.setColor(theme.getOutlineColor());
|
g2d.setColor(theme.getOutlineColor());
|
||||||
g2d.fill(extraSpaceArea);
|
g2d.fill(extraSpaceArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
long totalEndTime = System.nanoTime();
|
long totalEndTime = System.nanoTime();
|
||||||
|
|
||||||
totalStats.add(totalEndTime - totalStartTime);
|
totalStats.add(totalEndTime - totalStartTime);
|
||||||
|
|
||||||
logStats();
|
logStats();
|
||||||
|
|
||||||
return failedComponents;
|
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() {
|
public void logStats() {
|
||||||
// log render time stats periodically
|
// log render time stats periodically
|
||||||
if (System.currentTimeMillis() - lastStatsReportedTime > statReportFrequencyMs) {
|
if (System.currentTimeMillis() - lastStatsReportedTime > statReportFrequencyMs) {
|
||||||
lastStatsReportedTime = System.currentTimeMillis();
|
lastStatsReportedTime = System.currentTimeMillis();
|
||||||
String mapAsString = renderStatsByType.entrySet().stream().sorted((e1, e2) -> -Long.compare(e1.getValue().getNanoTime(), e2.getValue().getNanoTime()))
|
String mapAsString = renderStatsByType.entrySet().stream()
|
||||||
.map(e -> e.toString())
|
.sorted(
|
||||||
.collect(Collectors.joining("; ", "{", "}"));
|
(e1, e2) -> -Long.compare(e1.getValue().getNanoTime(), e2.getValue().getNanoTime()))
|
||||||
|
.map(e -> e.toString()).collect(Collectors.joining("; ", "{", "}"));
|
||||||
LOG.debug("Render stats: " + mapAsString);
|
LOG.debug("Render stats: " + mapAsString);
|
||||||
LOG.debug("Page stats: " + totalStats.toAvgString());
|
LOG.debug("Page stats: " + totalStats.toAvgString());
|
||||||
DrawingCache.Instance.logStats();
|
DrawingCache.Instance.logStats();
|
||||||
@@ -572,11 +643,13 @@ public class DrawingManager {
|
|||||||
public double getExtraSpace(Project project) {
|
public double getExtraSpace(Project project) {
|
||||||
double width = project.getWidth().convertToPixels();
|
double width = project.getWidth().convertToPixels();
|
||||||
double height = project.getHeight().convertToPixels();
|
double height = project.getHeight().convertToPixels();
|
||||||
double targetExtraSpace = EXTRA_SPACE * Math.max(width, height);
|
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 width = project.getWidth().convertToPixels();
|
||||||
double height = project.getHeight().convertToPixels();
|
double height = project.getHeight().convertToPixels();
|
||||||
|
|
||||||
@@ -588,7 +661,7 @@ public class DrawingManager {
|
|||||||
|
|
||||||
width *= zoomLevel;
|
width *= zoomLevel;
|
||||||
height *= zoomLevel;
|
height *= zoomLevel;
|
||||||
|
|
||||||
return new Dimension((int) width, (int) height);
|
return new Dimension((int) width, (int) height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,7 +679,7 @@ public class DrawingManager {
|
|||||||
configManager.writeValue(IPlugInPort.THEME_KEY, theme);
|
configManager.writeValue(IPlugInPort.THEME_KEY, theme);
|
||||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void findContinuityAreaAtPoint(Project project, Point2D p) {
|
public void findContinuityAreaAtPoint(Project project, Point2D p) {
|
||||||
if (continuityAreaCache == null)
|
if (continuityAreaCache == null)
|
||||||
continuityAreaCache = getContinuityAreas(project);
|
continuityAreaCache = getContinuityAreas(project);
|
||||||
@@ -620,7 +693,7 @@ public class DrawingManager {
|
|||||||
|
|
||||||
currentContinuityArea = null;
|
currentContinuityArea = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Area> getContinuityAreas(Project project) {
|
public List<Area> getContinuityAreas(Project project) {
|
||||||
// Find all individual continuity areas for all components
|
// Find all individual continuity areas for all components
|
||||||
List<Area> preliminaryAreas = new ArrayList<Area>();
|
List<Area> preliminaryAreas = new ArrayList<Area>();
|
||||||
@@ -628,11 +701,11 @@ public class DrawingManager {
|
|||||||
Set<Connection> connections = new HashSet<Connection>();
|
Set<Connection> connections = new HashSet<Connection>();
|
||||||
for (IDIYComponent<?> c : project.getComponents()) {
|
for (IDIYComponent<?> c : project.getComponents()) {
|
||||||
ComponentArea a = getComponentArea(c);
|
ComponentArea a = getComponentArea(c);
|
||||||
|
|
||||||
if (c instanceof IContinuity) {
|
if (c instanceof IContinuity) {
|
||||||
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
||||||
for (int j = i + 1; j < c.getControlPointCount(); j++)
|
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)));
|
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,30 +727,32 @@ public class DrawingManager {
|
|||||||
checkBreakout.set(i, true);
|
checkBreakout.set(i, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we need to break some areas out in case they are interrupted
|
// Check if we need to break some areas out in case they are interrupted
|
||||||
List<Area> areas = new ArrayList<Area>();
|
List<Area> areas = new ArrayList<Area>();
|
||||||
for (int i = 0; i < preliminaryAreas.size(); i++) {
|
for (int i = 0; i < preliminaryAreas.size(); i++) {
|
||||||
Area a = preliminaryAreas.get(i);
|
Area a = preliminaryAreas.get(i);
|
||||||
if (checkBreakout.get(i))
|
if (checkBreakout.get(i))
|
||||||
areas.addAll(AreaUtils.tryAreaBreakout(a));
|
areas.addAll(AreaUtils.tryAreaBreakout(a));
|
||||||
else
|
else
|
||||||
areas.add(a);
|
areas.add(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
CalcUtils.expandConnections(connections);
|
CalcUtils.expandConnections(connections);
|
||||||
|
|
||||||
AreaUtils.crunchAreas(areas, connections);
|
AreaUtils.crunchAreas(areas, connections);
|
||||||
|
|
||||||
return areas;
|
return areas;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Area> getContinuityAreaProximity(Project project, float threshold) {
|
public List<Area> getContinuityAreaProximity(Project project, float threshold) {
|
||||||
List<Area> continuityAreas = getContinuityAreas(project);
|
List<Area> continuityAreas = getContinuityAreas(project);
|
||||||
Stroke s = ObjectCache.getInstance().fetchBasicStroke(threshold - 1); // value eyeballed for approx good results
|
Stroke s = ObjectCache.getInstance().fetchBasicStroke(threshold - 1); // value eyeballed for
|
||||||
List<Area> expanded = continuityAreas.parallelStream().map((a) -> new Area(s.createStrokedShape(a))).collect(Collectors.toList());
|
// approx good results
|
||||||
|
List<Area> expanded = continuityAreas.parallelStream()
|
||||||
|
.map((a) -> new Area(s.createStrokedShape(a))).collect(Collectors.toList());
|
||||||
List<Area> intersections = new ArrayList<Area>();
|
List<Area> intersections = new ArrayList<Area>();
|
||||||
for (int i = 0; i < expanded.size() - 1; i++) {
|
for (int i = 0; i < expanded.size() - 1; i++) {
|
||||||
for (int j = i + 1; j < expanded.size(); j++) {
|
for (int j = i + 1; j < expanded.size(); j++) {
|
||||||
@@ -688,25 +763,28 @@ public class DrawingManager {
|
|||||||
intersections.add(first);
|
intersections.add(first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AreaUtils.crunchAreas(intersections, null);
|
AreaUtils.crunchAreas(intersections, null);
|
||||||
double minSize = new Size(1d, SizeUnit.cm).convertToPixels();
|
double minSize = new Size(1d, SizeUnit.cm).convertToPixels();
|
||||||
|
|
||||||
List<Area> shapes = new ArrayList<Area>();
|
List<Area> shapes = new ArrayList<Area>();
|
||||||
for (Area a : intersections) {
|
for (Area a : intersections) {
|
||||||
Rectangle2D bounds2d = a.getBounds2D();
|
Rectangle2D bounds2d = a.getBounds2D();
|
||||||
if (bounds2d.getWidth() < minSize)
|
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)
|
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;
|
this.proximityMarkers = shapes;
|
||||||
|
|
||||||
return shapes;
|
return shapes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3801,5 +3801,21 @@
|
|||||||
</changes>
|
</changes>
|
||||||
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
<url>https://github.com/bancika/diy-layout-creator/releases</url>
|
||||||
</org.diylc.appframework.update.Version>
|
</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>
|
</a>
|
||||||
</java.util.Arrays_-ArrayList>
|
</java.util.Arrays_-ArrayList>
|
||||||
|
|||||||
Binary file not shown.
@@ -23,10 +23,8 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.awt.geom.Area;
|
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
|
||||||
import org.diylc.appframework.miscutils.ConfigurationManager;
|
import org.diylc.appframework.miscutils.ConfigurationManager;
|
||||||
import org.diylc.awt.StringUtils;
|
import org.diylc.awt.StringUtils;
|
||||||
import org.diylc.common.HorizontalAlignment;
|
import org.diylc.common.HorizontalAlignment;
|
||||||
@@ -259,14 +257,26 @@ public abstract class AbstractGuitarPickup extends AbstractLabeledComponent<Stri
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Rectangle2D getCachingBounds() {
|
public Rectangle2D getCachingBounds() {
|
||||||
Area area = new Area();
|
|
||||||
Shape[] body = getBody();
|
Shape[] body = getBody();
|
||||||
int margin = 20;
|
int margin = 20;
|
||||||
for (Shape a : body)
|
double minX = 0;
|
||||||
if (a != null)
|
double minY = 0;
|
||||||
area.add(new Area(a));
|
double maxX = 0;
|
||||||
Rectangle2D bounds = area.getBounds2D();
|
double maxY = 0;
|
||||||
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
|
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 {
|
public enum Polarity {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.awt.Composite;
|
|||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Polygon;
|
import java.awt.Polygon;
|
||||||
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Area;
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
@@ -477,14 +478,26 @@ public class PotentiometerPanel extends AbstractPotentiometer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Rectangle2D getCachingBounds() {
|
public Rectangle2D getCachingBounds() {
|
||||||
Area area = new Area();
|
Shape[] body = getBody();
|
||||||
Area[] body = getBody();
|
|
||||||
int margin = 20;
|
int margin = 20;
|
||||||
for (Area a : body)
|
double minX = 0;
|
||||||
if (a != null)
|
double minY = 0;
|
||||||
area.add(a);
|
double maxX = 0;
|
||||||
Rectangle2D bounds = area.getBounds2D();
|
double maxY = 0;
|
||||||
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
|
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
|
@Override
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.awt.FontMetrics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.Shape;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.awt.geom.Area;
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
@@ -367,13 +368,25 @@ public class TransistorTO3 extends AbstractLabeledComponent<String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Rectangle2D getCachingBounds() {
|
public Rectangle2D getCachingBounds() {
|
||||||
Area area = new Area();
|
Shape[] body = getBody();
|
||||||
Area[] body = getBody();
|
|
||||||
int margin = 20;
|
int margin = 20;
|
||||||
for (Area a : body)
|
double minX = 0;
|
||||||
if (a != null)
|
double minY = 0;
|
||||||
area.add(a);
|
double maxX = 0;
|
||||||
Rectangle2D bounds = area.getBounds2D();
|
double maxY = 0;
|
||||||
return new Rectangle2D.Double(bounds.getX() - margin, bounds.getY() - margin, bounds.getWidth() + 2 * margin, bounds.getHeight() + 2 * margin);
|
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"/>
|
<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.MAIN_TYPE" value="org.diylc.RegressionTestRunner"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="diylc-swing"/>
|
<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"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="diylc-swing"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user