Bug 12212 fixed: Export a polyline in 2D broke it into several segments
[scilab.git] / scilab / modules / scirenderer / src / org / scilab / forge / scirenderer / implementation / g2d / motor / G2DStroke.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte Denizet
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  */
11
12 package org.scilab.forge.scirenderer.implementation.g2d.motor;
13
14 import java.awt.BasicStroke;
15 import java.awt.Stroke;
16 import java.util.HashMap;
17 import java.util.Map;
18
19 import org.scilab.forge.scirenderer.shapes.appearance.Appearance;
20
21 /**
22  * @author Calixte DENIZET
23  */
24 public class G2DStroke extends BasicStroke {
25
26     private static final int[] array = new int[16];
27     private static final G2DStroke BASIC = new G2DStroke(1, null, 0);
28
29     public G2DStroke(float lineWidth, float[] dash, float phase) {
30         super(lineWidth, CAP_BUTT, JOIN_MITER, 10.0f, dash, phase);
31     }
32
33     public static G2DStroke getStroke(Appearance appearance, double dashPhase) {
34         Appearance usedAppearance;
35         if (appearance == null) {
36             usedAppearance = new Appearance();
37         } else {
38             usedAppearance = appearance;
39         }
40
41         float factor = usedAppearance.getLineWidth();
42         if (factor == 0) {
43             return new G2DStroke(0, null, 0);
44         }
45
46         short pattern = usedAppearance.getLinePattern();
47         if (pattern == -1 ) {
48             if (factor == 1) {
49                 return BASIC;
50             }
51
52             return new G2DStroke(factor, null, 0);
53         }
54
55         return new G2DStroke(factor, decodePattern(factor, pattern), (float) dashPhase);
56     }
57
58     private static final float[] decodePattern(final float factor, short pattern) {
59         // If the pattern is 1111101011111010, from right to left it becomes
60         // 0101111101011111, the first 0 is put on the right 1011111010111110 and it is converted into
61         // 1, 1, 5, 1, 1, 1, 5, 1
62         int n = 0xFFFF & pattern;
63         int i = 0;
64         int t = Integer.numberOfTrailingZeros(n);
65         n = (n >> t);
66         int k = Integer.numberOfLeadingZeros(n) - 16;
67         while (n != 0) {
68             t = Integer.numberOfTrailingZeros(n);
69             if (t == 0) {
70                 t = Integer.numberOfTrailingZeros(0xFFFF - n);
71             }
72
73             array[i++] = t;
74             n = n >> t;
75         }
76         array[i] = k;
77
78         float[] ret = new float[i + 1];
79
80         for (int j = 0; j <= i; j++) {
81             ret[j] = ((float) array[j]) * factor;
82         }
83
84         return ret;
85     }
86 }