--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils.page;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+import java.math.BigDecimal;\r
+import java.util.NoSuchElementException;\r
+import java.util.StringTokenizer;\r
+\r
+import org.simantics.utils.page.MarginUtils;\r
+import org.simantics.utils.page.MarginUtils.Margin;\r
+import org.simantics.utils.page.MarginUtils.Margins;\r
+\r
+/**\r
+ * @see http://www.cl.cam.ac.uk/~mgk25/iso-paper.html for ISO paper dimensions\r
+ * \r
+ * TODO: use DataType 0.4 for string serialization of PageDesc\r
+ */\r
+public class PageDesc {\r
+\r
+ public static int toMillimeters(double points) {\r
+ return (int) Math.round(points * (25.4/72.));\r
+ }\r
+\r
+ public static int toPoints(double millimeters) {\r
+ return (int) Math.round(millimeters* (72./25.4));\r
+ }\r
+\r
+ public static final PageDesc INFINITE = new PageDesc("Infinite", PageOrientation.Portrait, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);\r
+ public static final PageDesc A0 = new PageDesc("A0", PageOrientation.Portrait, 841, 1189);\r
+ public static final PageDesc A1 = new PageDesc("A1", PageOrientation.Portrait, 594, 841);\r
+ public static final PageDesc A2 = new PageDesc("A2", PageOrientation.Portrait, 420, 594);\r
+ public static final PageDesc A3 = new PageDesc("A3", PageOrientation.Portrait, 297, 420);\r
+ public static final PageDesc A4 = new PageDesc("A4", PageOrientation.Portrait, 210, 297);\r
+ public static final PageDesc A5 = new PageDesc("A5", PageOrientation.Portrait, 148, 210);\r
+ public static final PageDesc A6 = new PageDesc("A6", PageOrientation.Portrait, 105, 148);\r
+ public static final PageDesc A7 = new PageDesc("A7", PageOrientation.Portrait, 74, 105);\r
+ public static final PageDesc A8 = new PageDesc("A8", PageOrientation.Portrait, 52, 74);\r
+ public static final PageDesc A9 = new PageDesc("A9", PageOrientation.Portrait, 37, 52);\r
+ public static final PageDesc A10 = new PageDesc("A10", PageOrientation.Portrait, 26, 37);\r
+ public static final PageDesc[] A = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };\r
+ public static final PageDesc[] items = { INFINITE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };\r
+ /** List of PDF usable formats. A sub-set of items. */\r
+ public static final PageDesc[] PDF_ITEMS = { A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 };\r
+\r
+ public static final PageDesc DEFAULT = A4;\r
+\r
+ private final String text;\r
+\r
+ private final PageOrientation orientation;\r
+\r
+ private final double widthInMM;\r
+\r
+ private final double heightInMM;\r
+\r
+ private final PageCentering centering;\r
+\r
+ private final Margins margins;\r
+\r
+\r
+ public static PageDesc[] getPredefinedDescriptions() {\r
+ return items;\r
+ }\r
+ \r
+ public static PageDesc getByName(String pageDescName) {\r
+ for (PageDesc item : items) {\r
+ if ( item.getText().equals( pageDescName ) ) return item;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public static PageDesc getDescription(String identification) {\r
+ for (PageDesc pd : getPredefinedDescriptions()) {\r
+ if (pd.getText().equals(identification))\r
+ return pd;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public static PageDesc getDescription(String identification, PageOrientation o) {\r
+ for (PageDesc pd : getPredefinedDescriptions()) {\r
+ if (pd.getText().equals(identification))\r
+ return pd.withOrientation(o);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public static PageDesc getDescription(PageOrientation o, double widthInMM, double heightInMM) {\r
+ for (PageDesc pd : getPredefinedDescriptions()) {\r
+ if (pd.widthInMM == widthInMM && pd.heightInMM == heightInMM)\r
+ return pd.withOrientation(o);\r
+ }\r
+ return new PageDesc("Custom", o, widthInMM, heightInMM);\r
+ }\r
+\r
+\r
+ public PageDesc(String text, PageOrientation o, double widthInMM, double heightInMM) {\r
+ this(text, o, PageCentering.TopLeftAtOrigin, widthInMM, heightInMM);\r
+ }\r
+\r
+ public String toRepr() {\r
+ return text + ":" + orientation + ":" + widthInMM + ":" + heightInMM\r
+ + ":" + margins.top.diagramAbsolute\r
+ + ":" + margins.bottom.diagramAbsolute\r
+ + ":" + margins.left.diagramAbsolute\r
+ + ":" + margins.right.diagramAbsolute; \r
+ }\r
+ \r
+ public static PageDesc fromRepr(String repr) {\r
+ String[] parts = repr.split(":", 8);\r
+ return new PageDesc(parts[0], PageOrientation.valueOf(parts[1]), \r
+ PageCentering.TopLeftAtOrigin,\r
+ Double.valueOf(parts[2]), Double.valueOf(parts[3]),\r
+ new Margins(\r
+ MarginUtils.marginOf(0, 0, Double.valueOf(parts[4])),\r
+ MarginUtils.marginOf(0, 0, Double.valueOf(parts[5])),\r
+ MarginUtils.marginOf(0, 0, Double.valueOf(parts[6])),\r
+ MarginUtils.marginOf(0, 0, Double.valueOf(parts[7]))\r
+ )\r
+ );\r
+ }\r
+\r
+ public PageDesc(String text, PageOrientation o, PageCentering c, double widthInMM, double heightInMM) {\r
+ this(text, o, c, widthInMM, heightInMM, MarginUtils.NO_MARGINS);\r
+ }\r
+\r
+ public PageDesc(String text, PageOrientation o, PageCentering c, double widthInMM, double heightInMM, Margins margins) {\r
+ if (o == null)\r
+ throw new IllegalArgumentException("null orientation");\r
+\r
+ this.text = text;\r
+ this.orientation = o;\r
+ this.centering = c;\r
+ this.widthInMM = widthInMM;\r
+ this.heightInMM = heightInMM;\r
+ this.margins = margins;\r
+ }\r
+\r
+ public boolean isInfinite() {\r
+ return widthInMM == Double.POSITIVE_INFINITY || heightInMM == Double.POSITIVE_INFINITY;\r
+ }\r
+\r
+ public String getText() {\r
+ return text;\r
+ }\r
+\r
+ public PageOrientation getOrientation() {\r
+ return orientation;\r
+ }\r
+\r
+ public PageCentering getCentering() {\r
+ return centering;\r
+ }\r
+\r
+ public boolean contains(double x, double y) {\r
+ if (isInfinite())\r
+ return true;\r
+\r
+ if (x < 0 || y < 0)\r
+ return false;\r
+ double maxX = getOrientedWidth();\r
+ double maxY = getOrientedHeight();\r
+ if (x > maxX || y > maxY)\r
+ return false;\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * @return\r
+ */\r
+ public double getLeftEdgePos() {\r
+ if (centering == PageCentering.CenteredAroundOrigin)\r
+ return -getOrientedWidth() * 0.5;\r
+ return 0.0;\r
+ }\r
+\r
+ /**\r
+ * @return\r
+ */\r
+ public double getTopEdgePos() {\r
+ if (centering == PageCentering.CenteredAroundOrigin)\r
+ return -getOrientedHeight() * 0.5;\r
+ return 0.0;\r
+ }\r
+\r
+ /**\r
+ * @return width dimension in millimeters\r
+ */\r
+ public double getWidth() {\r
+ return widthInMM;\r
+ }\r
+\r
+ /**\r
+ * @return height dimension in millimeters\r
+ */\r
+ public double getHeight() {\r
+ return heightInMM;\r
+ }\r
+\r
+ /**\r
+ * @return the margins associated with this page description\r
+ */\r
+ public Margins getMargins() {\r
+ return margins;\r
+ }\r
+\r
+ /**\r
+ * @return width dimension in millimeters with respect to the selected\r
+ * canvas orientation\r
+ */\r
+ public double getOrientedWidth() {\r
+ if (orientation == PageOrientation.Portrait)\r
+ return widthInMM;\r
+ return heightInMM;\r
+ }\r
+\r
+ /**\r
+ * @return height dimension in millimeters with respect to the selected\r
+ * canvas orientation\r
+ */\r
+ public double getOrientedHeight() {\r
+ if (orientation == PageOrientation.Portrait)\r
+ return heightInMM;\r
+ return widthInMM;\r
+ }\r
+\r
+ public PageDesc withSizeFrom(PageDesc another) {\r
+ return new PageDesc(text, orientation, centering, another.widthInMM, another.heightInMM, margins);\r
+ }\r
+\r
+ public PageDesc withOrientation(PageOrientation o) {\r
+ if (orientation.equals(o)) {\r
+ return this;\r
+ }\r
+ return new PageDesc(text, o, centering, widthInMM, heightInMM, margins);\r
+ }\r
+\r
+ public PageDesc withCentering(PageCentering c) {\r
+ if (centering.equals(c)) {\r
+ return this;\r
+ }\r
+ return new PageDesc(text, orientation, c, widthInMM, heightInMM, margins);\r
+ }\r
+\r
+ public PageDesc withText(String text) {\r
+ if (this.text.equals(text))\r
+ return this;\r
+ return new PageDesc(text, orientation, centering, widthInMM, heightInMM, margins);\r
+ }\r
+\r
+ public PageDesc withMargins(Margins margins) {\r
+ return new PageDesc(text, orientation, centering, widthInMM, heightInMM, margins);\r
+ }\r
+\r
+ public void getPageRectangle(Rectangle2D r) {\r
+ if (r == null)\r
+ throw new IllegalArgumentException("null rectangle");\r
+ r.setFrame(getLeftEdgePos(), getTopEdgePos(), getOrientedWidth(), getOrientedHeight());\r
+ }\r
+ \r
+ public void getMarginsRectangle(Rectangle2D r) {\r
+ if (r == null)\r
+ throw new IllegalArgumentException("null rectangle");\r
+ if (margins == null)\r
+ getPageRectangle(r);\r
+ else\r
+ r.setFrame(getLeftEdgePos()+margins.left.diagramAbsolute,\r
+ getTopEdgePos()+margins.top.diagramAbsolute,\r
+ getOrientedWidth()-(margins.left.diagramAbsolute+margins.right.diagramAbsolute),\r
+ getOrientedHeight()-(margins.top.diagramAbsolute+margins.bottom.diagramAbsolute));\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ final int PRIME = 31;\r
+ int result = 1;\r
+ long temp;\r
+ temp = Double.doubleToLongBits(heightInMM);\r
+ result = PRIME * result + (int) (temp ^ (temp >>> 32));\r
+ temp = Double.doubleToLongBits(widthInMM);\r
+ result = PRIME * result + (int) (temp ^ (temp >>> 32));\r
+ result = PRIME * result + orientation.hashCode();\r
+ result = PRIME * result + centering.hashCode();\r
+ result = PRIME * result + margins.hashCode();\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj)\r
+ return true;\r
+ if (obj == null)\r
+ return false;\r
+ if (getClass() != obj.getClass())\r
+ return false;\r
+ final PageDesc other = (PageDesc) obj;\r
+ if (Double.doubleToLongBits(heightInMM) != Double.doubleToLongBits(other.heightInMM))\r
+ return false;\r
+ if (Double.doubleToLongBits(widthInMM) != Double.doubleToLongBits(other.widthInMM))\r
+ return false;\r
+ if (!orientation.equals(other.orientation))\r
+ return false;\r
+ if (!centering.equals(other.centering))\r
+ return false;\r
+ if (!margins.equals(other.margins))\r
+ return false;\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return String.format("%s [%s, %s, %s, %s, %s]%s", getClass().getSimpleName(), text, orientation.toString(), widthInMM, heightInMM, centering.toString(), margins);\r
+ }\r
+\r
+ public static PageDesc deserialize(String desc, PageDesc defaultValue) {\r
+ if (desc == null)\r
+ return defaultValue;\r
+\r
+ PageDesc pd = null;\r
+ try {\r
+ StringTokenizer tok = new StringTokenizer(desc);\r
+ String w = tok.nextToken().trim();\r
+ String h = tok.nextToken().trim();\r
+ String orientation = tok.nextToken().trim();\r
+ String centering = tok.nextToken().trim();\r
+ String text = tok.nextToken("\u0001").trim();\r
+ String margins = tok.nextToken().trim();\r
+\r
+ double ww = new BigDecimal(w).doubleValue();\r
+ double hh = new BigDecimal(h).doubleValue();\r
+\r
+ PageDesc pd2 = PageDesc.getDescription(PageOrientation.valueOf(orientation), ww, hh);\r
+ pd2 = pd2.withCentering(PageCentering.valueOf(centering));\r
+ pd2 = pd2.withText(text);\r
+ pd2 = pd2.withMargins(deserializeMargins(margins, MarginUtils.NO_MARGINS));\r
+\r
+ pd = pd2;\r
+ } catch (IllegalArgumentException e) {\r
+ } catch (NoSuchElementException e) {\r
+ }\r
+ if (pd == null)\r
+ pd = defaultValue;\r
+ return pd;\r
+ }\r
+\r
+ public static String serialize(PageDesc desc) {\r
+ //return desc.getText();\r
+ return String.format("%s %s %s %s %s\u0001%s",\r
+ Double.toString(desc.getWidth()),\r
+ Double.toString(desc.getHeight()),\r
+ desc.getOrientation().toString(),\r
+ desc.getCentering().toString(),\r
+ desc.getText(),\r
+ serialize(desc.getMargins()));\r
+ }\r
+\r
+ public static String serialize(Margins margins) {\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(serialize(margins.top));\r
+ sb.append(";");\r
+ sb.append(serialize(margins.bottom));\r
+ sb.append(";");\r
+ sb.append(serialize(margins.left));\r
+ sb.append(";");\r
+ sb.append(serialize(margins.right));\r
+ return sb.toString();\r
+ }\r
+\r
+ private static String serialize(Margin margin) {\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append(margin.controlRelative);\r
+ sb.append(" ");\r
+ sb.append(margin.controlAbsolute);\r
+ sb.append(" ");\r
+ sb.append(margin.diagramAbsolute);\r
+ return sb.toString();\r
+ }\r
+\r
+ /**\r
+ * @param margins\r
+ * @param defaultValue valid margins\r
+ * @return\r
+ */\r
+ public static Margins deserializeMargins(String margins, Margins defaultValue) {\r
+ if (defaultValue == null)\r
+ throw new NullPointerException("null default value");\r
+\r
+ String[] split = margins.split(";");\r
+ if (split.length != 4)\r
+ return defaultValue;\r
+\r
+ Margin top = deserializeMargins(split[0], defaultValue.top);\r
+ Margin bottom = deserializeMargins(split[1], defaultValue.bottom);\r
+ Margin left = deserializeMargins(split[2], defaultValue.left);\r
+ Margin right = deserializeMargins(split[3], defaultValue.right);\r
+ return new Margins(top, bottom, left, right);\r
+ }\r
+\r
+ /**\r
+ * @param margin\r
+ * @param defaultValue a valid margin\r
+ * @return\r
+ */\r
+ private static Margin deserializeMargins(String margin, Margin defaultValue) {\r
+ if (defaultValue == null)\r
+ throw new NullPointerException("null default value");\r
+\r
+ try {\r
+ StringTokenizer tok = new StringTokenizer(margin);\r
+ String cr = tok.nextToken().trim();\r
+ String ca = tok.nextToken().trim();\r
+ String da = tok.nextToken().trim();\r
+ return new Margin(Double.parseDouble(cr), Double.parseDouble(ca), Double.parseDouble(da));\r
+ } catch (NumberFormatException e) {\r
+ return defaultValue;\r
+ }\r
+ }\r
+\r
+}\r