Skip to content

Commit 65d2379

Browse files
committed
implements Image.getScaledInstance; fixes DOMNode.getImageNode
1 parent 6aa6916 commit 65d2379

File tree

4 files changed

+289
-20
lines changed

4 files changed

+289
-20
lines changed

sources/net.sf.j2s.java.core/src/java/awt/Image.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
*/
2828
package java.awt;
2929

30+
import java.awt.image.AreaAveragingScaleFilter;
31+
import java.awt.image.FilteredImageSource;
32+
import java.awt.image.ImageFilter;
3033
import java.awt.image.ImageObserver;
3134
import java.awt.image.ImageProducer;
35+
import java.awt.image.ReplicateScaleFilter;
3236

3337

3438
/**
@@ -164,16 +168,15 @@ public abstract class Image {
164168
* @since JDK1.1
165169
*/
166170
public Image getScaledInstance(int width, int height, int hints) {
167-
// ImageFilter filter;
168-
// if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
169-
// filter = new AreaAveragingScaleFilter(width, height);
170-
// } else {
171-
// filter = new ReplicateScaleFilter(width, height);
172-
// }
173-
// ImageProducer prod;
174-
// prod = new FilteredImageSource(getSource(), filter);
175-
// return Toolkit.getDefaultToolkit().createImage(prod);
176-
return null;
171+
ImageFilter filter;
172+
if ((hints & (SCALE_SMOOTH | SCALE_AREA_AVERAGING)) != 0) {
173+
filter = new AreaAveragingScaleFilter(width, height);
174+
} else {
175+
filter = new ReplicateScaleFilter(width, height);
176+
}
177+
ImageProducer prod;
178+
prod = new FilteredImageSource(getSource(), filter);
179+
return Toolkit.getDefaultToolkit().createImage(prod);
177180
}
178181

