Skip to content

Commit 577b1d6

Browse files
committed
GC#drawImage methods now consider applied Transformations
If a transform is applied via the GC, then both drawImage APIs consider now the best fitting handle by requesting it through the width/height of the full image scaled by the scaleFactor (relating destination width/height to source winowdth/height) times the width/height scaling induced by the transformation.
1 parent c205219 commit 577b1d6

1 file changed

Lines changed: 220 additions & 122 deletions

File tree

  • examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets

examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet389.java

Lines changed: 220 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
package org.eclipse.swt.snippets;
1212

1313
import org.eclipse.swt.*;
14+
import org.eclipse.swt.events.*;
1415
import org.eclipse.swt.graphics.*;
1516
import org.eclipse.swt.layout.*;
1617
import org.eclipse.swt.widgets.*;
@@ -20,7 +21,9 @@
2021
*
2122
* The GC provides two relevant drawImage methods: one that scales an entire
2223
* image to a destination rectangle, and another that crops a source region and
23-
* scales it to the destination.
24+
* scales it to the destination. The snippet allows to select any source area
25+
* of an image and draw it to a specific target size. Additionally you can scale
26+
* it additionally to the selected target size and rotate the image.
2427
*
2528
* This snippet allows experimenting with different source and destination
2629
* values for the second method. Within the method, the GC receives the
@@ -39,11 +42,8 @@ public class Snippet389 {
3942
private static final String IMAGE_PATH_100 = IMAGES_ROOT + IMAGE_100;
4043
private static final String IMAGE_PATH_200 = IMAGES_ROOT + IMAGE_200;
4144

42-
static int srcX, srcY, srcW, srcH;
43-
static int dstX, dstY, dstW, dstH;
44-
4545
public static void main(String[] args) {
46-
46+
Display display = new Display();
4747
ImageFileNameProvider filenameProvider = zoom -> {
4848
switch (zoom) {
4949
case 100:
@@ -54,113 +54,12 @@ public static void main(String[] args) {
5454
return null;
5555
}
5656
};
57-
58-
Display display = new Display();
59-
Shell shell = new Shell(display);
60-
shell.setText("GC#drawImage Interactive");
61-
shell.setLayout(new GridLayout(2, false));
62-
6357
Image image = new Image(display, filenameProvider);
64-
Rectangle imgBounds = image.getBounds();
65-
66-
final int fixedDstW = imgBounds.width * 2;
67-
final int fixedDstH = imgBounds.height * 2;
68-
srcX = imgBounds.width / 2;
69-
srcY = imgBounds.height / 2;
70-
srcW = imgBounds.width / 2;
71-
srcH = imgBounds.height / 2;
72-
73-
dstX = 0;
74-
dstY = 0;
75-
dstW = imgBounds.width;
76-
dstH = imgBounds.height;
77-
78-
Group controls = new Group(shell, SWT.NONE);
79-
controls.setText("GC#drawImage Arguments");
80-
controls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
81-
controls.setLayout(new GridLayout(2, false));
82-
83-
Text tSrcX = field(controls, "srcX", srcX);
84-
Text tSrcY = field(controls, "srcY", srcY);
85-
Text tSrcW = field(controls, "srcWidth", srcW);
86-
Text tSrcH = field(controls, "srcHeight", srcH);
87-
88-
Text tDstX = field(controls, "destX", dstX);
89-
Text tDstY = field(controls, "destY", dstY);
90-
Text tDstW = field(controls, "destWidth", dstW);
91-
Text tDstH = field(controls, "destHeight", dstH);
92-
93-
Button apply = new Button(controls, SWT.PUSH);
94-
apply.setText("Apply");
95-
apply.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
96-
97-
Composite draw = new Composite(shell, SWT.NONE);
98-
draw.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
99-
draw.setLayout(new GridLayout(2, true));
100-
101-
Canvas srcCanvas = new Canvas(draw, SWT.BORDER);
102-
srcCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
103-
srcCanvas.addListener(SWT.Paint, e -> {
104-
GC gc = e.gc;
105-
Rectangle ca = srcCanvas.getClientArea();
106-
107-
int ix = (ca.width - imgBounds.width) / 2;
108-
int iy = (ca.height - imgBounds.height) / 2;
109-
110-
gc.drawImage(image, ix, iy);
111-
112-
gc.setLineStyle(SWT.LINE_DASH);
113-
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
114-
gc.drawRectangle(ix, iy, imgBounds.width, imgBounds.height);
115-
116-
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
117-
gc.setLineWidth(2);
118-
gc.drawRectangle(ix + srcX, iy + srcY, srcW, srcH);
119-
});
120-
121-
Canvas dstCanvas = new Canvas(draw, SWT.BORDER);
122-
dstCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
123-
dstCanvas.addListener(SWT.Paint, e -> {
124-
GC gc = e.gc;
125-
Rectangle ca = dstCanvas.getClientArea();
126-
127-
int px = (ca.width - fixedDstW) / 2;
128-
int py = (ca.height - fixedDstH) / 2;
129-
130-
gc.drawImage(image, srcX, srcY, srcW, srcH, px + dstX, py + dstY, dstW, dstH);
131-
132-
gc.setLineStyle(SWT.LINE_DASH);
133-
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
134-
gc.drawRectangle(px, py, fixedDstW, fixedDstH);
135-
136-
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
137-
gc.setLineWidth(2);
138-
gc.drawRectangle(px + dstX, py + dstY, dstW, dstH);
139-
});
140-
141-
Label srcLabel = new Label(draw, SWT.CENTER);
142-
srcLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
143-
srcLabel.setText("150 x 150");
144-
145-
Label dstLabel = new Label(draw, SWT.CENTER);
146-
dstLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
147-
dstLabel.setText("300 x 300");
148-
149-
apply.addListener(SWT.Selection, e -> {
150-
srcX = parse(tSrcX);
151-
srcY = parse(tSrcY);
152-
srcW = parse(tSrcW);
153-
srcH = parse(tSrcH);
154-
155-
dstX = parse(tDstX);
156-
dstY = parse(tDstY);
157-
dstW = parse(tDstW);
158-
dstH = parse(tDstH);
159-
160-
srcCanvas.redraw();
161-
dstCanvas.redraw();
162-
});
58+
Shell shell = new Shell();
59+
shell.setLayout(new FillLayout());
60+
shell.setText("GC#drawImage Interactive");
16361

62+
new CropImageView(shell, image);
16463
shell.setSize(1000, 600);
16564
shell.open();
16665

@@ -173,19 +72,218 @@ public static void main(String[] args) {
17372
display.dispose();
17473
}
17574

176-
static Text field(Composite parent, String label, int value) {
177-
new Label(parent, SWT.NONE).setText(label);
178-
Text t = new Text(parent, SWT.BORDER);
179-
t.setText(String.valueOf(value));
180-
t.setLayoutData(new GridData(70, SWT.DEFAULT));
181-
return t;
182-
}
75+
private static class CropImageView extends Composite {
76+
77+
private Image image;
78+
private int srcX, srcY, srcW, srcH;
79+
private int dstX, dstY, dstW, dstH;
80+
private float transformationScale;
81+
private int transformationRotation;
82+
private Text textSrcX, textSrcY, textSrcW, textSrcH;
83+
private Text textDstX, textDstY, textDstW, textDstH;
84+
private Text textScale;
85+
private Slider rotationSlider;
86+
private Canvas srcCanvas;
87+
private Canvas dstCanvas;
88+
89+
public CropImageView(Composite parent, Image image) {
90+
super(parent, SWT.None);
91+
this.image = image;
92+
init();
93+
}
94+
95+
private void init() {
96+
setLayout(new GridLayout(2, false));
97+
98+
Rectangle imgBounds = image.getBounds();
99+
100+
final int fixedDstW = imgBounds.width * 2;
101+
final int fixedDstH = imgBounds.height * 2;
102+
srcX = imgBounds.width / 2;
103+
srcY = imgBounds.height / 2;
104+
srcW = imgBounds.width / 2;
105+
srcH = imgBounds.height / 2;
106+
107+
dstX = 0;
108+
dstY = 0;
109+
dstW = imgBounds.width;
110+
dstH = imgBounds.height;
111+
112+
transformationScale = 1;
113+
transformationRotation = 0;
114+
115+
Group controls = new Group(this, SWT.NONE);
116+
controls.setText("GC#drawImage Arguments");
117+
controls.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
118+
controls.setLayout(new GridLayout(2, false));
119+
120+
textSrcX = field(controls, "srcX", srcX);
121+
textSrcY = field(controls, "srcY", srcY);
122+
textSrcW = field(controls, "srcWidth", srcW);
123+
textSrcH = field(controls, "srcHeight", srcH);
124+
125+
textDstX = field(controls, "destX", dstX);
126+
textDstY = field(controls, "destY", dstY);
127+
textDstW = field(controls, "destWidth", dstW);
128+
textDstH = field(controls, "destHeight", dstH);
129+
130+
textScale = field(controls, "Scale Factor", transformationScale);
131+
rotationSlider = slider(controls, "Rotation", transformationRotation, 361);
132+
133+
Button apply = new Button(controls, SWT.PUSH);
134+
apply.setText("Apply");
135+
apply.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
136+
137+
Composite draw = new Composite(this, SWT.NONE);
138+
draw.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
139+
draw.setLayout(new GridLayout(2, true));
140+
141+
srcCanvas = new Canvas(draw, SWT.BORDER);
142+
srcCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
143+
srcCanvas.addListener(SWT.Paint, e -> {
144+
try {
145+
GC gc = e.gc;
146+
Rectangle ca = srcCanvas.getClientArea();
147+
148+
int ix = (ca.width - imgBounds.width) / 2;
149+
int iy = (ca.height - imgBounds.height) / 2;
150+
Transform translationTransform = new Transform(getDisplay());
151+
translationTransform.translate(ix, iy);
152+
gc.setTransform(translationTransform);
153+
gc.drawImage(image, 0, 0);
154+
155+
gc.setLineStyle(SWT.LINE_DASH);
156+
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
157+
gc.drawRectangle(0, 0, imgBounds.width, imgBounds.height);
158+
159+
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_RED));
160+
gc.setLineWidth(2);
161+
gc.drawRectangle(srcX, srcY, srcW, srcH);
162+
} catch (Exception ex) {
163+
MessageBox box = new MessageBox(getShell());
164+
box.setText("Invalid values");
165+
box.setMessage("There seem to be invalid value, the images cannot be drawn.");
166+
box.open();
167+
}
168+
});
169+
170+
dstCanvas = new Canvas(draw, SWT.BORDER);
171+
dstCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
172+
dstCanvas.addListener(SWT.Paint, e -> {
173+
try {
174+
GC gc = e.gc;
175+
Rectangle ca = dstCanvas.getClientArea();
176+
177+
int px = (ca.width - fixedDstW) / 2;
178+
int py = (ca.height - fixedDstH) / 2;
179+
Transform translationTransform = new Transform(getDisplay());
180+
translationTransform.translate(px + dstX, py + dstY);
181+
182+
translationTransform.translate(fixedDstW / 2f, fixedDstH / 2f);
183+
if (transformationScale > 1) {
184+
translationTransform.scale(transformationScale, transformationScale);
185+
}
186+
if (transformationRotation != 0) {
187+
translationTransform.rotate(transformationRotation);
188+
}
189+
translationTransform.translate(-fixedDstW / 2f, -fixedDstH / 2f);
190+
gc.setTransform(translationTransform);
191+
192+
Rectangle imageBounds = image.getBounds();
193+
if (imageBounds.equals(new Rectangle(srcX, srcY, srcW, srcH))) {
194+
gc.drawImage(image, 0, 0, dstW, dstH);
195+
} else {
196+
gc.drawImage(image, srcX, srcY, srcW, srcH, 0, 0, dstW, dstH);
197+
}
198+
199+
gc.setLineStyle(SWT.LINE_DASH);
200+
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
201+
gc.drawRectangle(0, 0, fixedDstW, fixedDstH);
202+
203+
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_RED));
204+
gc.setLineWidth(2);
205+
gc.drawRectangle(0, 0, dstW, dstH);
206+
} catch (Exception ex) {
207+
MessageBox box = new MessageBox(getShell());
208+
box.setText("Invalid values");
209+
box.setMessage("There seem to be invalid value, the images cannot be drawn.");
210+
box.open();
211+
}
212+
});
213+
214+
Label srcLabel = new Label(draw, SWT.CENTER);
215+
srcLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
216+
srcLabel.setText("150 x 150");
217+
218+
Label dstLabel = new Label(draw, SWT.CENTER);
219+
dstLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
220+
dstLabel.setText("300 x 300");
221+
222+
apply.addListener(SWT.Selection, e -> {
223+
refreshView();
224+
});
225+
}
183226

