Bug 12492 fixed: Exported EPS files were invalid when dash patterns were too long 60/13160/2
Calixte DENIZET [Fri, 15 Nov 2013 11:36:13 +0000 (12:36 +0100)]
Change-Id: Ic32b9734f3c2e50a8e8d44695a3b8ee836781812

scilab/CHANGES_5.5.X
scilab/modules/scirenderer/src/org/scilab/forge/scirenderer/implementation/g2d/motor/G2DStroke.java

index 060e8e2..df57beb 100644 (file)
@@ -76,6 +76,8 @@ Scilab Bug Fixes
 
 * Bug #11680 fixed - GUI functions in Scilab 5.4.X were much slower than in Scilab 5.3.3.
 
+* Bug #12492 fixed - Exported EPS files were invalid when dash patterns were too long.
+
 * Bug #12682 fixed - Key events were disabled after zooming.
 
 * Bug #12769 fixed - xset("window", 1) did not set the current axes.
index b107fd3..f2fbc86 100644 (file)
@@ -22,6 +22,9 @@ public class G2DStroke extends BasicStroke {
 
     private static final int[] array = new int[16];
     private static final G2DStroke BASIC = new G2DStroke(1, null, 0);
+    private static float[] prevArray;
+    private static float prevFactor = -1;
+    private static short prevPattern = -1;
 
     public G2DStroke(float lineWidth, float[] dash, float phase) {
         super(lineWidth, CAP_BUTT, JOIN_MITER, 10.0f, dash, phase);
@@ -49,7 +52,13 @@ public class G2DStroke extends BasicStroke {
             return new G2DStroke(factor, null, 0);
         }
 
-        return new G2DStroke(factor, decodePattern(factor, pattern), (float) dashPhase);
+        if (factor != prevFactor || pattern != prevPattern) {
+            prevFactor = factor;
+            prevPattern = pattern;
+            prevArray = decodePattern(factor, pattern);
+        }
+
+        return new G2DStroke(factor, prevArray, (float) dashPhase);
     }
 
     private static final float[] decodePattern(final float factor, short pattern) {
@@ -61,6 +70,19 @@ public class G2DStroke extends BasicStroke {
         int t = Integer.numberOfTrailingZeros(n);
         n = (n >> t);
         int k = Integer.numberOfLeadingZeros(n) - 16;
+
+        // Here we try to have a shorter pattern (EPS and PS don't like too long pattern in setdash function)
+        // If the pattern is 101101101101, we can factorize the number by 101 (101+101x1000+101x1000000+101x1000000000)
+        // so we test if the pattern can be divided by 101010...., by 100100100..., ...)
+        int twopm1 = (1 << 16) - 1;
+        for (int j = 2; 2 <= 16; j++) {
+            int q = twopm1 / ((1 << j) - 1);
+            if (n % q == 0) {
+                n = n / q;
+                break;
+            }
+        }
+
         while (n != 0) {
             t = Integer.numberOfTrailingZeros(n);
             if (t == 0) {