179182
/**

sources/net.sf.j2s.java.core/src/java/awt/image/ImageFilter.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ public ImageFilter getFilterInstance(ImageConsumer ic) {
8686
* with the filtering operation.
8787
* @see ImageConsumer#setDimensions
8888
*/
89-
public void setDimensions(int width, int height) {
89+
@Override
90+
public void setDimensions(int width, int height) {
9091
consumer.setDimensions(width, height);
9192
}
9293

@@ -103,7 +104,8 @@ public void setDimensions(int width, int height) {
103104
* @param props the properties from the source object
104105
* @exception NullPointerException if <code>props</code> is null
105106
*/
106-
public void setProperties(Hashtable<?,?> props) {
107+
@Override
108+
public void setProperties(Hashtable<?,?> props) {
107109
Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone();
108110
Object o = p.get("filters");
109111
if (o == null) {
@@ -125,7 +127,8 @@ public void setProperties(Hashtable<?,?> props) {
125127
* with the filtering operation.
126128
* @see ImageConsumer#setColorModel
127129
*/
128-
public void setColorModel(ColorModel model) {
130+
@Override
131+
public void setColorModel(ColorModel model) {
129132
consumer.setColorModel(model);
130133
}
131134

@@ -140,7 +143,8 @@ public void setColorModel(ColorModel model) {
140143
* with the filtering operation.
141144
* @see ImageConsumer#setHints
142145
*/
143-
public void setHints(int hints) {
146+
@Override
147+
public void setHints(int hints) {
144148
consumer.setHints(hints);
145149
}
146150

@@ -155,7 +159,8 @@ public void setHints(int hints) {
155159
* with the filtering operation.
156160
* @see ImageConsumer#setPixels
157161
*/
158-
public void setPixels(int x, int y, int w, int h,
162+
@Override
163+
public void setPixels(int x, int y, int w, int h,
159164
ColorModel model, byte pixels[], int off,
160165
int scansize) {
161166
consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
@@ -172,7 +177,8 @@ public void setPixels(int x, int y, int w, int h,
172177
* with the filtering operation.
173178
* @see ImageConsumer#setPixels
174179
*/
175-
public void setPixels(int x, int y, int w, int h,
180+
@Override
181+
public void setPixels(int x, int y, int w, int h,
176182
ColorModel model, int pixels[], int off,
177183
int scansize) {
178184
consumer.setPixels(x, y, w, h, model, pixels, off, scansize);
@@ -189,7 +195,8 @@ public void setPixels(int x, int y, int w, int h,
189195
* with the filtering operation.
190196
* @see ImageConsumer#imageComplete
191197
*/
192-
public void imageComplete(int status) {
198+
@Override
199+
public void imageComplete(int status) {
193200
consumer.imageComplete(status);
194201
}
195202

@@ -247,7 +254,8 @@ public void resendTopDownLeftRight(ImageProducer ip) {
247254
/**
248255
* Clones this object.
249256
*/
250-
public Object clone() {
257+
@Override
258+
public Object clone() {
251259
try {
252260
return super.clone();
253261
} catch (CloneNotSupportedException e) {
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
/*
2+
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package java.awt.image;
27+
28+
import java.util.Hashtable;
29+
30+
/**
31+
* An ImageFilter class for scaling images using the simplest algorithm.
32+
* This class extends the basic ImageFilter Class to scale an existing
33+
* image and provide a source for a new image containing the resampled
34+
* image. The pixels in the source image are sampled to produce pixels
35+
* for an image of the specified size by replicating rows and columns of
36+
* pixels to scale up or omitting rows and columns of pixels to scale
37+
* down.
38+
* <p>It is meant to be used in conjunction with a FilteredImageSource
39+
* object to produce scaled versions of existing images. Due to
40+
* implementation dependencies, there may be differences in pixel values
41+
* of an image filtered on different platforms.
42+
*
43+
* @see FilteredImageSource
44+
* @see ImageFilter
45+
*
46+
* @author Jim Graham
47+
*/
48+
public class ReplicateScaleFilter extends ImageFilter {
49+
50+
/**
51+
* The width of the source image.
52+
*/
53+
protected int srcWidth;
54+
55+
/**
56+
* The height of the source image.
57+
*/
58+
protected int srcHeight;
59+
60+
/**
61+
* The target width to scale the image.
62+
*/
63+
protected int destWidth;
64+
65+
/**
66+
* The target height to scale the image.
67+
*/
68+
protected int destHeight;
69+
70+
/**
71+
* An <code>int</code> array containing information about a
72+
* row of pixels.
73+
*/
74+
protected int srcrows[];
75+
76+
/**
77+
* An <code>int</code> array containing information about a
78+
* column of pixels.
79+
*/
80+
protected int srccols[];
81+
82+
/**
83+
* A <code>byte</code> array initialized with a size of
84+
* {@link #destWidth} and used to deliver a row of pixel
85+
* data to the {@link ImageConsumer}.
86+
*/
87+
protected Object outpixbuf;
88+
89+
/**
90+
* Constructs a ReplicateScaleFilter that scales the pixels from
91+
* its source Image as specified by the width and height parameters.
92+
* @param width the target width to scale the image
93+
* @param height the target height to scale the image
94+
* @throws IllegalArgumentException if <code>width</code> equals
95+
* zero or <code>height</code> equals zero
96+
*/
97+
public ReplicateScaleFilter(int width, int height) {
98+
if (width == 0 || height == 0) {
99+
throw new IllegalArgumentException("Width ("+width+
100+
") and height ("+height+
101+
") must be non-zero");
102+
}
103+
destWidth = width;
104+
destHeight = height;
105+
}
106+
107+
/**
108+
* Passes along the properties from the source object after adding a
109+
* property indicating the scale applied.
110+
* This method invokes <code>super.setProperties</code>,
111+
* which might result in additional properties being added.
112+
* <p>
113+
* Note: This method is intended to be called by the
114+
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
115+
* are being filtered. Developers using
116+
* this class to filter pixels from an image should avoid calling
117+
* this method directly since that operation could interfere
118+
* with the filtering operation.
119+
*/
120+
@Override
121+
public void setProperties(Hashtable<?,?> props) {
122+
Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone();
123+
String key = "rescale";
124+
String val = destWidth + "x" + destHeight;
125+
Object o = p.get(key);
126+
if (o != null && o instanceof String) {
127+
val = ((String) o) + ", " + val;
128+
}
129+
p.put(key, val);
130+
super.setProperties(p);
131+
}
132+
133+
/**
134+
* Override the dimensions of the source image and pass the dimensions
135+
* of the new scaled size to the ImageConsumer.
136+
* <p>
137+
* Note: This method is intended to be called by the
138+
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
139+
* are being filtered. Developers using
140+
* this class to filter pixels from an image should avoid calling
141+
* this method directly since that operation could interfere
142+
* with the filtering operation.
143+
* @see ImageConsumer
144+
*/
145+
@Override
146+
public void setDimensions(int w, int h) {
147+
srcWidth = w;
148+
srcHeight = h;
149+
if (destWidth < 0) {
150+
if (destHeight < 0) {
151+
destWidth = srcWidth;
152+
destHeight = srcHeight;
153+
} else {
154+
destWidth = srcWidth * destHeight / srcHeight;
155+
}
156+
} else if (destHeight < 0) {
157+
destHeight = srcHeight * destWidth / srcWidth;
158+
}
159+
consumer.setDimensions(destWidth, destHeight);
160+
}
161+
162+
private void calculateMaps() {
163+
srcrows = new int[destHeight + 1];
164+
for (int y = 0; y <= destHeight; y++) {
165+
srcrows[y] = (2 * y * srcHeight + srcHeight) / (2 * destHeight);
166+
}
167+
srccols = new int[destWidth + 1];
168+
for (int x = 0; x <= destWidth; x++) {
169+
srccols[x] = (2 * x * srcWidth + srcWidth) / (2 * destWidth);
170+
}
171+
}
172+
173+
/**
174+
* Choose which rows and columns of the delivered byte pixels are
175+
* needed for the destination scaled image and pass through just
176+
* those rows and columns that are needed, replicated as necessary.
177+
* <p>
178+
* Note: This method is intended to be called by the
179+
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
180+
* are being filtered. Developers using
181+
* this class to filter pixels from an image should avoid calling
182+
* this method directly since that operation could interfere
183+
* with the filtering operation.
184+
*/
185+
@Override
186+
public void setPixels(int x, int y, int w, int h,
187+
ColorModel model, byte pixels[], int off,
188+
int scansize) {
189+
if (srcrows == null || srccols == null) {
190+
calculateMaps();
191+
}
192+
int sx, sy;
193+
int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * srcWidth);
194+
int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * srcHeight);
195+
byte outpix[];
196+
if (outpixbuf != null && outpixbuf instanceof byte[]) {
197+
outpix = (byte[]) outpixbuf;
198+
} else {
199+
outpix = new byte[destWidth];
200+
outpixbuf = outpix;
201+
}
202+
for (int dy = dy1; (sy = srcrows[dy]) < y + h; dy++) {
203+
int srcoff = off + scansize * (sy - y);
204+
int dx;
205+
for (dx = dx1; (sx = srccols[dx]) < x + w; dx++) {
206+
outpix[dx] = pixels[srcoff + sx - x];
207+
}
208+
if (dx > dx1) {
209+
consumer.setPixels(dx1, dy, dx - dx1, 1,
210+
model, outpix, dx1, destWidth);
211+
}
212+
}
213+
}
214+
215+
/**
216+
* Choose which rows and columns of the delivered int pixels are
217+
* needed for the destination scaled image and pass through just
218+
* those rows and columns that are needed, replicated as necessary.
219+
* <p>
220+
* Note: This method is intended to be called by the
221+
* <code>ImageProducer</code> of the <code>Image</code> whose pixels
222+
* are being filtered. Developers using
223+
* this class to filter pixels from an image should avoid calling
224+
* this method directly since that operation could interfere
225+
* with the filtering operation.
226+
*/
227+
@Override
228+
public void setPixels(int x, int y, int w, int h,
229+
ColorModel model, int pixels[], int off,
230+
int scansize) {
231+
if (srcrows == null || srccols == null) {
232+
calculateMaps();
233+
}
234+
int sx, sy;
235+
int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * srcWidth);
236+
int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * srcHeight);
237+
int outpix[];
238+
if (outpixbuf != null && outpixbuf instanceof int[]) {
239+
outpix = (int[]) outpixbuf;
240+
} else {
241+
outpix = new int[destWidth];
242+
outpixbuf = outpix;
243+
}
244+
for (int dy = dy1; (sy = srcrows[dy]) < y + h; dy++) {
245+
int srcoff = off + scansize * (sy - y);
246+
int dx;
247+
for (dx = dx1; (sx = srccols[dx]) < x + w; dx++) {
248+
outpix[dx] = pixels[srcoff + sx - x];
249+
}
250+
if (dx > dx1) {
251+
consumer.setPixels(dx1, dy, dx - dx1, 1,
252+
model, outpix, dx1, destWidth);
253+
}
254+
}
255+
}
256+
}

sources/net.sf.j2s.java.core/src/swingjs/api/js/DOMNode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.awt.JSComponent;
88
import java.awt.Rectangle;
99

10+
import swingjs.JSGraphics2D;
1011
import swingjs.JSUtil;
1112
import swingjs.plaf.JSComponentUI;
1213

@@ -202,11 +203,12 @@ public static void setCursor(String c, Component comp) {
202203
*/
203204
}
204205

205-
public static DOMNode getImageNode(Image img) {
206+
public static DOMNode getImageNode(Image img) {
206207
// note that canvas takes precedence over imgNode, because
207208
// imgNode is a placeholder for the original image, but canvas
208209
// will be an op-filtered image
209-
return (/** @j2sNative img.秘canvas || img.秘imgNode ||*/ null);
210+
return (/** @j2sNative img.秘canvas || img.秘imgNode || */
211+
(DOMNode) (Object) ((JSGraphics2D) (Object) img.getGraphics()).getCanvas());
210212
}
211213

212214
public static void addHorizontalGap(DOMNode domNode, int gap) {

0 commit comments

Comments
 (0)