Bugs 2547 ... 46/10546/3
Calixte DENIZET [Wed, 20 Feb 2013 11:34:35 +0000 (12:34 +0100)]
Change-Id: I2d53f3b90883a393cb4f8894614af8856ed57be1

scilab/CHANGES_5.4.X
scilab/modules/graphic_export/src/java/org/scilab/modules/graphic_export/Export.java
scilab/modules/renderer/src/java/org/scilab/modules/renderer/JoGLView/mark/MarkSpriteFactory.java

index 4c80fb5..e9a0d0d 100644 (file)
@@ -217,6 +217,8 @@ Other changes
 Bug fixes
 ==========
 
+* Bug #2547 fixed - Too small marks were not correctly exported.
+
 * Bug #3313 fixed - In the documentation, the title of a link was using the
                     id instead of the title of the page.
 
@@ -231,6 +233,9 @@ Bug fixes
 
 * Bug #6583 fixed - jmat() was poorly documented.
 
+* Bug #6890 fixed - Strings were exported as shapes rather than Postscript
+                    strings in EPS/PS export.
+
 * Bug #7058 fixed - There was an error in mathml formula in beta function help.
 
 * Bug #7190 fixed - is_absolute_path was not documented.
index 928a18d..f1ff989 100644 (file)
 package org.scilab.modules.graphic_export;
 
 import java.awt.Dimension;
+import java.awt.Font;
 import java.awt.Graphics2D;
+import java.awt.Shape;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.PathIterator;
 import java.awt.image.BufferedImage;
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
@@ -24,6 +28,8 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
 import java.text.AttributedCharacterIterator;
 import java.util.HashMap;
 import java.util.Map;
@@ -39,6 +45,7 @@ import org.apache.xmlgraphics.java2d.ps.AbstractPSDocumentGraphics2D;
 import org.apache.xmlgraphics.java2d.ps.EPSDocumentGraphics2D;
 import org.apache.xmlgraphics.java2d.ps.PSDocumentGraphics2D;
 import org.apache.xmlgraphics.ps.DSCConstants;
+import org.apache.xmlgraphics.ps.PSGenerator;
 import org.scilab.forge.scirenderer.Canvas;
 import org.scilab.forge.scirenderer.implementation.g2d.G2DCanvas;
 import org.scilab.forge.scirenderer.implementation.g2d.G2DCanvasFactory;
