vhardy 01/09/18 03:55:55 Modified: . build.xml test-resources/org/apache/batik/svggen regsvggen.xml test-resources/org/apache/batik/svggen/resources Messages.properties test-resources/org/apache/batik/test regard.xml Added: test-sources/org/apache/batik/svggen JPainterCompare.java JPainterComponent.java NegativeLengths.java Log: Fixed bug# 929 and #1574. Revision Changes Path 1.83 +18 -1 xml-batik/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/xml-batik/build.xml,v retrieving revision 1.82 retrieving revision 1.83 diff -u -r1.82 -r1.83 --- build.xml 2001/09/17 20:45:18 1.82 +++ build.xml 2001/09/18 10:55:54 1.83 @@ -44,7 +44,7 @@ [win32] .\build.bat help - $Id: build.xml,v 1.82 2001/09/17 20:45:18 deweese Exp $ + $Id: build.xml,v 1.83 2001/09/18 10:55:54 vhardy Exp $ --> @@ -134,6 +134,7 @@ <echo message=" regard --> runs the regard regression utility"/> <echo message=" runtestsuite --> runs a TestSuite, given an XML test suite"/> <echo message=" document"/> + <echo message=" showpainter --> runs a Painter test instance to check its rendering."/> <echo message=" javadoc --> generates the API documentation"/> <echo message=" site --> generates the site documentation"/> <echo message=" sitedoc --> generates the site documentation without"/> @@ -730,6 +731,22 @@ <pathelement location="test-resources" /> </classpath> <arg line="test-resources/org/apache/batik/test/regard.xml"/> + </java> + </target> + + <target name="showpainter" + depends="compiletest, testdirs" + description="Runs test suite whose file or uri is passed as an input"> + <java fork="yes" + classname="${class-prefix}.svggen.JPainterCompare"> + <classpath> + <pathelement location="${dest}" /> + <path refid="libs-classpath"/> + <path refid="libs-build-classpath"/> + <pathelement location="resources" /> + <pathelement location="test-resources" /> + </classpath> + <arg line="${args}"/> </java> </target> 1.5 +20 -3 xml-batik/test-resources/org/apache/batik/svggen/regsvggen.xml Index: regsvggen.xml =================================================================== RCS file: /home/cvs/xml-batik/test-resources/org/apache/batik/svggen/regsvggen.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- regsvggen.xml 2001/05/02 08:49:23 1.4 +++ regsvggen.xml 2001/09/18 10:55:54 1.5 @@ -8,7 +8,7 @@ <!-- ========================================================================= --> <!-- @author [EMAIL PROTECTED] --> -<!-- @version $Id: regsvggen.xml,v 1.4 2001/05/02 08:49:23 cjolif Exp $ --> +<!-- @version $Id: regsvggen.xml,v 1.5 2001/09/18 10:55:54 vhardy Exp $ --> <!-- ========================================================================= --> <testSuite name="SVGGraphics2D Accuracy Testing"> <test class="org.apache.batik.svggen.SVGAccuracyTest"> @@ -82,11 +82,20 @@ <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/GraphicObjects.svg"/> <property name="SaveSVG" class="java.io.File" value="test-references/org/apache/batik/svggen/candidate-ref/GraphicObjects.svg" /> </test> + <test class="org.apache.batik.svggen.SVGAccuracyTest"> <arg class="org.apache.batik.svggen.Lookup" /> - <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/Lookup.svg"/> + <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/Lookup.svg"/> <property name="SaveSVG" class="java.io.File" value="test-references/org/apache/batik/svggen/candidate-ref/Lookup.svg" /> </test> + + <test class="org.apache.batik.svggen.SVGAccuracyTest"> + <arg class="org.apache.batik.svggen.NegativeLengths" /> + <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/NegativeLengths.svg"/> + <property name="SaveSVG" class="java.io.File" value="test-references/org/apache/batik/svggen/candidate-ref/NegativeLengths.svg" /> + </test> + + <test class="org.apache.batik.svggen.SVGAccuracyTest"> <arg class="org.apache.batik.svggen.Paints" /> <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/Paints.svg"/> @@ -187,11 +196,19 @@ <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/ContextGraphicObjects.svg"/> <property name="SaveSVG" class="java.io.File" value="test-references/org/apache/batik/svggen/candidate-ref/ContextGraphicObjects.svg" /> </test> + <test class="org.apache.batik.svggen.GeneratorContext"> <arg class="org.apache.batik.svggen.Lookup" /> - <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/ContextLookup.svg"/> + <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/ContextLookup.svg"/> <property name="SaveSVG" class="java.io.File" value="test-references/org/apache/batik/svggen/candidate-ref/ContextLookup.svg" /> </test> + + <test class="org.apache.batik.svggen.GeneratorContext"> + <arg class="org.apache.batik.svggen.NegativeLengths" /> + <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/ContextNegativeLengths.svg"/> + <property name="SaveSVG" class="java.io.File" value="test-references/org/apache/batik/svggen/candidate-ref/ContextNegativeLengths.svg" /> + </test> + <test class="org.apache.batik.svggen.GeneratorContext"> <arg class="org.apache.batik.svggen.Paints" /> <arg class="java.net.URL" value="file:test-references/org/apache/batik/svggen/ContextPaints.svg"/> 1.2 +43 -0 xml-batik/test-resources/org/apache/batik/svggen/resources/Messages.properties Index: Messages.properties =================================================================== RCS file: /home/cvs/xml-batik/test-resources/org/apache/batik/svggen/resources/Messages.properties,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Messages.properties 2001/04/20 06:36:17 1.1 +++ Messages.properties 2001/09/18 10:55:54 1.2 @@ -25,6 +25,49 @@ SVGAccuracyTest.error.generated.svg.inaccurate = \ Generated SVG is inaccurate. +JPainterCompare.error.class.not.painter = \ +Error: {0} is not a Painter. It does not implement the \ +Painter interface. + +JPainterCompare.error.could.not.instanciate.object = \ +Error: Could not instanciate an object of class {0}. \ +Got a {1} exception. + +JPainterCompare.error.could.not.load.class = \ +Error: could not load class {0}. \ +Got a {1} exception. + +JPainterCompare.error.could.not.transcode.to.svg = \ +Error: could not transcode Painter to SVG. \ +Got a {0} exception. + +JPainterCompare.error.could.not.convert.file.path.to.url = \ +Error: could not convert temporary file path to URL. + +JPainterCompare.error.could.not.render.generated.svg = \ +Error: could not render generated SVG. + +# +# Config +# +JPainterCompare.config.tmp.file.prefix = \ +JPainterCompareSVG_ + +# +# Messages +# +JPainterCompare.messages.instanciated.object = \ +Instanciated object. + +JPainterCompare.messages.loaded.class = \ +... finished loading class {0} + +JPainterCompare.messages.loading.class = \ +Loading class {0} ... + +JPainterCompare.messages.usage = \ +Usage: org.apache.batik.svggen.JPainterCompare <className> + # # Entry Keys # 1.7 +8 -4 xml-batik/test-resources/org/apache/batik/test/regard.xml Index: regard.xml =================================================================== RCS file: /home/cvs/xml-batik/test-resources/org/apache/batik/test/regard.xml,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- regard.xml 2001/09/05 10:00:35 1.6 +++ regard.xml 2001/09/18 10:55:55 1.7 @@ -11,7 +11,7 @@ <!-- regression testing. --> <!-- --> <!-- @author [EMAIL PROTECTED] --> -<!-- @version $Id: regard.xml,v 1.6 2001/09/05 10:00:35 vhardy Exp $ --> +<!-- @version $Id: regard.xml,v 1.7 2001/09/18 10:55:55 vhardy Exp $ --> <!-- ========================================================================= --> <testRun name="Batik Standard Regression Test Run"> <testRun name="REGARD"> @@ -28,12 +28,16 @@ </arg> </testReportProcessor> + <!-- <testSuite href="file:test-resources/org/apache/batik/util/regParsedURL.xml" /> <testSuite href="file:test-resources/org/apache/batik/util/regBase64.xml" /> - <testSuite href="file:test-resources/org/apache/batik/test/samplesRendering.xml" /> + <testSuite href="file:test-resources/org/apache/batik/test/samplesRendering.xml" /> <testSuite href="file:test-resources/org/apache/batik/svggen/regsvggen.xml" /> - <testSuite href="file:test-resources/org/apache/batik/test/unitTesting.xml" /> - <testSuite href="file:test-resources/org/apache/batik/test/beSuite.xml" /> + <testSuite href="file:test-resources/org/apache/batik/test/unitTesting.xml" /> + <testSuite href="file:test-resources/org/apache/batik/test/beSuite.xml" /> + --> + + <testSuite href="file:test-resources/org/apache/batik/svggen/regsvggen.xml" /> </testRun> </testRun> 1.1 xml-batik/test-sources/org/apache/batik/svggen/JPainterCompare.java Index: JPainterCompare.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.batik.svggen; import java.awt.*; import java.awt.geom.*; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import java.net.URL; import java.net.MalformedURLException; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import org.apache.batik.util.SVGConstants; import org.apache.batik.swing.JSVGCanvas; import org.apache.batik.swing.svg.SVGDocumentLoaderListener; import org.apache.batik.swing.svg.SVGDocumentLoaderAdapter; import org.apache.batik.swing.svg.SVGDocumentLoaderEvent; import org.apache.batik.svggen.SVGGraphics2D; import org.apache.batik.dom.svg.SVGDOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.DOMImplementation; /** * Simple component which displays, side by side, the drawing * created by a <tt>Painter</tt>, rendered in a * <tt>JPainterComponent</tt> on the left, and in a * <tt>JSVGCanvas</tt> on the right, where the SVG * displayed is the one created by the <tt>SVGGraphics2D</tt> * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> * @version $Id: JPainterCompare.java,v 1.1 2001/09/18 10:55:55 vhardy Exp $ */ public class JPainterCompare extends JPanel implements SVGConstants{ /** * Canvas size for all tests */ public static final Dimension CANVAS_SIZE = new Dimension(300, 400); public static String MESSAGES_USAGE = "JPainterCompare.messages.usage"; public static String MESSAGES_LOADING_CLASS = "JPainterCompare.messages.loading.class"; public static String MESSAGES_LOADED_CLASS = "JPainterCompare.messages.loaded.class"; public static String MESSAGES_INSTANCIATED_OBJECT = "JPainterCompare.messages.instanciated.object"; public static String ERROR_COULD_NOT_LOAD_CLASS = "JPainterCompare.error.could.not.load.class"; public static String ERROR_COULD_NOT_INSTANCIATE_OBJECT = "JPainterCompare.error.could.not.instanciate.object"; public static String ERROR_CLASS_NOT_PAINTER = "JPainterCompare.error.class.not.painter"; public static String ERROR_COULD_NOT_TRANSCODE_TO_SVG = "JPainterCompare.error.could.not.transcode.to.svg"; public static String ERROR_COULD_NOT_CONVERT_FILE_PATH_TO_URL = "JPainterCompare.error.could.not.convert.file.path.to.url"; public static String ERROR_COULD_NOT_RENDER_GENERATED_SVG = "JPainterCompare.error.could.not.render.generated.svg"; public static String CONFIG_TMP_FILE_PREFIX = "JPainterCompare.config.tmp.file.prefix"; /** * Builds an <tt>SVGGraphics2D</tt> with a default * configuration. */ protected SVGGraphics2D buildSVGGraphics2D() { // CSSDocumentHandler.setParserClassName(CSS_PARSER_CLASS_NAME); DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); String namespaceURI = SVGDOMImplementation.SVG_NAMESPACE_URI; Document domFactory = impl.createDocument(namespaceURI, SVG_SVG_TAG, null); return new SVGGraphics2D(domFactory); } static class LoaderListener extends SVGDocumentLoaderAdapter{ public final String sem = "sem"; public boolean success = false; public void documentLoadingFailed(SVGDocumentLoaderEvent e){ synchronized(sem){ sem.notifyAll(); } } public void documentLoadingCompleted(SVGDocumentLoaderEvent e){ success = true; synchronized(sem){ sem.notifyAll(); } } } /** * Constructor */ public JPainterCompare(Painter painter){ // First, create the AWT reference. JPainterComponent ref = new JPainterComponent(painter); // Now, generate the SVG from this Painter SVGGraphics2D g2d = buildSVGGraphics2D(); g2d.setSVGCanvasSize(CANVAS_SIZE); // // Generate SVG content // File tmpFile = null; try{ tmpFile = File.createTempFile(CONFIG_TMP_FILE_PREFIX, ".svg"); OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(tmpFile), "UTF-8"); painter.paint(g2d); g2d.stream(osw); osw.flush(); }catch(Exception e){ e.printStackTrace(); throw new IllegalArgumentException (Messages.formatMessage(ERROR_COULD_NOT_TRANSCODE_TO_SVG, new Object[]{e.getClass().getName()})); } // // Now, transcode SVG to a BufferedImage // JSVGCanvas svgCanvas = new JSVGCanvas(); LoaderListener l = new LoaderListener(); svgCanvas.addSVGDocumentLoaderListener(l); try{ svgCanvas.setURI(tmpFile.toURL().toString()); synchronized(l.sem){ l.sem.wait(); } }catch(Exception e){ e.printStackTrace(); new Error (Messages.formatMessage(ERROR_COULD_NOT_CONVERT_FILE_PATH_TO_URL, new Object[]{e.getMessage()})); } if(l.success){ setLayout(new GridLayout(1,2)); add(ref); add(svgCanvas); } else{ throw new Error (Messages.formatMessage(ERROR_COULD_NOT_RENDER_GENERATED_SVG,null)); } } public Dimension getPreferredSize(){ return new Dimension(CANVAS_SIZE.width*2, CANVAS_SIZE.height); } /* * Debug application: shows the image creatd by a <tt>Painter</tt> * on the left and the image created by a <tt>JSVGComponent</tt> * from the SVG generated by <tt>SVGGraphics2D</tt> from the same * <tt>Painter</tt> on the right. * */ public static void main(String args[]){ if(args.length <= 0){ System.out.println(Messages.formatMessage (MESSAGES_USAGE, null)); System.exit(0); } // Load class. String className = args[0]; System.out.println (Messages.formatMessage(MESSAGES_LOADING_CLASS, new Object[]{className})); Class cl = null; try{ cl = Class.forName(className); System.out.println (Messages.formatMessage(MESSAGES_LOADED_CLASS, new Object[]{className})); }catch(Exception e){ System.out.println (Messages.formatMessage(ERROR_COULD_NOT_LOAD_CLASS, new Object[] {className, e.getClass().getName() })); System.exit(0); } // Instanciate object Object o = null; try{ o = cl.newInstance(); System.out.println (Messages.formatMessage(MESSAGES_INSTANCIATED_OBJECT, null)); }catch(Exception e){ System.out.println (Messages.formatMessage(ERROR_COULD_NOT_INSTANCIATE_OBJECT, new Object[] {className, e.getClass().getName()})); System.exit(0); } // Cast to Painter Painter p = null; try{ p = (Painter)o; }catch(ClassCastException e){ System.out.println (Messages.formatMessage(ERROR_CLASS_NOT_PAINTER, new Object[]{className})); System.exit(0); } // Build frame JFrame f = new JFrame(); JPainterCompare c = new JPainterCompare(p); c.setBackground(Color.white); c.setPreferredSize(new Dimension(300, 400)); f.getContentPane().add(c); f.getContentPane().setBackground(Color.white); f.pack(); f.setVisible(true); } } 1.1 xml-batik/test-sources/org/apache/batik/svggen/JPainterComponent.java Index: JPainterComponent.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.batik.svggen; import java.awt.*; import java.awt.geom.*; import javax.swing.JComponent; import javax.swing.JFrame; /** * Simple component which displays the rendering created by * a <tt>Painter</tt>. * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> * @version $Id: JPainterComponent.java,v 1.1 2001/09/18 10:55:55 vhardy Exp $ */ public class JPainterComponent extends JComponent { /** * <tt>Painter</tt> */ protected Painter painter; /** * Delegates to its <tt>Painter</tt> */ public void paint(Graphics _g){ Graphics2D g = (Graphics2D)_g; painter.paint(g); } /** * Constructor */ public JPainterComponent(Painter painter){ this.painter = painter; } } 1.1 xml-batik/test-sources/org/apache/batik/svggen/NegativeLengths.java Index: NegativeLengths.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.batik.svggen; import java.awt.*; import java.awt.geom.*; /** * This test validates the convertion of Java 2D negative length values:<br /> * - On rectangles: a negative width or height makes the rectangle invisible.<br /> * - On rounded rectangles: a negative width or height makes the rectangle invisible.<br /> * - On ellipses: a negative width or height makes the ellipse invisible<br /> * - On 3D rect: a negative width *and* height makes the rectangle invisible. A * negative width or height makes the rectangle display as a line.<br /> * The above behavior is that of the default Graphics2D implementations. * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> * @version $Id: NegativeLengths.java,v 1.1 2001/09/18 10:55:55 vhardy Exp $ */ public class NegativeLengths implements Painter { public void paint(Graphics2D g){ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setPaint(Color.black); // Rectangle g.drawString("Rectangle", 10, 20); // w negative, h negative Rectangle rect = new Rectangle(10, 30, -10, -8); g.draw(rect); // w negative, h zero rect = new Rectangle(30, 30, -10, 0); g.draw(rect); // w negative, h positive rect = new Rectangle(50, 30, -10, 8); g.draw(rect); // w zero, h negative rect = new Rectangle(70, 30, 0, -8); g.draw(rect); // w zero, h zero rect = new Rectangle(90, 30, 0, 0); g.draw(rect); // w zero, h positive rect = new Rectangle(110, 30, 0, 8); g.draw(rect); // w positive, h negative rect = new Rectangle(130, 30, 10, -8); g.draw(rect); // w positive, h zero rect = new Rectangle(150, 30, 5, 0); g.draw(rect); // w positive, h positive rect = new Rectangle(170, 30, 5, 8); g.draw(rect); g.translate(0, 35); // // Round Rectangle // g.drawString("RoundRectangle2D", 10, 20); // w negative, h negative RoundRectangle2D rrect = new RoundRectangle2D.Double(10, 30, -10, -8, 2, 2); g.draw(rrect); // w negative, h zero rrect = new RoundRectangle2D.Double(30, 30, -10, 0, 2, 2); g.draw(rrect); // w negative, h positive rrect = new RoundRectangle2D.Double(50, 30, -10, 8, 2, 2); g.draw(rrect); // w zero, h negative rrect = new RoundRectangle2D.Double(70, 30, 0, -8, 2, 2); g.draw(rrect); // w zero, h zero rrect = new RoundRectangle2D.Double(90, 30, 0, 0, 2, 2); g.draw(rrect); // w zero, h positive rrect = new RoundRectangle2D.Double(110, 30, 0, 8, 2, 2); g.draw(rrect); // w positive, h negative rrect = new RoundRectangle2D.Double(130, 30, 5, -8, 2, 2); g.draw(rrect); // w positive, h zero rrect = new RoundRectangle2D.Double(150, 30, 5, 0, 2, 2); g.draw(rrect); // w positive, h positive rrect = new RoundRectangle2D.Double(170, 30, 5, 8, 2, 2); g.draw(rrect); g.translate(0, 35); // // Round Rectangle 2 // g.drawString("RoundRectangle2D, negative radius", 10, 20); // w negative, h negative rrect = new RoundRectangle2D.Double(10, 30, -10, -8, -2, -2); g.draw(rrect); // w negative, h zero rrect = new RoundRectangle2D.Double(30, 30, -10, 0, -2, -2); g.draw(rrect); // w negative, h positive rrect = new RoundRectangle2D.Double(50, 30, -10, 8, -2, -2); g.draw(rrect); // w zero, h negative rrect = new RoundRectangle2D.Double(70, 30, 0, -8, -2, -2); g.draw(rrect); // w zero, h zero rrect = new RoundRectangle2D.Double(90, 30, 0, 0, -2, -2); g.draw(rrect); // w zero, h positive rrect = new RoundRectangle2D.Double(110, 30, 0, 8, -2, -2); g.draw(rrect); // w positive, h negative rrect = new RoundRectangle2D.Double(130, 30, 5, -8, -2, -2); g.draw(rrect); // w positive, h zero rrect = new RoundRectangle2D.Double(150, 30, 5, 0, -2, -2); g.draw(rrect); // w positive, h positive rrect = new RoundRectangle2D.Double(170, 30, 5, 8, -2, -2); g.draw(rrect); g.translate(0, 35); // // Circle // g.drawString("Circle", 10, 20); // w negative Ellipse2D circle = new Ellipse2D.Double(10, 30, -10, -10); g.draw(circle); // w zero, h negative circle = new Ellipse2D.Double(30, 30, 0, 0); g.draw(circle); // w positive, h negative circle = new Ellipse2D.Double(50, 30, 5, 5); g.draw(circle); g.translate(0, 35); // // Ellipse // g.drawString("Ellipse", 10, 20); // w negative, h negative Ellipse2D ellipse = new Ellipse2D.Double(10, 30, -10, -8); g.draw(ellipse); // w negative, h zero ellipse = new Ellipse2D.Double(30, 30, -10, 0); g.draw(ellipse); // w negative, h positive ellipse = new Ellipse2D.Double(50, 30, -10, 8); g.draw(ellipse); // w zero, h negative ellipse = new Ellipse2D.Double(70, 30, 0, -8); g.draw(ellipse); // w zero, h zero ellipse = new Ellipse2D.Double(90, 30, 0, 0); g.draw(ellipse); // w zero, h positive ellipse = new Ellipse2D.Double(110, 30, 0, 8); g.draw(ellipse); // w positive, h negative ellipse = new Ellipse2D.Double(130, 30, 5, -8); g.draw(ellipse); // w positive, h zero ellipse = new Ellipse2D.Double(150, 30, 5, 0); g.draw(ellipse); // w positive, h positive ellipse = new Ellipse2D.Double(170, 30, 5, 8); g.draw(ellipse); g.translate(0, 35); // 3D Rect g.drawString("fill3Drect", 10, 20); // w negative, h negative g.setColor(new Color(192, 192, 192)); g.fill3DRect(10, 30, -10, -8, true); // w negative, h zero g.fill3DRect(30, 30, -10, 0, true); // w negative, h positive g.fill3DRect(50, 30, -10, 8, true); // w zero, h negative g.fill3DRect(70, 30, 0, -8, true); // w zero, h zero g.fill3DRect(90, 30, 0, 0, true); // w zero, h positive g.fill3DRect(110, 30, 0, 8, true); // w positive, h negative g.fill3DRect(130, 30, 5, -8, true); // w positive, h zero g.fill3DRect(150, 30, 5, 0, true); // w positive, h positive g.fill3DRect(170, 30, 5, 8, true); g.translate(0, 40); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]