1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.utils.page;
\r
14 import java.awt.geom.Rectangle2D;
\r
15 import java.math.BigDecimal;
\r
16 import java.util.NoSuchElementException;
\r
17 import java.util.StringTokenizer;
\r
19 import org.simantics.utils.page.MarginUtils;
\r
20 import org.simantics.utils.page.MarginUtils.Margin;
\r
21 import org.simantics.utils.page.MarginUtils.Margins;
\r
24 * @see http://www.cl.cam.ac.uk/~mgk25/iso-paper.html for ISO paper dimensions
\r
26 * TODO: use DataType 0.4 for string serialization of PageDesc
\r
28 public class PageDesc {
\r
30 public static int toMillimeters(double points) {
\r
31 return (int) Math.round(points * (25.4/72.));
\r
34 public static int toPoints(double millimeters) {
\r
35 return (int) Math.round(millimeters* (72./25.4));
\r
38 public static final PageDesc INFINITE = new PageDesc("Infinite", PageOrientation.Portrait, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
\r
39 public static final PageDesc A0 = new PageDesc("A0", PageOrientation.Portrait, 841, 1189);
\r
40 public static final PageDesc A1 = new PageDesc("A1", PageOrientation.Portrait, 594, 841);
\r
41 public static final PageDesc A2 = new PageDesc("A2", PageOrientation.Portrait, 420, 594);
\r
42 public static final PageDesc A3 = new PageDesc("A3", PageOrientation.Portrait, 297, 420);
\r
43 public static final PageDesc A4 = new PageDesc("A4", PageOrientation.Portrait, 210, 297);
\r
44 public static final PageDesc A5 = new PageDesc("A5", PageOrientation.Portrait, 148, 210);
\r
45 public static final PageDesc A6 = new PageDesc("A6", PageOrientation.Portrait, 105, 148);
\r
46 public static final PageDesc A7 = new PageDesc("A7", PageOrientation.Portrait, 74, 105);
\r
47 public static final PageDesc A8 = new PageDesc("A8", PageOrientation.Portrait, 52, 74);
\r
48 public static final PageDesc A9 = new PageDesc("A9", PageOrientation.Portrait, 37, 52);
\r
49 public static final PageDesc A10 = new PageDesc("A10", PageOrientation.Portrait, 26, 37);
\r
50 public static final PageDesc[] A = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };
\r
51 public static final PageDesc[] items = { INFINITE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };
\r
52 /** List of PDF usable formats. A sub-set of items. */
\r
53 public static final PageDesc[] PDF_ITEMS = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };
\r
55 public static final PageDesc DEFAULT = A4;
\r
57 private final String text;
\r
59 private final PageOrientation orientation;
\r
61 private final double widthInMM;
\r
63 private final double heightInMM;
\r
65 private final PageCentering centering;
\r
67 private final Margins margins;
\r
70 public static PageDesc[] getPredefinedDescriptions() {
\r
74 public static PageDesc getByName(String pageDescName) {
\r
75 for (PageDesc item : items) {
\r
76 if ( item.getText().equals( pageDescName ) ) return item;
\r
81 public static PageDesc getDescription(String identification) {
\r
82 for (PageDesc pd : getPredefinedDescriptions()) {
\r
83 if (pd.getText().equals(identification))
\r
89 public static PageDesc getDescription(String identification, PageOrientation o) {
\r
90 for (PageDesc pd : getPredefinedDescriptions()) {
\r
91 if (pd.getText().equals(identification))
\r
92 return pd.withOrientation(o);
\r
97 public static PageDesc getDescription(PageOrientation o, double widthInMM, double heightInMM) {
\r
98 for (PageDesc pd : getPredefinedDescriptions()) {
\r
99 if (pd.widthInMM == widthInMM && pd.heightInMM == heightInMM)
\r
100 return pd.withOrientation(o);
\r
102 return new PageDesc("Custom", o, widthInMM, heightInMM);
\r
106 public PageDesc(String text, PageOrientation o, double widthInMM, double heightInMM) {
\r
107 this(text, o, PageCentering.TopLeftAtOrigin, widthInMM, heightInMM);
\r
110 public String toRepr() {
\r
111 return text + ":" + orientation + ":" + widthInMM + ":" + heightInMM
\r
112 + ":" + margins.top.diagramAbsolute
\r
113 + ":" + margins.bottom.diagramAbsolute
\r
114 + ":" + margins.left.diagramAbsolute
\r
115 + ":" + margins.right.diagramAbsolute;
\r
118 public static PageDesc fromRepr(String repr) {
\r
119 String[] parts = repr.split(":", 8);
\r
120 return new PageDesc(parts[0], PageOrientation.valueOf(parts[1]),
\r
121 PageCentering.TopLeftAtOrigin,
\r
122 Double.valueOf(parts[2]), Double.valueOf(parts[3]),
\r
124 MarginUtils.marginOf(0, 0, Double.valueOf(parts[4])),
\r
125 MarginUtils.marginOf(0, 0, Double.valueOf(parts[5])),
\r
126 MarginUtils.marginOf(0, 0, Double.valueOf(parts[6])),
\r
127 MarginUtils.marginOf(0, 0, Double.valueOf(parts[7]))
\r
132 public PageDesc(String text, PageOrientation o, PageCentering c, double widthInMM, double heightInMM) {
\r
133 this(text, o, c, widthInMM, heightInMM, MarginUtils.NO_MARGINS);
\r
136 public PageDesc(String text, PageOrientation o, PageCentering c, double widthInMM, double heightInMM, Margins margins) {
\r
138 throw new IllegalArgumentException("null orientation");
\r
141 this.orientation = o;
\r
142 this.centering = c;
\r
143 this.widthInMM = widthInMM;
\r
144 this.heightInMM = heightInMM;
\r
145 this.margins = margins;
\r
148 public boolean isInfinite() {
\r
149 return widthInMM == Double.POSITIVE_INFINITY || heightInMM == Double.POSITIVE_INFINITY;
\r
152 public String getText() {
\r
156 public PageOrientation getOrientation() {
\r
157 return orientation;
\r
160 public PageCentering getCentering() {
\r
164 public boolean contains(double x, double y) {
\r
168 if (x < 0 || y < 0)
\r
170 double maxX = getOrientedWidth();
\r
171 double maxY = getOrientedHeight();
\r
172 if (x > maxX || y > maxY)
\r
180 public double getLeftEdgePos() {
\r
181 if (centering == PageCentering.CenteredAroundOrigin)
\r
182 return -getOrientedWidth() * 0.5;
\r
189 public double getTopEdgePos() {
\r
190 if (centering == PageCentering.CenteredAroundOrigin)
\r
191 return -getOrientedHeight() * 0.5;
\r
196 * @return width dimension in millimeters
\r
198 public double getWidth() {
\r
203 * @return height dimension in millimeters
\r
205 public double getHeight() {
\r
210 * @return the margins associated with this page description
\r
212 public Margins getMargins() {
\r
217 * @return width dimension in millimeters with respect to the selected
\r
218 * canvas orientation
\r
220 public double getOrientedWidth() {
\r
221 if (orientation == PageOrientation.Portrait)
\r
227 * @return height dimension in millimeters with respect to the selected
\r
228 * canvas orientation
\r
230 public double getOrientedHeight() {
\r
231 if (orientation == PageOrientation.Portrait)
\r
236 public PageDesc withSizeFrom(PageDesc another) {
\r
237 return new PageDesc(text, orientation, centering, another.widthInMM, another.heightInMM, margins);
\r
240 public PageDesc withOrientation(PageOrientation o) {
\r
241 if (orientation.equals(o)) {
\r
244 return new PageDesc(text, o, centering, widthInMM, heightInMM, margins);
\r
247 public PageDesc withCentering(PageCentering c) {
\r
248 if (centering.equals(c)) {
\r
251 return new PageDesc(text, orientation, c, widthInMM, heightInMM, margins);
\r
254 public PageDesc withText(String text) {
\r
255 if (this.text.equals(text))
\r
257 return new PageDesc(text, orientation, centering, widthInMM, heightInMM, margins);
\r
260 public PageDesc withMargins(Margins margins) {
\r
261 return new PageDesc(text, orientation, centering, widthInMM, heightInMM, margins);
\r
264 public void getPageRectangle(Rectangle2D r) {
\r
266 throw new IllegalArgumentException("null rectangle");
\r
267 r.setFrame(getLeftEdgePos(), getTopEdgePos(), getOrientedWidth(), getOrientedHeight());
\r
270 public void getMarginsRectangle(Rectangle2D r) {
\r
272 throw new IllegalArgumentException("null rectangle");
\r
273 if (margins == null)
\r
274 getPageRectangle(r);
\r
276 r.setFrame(getLeftEdgePos()+margins.left.diagramAbsolute,
\r
277 getTopEdgePos()+margins.top.diagramAbsolute,
\r
278 getOrientedWidth()-(margins.left.diagramAbsolute+margins.right.diagramAbsolute),
\r
279 getOrientedHeight()-(margins.top.diagramAbsolute+margins.bottom.diagramAbsolute));
\r
283 public int hashCode() {
\r
284 final int PRIME = 31;
\r
287 temp = Double.doubleToLongBits(heightInMM);
\r
288 result = PRIME * result + (int) (temp ^ (temp >>> 32));
\r
289 temp = Double.doubleToLongBits(widthInMM);
\r
290 result = PRIME * result + (int) (temp ^ (temp >>> 32));
\r
291 result = PRIME * result + orientation.hashCode();
\r
292 result = PRIME * result + centering.hashCode();
\r
293 result = PRIME * result + margins.hashCode();
\r
298 public boolean equals(Object obj) {
\r
303 if (getClass() != obj.getClass())
\r
305 final PageDesc other = (PageDesc) obj;
\r
306 if (Double.doubleToLongBits(heightInMM) != Double.doubleToLongBits(other.heightInMM))
\r
308 if (Double.doubleToLongBits(widthInMM) != Double.doubleToLongBits(other.widthInMM))
\r
310 if (!orientation.equals(other.orientation))
\r
312 if (!centering.equals(other.centering))
\r
314 if (!margins.equals(other.margins))
\r
320 public String toString() {
\r
321 return String.format("%s [%s, %s, %s, %s, %s]%s", getClass().getSimpleName(), text, orientation.toString(), widthInMM, heightInMM, centering.toString(), margins);
\r
324 public static PageDesc deserialize(String desc, PageDesc defaultValue) {
\r
326 return defaultValue;
\r
328 PageDesc pd = null;
\r
330 StringTokenizer tok = new StringTokenizer(desc);
\r
331 String w = tok.nextToken().trim();
\r
332 String h = tok.nextToken().trim();
\r
333 String orientation = tok.nextToken().trim();
\r
334 String centering = tok.nextToken().trim();
\r
335 String text = tok.nextToken("\u0001").trim();
\r
336 String margins = tok.nextToken().trim();
\r
338 double ww = new BigDecimal(w).doubleValue();
\r
339 double hh = new BigDecimal(h).doubleValue();
\r
341 PageDesc pd2 = PageDesc.getDescription(PageOrientation.valueOf(orientation), ww, hh);
\r
342 pd2 = pd2.withCentering(PageCentering.valueOf(centering));
\r
343 pd2 = pd2.withText(text);
\r
344 pd2 = pd2.withMargins(deserializeMargins(margins, MarginUtils.NO_MARGINS));
\r
347 } catch (IllegalArgumentException e) {
\r
348 } catch (NoSuchElementException e) {
\r
355 public static String serialize(PageDesc desc) {
\r
356 //return desc.getText();
\r
357 return String.format("%s %s %s %s %s\u0001%s",
\r
358 Double.toString(desc.getWidth()),
\r
359 Double.toString(desc.getHeight()),
\r
360 desc.getOrientation().toString(),
\r
361 desc.getCentering().toString(),
\r
363 serialize(desc.getMargins()));
\r
366 public static String serialize(Margins margins) {
\r
367 StringBuilder sb = new StringBuilder();
\r
368 sb.append(serialize(margins.top));
\r
370 sb.append(serialize(margins.bottom));
\r
372 sb.append(serialize(margins.left));
\r
374 sb.append(serialize(margins.right));
\r
375 return sb.toString();
\r
378 private static String serialize(Margin margin) {
\r
379 StringBuilder sb = new StringBuilder();
\r
380 sb.append(margin.controlRelative);
\r
382 sb.append(margin.controlAbsolute);
\r
384 sb.append(margin.diagramAbsolute);
\r
385 return sb.toString();
\r
390 * @param defaultValue valid margins
\r
393 public static Margins deserializeMargins(String margins, Margins defaultValue) {
\r
394 if (defaultValue == null)
\r
395 throw new NullPointerException("null default value");
\r
397 String[] split = margins.split(";");
\r
398 if (split.length != 4)
\r
399 return defaultValue;
\r
401 Margin top = deserializeMargins(split[0], defaultValue.top);
\r
402 Margin bottom = deserializeMargins(split[1], defaultValue.bottom);
\r
403 Margin left = deserializeMargins(split[2], defaultValue.left);
\r
404 Margin right = deserializeMargins(split[3], defaultValue.right);
\r
405 return new Margins(top, bottom, left, right);
\r
410 * @param defaultValue a valid margin
\r
413 private static Margin deserializeMargins(String margin, Margin defaultValue) {
\r
414 if (defaultValue == null)
\r
415 throw new NullPointerException("null default value");
\r
418 StringTokenizer tok = new StringTokenizer(margin);
\r
419 String cr = tok.nextToken().trim();
\r
420 String ca = tok.nextToken().trim();
\r
421 String da = tok.nextToken().trim();
\r
422 return new Margin(Double.parseDouble(cr), Double.parseDouble(ca), Double.parseDouble(da));
\r
423 } catch (NumberFormatException e) {
\r
424 return defaultValue;
\r