184-
static int parse(Text t) {
185-
try {
186-
return Integer.parseInt(t.getText());
187-
} catch (NumberFormatException e) {
188-
return 0;
227+
private void refreshView() {
228+
srcX = parseInt(textSrcX);
229+
srcY = parseInt(textSrcY);
230+
srcW = parseInt(textSrcW);
231+
srcH = parseInt(textSrcH);
232+
233+
dstX = parseInt(textDstX);
234+
dstY = parseInt(textDstY);
235+
dstW = parseInt(textDstW);
236+
dstH = parseInt(textDstH);
237+
238+
transformationScale = parseFloat(textScale);
239+
transformationRotation = rotationSlider.getSelection();
240+
241+
srcCanvas.redraw();
242+
dstCanvas.redraw();
243+
}
244+
245+
Text field(Composite parent, String label, Number value) {
246+
new Label(parent, SWT.NONE).setText(label);
247+
Text t = new Text(parent, SWT.BORDER);
248+
t.setText(value.toString());
249+
t.setLayoutData(new GridData(70, SWT.DEFAULT));
250+
return t;
251+
}
252+
253+
Slider slider(Composite parent, String text, int value, int maxValue) {
254+
Label label = new Label(parent, SWT.NONE);
255+
label.setText(text);
256+
label.setLayoutData(new GridData());
257+
258+
Slider slider = new Slider(parent, SWT.BORDER);
259+
GridData gd = new GridData();
260+
gd.grabExcessHorizontalSpace = true;
261+
gd.horizontalSpan = 2;
262+
slider.setLayoutData(gd);
263+
slider.setValues(value, 0, maxValue, 1, 1, 1);
264+
slider.addSelectionListener(new SelectionAdapter() {
265+
@Override
266+
public void widgetSelected(SelectionEvent e) {
267+
refreshView();
268+
}
269+
});
270+
return slider;
271+
}
272+
273+
int parseInt(Text t) {
274+
try {
275+
return Integer.parseInt(t.getText());
276+
} catch (NumberFormatException e) {
277+
return 0;
278+
}
279+
}
280+
281+
float parseFloat(Text t) {
282+
try {
283+
return Float.parseFloat(t.getText());
284+
} catch (NumberFormatException e) {
285+
return 0;
286+
}
189287
}
190288
}
191289
}

0 commit comments

Comments
 (0)