1
2 package org.freehep.graphicsio.emf.gdi;
3
4 import org.freehep.graphicsio.emf.EMFConstants;
5 import org.freehep.graphicsio.emf.EMFRenderer;
6
7 import java.util.logging.Logger;
8 import java.awt.BasicStroke;
9 import java.awt.Shape;
10 import java.awt.Stroke;
11 import java.awt.geom.AffineTransform;
12 import java.awt.geom.Rectangle2D;
13
14
15
16
17
18 public abstract class AbstractPen implements EMFConstants, GDIObject {
19
20
21
22
23
24 private class InsideFrameStroke implements Stroke {
25
26 private BasicStroke stroke;
27
28 public InsideFrameStroke (
29 float width,
30 int cap,
31 int join,
32 float miterlimit,
33 float dash[],
34 float dash_phase) {
35
36 stroke = new BasicStroke(width, cap, join, miterlimit, dash, dash_phase);
37 }
38
39 public Shape createStrokedShape(Shape shape) {
40 if (shape == null) {
41 return null;
42 }
43
44 Rectangle2D oldBounds = shape.getBounds2D();
45 float witdh = stroke.getLineWidth();
46
47
48
49 AffineTransform at = new AffineTransform();
50 if (oldBounds.getWidth() > 0) {
51 at.scale(
52 (oldBounds.getWidth() - witdh) /
53 oldBounds.getWidth(), 1);
54 }
55
56 if (oldBounds.getHeight() > 0) {
57 at.scale(1,
58 (oldBounds.getHeight() - witdh)
59 / oldBounds.getHeight());
60 }
61
62
63 shape = at.createTransformedShape(shape);
64 Rectangle2D newBounds = shape.getBounds2D();
65
66
67 AffineTransform moveBackTransform = AffineTransform.getTranslateInstance(
68 oldBounds.getX() - newBounds.getX() + witdh / 2,
69 oldBounds.getY() - newBounds.getY() + witdh / 2);
70 shape = moveBackTransform.createTransformedShape(shape);
71
72
73 return stroke.createStrokedShape(shape);
74 }
75 }
76
77
78
79
80 private static final Logger logger = Logger.getLogger("org.freehep.graphicsio.emf");
81
82
83
84
85
86
87 protected int getJoin(int penStyle) {
88 switch (penStyle & 0xF000) {
89 case EMFConstants.PS_JOIN_ROUND:
90 return BasicStroke.JOIN_ROUND;
91 case EMFConstants.PS_JOIN_BEVEL:
92 return BasicStroke.JOIN_BEVEL;
93 case EMFConstants.PS_JOIN_MITER:
94 return BasicStroke.JOIN_MITER;
95 default:
96 logger.warning("got unsupported pen style " + penStyle);
97 return BasicStroke.JOIN_ROUND;
98 }
99 }
100
101
102
103
104
105
106 protected int getCap(int penStyle) {
107 switch (penStyle & 0xF00) {
108 case EMFConstants.PS_ENDCAP_ROUND:
109 return BasicStroke.CAP_ROUND;
110 case EMFConstants.PS_ENDCAP_SQUARE:
111 return BasicStroke.CAP_SQUARE;
112 case EMFConstants.PS_ENDCAP_FLAT:
113 return BasicStroke.CAP_BUTT;
114 default:
115 logger.warning("got unsupported pen style " + penStyle);
116 return BasicStroke.CAP_ROUND;
117 }
118 }
119
120
121
122
123
124
125
126 protected float[] getDash(int penStyle, int[] style) {
127 switch (penStyle & 0xFF) {
128 case EMFConstants.PS_SOLID:
129
130
131 return null;
132 case EMFConstants.PS_DASH:
133 return new float[] { 5, 5 };
134 case EMFConstants.PS_DOT:
135 return new float[] { 1, 2 };
136 case EMFConstants.PS_DASHDOT:
137 return new float[] { 5, 2, 1, 2 };
138 case EMFConstants.PS_DASHDOTDOT:
139 return new float[] { 5, 2, 1, 2, 1, 2 };
140 case EMFConstants.PS_INSIDEFRAME:
141
142
143 return null;
144 case EMFConstants.PS_NULL:
145
146
147 return null;
148 case EMFConstants.PS_USERSTYLE:
149 if (style != null && style.length > 0) {
150 float[] result = new float[style.length];
151 for (int i = 0; i < style.length; i++) {
152 result[i] = style[i];
153 }
154 return result;
155 } else {
156 return null;
157 }
158 default:
159 logger.warning("got unsupported pen style " + penStyle);
160
161
162 return null;
163 }
164 }
165
166
167
168
169
170 private boolean isInsideFrameStroke(int penStyle) {
171 return (penStyle & 0xFF) == EMFConstants.PS_INSIDEFRAME;
172 }
173
174 protected Stroke createStroke(
175 EMFRenderer renderer,
176 int penStyle,
177 int[] style,
178 float width) {
179
180 if (isInsideFrameStroke(penStyle)) {
181 return new InsideFrameStroke(
182 width,
183 getCap(penStyle),
184 getJoin(penStyle),
185 renderer.getMeterLimit(),
186 getDash(penStyle, style),
187 0);
188 } else {
189 return new BasicStroke(
190 width,
191 getCap(penStyle),
192 getJoin(penStyle),
193 renderer.getMeterLimit(),
194 getDash(penStyle, style),
195 0);
196 }
197 }
198 }