]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils/src/org/simantics/utils/page/PageDesc.java
Prevent NPEs in ViewUtils layout loading code
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / page / PageDesc.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.utils.page;
13
14 import java.awt.geom.Rectangle2D;
15 import java.math.BigDecimal;
16 import java.util.NoSuchElementException;
17 import java.util.StringTokenizer;
18
19 import org.simantics.utils.page.MarginUtils;
20 import org.simantics.utils.page.MarginUtils.Margin;
21 import org.simantics.utils.page.MarginUtils.Margins;
22
23 /**
24  * @see http://www.cl.cam.ac.uk/~mgk25/iso-paper.html for ISO paper dimensions
25  * 
26  * TODO: use DataType 0.4 for string serialization of PageDesc
27  */
28 public class PageDesc {
29
30     public static int toMillimeters(double points) {
31         return (int) Math.round(points * (25.4/72.));
32     }
33
34     public static int toPoints(double millimeters) {
35         return (int) Math.round(millimeters* (72./25.4));
36     }
37
38     public static final PageDesc  INFINITE = new PageDesc("Infinite", PageOrientation.Portrait, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
39     public static final PageDesc  A0                    = new PageDesc("A0", PageOrientation.Portrait, 841, 1189);
40     public static final PageDesc  A1                    = new PageDesc("A1", PageOrientation.Portrait, 594, 841);
41     public static final PageDesc  A2                    = new PageDesc("A2", PageOrientation.Portrait, 420, 594);
42     public static final PageDesc  A3                    = new PageDesc("A3", PageOrientation.Portrait, 297, 420);
43     public static final PageDesc  A4                    = new PageDesc("A4", PageOrientation.Portrait, 210, 297);
44     public static final PageDesc  A5                    = new PageDesc("A5", PageOrientation.Portrait, 148, 210);
45     public static final PageDesc  A6                    = new PageDesc("A6", PageOrientation.Portrait, 105, 148);
46     public static final PageDesc  A7                    = new PageDesc("A7", PageOrientation.Portrait, 74, 105);
47     public static final PageDesc  A8                    = new PageDesc("A8", PageOrientation.Portrait, 52, 74);
48     public static final PageDesc  A9                    = new PageDesc("A9", PageOrientation.Portrait, 37, 52);
49     public static final PageDesc  A10                   = new PageDesc("A10", PageOrientation.Portrait, 26, 37);
50     public static final PageDesc[]     A = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };
51     public static final PageDesc[]     items    = { INFINITE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };
52     /** List of PDF usable formats. A sub-set of items. */
53     public static final PageDesc[]     PDF_ITEMS    = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };
54
55     public static final PageDesc  DEFAULT  = A4;
56
57     private final String          text;
58
59     private final PageOrientation orientation;
60
61     private final double          widthInMM;
62
63     private final double          heightInMM;
64
65     private final PageCentering   centering;
66
67     private final Margins         margins;
68
69
70     public static PageDesc[] getPredefinedDescriptions() {
71         return items;
72     }
73     
74     public static PageDesc getByName(String pageDescName) {
75         for (PageDesc item : items) {
76                 if ( item.getText().equals( pageDescName ) ) return item;
77         }
78         return null;
79     }
80
81     public static PageDesc getDescription(String identification) {
82         for (PageDesc pd : getPredefinedDescriptions()) {
83             if (pd.getText().equals(identification))
84                 return pd;
85         }
86         return null;
87     }
88
89     public static PageDesc getDescription(String identification, PageOrientation o) {
90         for (PageDesc pd : getPredefinedDescriptions()) {
91             if (pd.getText().equals(identification))
92                 return pd.withOrientation(o);
93         }
94         return null;
95     }
96
97     public static PageDesc getDescription(PageOrientation o, double widthInMM, double heightInMM) {
98         for (PageDesc pd : getPredefinedDescriptions()) {
99             if (pd.widthInMM == widthInMM && pd.heightInMM == heightInMM)
100                 return pd.withOrientation(o);
101         }
102         return new PageDesc("Custom", o, widthInMM, heightInMM);
103     }
104
105
106     public PageDesc(String text, PageOrientation o, double widthInMM, double heightInMM) {
107         this(text, o, PageCentering.TopLeftAtOrigin, widthInMM, heightInMM);
108     }
109
110     public String toRepr() {
111         return text + ":" + orientation + ":" + widthInMM + ":" + heightInMM
112                 + ":" + margins.top.diagramAbsolute
113                 + ":" + margins.bottom.diagramAbsolute
114                 + ":" + margins.left.diagramAbsolute
115                 + ":" + margins.right.diagramAbsolute; 
116     }
117     
118     public static PageDesc fromRepr(String repr) {
119         String[] parts = repr.split(":", 8);
120         return new PageDesc(parts[0], PageOrientation.valueOf(parts[1]), 
121                 PageCentering.TopLeftAtOrigin,
122                 Double.valueOf(parts[2]), Double.valueOf(parts[3]),
123                 new Margins(
124                         MarginUtils.marginOf(0, 0, Double.valueOf(parts[4])),
125                         MarginUtils.marginOf(0, 0, Double.valueOf(parts[5])),
126                         MarginUtils.marginOf(0, 0, Double.valueOf(parts[6])),
127                         MarginUtils.marginOf(0, 0, Double.valueOf(parts[7]))
128                         )
129                 );
130     }
131
132     public PageDesc(String text, PageOrientation o, PageCentering c, double widthInMM, double heightInMM) {
133         this(text, o, c, widthInMM, heightInMM, MarginUtils.NO_MARGINS);
134     }
135
136     public PageDesc(String text, PageOrientation o, PageCentering c, double widthInMM, double heightInMM, Margins margins) {
137         if (o == null)
138             throw new IllegalArgumentException("null orientation");
139
140         this.text = text;
141         this.orientation = o;
142         this.centering = c;
143         this.widthInMM = widthInMM;
144         this.heightInMM = heightInMM;
145         this.margins = margins;
146     }
147
148     public boolean isInfinite() {
149         return widthInMM == Double.POSITIVE_INFINITY || heightInMM == Double.POSITIVE_INFINITY;
150     }
151
152     public String getText() {
153         return text;
154     }
155
156     public PageOrientation getOrientation() {
157         return orientation;
158     }
159
160     public PageCentering getCentering() {
161         return centering;
162     }
163
164     public boolean contains(double x, double y) {
165         if (isInfinite())
166             return true;
167
168         if (x < 0 || y < 0)
169             return false;
170         double maxX = getOrientedWidth();
171         double maxY = getOrientedHeight();
172         if (x > maxX || y > maxY)
173             return false;
174         return true;
175     }
176
177     /**
178      * @return
179      */
180     public double getLeftEdgePos() {
181         if (centering == PageCentering.CenteredAroundOrigin)
182             return -getOrientedWidth() * 0.5;
183         return 0.0;
184     }
185
186     /**
187      * @return
188      */
189     public double getTopEdgePos() {
190         if (centering == PageCentering.CenteredAroundOrigin)
191             return -getOrientedHeight() * 0.5;
192         return 0.0;
193     }
194
195     /**
196      * @return width dimension in millimeters
197      */
198     public double getWidth() {
199         return widthInMM;
200     }
201
202     /**
203      * @return height dimension in millimeters
204      */
205     public double getHeight() {
206         return heightInMM;
207     }
208
209     /**
210      * @return the margins associated with this page description
211      */
212     public Margins getMargins() {
213         return margins;
214     }
215
216     /**
217      * @return width dimension in millimeters with respect to the selected
218      *         canvas orientation
219      */
220     public double getOrientedWidth() {
221         if (orientation == PageOrientation.Portrait)
222             return widthInMM;
223         return heightInMM;
224     }
225
226     /**
227      * @return height dimension in millimeters with respect to the selected
228      *         canvas orientation
229      */
230     public double getOrientedHeight() {
231         if (orientation == PageOrientation.Portrait)
232             return heightInMM;
233         return widthInMM;
234     }
235
236     public PageDesc withSizeFrom(PageDesc another) {
237         return new PageDesc(text, orientation, centering, another.widthInMM, another.heightInMM, margins);
238     }
239
240     public PageDesc withOrientation(PageOrientation o) {
241         if (orientation.equals(o)) {
242             return this;
243         }
244         return new PageDesc(text, o, centering, widthInMM, heightInMM, margins);
245     }
246
247     public PageDesc withCentering(PageCentering c) {
248         if (centering.equals(c)) {
249             return this;
250         }
251         return new PageDesc(text, orientation, c, widthInMM, heightInMM, margins);
252     }
253
254     public PageDesc withText(String text) {
255         if (this.text.equals(text))
256             return this;
257         return new PageDesc(text, orientation, centering, widthInMM, heightInMM, margins);
258     }
259
260     public PageDesc withMargins(Margins margins) {
261         return new PageDesc(text, orientation, centering, widthInMM, heightInMM, margins);
262     }
263
264     public void getPageRectangle(Rectangle2D r) {
265         if (r == null)
266             throw new IllegalArgumentException("null rectangle");
267         r.setFrame(getLeftEdgePos(), getTopEdgePos(), getOrientedWidth(), getOrientedHeight());
268     }
269     
270     public void getMarginsRectangle(Rectangle2D r) {
271         if (r == null)
272             throw new IllegalArgumentException("null rectangle");
273         if (margins == null)
274                 getPageRectangle(r);
275         else
276                 r.setFrame(getLeftEdgePos()+margins.left.diagramAbsolute,
277                                    getTopEdgePos()+margins.top.diagramAbsolute,
278                                    getOrientedWidth()-(margins.left.diagramAbsolute+margins.right.diagramAbsolute),
279                                    getOrientedHeight()-(margins.top.diagramAbsolute+margins.bottom.diagramAbsolute));
280     }
281
282     @Override
283     public int hashCode() {
284         final int PRIME = 31;
285         int result = 1;
286         long temp;
287         temp = Double.doubleToLongBits(heightInMM);
288         result = PRIME * result + (int) (temp ^ (temp >>> 32));
289         temp = Double.doubleToLongBits(widthInMM);
290         result = PRIME * result + (int) (temp ^ (temp >>> 32));
291         result = PRIME * result + orientation.hashCode();
292         result = PRIME * result + centering.hashCode();
293         result = PRIME * result + margins.hashCode();
294         return result;
295     }
296
297     @Override
298     public boolean equals(Object obj) {
299         if (this == obj)
300             return true;
301         if (obj == null)
302             return false;
303         if (getClass() != obj.getClass())
304             return false;
305         final PageDesc other = (PageDesc) obj;
306         if (Double.doubleToLongBits(heightInMM) != Double.doubleToLongBits(other.heightInMM))
307             return false;
308         if (Double.doubleToLongBits(widthInMM) != Double.doubleToLongBits(other.widthInMM))
309             return false;
310         if (!orientation.equals(other.orientation))
311             return false;
312         if (!centering.equals(other.centering))
313             return false;
314         if (!margins.equals(other.margins))
315             return false;
316         return true;
317     }
318
319     @Override
320     public String toString() {
321         return String.format("%s [%s, %s, %s, %s, %s]%s", getClass().getSimpleName(), text, orientation.toString(), widthInMM, heightInMM, centering.toString(), margins);
322     }
323
324     public static PageDesc deserialize(String desc, PageDesc defaultValue) {
325         if (desc == null)
326             return defaultValue;
327
328         PageDesc pd = null;
329         try {
330             StringTokenizer tok = new StringTokenizer(desc);
331             String w = tok.nextToken().trim();
332             String h = tok.nextToken().trim();
333             String orientation = tok.nextToken().trim();
334             String centering = tok.nextToken().trim();
335             String text = tok.nextToken("\u0001").trim();
336             String margins = tok.nextToken().trim();
337
338             double ww = new BigDecimal(w).doubleValue();
339             double hh = new BigDecimal(h).doubleValue();
340
341             PageDesc pd2 = PageDesc.getDescription(PageOrientation.valueOf(orientation), ww, hh);
342             pd2 = pd2.withCentering(PageCentering.valueOf(centering));
343             pd2 = pd2.withText(text);
344             pd2 = pd2.withMargins(deserializeMargins(margins, MarginUtils.NO_MARGINS));
345
346             pd = pd2;
347         } catch (IllegalArgumentException e) {
348         } catch (NoSuchElementException e) {
349         }
350         if (pd == null)
351             pd = defaultValue;
352         return pd;
353     }
354
355     public static String serialize(PageDesc desc) {
356         //return desc.getText();
357         return String.format("%s %s %s %s %s\u0001%s",
358                 Double.toString(desc.getWidth()),
359                 Double.toString(desc.getHeight()),
360                 desc.getOrientation().toString(),
361                 desc.getCentering().toString(),
362                 desc.getText(),
363                 serialize(desc.getMargins()));
364     }
365
366     public static String serialize(Margins margins) {
367         StringBuilder sb = new StringBuilder();
368         sb.append(serialize(margins.top));
369         sb.append(";");
370         sb.append(serialize(margins.bottom));
371         sb.append(";");
372         sb.append(serialize(margins.left));
373         sb.append(";");
374         sb.append(serialize(margins.right));
375         return sb.toString();
376     }
377
378     private static String serialize(Margin margin) {
379         StringBuilder sb = new StringBuilder();
380         sb.append(margin.controlRelative);
381         sb.append(" ");
382         sb.append(margin.controlAbsolute);
383         sb.append(" ");
384         sb.append(margin.diagramAbsolute);
385         return sb.toString();
386     }
387
388     /**
389      * @param margins
390      * @param defaultValue valid margins
391      * @return
392      */
393     public static Margins deserializeMargins(String margins, Margins defaultValue) {
394         if (defaultValue == null)
395             throw new NullPointerException("null default value");
396
397         String[] split = margins.split(";");
398         if (split.length != 4)
399             return defaultValue;
400
401         Margin top = deserializeMargins(split[0], defaultValue.top);
402         Margin bottom = deserializeMargins(split[1], defaultValue.bottom);
403         Margin left = deserializeMargins(split[2], defaultValue.left);
404         Margin right = deserializeMargins(split[3], defaultValue.right);
405         return new Margins(top, bottom, left, right);
406     }
407
408     /**
409      * @param margin
410      * @param defaultValue a valid margin
411      * @return
412      */
413     private static Margin deserializeMargins(String margin, Margin defaultValue) {
414         if (defaultValue == null)
415             throw new NullPointerException("null default value");
416
417         try {
418             StringTokenizer tok = new StringTokenizer(margin);
419             String cr = tok.nextToken().trim();
420             String ca = tok.nextToken().trim();
421             String da = tok.nextToken().trim();
422             return new Margin(Double.parseDouble(cr), Double.parseDouble(ca), Double.parseDouble(da));
423         } catch (NumberFormatException e) {
424             return defaultValue;
425         }
426     }
427
428 }