@@ -200,11 +207,11 @@ public class Export {
             Canvas canvas = G2DCanvasFactory.createCanvas(g2d, width, height);
             DrawerVisitor oldVisitor = DrawerVisitor.getVisitor(uid);
             DrawerVisitor visitor = new DrawerVisitor(null, canvas, figure) {
-                @Override
-                public void updateObject(String id, int property) {
-                    // Don't update during the export
-                }
-            };
+                    @Override
+                    public void updateObject(String id, int property) {
+                        // Don't update during the export
+                    }
+                };
 
             try {
                 canvas.setMainDrawer(visitor);
@@ -303,16 +310,16 @@ public class Export {
                 DrawerVisitor oldVisitor = DrawerVisitor.getVisitor(uid);
                 joglCanvas = (JoGLCanvas) JoGLCanvasFactory.createCanvas(dims[0], dims[1]);
                 DrawerVisitor visitor = new DrawerVisitor(null, joglCanvas, figure) {
-                    @Override
-                    public void updateObject(String id, int property) {
-                        // Don't update during the export
-                    }
+                        @Override
+                        public void updateObject(String id, int property) {
+                            // Don't update during the export
+                        }
 
-                    @Override
-                    public void deleteObject(String id) {
-                        // Don't delete during the export
-                    }
-                };
+                        @Override
+                        public void deleteObject(String id) {
+                            // Don't delete during the export
+                        }
+                    };
                 joglCanvas.setMainDrawer(visitor);
                 joglCanvas.redraw();
                 GraphicController.getController().unregister(visitor);
@@ -383,33 +390,33 @@ public class Export {
      */
     private static Exporter getExporter(TYPE type) {
         switch (type) {
-            case PNG :
-                return new PNGExporter();
-            case GIF :
-                return new GIFExporter();
-            case JPEG :
-                return new JPEGExporter();
-            case BMP :
-                return new BMPExporter();
-            case PPM :
-                return new PPMExporter();
-            case SVG :
-                if (!svgLoaded) {
-                    ScilabCommonsUtils.loadOnUse(CLASSPATH_SVG_EXPORT_NAME);
-                    svgLoaded = true;
-                }
-                return new SVGExporter();
-            case PDF :
-                loadPDF();
-                return new PDFExporter();
-            case PS :
-                loadPDF();
-                return new PSExporter();
-            case EPS :
-                loadPDF();
-                return new EPSExporter();
-            default :
-                break;
+        case PNG :
+            return new PNGExporter();
+        case GIF :
+            return new GIFExporter();
+        case JPEG :
+            return new JPEGExporter();
+        case BMP :
+            return new BMPExporter();
+        case PPM :
+            return new PPMExporter();
+        case SVG :
+            if (!svgLoaded) {
+                ScilabCommonsUtils.loadOnUse(CLASSPATH_SVG_EXPORT_NAME);
+                svgLoaded = true;
+            }
+            return new SVGExporter();
+        case PDF :
+            loadPDF();
+            return new PDFExporter();
+        case PS :
+            loadPDF();
+            return new PSExporter();
+        case EPS :
+            loadPDF();
+            return new EPSExporter();
+        default :
+            break;
         }
 
         return null;
@@ -583,16 +590,18 @@ public class Export {
             ctx.setEmbeddedFontsOn(true);
             g2d = new SVGGraphics2D(ctx, false) {
 
-                public void drawString(String s, float x, float y) {
-                    textAsShapes = getFont().getFontName().startsWith("jlm");
-                    super.drawString(s, x, y);
-                }
+                    @Override
+                    public void drawString(String s, float x, float y) {
+                        textAsShapes = getFont().getFontName().startsWith("jlm");
+                        super.drawString(s, x, y);
+                    }
 
-                public void drawString(AttributedCharacterIterator ati, float x, float y) {
-                    textAsShapes = getFont().getFontName().startsWith("jlm");
-                    super.drawString(ati, x, y);
-                }
-            };
+                    @Override
+                    public void drawString(AttributedCharacterIterator ati, float x, float y) {
+                        textAsShapes = getFont().getFontName().startsWith("jlm");
+                        super.drawString(ati, x, y);
+                    }
+                };
             if (params.orientation == ExportParams.LANDSCAPE) {
                 g2d.setSVGCanvasSize(new Dimension(height, width));
                 AffineTransform transf = AffineTransform.getRotateInstance(Math.PI / 2);
@@ -712,16 +721,88 @@ public class Export {
                     out = new BufferedOutputStream(new FileOutputStream(file));
                 }
                 g2d = new PSDocumentGraphics2D(true, out, width, height) {
-                    @Override
-                    protected void writePageHeader() throws IOException {
-                        super.writePageHeader();
-                        if (params.orientation == ExportParams.LANDSCAPE) {
-                            gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Landscape");
-                        } else {
-                            gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Portrait");
+                        @Override
+                        protected void writePageHeader() throws IOException {
+                            super.writePageHeader();
+                            if (params.orientation == ExportParams.LANDSCAPE) {
+                                gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Landscape");
+                            } else {
+                                gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Portrait");
+                            }
+                            gen.writeln("/ReEncode { /MyEncoding exch def exch findfont dup length dict begin {def} forall /Encoding MyEncoding def currentdict end definefont } def");
+                            gen.writeln("/Helvetica /HelveticaLatin1 ISOLatin1Encoding ReEncode");
+                            gen.writeln("/Times /TimesLatin1 ISOLatin1Encoding ReEncode");
                         }
-                    }
-                };
+
+                        @Override
+                        public void drawString(String s, float x, float y) {
+                            if (s != null && !s.isEmpty()) {
+                                CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
+                                if (encoder.canEncode(s)) {
+                                    Font font = getFont();
+                                    boolean sserif = font.getName().equals("SansSerif");
+                                    boolean serif = font.getName().equals("Serif");
+                                    if (sserif || serif) {
+                                        try {
+                                            preparePainting();
+                                            establishColor(getColor());
+                                            gen.writeln((sserif ? "/HelveticaLatin1" : "/TimesLatin1") + " " + gen.formatDouble(getFont().getSize()) + " F");
+
+                                            gen.saveGraphicsState();
+                                            Shape imclip = getClip();
+                                            writeClip(imclip);
+
+                                            AffineTransform trans = getTransform();
+                                            boolean newTransform = gen.getCurrentState().checkTransform(trans) && !trans.isIdentity();
+
+                                            if (newTransform) {
+                                                gen.concatMatrix(trans);
+                                            }
+
+                                            gen.writeln(gen.formatDouble(x)
+                                                        + " " + gen.formatDouble(y)
+                                                        + " M 1 -1 scale");
+
+                                            StringBuffer buf = new StringBuffer("(");
+                                            for (int i = 0; i < s.length(); i++) {
+                                                PSGenerator.escapeChar(s.charAt(i), buf);
+                                            }
+                                            buf.append(") t");
+
+                                            gen.writeln(buf.toString());
+
+                                            gen.restoreGraphicsState();
+                                        } catch (IOException e) {
+                                            System.err.println(e);
+                                        }
+
+                                        return;
+                                    }
+                                }
+
+                                super.drawString(s, x, y);
+                            }
+                        }
+
+                        @Override
+                        public int processShape(Shape s) throws IOException {
+                            if (s instanceof Ellipse2D.Double) {
+                                Ellipse2D.Double ell = (Ellipse2D.Double) s;
+                                if (ell.height == ell.width) {
+                                    gen.writeln(gen.formatDouble(ell.x + ell.width / 2)
+                                                + " " + gen.formatDouble(ell.y + ell.height / 2)
+                                                + " " + gen.formatDouble(ell.width / 2)
+                                                + " " + gen.formatDouble(0d)
+                                                + " " + gen.formatDouble(360d)
+                                                + " arc cp");
+
+                                    return PathIterator.WIND_NON_ZERO;
+                                }
+                            }
+
+                            return super.processShape(s);
+                        }
+                    };
                 g2d.setGraphicContext(new GraphicContext());
             } catch (IOException e) { }
 
@@ -772,16 +853,89 @@ public class Export {
                     out = new BufferedOutputStream(new FileOutputStream(file));
                 }
                 g2d = new EPSDocumentGraphics2D(true) {
-                    @Override
-                    protected void writePageHeader() throws IOException {
-                        super.writePageHeader();
-                        if (params.orientation == ExportParams.LANDSCAPE) {
-                            gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Landscape");
-                        } else {
-                            gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Portrait");
+                        @Override
+                        protected void writePageHeader() throws IOException {
+                            super.writePageHeader();
+                            if (params.orientation == ExportParams.LANDSCAPE) {
+                                gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Landscape");
+                            } else {
+                                gen.writeDSCComment(DSCConstants.PAGE_ORIENTATION, "Portrait");
+                            }
+                            gen.writeln("/ReEncode { /MyEncoding exch def exch findfont dup length dict begin {def} forall /Encoding MyEncoding def currentdict end definefont } def");
+                            gen.writeln("/Helvetica /HelveticaLatin1 ISOLatin1Encoding ReEncode");
+                            gen.writeln("/Times /TimesLatin1 ISOLatin1Encoding ReEncode");
                         }
-                    }
-                };
+
+                        @Override
+                        public void drawString(String s, float x, float y) {
+                            if (s != null && !s.isEmpty()) {
+                                CharsetEncoder encoder = Charset.forName("ISO-8859-1").newEncoder();
+                                if (encoder.canEncode(s)) {
+                                    Font font = getFont();
+                                    boolean sserif = font.getName().equals("SansSerif");
+                                    boolean serif = font.getName().equals("Serif");
+                                    if (sserif || serif) {
+                                        try {
+                                            preparePainting();
+                                            establishColor(getColor());
+                                            gen.writeln((sserif ? "/HelveticaLatin1" : "/TimesLatin1") + " " + gen.formatDouble(getFont().getSize()) + " F");
+
+                                            gen.saveGraphicsState();
+                                            Shape imclip = getClip();
+                                            writeClip(imclip);
+
+                                            AffineTransform trans = getTransform();
+                                            boolean newTransform = gen.getCurrentState().checkTransform(trans) && !trans.isIdentity();
+
+                                            if (newTransform) {
+                                                gen.concatMatrix(trans);
+                                            }
+
+                                            gen.writeln(gen.formatDouble(x)
+                                                        + " " + gen.formatDouble(y)
+                                                        + " M 1 -1 scale");
+
+                                            StringBuffer buf = new StringBuffer("(");
+                                            for (int i = 0; i < s.length(); i++) {
+                                                PSGenerator.escapeChar(s.charAt(i), buf);
+                                            }
+                                            buf.append(") t");
+
+                                            gen.writeln(buf.toString());
+
+                                            gen.restoreGraphicsState();
+                                        } catch (IOException e) {
+                                            System.err.println(e);
+                                        }
+
+                                        return;
+                                    }
+                                }
+
+                                super.drawString(s, x, y);
+                            }
+                        }
+
+                        @Override
+                        public int processShape(Shape s) throws IOException {
+                            if (s instanceof Ellipse2D.Double) {
+                                Ellipse2D.Double ell = (Ellipse2D.Double) s;
+                                if (ell.height == ell.width) {
+                                    gen.writeln(gen.formatDouble(ell.x + ell.width / 2)
+                                                + " " + gen.formatDouble(ell.y + ell.height / 2)
+                                                + " " + gen.formatDouble(ell.width / 2)
+                                                + " " + gen.formatDouble(0d)
+                                                + " " + gen.formatDouble(360d)
+                                                + " arc cp");
+
+                                    return PathIterator.WIND_NON_ZERO;
+                                }
+                            }
+
+                            return super.processShape(s);
+                        }
+
+                    };
                 g2d.setupDocument(out, width, height);
                 g2d.setGraphicContext(new GraphicContext());
             } catch (IOException e) { }
index d1c7dd8..4070ada 100644 (file)
@@ -84,39 +84,39 @@ public class MarkSpriteFactory {
 
         if (finalSize != 1) {
             switch (mark.getStyle()) {
-                case  0:
-                    return new DotSpriteDrawer(foregroundColor, finalSize);
-                case  1:
-                    return new PlusSpriteDrawer(appearance, finalSize);
-                case  2:
-                    return new CrossSpriteDrawer(appearance, finalSize);
-                case  3:
-                    return new StarSpriteDrawer(appearance, finalSize);
-                case  4:
-                    return new FilledDiamondSpriteDrawer(foregroundColor, finalSize);
-                case  5:
-                    return new DiamondSpriteDrawer(appearance, finalSize);
-                case  6:
-                    return new TriangleUpSpriteDrawer(appearance, finalSize);
-                case  7:
-                    return new TriangleDownSpriteDrawer(appearance, finalSize);
-                case  8:
-                    return new DiamondPlusSpriteDrawer(appearance, finalSize);
-                case  9:
-                    return new CircleSpriteDrawer(appearance, finalSize);
-                case 10:
-                    return new AsteriskSpriteDrawer(appearance, finalSize);
-                case 11:
-                    return new SquareSpriteDrawer(appearance, finalSize);
-                case 12:
-                    return new TriangleRightSpriteDrawer(appearance, finalSize);
-                case 13:
-                    return new TriangleLeftSpriteDrawer(appearance, finalSize);
-                case 14:
-                    return new PentagramSpriteDrawer(appearance, finalSize);
-
-                default:
-                    return new PlusSpriteDrawer(appearance, finalSize);
+            case  0:
+                return new DotSpriteDrawer(foregroundColor, finalSize);
+            case  1:
+                return new PlusSpriteDrawer(appearance, finalSize);
+            case  2:
+                return new CrossSpriteDrawer(appearance, finalSize);
+            case  3:
+                return new StarSpriteDrawer(appearance, finalSize);
+            case  4:
+                return new FilledDiamondSpriteDrawer(foregroundColor, finalSize);
+            case  5:
+                return new DiamondSpriteDrawer(appearance, finalSize);
+            case  6:
+                return new TriangleUpSpriteDrawer(appearance, finalSize);
+            case  7:
+                return new TriangleDownSpriteDrawer(appearance, finalSize);
+            case  8:
+                return new DiamondPlusSpriteDrawer(appearance, finalSize);
+            case  9:
+                return new CircleSpriteDrawer(appearance, finalSize);
+            case 10:
+                return new AsteriskSpriteDrawer(appearance, finalSize);
+            case 11:
+                return new SquareSpriteDrawer(appearance, finalSize);
+            case 12:
+                return new TriangleRightSpriteDrawer(appearance, finalSize);
+            case 13:
+                return new TriangleLeftSpriteDrawer(appearance, finalSize);
+            case 14:
+                return new PentagramSpriteDrawer(appearance, finalSize);
+
+            default:
+                return new PlusSpriteDrawer(appearance, finalSize);
             }
         } else {
             return new PlusSpriteDrawer(appearance, finalSize);
@@ -177,20 +177,14 @@ public class MarkSpriteFactory {
      * Scilab ID = 1
      */
     private static class PlusSpriteDrawer extends ScilabSpriteDrawer {
-        private final int[] coordinate1;
-        private final int[] coordinate2;
 
         public PlusSpriteDrawer(Appearance appearance, int size) {
             super(appearance, size);
-            int r = size / 2;
-            coordinate1 = new int[] { -r, 0, r, 0};
-            coordinate2 = new int[] { 0, -r, 0, r};
         }
 
         @Override
         public void draw(TextureDrawingTools textureDrawingTools) {
-            textureDrawingTools.drawPolyline(coordinate1, appearance);
-            textureDrawingTools.drawPolyline(coordinate2, appearance);
+            textureDrawingTools.drawPlus(size, appearance);
         }
     }