|
| 1 | +/* |
| 2 | + * OpenSlide, a library for reading whole slide image files |
| 3 | + * |
| 4 | + * Copyright (c) 2007-2010 Carnegie Mellon University |
| 5 | + * All rights reserved. |
| 6 | + * |
| 7 | + * OpenSlide is free software: you can redistribute it and/or modify |
| 8 | + * it under the terms of the GNU Lesser General Public License as |
| 9 | + * published by the Free Software Foundation, version 2.1. |
| 10 | + * |
| 11 | + * OpenSlide is distributed in the hope that it will be useful, |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | + * GNU Lesser General Public License for more details. |
| 15 | + * |
| 16 | + * You should have received a copy of the GNU Lesser General Public |
| 17 | + * License along with OpenSlide. If not, see |
| 18 | + * <http://www.gnu.org/licenses/>. |
| 19 | + * |
| 20 | + */ |
| 21 | + |
1 | 22 | package edu.cmu.cs.openslide.gui; |
2 | 23 |
|
3 | | -import java.awt.Rectangle; |
4 | 24 | import java.awt.Shape; |
5 | | -import java.awt.geom.*; |
6 | | -import java.util.Collections; |
7 | | -import java.util.HashMap; |
8 | | -import java.util.Map; |
9 | | - |
10 | | -public class Annotation { |
11 | | - public static class Bean { |
12 | | - public static class Pair { |
13 | | - public Pair(String name, String value) { |
14 | | - this.name = name; |
15 | | - this.value = value; |
16 | | - } |
17 | | - |
18 | | - public Pair() { |
19 | | - }; |
20 | | - |
21 | | - public String getName() { |
22 | | - return name; |
23 | | - } |
24 | | - |
25 | | - public void setName(String name) { |
26 | | - this.name = name; |
27 | | - } |
28 | | - |
29 | | - public String getValue() { |
30 | | - return value; |
31 | | - } |
32 | | - |
33 | | - public void setValue(String value) { |
34 | | - this.value = value; |
35 | | - } |
36 | | - |
37 | | - private String name; |
38 | | - |
39 | | - private String value; |
40 | | - } |
41 | | - |
42 | | - private Pair annotations[]; |
43 | | - |
44 | | - private String shape; |
45 | | - |
46 | | - public String getShape() { |
47 | | - return shape; |
48 | | - } |
49 | | - |
50 | | - public Pair[] getAnnotations() { |
51 | | - return annotations; |
52 | | - } |
53 | | - |
54 | | - public void setAnnotations(Pair[] annotations) { |
55 | | - this.annotations = annotations; |
56 | | - } |
57 | | - |
58 | | - public void setShape(String shape) { |
59 | | - this.shape = shape; |
60 | | - } |
61 | | - |
62 | | - public Bean() { |
63 | | - } |
64 | | - |
65 | | - public Annotation toAnnotation() { |
66 | | - Map<String, String> annotations; |
67 | | - if (this.annotations != null) { |
68 | | - annotations = new HashMap<String, String>(); |
69 | | - for (int i = 0; i < this.annotations.length; i++) { |
70 | | - Pair p = this.annotations[i]; |
71 | | - annotations.put(p.getName(), p.getValue()); |
72 | | - } |
73 | | - } else { |
74 | | - annotations = Collections.emptyMap(); |
75 | | - } |
76 | | - |
77 | | - String[] segs = shape.split(" "); |
78 | | - Path2D p = new Path2D.Double(); |
79 | | - |
80 | | - int i = 0; |
81 | | - while (i < segs.length) { |
82 | | - switch (segs[i++].charAt(0)) { |
83 | | - case 'Z': |
84 | | - p.closePath(); |
85 | | - break; |
86 | | - case 'C': |
87 | | - p.curveTo(Double.parseDouble(segs[i++]), Double |
88 | | - .parseDouble(segs[i++]), Double |
89 | | - .parseDouble(segs[i++]), Double |
90 | | - .parseDouble(segs[i++]), Double |
91 | | - .parseDouble(segs[i++]), Double |
92 | | - .parseDouble(segs[i++])); |
93 | | - break; |
94 | | - case 'L': |
95 | | - p.lineTo(Double.parseDouble(segs[i++]), Double |
96 | | - .parseDouble(segs[i++])); |
97 | | - break; |
98 | | - case 'M': |
99 | | - p.moveTo(Double.parseDouble(segs[i++]), Double |
100 | | - .parseDouble(segs[i++])); |
101 | | - break; |
102 | | - case 'Q': |
103 | | - p.quadTo(Double.parseDouble(segs[i++]), Double |
104 | | - .parseDouble(segs[i++]), Double |
105 | | - .parseDouble(segs[i++]), Double |
106 | | - .parseDouble(segs[i++])); |
107 | | - break; |
108 | | - } |
109 | | - } |
110 | | - return new Annotation(p, annotations); |
111 | | - } |
112 | | - |
113 | | - Bean(Shape shape, Map<String, String> annotations) { |
114 | | - this.shape = serialize(shape); |
115 | | - this.annotations = new Pair[annotations.size()]; |
116 | | - int i = 0; |
117 | | - for (Map.Entry<String, String> e : annotations.entrySet()) { |
118 | | - this.annotations[i] = new Pair(e.getKey(), e.getValue()); |
119 | | - i++; |
120 | | - } |
121 | | - } |
122 | | - |
123 | | - private static String serialize(Shape s) { |
124 | | - PathIterator p = s.getPathIterator(null); |
125 | | - StringBuilder sb = new StringBuilder(); |
126 | | - |
127 | | - while (!p.isDone()) { |
128 | | - double coords[] = new double[6]; |
129 | | - |
130 | | - switch (p.currentSegment(coords)) { |
131 | | - case PathIterator.SEG_CLOSE: |
132 | | - sb.append(" Z"); |
133 | | - break; |
134 | | - case PathIterator.SEG_CUBICTO: |
135 | | - sb.append(" C"); |
136 | | - sb.append(" " + coords[0]); |
137 | | - sb.append(" " + coords[1]); |
138 | | - sb.append(" " + coords[2]); |
139 | | - sb.append(" " + coords[3]); |
140 | | - sb.append(" " + coords[4]); |
141 | | - sb.append(" " + coords[5]); |
142 | | - break; |
143 | | - case PathIterator.SEG_LINETO: |
144 | | - sb.append(" L"); |
145 | | - sb.append(" " + coords[0]); |
146 | | - sb.append(" " + coords[1]); |
147 | | - break; |
148 | | - case PathIterator.SEG_MOVETO: |
149 | | - sb.append(" M"); |
150 | | - sb.append(" " + coords[0]); |
151 | | - sb.append(" " + coords[1]); |
152 | | - break; |
153 | | - case PathIterator.SEG_QUADTO: |
154 | | - sb.append(" Q"); |
155 | | - sb.append(" " + coords[0]); |
156 | | - sb.append(" " + coords[1]); |
157 | | - sb.append(" " + coords[2]); |
158 | | - sb.append(" " + coords[3]); |
159 | | - sb.append(" " + coords[4]); |
160 | | - sb.append(" " + coords[5]); |
161 | | - break; |
162 | | - } |
163 | | - |
164 | | - p.next(); |
165 | | - } |
166 | | - return sb.toString().trim(); |
167 | | - } |
168 | | - } |
169 | | - |
170 | | - final private Map<String, String> annotations; |
171 | | - |
172 | | - final private Shape shape; |
173 | | - |
174 | | - final static private Map<String, String> EMPTY_MAP = Collections.emptyMap(); |
175 | | - |
176 | | - public Annotation(Shape shape, Map<String, String> annotations) { |
177 | | - if (shape == null) { |
178 | | - throw new NullPointerException("shape cannot be null"); |
179 | | - } |
180 | | - this.shape = new ImmutableShape(shape); |
181 | | - |
182 | | - this.annotations = Collections.unmodifiableMap(annotations); |
183 | | - } |
184 | | - |
185 | | - public Annotation(Shape shape) { |
186 | | - this(shape, EMPTY_MAP); |
187 | | - } |
188 | | - |
189 | | - public Map<String, String> getAnnotations() { |
190 | | - return annotations; |
191 | | - } |
192 | | - |
193 | | - public Shape getShape() { |
194 | | - return shape; |
195 | | - } |
196 | | - |
197 | | - final private static class ImmutableShape implements Shape { |
198 | | - final private Shape shape; |
199 | | - |
200 | | - public boolean contains(double x, double y, double w, double h) { |
201 | | - return shape.contains(x, y, w, h); |
202 | | - } |
203 | | - |
204 | | - public boolean contains(double x, double y) { |
205 | | - return shape.contains(x, y); |
206 | | - } |
207 | | - |
208 | | - public boolean contains(Point2D p) { |
209 | | - return shape.contains(p); |
210 | | - } |
211 | | - |
212 | | - public boolean contains(Rectangle2D r) { |
213 | | - return shape.contains(r); |
214 | | - } |
215 | | - |
216 | | - public Rectangle getBounds() { |
217 | | - return shape.getBounds(); |
218 | | - } |
219 | | - |
220 | | - public Rectangle2D getBounds2D() { |
221 | | - return shape.getBounds2D(); |
222 | | - } |
223 | | - |
224 | | - public PathIterator getPathIterator(AffineTransform at, double flatness) { |
225 | | - return shape.getPathIterator(at, flatness); |
226 | | - } |
227 | | - |
228 | | - public PathIterator getPathIterator(AffineTransform at) { |
229 | | - return shape.getPathIterator(at); |
230 | | - } |
231 | | - |
232 | | - public boolean intersects(double x, double y, double w, double h) { |
233 | | - return shape.intersects(x, y, w, h); |
234 | | - } |
235 | 25 |
|
236 | | - public boolean intersects(Rectangle2D r) { |
237 | | - return shape.intersects(r); |
238 | | - } |
| 26 | +public interface Annotation { |
239 | 27 |
|
240 | | - public ImmutableShape(Shape s) { |
241 | | - shape = s; |
242 | | - } |
243 | | - } |
| 28 | + Shape getShape(); |
244 | 29 |
|
245 | | - public Bean toBean() { |
246 | | - return new Bean(shape, annotations); |
247 | | - } |
248 | 30 | } |
0 commit comments