| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package java.awt; |
| |
| import java.awt.event.WindowAdapter; |
| import java.awt.event.WindowEvent; |
| import java.awt.geom.AffineTransform; |
| import java.awt.geom.CubicCurve2D; |
| import java.awt.geom.GeneralPath; |
| import java.awt.geom.Line2D; |
| import java.awt.geom.QuadCurve2D; |
| import java.awt.image.BufferedImage; |
| import java.io.File; |
| import java.io.FileReader; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.Reader; |
| import java.io.StreamTokenizer; |
| import java.io.Writer; |
| import java.util.Arrays; |
| |
| //import javax.imageio.ImageIO; |
| |
| import org.apache.harmony.awt.gl.MultiRectAreaOp; |
| |
| import junit.framework.Assert; |
| |
| public abstract class Tools { |
| |
| static String typeName[] = {"move", "line", "quad", "cubic", "close"}; |
| |
| static int findString(String buf[], String value) { |
| for(int i = 0; i < buf.length; i++) { |
| if (buf[i].equals(value)) { |
| return i; |
| } |
| } |
| Assert.fail("Unknown value " + value); |
| return -1; |
| } |
| |
| public static String getClasstPath(Class clazz) { |
| String name = clazz.getName(); |
| name = name.substring(0, name.lastIndexOf('.')); |
| |
| return name.replace('.', '/') + '/'; |
| } |
| |
| public static void checkDeadLoop(Component c, int[] count) { |
| final int DEAD_LOOP_TIMEOUT = 1000; |
| final int VALID_NUMBER_OF_PAINT_CALLS = 15; |
| |
| Frame f = new Frame(); |
| |
| f.add(c); |
| f.setSize(300,200); |
| f.setVisible(true); |
| |
| try { |
| Thread.sleep(DEAD_LOOP_TIMEOUT); |
| } catch (Exception e) {} |
| |
| f.dispose(); |
| |
| Assert.assertTrue("paint() called " + count[0] + |
| " times, a dead loop occurred", |
| count[0] <= VALID_NUMBER_OF_PAINT_CALLS); |
| } |
| |
| public static class Shape { |
| |
| static int pointCount[] = { |
| 2, // MOVE |
| 2, // LINE |
| 4, // QUAD |
| 6, // CUBIC |
| 0 // CLOSE |
| }; |
| |
| static final double IMAGE_REL_BORDER = 0.1; |
| static final double IMAGE_MIN_BORDER = 10.0; |
| static final double IMAGE_MAX_BORDER = 100.0; |
| static final Color backColor = Color.white; |
| |
| public static Frame show(final java.awt.Shape shape) { |
| Frame f = new Frame("Shape") { |
| |
| public void paint(Graphics g) { |
| // Background |
| g.setColor(Color.white); |
| g.fillRect(0, 0, getWidth(), getHeight()); |
| |
| // Fill shape |
| g.setColor(Color.lightGray); |
| ((Graphics2D)g).fill(shape); |
| |
| // Draw shape |
| g.setColor(Color.black); |
| ((Graphics2D)g).draw(shape); |
| |
| // java.awt.image.BufferedImage img = Shape.createImage(shape, null, Color.gray, Color.lightGray); |
| // g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), null); |
| } |
| |
| }; |
| |
| f.addWindowListener( |
| new WindowAdapter() { |
| public void windowClosing(WindowEvent e) { |
| System.exit(0); |
| } |
| } |
| ); |
| |
| f.setSize(600, 400); |
| f.show(); |
| return f; |
| } |
| |
| public static void save(java.awt.Shape s, String fileName) { |
| try { |
| FileWriter f = new FileWriter(fileName); |
| java.awt.geom.PathIterator p = s.getPathIterator(null); |
| double coords[] = new double[6]; |
| while(!p.isDone()) { |
| int type = p.currentSegment(coords); |
| f.write(typeName[type] + getCoords(coords, pointCount[type]) + "\n"); |
| p.next(); |
| } |
| f.close(); |
| } catch (IOException e) { |
| Assert.fail("Can''t write to file " + fileName); |
| } |
| } |
| |
| public static java.awt.Shape load(String fileName) { |
| GeneralPath s = null; |
| try { |
| FileReader f = new FileReader(fileName); |
| s = new GeneralPath(); |
| StreamTokenizer t = new StreamTokenizer(f); |
| int count = 0; |
| int type = 0; |
| float coords[] = new float[6]; |
| while(t.nextToken() != StreamTokenizer.TT_EOF) { |
| switch(t.ttype) { |
| case StreamTokenizer.TT_EOL: |
| break; |
| case StreamTokenizer.TT_WORD: |
| type = findString(typeName, t.sval); |
| if (type == java.awt.geom.PathIterator.SEG_CLOSE) { |
| s.closePath(); |
| } |
| break; |
| case StreamTokenizer.TT_NUMBER: |
| coords[count++] = (float)t.nval; |
| if (count == pointCount[type]) { |
| count = 0; |
| switch(type) { |
| case java.awt.geom.PathIterator.SEG_MOVETO: |
| s.moveTo(coords[0], coords[1]); |
| break; |
| case java.awt.geom.PathIterator.SEG_LINETO: |
| s.lineTo(coords[0], coords[1]); |
| break; |
| case java.awt.geom.PathIterator.SEG_QUADTO: |
| s.quadTo(coords[0], coords[1], coords[2], coords[3]); |
| break; |
| case java.awt.geom.PathIterator.SEG_CUBICTO: |
| s.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); |
| break; |
| } |
| } |
| break; |
| } |
| } |
| f.close(); |
| } catch (IOException e) { |
| Assert.fail("Can''t read file " + fileName); |
| } |
| return s; |
| } |
| |
| static String getCoords(double coords[], int count) { |
| String s = ""; |
| for(int i = 0; i < count; i++) { |
| s = s + " " + coords[i]; |
| } |
| return s; |
| } |
| |
| public static java.awt.image.BufferedImage createImage(java.awt.Shape shape, AffineTransform t, Color draw, Color fill) { |
| |
| // Calculate image border |
| Rectangle r = shape.getBounds(); |
| double border = r.getWidth() * IMAGE_REL_BORDER; |
| border = Math.min(IMAGE_MAX_BORDER, border); |
| border = Math.max(IMAGE_MIN_BORDER, border); |
| |
| // Shift shape in the center of the image |
| if (t == null) { |
| t = AffineTransform.getTranslateInstance(- r.getX() + border, - r.getY() + border); |
| } else { |
| t.setToTranslation(- r.getX() + border, - r.getY() + border); |
| } |
| java.awt.geom.GeneralPath dst = new java.awt.geom.GeneralPath(); |
| dst.append(shape.getPathIterator(t), false); |
| |
| java.awt.image.BufferedImage img = |
| new java.awt.image.BufferedImage( |
| (int)(r.getWidth() + border * 2.0), |
| (int)(r.getHeight() + border * 2.0), |
| java.awt.image.BufferedImage.TYPE_INT_RGB); |
| |
| Graphics g = img.getGraphics(); |
| |
| // Background |
| g.setColor(backColor); |
| g.fillRect(0, 0, img.getWidth(), img.getHeight()); |
| |
| // Fill shape |
| g.setColor(fill); |
| ((Graphics2D)g).fill(dst); |
| |
| // Draw shape |
| g.setColor(draw); |
| ((Graphics2D)g).draw(dst); |
| |
| return img; |
| } |
| |
| public static boolean equals(java.awt.Shape s1, java.awt.Shape s2, double delta) { |
| return PathIterator.equals(s1.getPathIterator(null), s2.getPathIterator(null), delta); |
| } |
| |
| public static boolean equals(java.awt.Shape s1, java.awt.Shape s2, float delta) { |
| return PathIterator.equals(s1.getPathIterator(null), s2.getPathIterator(null), delta); |
| } |
| |
| public static java.awt.Shape scale(java.awt.Shape shape, double k) { |
| java.awt.geom.PathIterator path = shape.getPathIterator(AffineTransform.getScaleInstance(k, k)); |
| java.awt.geom.GeneralPath dst = new java.awt.geom.GeneralPath(path.getWindingRule()); |
| dst.append(path, false); |
| return dst; |
| } |
| |
| public static java.awt.Shape flip(java.awt.Shape shape) { |
| java.awt.geom.PathIterator path = shape.getPathIterator(new AffineTransform(0, 1, 1, 0, 0, 0)); |
| java.awt.geom.GeneralPath dst = new java.awt.geom.GeneralPath(path.getWindingRule()); |
| dst.append(path, false); |
| return dst; |
| } |
| |
| public static String toString(java.awt.Shape shape) { |
| return shape.getClass().getName() + "\n" + PathIterator.toString(shape.getPathIterator(null)); |
| } |
| |
| public static void drawColored(java.awt.Shape shape, Graphics2D g) { |
| java.awt.geom.PathIterator path = shape.getPathIterator(null); |
| float cx = 0; |
| float cy = 0; |
| float coords[] = new float[6]; |
| while(!path.isDone()) { |
| switch(path.currentSegment(coords)) { |
| case java.awt.geom.PathIterator.SEG_MOVETO: |
| cx = coords[0]; |
| cy = coords[1]; |
| break; |
| case java.awt.geom.PathIterator.SEG_LINETO: |
| g.setColor(Color.blue); |
| g.draw(new Line2D.Float(cx, cy, cx = coords[0], cy = coords[1])); |
| break; |
| case java.awt.geom.PathIterator.SEG_QUADTO: |
| g.setColor(Color.green); |
| g.draw(new QuadCurve2D.Float(cx, cy, coords[0], coords[1], cx = coords[2], cy = coords[3])); |
| break; |
| case java.awt.geom.PathIterator.SEG_CUBICTO: |
| g.setColor(Color.red); |
| g.draw(new CubicCurve2D.Float(cx, cy, coords[0], coords[1], coords[2], coords[3], cx = coords[4], cy = coords[5])); |
| break; |
| case java.awt.geom.PathIterator.SEG_CLOSE: |
| break; |
| } |
| path.next(); |
| } |
| } |
| |
| } |
| |
| public static class BasicStroke { |
| |
| static String propName[] = new String[] {"width", "cap", "join", "miter", "dash", "phase"}; |
| static String capName[] = new String[] {"BUTT", "ROUND", "SQUARE"}; |
| static String joinName[] = new String[] {"MITER", "ROUND", "BEVEL"}; |
| |
| public static void save(java.awt.BasicStroke bs, String fileName) { |
| try { |
| FileWriter f = new FileWriter(fileName); |
| save(bs, f); |
| f.close(); |
| } catch (IOException e) { |
| Assert.fail("Can''t write to file " + fileName); |
| } |
| } |
| |
| public static void save(java.awt.BasicStroke bs, Writer f) throws IOException { |
| f.write("width " + bs.getLineWidth() + "\n"); |
| f.write("cap " + capName[bs.getEndCap()] + "\n"); |
| f.write("join "+ joinName[bs.getLineJoin()] + "\n"); |
| f.write("miter " + bs.getMiterLimit() + "\n"); |
| float dash[] = bs.getDashArray(); |
| if (dash != null) { |
| String str = ""; |
| for (float element : dash) { |
| str = str + element + " "; |
| } |
| f.write("dash " + str + "\n"); |
| f.write("phase " + bs.getDashPhase()); |
| } |
| } |
| |
| public static java.awt.BasicStroke load(String fileName) { |
| java.awt.BasicStroke bs = null; |
| try { |
| FileReader f = new FileReader(fileName); |
| bs = load(f); |
| f.close(); |
| } catch (IOException e) { |
| Assert.fail("Can''t read file " + fileName); |
| } |
| return bs; |
| } |
| |
| public static java.awt.BasicStroke load(Reader f) throws IOException { |
| // Set default values |
| java.awt.BasicStroke bs = new java.awt.BasicStroke(); |
| float width = bs.getLineWidth(); |
| int cap = bs.getEndCap(); |
| int join = bs.getLineJoin(); |
| float miterLimit = bs.getMiterLimit(); |
| float dash[] = bs.getDashArray(); |
| float dashPhase = bs.getDashPhase(); |
| |
| int prop = -1; |
| int dashCount = 0; |
| StreamTokenizer t = new StreamTokenizer(f); |
| |
| while(t.nextToken() != StreamTokenizer.TT_EOF) { |
| switch(t.ttype) { |
| case StreamTokenizer.TT_EOL: |
| break; |
| case StreamTokenizer.TT_WORD: |
| switch(prop) { |
| case 4: // dash |
| float tmp[] = new float[dashCount]; |
| System.arraycopy(dash, 0, tmp, 0, dashCount); |
| dash = tmp; |
| case -1: |
| prop = findString(propName, t.sval); |
| break; |
| case 1: // cap |
| cap = findString(capName, t.sval); |
| prop = -1; |
| break; |
| case 2: // join |
| join = findString(joinName, t.sval); |
| prop = -1; |
| break; |
| } |
| break; |
| case StreamTokenizer.TT_NUMBER: |
| switch(prop) { |
| case 0: // width |
| width = (float)t.nval; |
| prop = -1; |
| break; |
| case 3: // miterLimit |
| miterLimit = (float)t.nval; |
| prop = -1; |
| break; |
| case 4: // dash |
| if (dash == null) { |
| dash = new float[10]; |
| dashCount = 0; |
| } |
| dash[dashCount++] = (float)t.nval; |
| break; |
| case 5: // dashPhase |
| dashPhase = (float)t.nval; |
| prop = -1; |
| break; |
| } |
| break; |
| } |
| } |
| return new java.awt.BasicStroke(width, cap, join,miterLimit, dash, dashPhase); |
| } |
| |
| } |
| |
| public static class BufferedImage { |
| |
| public static java.awt.image.BufferedImage load(String filename) { |
| java.awt.image.BufferedImage img = null; |
| try { |
| // Code should be enabled when imageio is supported |
| // img = ImageIO.read(new java.io.File(filename)); |
| return null; |
| } catch (Exception e) { |
| Assert.fail("Can't open file: " + filename); |
| } |
| return img; |
| } |
| |
| public static void save(java.awt.image.BufferedImage img, String filename) { |
| try { |
| // Code should be enabled when imageio is supported |
| // ImageIO.write(img, "jpg", new java.io.File(filename)); |
| } catch (Exception e) { |
| Assert.fail("Can't save file: " + filename); |
| } |
| } |
| |
| public static java.awt.image.BufferedImage loadIcon(String filename) { |
| try { |
| // Code should be enabled when imageio is supported |
| // return ImageIO.read(new java.io.File(filename)); |
| } catch(Exception e) { |
| Assert.fail("Can't open file: " + filename); |
| } |
| return null; |
| } |
| |
| public static void saveIcon(java.awt.image.BufferedImage img, String filename) { |
| try { |
| // Code should be enabled when imageio is supported |
| // ImageIO.write(img, "png", new java.io.File(filename)); |
| } catch(Exception e) { |
| Assert.fail("Can't save file: " + filename); |
| } |
| } |
| |
| } |
| |
| public static class File { |
| |
| public static String changeExt(String file, String newExt) { |
| int k = file.lastIndexOf('.'); |
| return file.substring(0, k) + newExt; |
| } |
| |
| public static String extractFileName(String file) { |
| int k; |
| if ((k = file.lastIndexOf('/')) == -1) { |
| if ((k = file.lastIndexOf('\\')) == -1) { |
| k = 1; |
| } |
| } |
| return file.substring(k + 1); |
| } |
| |
| public static String extractFileExt(String file) { |
| int k = file.lastIndexOf('.'); |
| return file.substring(k + 1); |
| } |
| |
| } |
| |
| public static class PathIterator { |
| |
| public static String equalsError = ""; |
| |
| static boolean coordsEquals(double coords1[], double coords2[], int count, double delta) { |
| for(int i = 0; i < count; i++) { |
| if (Math.abs(coords1[i] - coords2[i]) > delta) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| static boolean coordsEquals(float coords1[], float coords2[], int count, float delta) { |
| for(int i = 0; i < count; i++) { |
| if (Math.abs(coords1[i] - coords2[i]) > delta) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| public static boolean equals(java.awt.geom.PathIterator p1, java.awt.geom.PathIterator p2, double delta) { |
| equalsError = ""; |
| if (p1.getWindingRule() != p2.getWindingRule()) { |
| equalsError = "WindingRule expected " + p1.getWindingRule() + " but was " + p2.getWindingRule(); |
| return false; |
| } |
| int count = 0; |
| double coords1[] = new double[6]; |
| double coords2[] = new double[6]; |
| while(!p1.isDone() && !p2.isDone()) { |
| int type1 = p1.currentSegment(coords1); |
| int type2 = p2.currentSegment(coords2); |
| if (type1 != type2 || !coordsEquals(coords1, coords2, Shape.pointCount[type1], delta)) { |
| equalsError = "Expected #" + count + " segment "+ typeName[type1] + Arrays.toString(coords1) + " but was " + typeName[type2] + Arrays.toString(coords2); |
| return false; |
| } |
| p1.next(); |
| p2.next(); |
| count++; |
| } |
| if (p1.isDone() != p2.isDone()) { |
| equalsError = "Expected #" + count + " isDone " + p1.isDone() + " but was " + p2.isDone(); |
| return false; |
| } |
| return true; |
| } |
| |
| public static boolean equals(java.awt.geom.PathIterator p1, java.awt.geom.PathIterator p2, float delta) { |
| if (p1.getWindingRule() != p2.getWindingRule()) { |
| return false; |
| } |
| float coords1[] = new float[6]; |
| float coords2[] = new float[6]; |
| while(!p1.isDone() && !p2.isDone()) { |
| int type1 = p1.currentSegment(coords1); |
| int type2 = p2.currentSegment(coords2); |
| if (type1 != type2 || !coordsEquals(coords1, coords2, Shape.pointCount[type1], delta)) { |
| return false; |
| } |
| p1.next(); |
| p2.next(); |
| } |
| if (p1.isDone() != p2.isDone()) { |
| return false; |
| } |
| return true; |
| } |
| |
| public static String toString(java.awt.geom.PathIterator path) { |
| String out = ""; |
| float coords[] = new float[6]; |
| while(!path.isDone()) { |
| switch(path.currentSegment(coords)) { |
| case java.awt.geom.PathIterator.SEG_MOVETO: |
| out += "move(" + coords[0] + "," + coords[1] + ")\n"; |
| break; |
| case java.awt.geom.PathIterator.SEG_LINETO: |
| out += "line(" + coords[0] + "," + coords[1] + ")\n"; |
| break; |
| case java.awt.geom.PathIterator.SEG_QUADTO: |
| out += "quad(" + coords[0] + "," + coords[1] + "," + coords[2] + "," + coords[3] + ")\n"; |
| break; |
| case java.awt.geom.PathIterator.SEG_CUBICTO: |
| out += "cubic(" + coords[0] + "," + coords[1] + "," + coords[2] + "," + coords[3] + "," + coords[4] + "," + coords[5] + ")\n"; |
| break; |
| case java.awt.geom.PathIterator.SEG_CLOSE: |
| out += "close\n"; |
| break; |
| } |
| path.next(); |
| } |
| out += "done\n"; |
| return out; |
| } |
| } |
| |
| public static class MultiRectArea { |
| |
| public final static Color[] color = new Color[] { |
| Color.blue, |
| Color.green, |
| Color.red, |
| Color.yellow, |
| Color.MAGENTA, |
| Color.orange, |
| Color.lightGray, |
| Color.cyan, |
| Color.pink |
| }; |
| |
| public final static Color[] colorBlue = new Color[] { |
| new Color(0x3F), |
| new Color(0x5F), |
| new Color(0x7F), |
| new Color(0x9F), |
| new Color(0xBF), |
| new Color(0xDF), |
| new Color(0xFF) |
| }; |
| |
| public final static Color[] colorGreen = new Color[] { |
| new Color(0x3F00), |
| new Color(0x5F00), |
| new Color(0x7F00), |
| new Color(0x9F00), |
| new Color(0xBF00), |
| new Color(0xDF00), |
| new Color(0xFF00) |
| }; |
| |
| static final int BORDER = 30; |
| static final Color colorBack = Color.white; |
| |
| public static void save(org.apache.harmony.awt.gl.MultiRectArea area, String fileName) { |
| try { |
| FileWriter f = new FileWriter(fileName); |
| Rectangle[] rect = area.getRectangles(); |
| for (Rectangle element : rect) { |
| f.write( |
| element.x + "," + |
| element.y + "," + |
| (element.width + element.x - 1) + "," + |
| (element.height + element.y - 1) + "\n"); |
| } |
| f.close(); |
| } catch (IOException e) { |
| Assert.fail("Can''t write to file " + fileName); |
| } |
| } |
| |
| public static org.apache.harmony.awt.gl.MultiRectArea load(String fileName) { |
| org.apache.harmony.awt.gl.MultiRectArea area = null; |
| try { |
| int[] buf = MultiRectAreaOp.createBuf(0); |
| int count = 1; |
| |
| FileReader f = new FileReader(fileName); |
| StreamTokenizer t = new StreamTokenizer(f); |
| while(t.nextToken() != StreamTokenizer.TT_EOF) { |
| if (t.ttype == StreamTokenizer.TT_NUMBER) { |
| buf = MultiRectAreaOp.checkBufSize(buf, 1); |
| buf[count++] = (int)t.nval; |
| } |
| } |
| f.close(); |
| |
| int j = 0; |
| Rectangle[] rect = new Rectangle[(count - 1) / 4]; |
| for(int i = 1; i < count; i += 4) { |
| rect[j++] = new Rectangle( |
| buf[i], |
| buf[i + 1], |
| buf[i + 2] - buf[i] + 1, |
| buf[i + 3] - buf[i + 1] + 1); |
| } |
| area = new org.apache.harmony.awt.gl.MultiRectArea(rect); |
| } catch (IOException e) { |
| Assert.fail("Can''t read file " + fileName); |
| } |
| return area; |
| } |
| |
| public static java.awt.image.BufferedImage createImage(org.apache.harmony.awt.gl.MultiRectArea area) { |
| return createImage(area, color); |
| } |
| |
| public static java.awt.image.BufferedImage createImage(org.apache.harmony.awt.gl.MultiRectArea area, Color[] palette) { |
| |
| // Calculate image border |
| Rectangle bounds = area.getBounds(); |
| int width = bounds.x + bounds.width + BORDER; |
| int height = bounds.y + bounds.height + BORDER; |
| |
| java.awt.image.BufferedImage img = |
| new java.awt.image.BufferedImage( |
| width, height, |
| java.awt.image.BufferedImage.TYPE_INT_RGB); |
| |
| Graphics g = img.getGraphics(); |
| |
| // Background |
| g.setColor(colorBack); |
| g.fillRect(0, 0, img.getWidth(), img.getHeight()); |
| |
| Rectangle[] rect = area.getRectangles(); |
| for(int i = 0; i < rect.length; i++) { |
| g.setColor(palette[i % palette.length]); |
| g.fillRect(rect[i].x, rect[i].y, rect[i].width, rect[i].height); |
| } |
| return img; |
| } |
| |
| } |
| |
| } |