|
8 | 8 | import org.eclipse.draw2d.FreeformFigure; |
9 | 9 | import org.eclipse.draw2d.IFigure; |
10 | 10 | import org.eclipse.draw2d.SWTGraphics; |
| 11 | +import org.eclipse.draw2d.geometry.Dimension; |
11 | 12 | import org.eclipse.draw2d.geometry.Rectangle; |
12 | 13 | import org.eclipse.gef.EditPartFactory; |
13 | 14 | import org.eclipse.gef.GraphicalViewer; |
|
16 | 17 | import org.eclipse.gef.editparts.FreeformGraphicalRootEditPart; |
17 | 18 | import org.eclipse.gef.editparts.LayerManager; |
18 | 19 | import org.eclipse.gef.ui.parts.GraphicalViewerImpl; |
19 | | -import org.eclipse.swt.graphics.AutoscalingMode; |
20 | 20 | import org.eclipse.swt.graphics.GC; |
21 | 21 | import org.eclipse.swt.graphics.Image; |
22 | | -import org.eclipse.swt.layout.FillLayout; |
| 22 | +import org.eclipse.swt.graphics.ImageData; |
| 23 | +import org.eclipse.swt.internal.DPIUtil; |
23 | 24 | import org.eclipse.swt.widgets.Composite; |
24 | | -import org.eclipse.swt.widgets.Display; |
25 | 25 | import org.eclipse.swt.widgets.Shell; |
26 | 26 |
|
27 | 27 | import com.archimatetool.editor.diagram.DiagramEditorFactoryExtensionHandler; |
28 | 28 | import com.archimatetool.editor.diagram.IDiagramEditorFactory; |
29 | 29 | import com.archimatetool.editor.diagram.editparts.ArchimateDiagramEditPartFactory; |
| 30 | +import com.archimatetool.editor.diagram.figures.FigureUtils; |
30 | 31 | import com.archimatetool.editor.diagram.sketch.editparts.SketchEditPartFactory; |
31 | 32 | import com.archimatetool.model.IArchimateDiagramModel; |
32 | 33 | import com.archimatetool.model.IDiagramModel; |
@@ -70,8 +71,7 @@ else if(model instanceof ISketchModel) { |
70 | 71 | } |
71 | 72 |
|
72 | 73 | GraphicalViewerImpl viewer = new GraphicalViewerImpl(); |
73 | | - viewer.createControl(parent).setAutoscalingMode(AutoscalingMode.ENABLED); // Stops text clipping on Windows |
74 | | - |
| 74 | + viewer.createControl(parent); |
75 | 75 | viewer.setEditPartFactory(editPartFactory); |
76 | 76 |
|
77 | 77 | RootEditPart rootPart = new FreeformGraphicalRootEditPart(); |
@@ -105,13 +105,13 @@ public static Image createImage(IDiagramModel model, double scale, int margin) { |
105 | 105 | */ |
106 | 106 | public static ModelReferencedImage createModelReferencedImage(IDiagramModel model, double scale, int margin) { |
107 | 107 | Shell shell = new Shell(); |
108 | | - shell.setLayout(new FillLayout()); |
109 | | - |
110 | | - GraphicalViewer viewer = createViewer(model, shell); |
111 | | - ModelReferencedImage image = createModelReferencedImage(viewer, scale, margin); |
112 | | - shell.dispose(); |
113 | | - |
114 | | - return image; |
| 108 | + try { |
| 109 | + GraphicalViewer viewer = createViewer(model, shell); |
| 110 | + return createModelReferencedImage(viewer, scale, margin); |
| 111 | + } |
| 112 | + finally { |
| 113 | + shell.dispose(); |
| 114 | + } |
115 | 115 | } |
116 | 116 |
|
117 | 117 | /** |
@@ -155,27 +155,84 @@ private static ModelReferencedImage createModelReferencedImage(IFigure figure, d |
155 | 155 | bounds.expand(margin / scale, margin / scale); |
156 | 156 | } |
157 | 157 |
|
158 | | - Image image = new Image(Display.getDefault(), (int)(bounds.width * scale), (int)(bounds.height * scale)); |
| 158 | + // On Windows use the scaled method else just create image with scale |
| 159 | + Image image = FigureUtils.isAutoScaleEnabled() ? createAutoScaledImage(figure, bounds, scale) : createImageAtScale(figure, bounds, 1.0, scale); |
| 160 | + return new ModelReferencedImage(image, bounds); |
| 161 | + } |
| 162 | + |
| 163 | + /** |
| 164 | + * Create a scaled image on Windows depending on device zoom |
| 165 | + * Comes from https://github.com/eclipse-gef/gef-classic/discussions/1151 |
| 166 | + */ |
| 167 | + @SuppressWarnings("restriction") |
| 168 | + private static Image createAutoScaledImage(IFigure figure, Rectangle bounds, double imageScale) { |
| 169 | + int deviceZoom = DPIUtil.getDeviceZoom(); |
| 170 | + double displayScale = deviceZoom / 100.0; |
| 171 | + |
| 172 | + // Create the image at scale |
| 173 | + Image imageZoom = createImageAtScale(figure, bounds, displayScale, imageScale); |
| 174 | + |
| 175 | + // If device zoom is 100% no need for any more processing |
| 176 | + if(deviceZoom == 100) { |
| 177 | + return imageZoom; |
| 178 | + } |
| 179 | + |
| 180 | + // Image is stored at 100% zoom, but is scaled by the monitor zoom |
| 181 | + ImageData imageDataZoom = imageZoom.getImageData(100); |
| 182 | + Image tmp = new Image(null, imageDataZoom); |
| 183 | + imageZoom.dispose(); |
| 184 | + |
| 185 | + int width100 = imageDataZoom.width * 100 / deviceZoom; |
| 186 | + int height100 = imageDataZoom.height * 100 / deviceZoom; |
| 187 | + Image image = new Image(null, width100, height100); |
| 188 | + |
159 | 189 | GC gc = new GC(image); |
160 | | - SWTGraphics graphics = new ImageGraphics(gc); // Use ImageGraphics so we can get actual scale |
| 190 | + image.getImageData(deviceZoom); |
| 191 | + gc.drawImage(tmp, 0, 0, width100, height100); |
| 192 | + gc.dispose(); |
| 193 | + |
| 194 | + tmp.dispose(); |
161 | 195 |
|
162 | | - if(scale != 1) { |
163 | | - graphics.scale(scale); |
| 196 | + return image; |
| 197 | + } |
| 198 | + |
| 199 | + /** |
| 200 | + * Create a scaled image |
| 201 | + * Parts from https://github.com/eclipse-gef/gef-classic/discussions/1151 |
| 202 | + */ |
| 203 | + private static Image createImageAtScale(IFigure figure, Rectangle bounds, double displayScale, double imageScale) { |
| 204 | + Dimension size = bounds.getSize(); |
| 205 | + |
| 206 | + // Scale size by display scale * image scale |
| 207 | + size.scale(displayScale * imageScale); |
| 208 | + |
| 209 | + Image image = new Image(null, size.width, size.height); |
| 210 | + |
| 211 | + GC gc = new GC(image); |
| 212 | + |
| 213 | + // Force image to be drawn as if at 100% zoom |
| 214 | + // This is the magic that stops text clipping |
| 215 | + if(FigureUtils.isAutoScaleEnabled()) { |
| 216 | + image.getImageData(100); |
164 | 217 | } |
| 218 | + |
| 219 | + SWTGraphics graphics = new ImageGraphics(gc); |
| 220 | + |
| 221 | + // Scale by display and image scale |
| 222 | + graphics.scale(displayScale * imageScale); |
165 | 223 |
|
166 | 224 | // Compensate for negative co-ordinates |
167 | 225 | graphics.translate(bounds.x * -1, bounds.y * -1); |
168 | | - |
169 | | - // Paint onto graphics |
170 | | - figure.paint(graphics); |
171 | 226 |
|
172 | | - // Dispose |
173 | | - gc.dispose(); |
| 227 | + // Paint figure |
| 228 | + figure.paint(graphics); |
| 229 | + |
174 | 230 | graphics.dispose(); |
| 231 | + gc.dispose(); |
175 | 232 |
|
176 | | - return new ModelReferencedImage(image, bounds); |
| 233 | + return image; |
177 | 234 | } |
178 | | - |
| 235 | + |
179 | 236 | /** |
180 | 237 | * Return the extents of the diagram by extending from the left-topmost child to the right-bottom-most child. |
181 | 238 | * If there are no children in the diagram a minimal size of 100x100 is returned. |
|
0 commit comments