]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/utils/GridUtil.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / utils / GridUtil.java
diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/utils/GridUtil.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/utils/GridUtil.java
new file mode 100644 (file)
index 0000000..b8caadb
--- /dev/null
@@ -0,0 +1,247 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * 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.g2d.utils;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Font;\r
+import java.awt.FontMetrics;\r
+import java.awt.Graphics2D;\r
+import java.awt.font.FontRenderContext;\r
+import java.awt.font.GlyphVector;\r
+import java.awt.font.LineMetrics;\r
+import java.awt.geom.Line2D;\r
+import java.text.Format;\r
+\r
+import org.simantics.scenegraph.utils.GridUtils;\r
+\r
+public class GridUtil {\r
+\r
+    public static final BasicStroke GRID_LINE_STROKE;\r
+    public static final BasicStroke RULER_LINE_STROKE;\r
+    public static final Font RULER_FONT;    \r
+    public static final Font RULER_FONT_BOLD;    \r
+       public static final FontRenderContext frc = new FontRenderContext(null, true, true);                            \r
+\r
+    static {\r
+       RULER_LINE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f);\r
+       GRID_LINE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f);\r
+       RULER_FONT = new Font("Tahoma", Font.PLAIN, 12);\r
+       RULER_FONT_BOLD = new Font("Tahoma", Font.BOLD, 12);\r
+    }\r
+    \r
+    public GridUtil() {\r
+    }\r
+       \r
+    public static void paintGridLines(\r
+               GridSpacing xgrid, GridSpacing ygrid, \r
+               Graphics2D g, \r
+               double xMin, double yMax, \r
+               double controlWidth, \r
+               double controlHeightForVerticalLines,\r
+               double controlHeightForHorizLines) {\r
+       \r
+       g.setStroke(GRID_LINE_STROKE);\r
+        Line2D line = new Line2D.Double();\r
+       \r
+       if (xgrid != null) {\r
+               // Vertical lines\r
+               double controlX = GridUtils.distanceToNextGridCoordScaled(xMin, xgrid.segment, xgrid.pixelsPerUnit);\r
+       \r
+               while (controlX <= controlWidth+0.1) {\r
+                       line.setLine(controlX, 0, controlX, (int) (controlHeightForVerticalLines - 1));\r
+                       g.draw(line);\r
+                   controlX += xgrid.pixelsPerSegment;\r
+               }\r
+       }\r
+\r
+        // Horizontal lines\r
+        if (ygrid != null) {\r
+               double canvasDiff = GridUtils.distanceToNextGridCoord(yMax, ygrid.segment);\r
+               double controlY = controlHeightForHorizLines - canvasDiff * ygrid.pixelsPerUnit;\r
+               \r
+               while (controlY >= -0.1) {\r
+                       line.setLine(0, controlY, (int) (controlWidth - 1), controlY);\r
+                       g.draw(line);           \r
+                   controlY -= ygrid.pixelsPerSegment;\r
+               }\r
+        }\r
+    }\r
+    \r
+    public static void paintHorizontalRuler(\r
+               GridSpacing grid, \r
+               Graphics2D g, \r
+               double xMin, \r
+               double controlWidth,  \r
+               Format labelFormat) {           \r
+       g.setStroke(RULER_LINE_STROKE);\r
+        \r
+        // Draw ticks\r
+       double canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment);\r
+       double canvasX = xMin + canvasDiff;\r
+        double controlX = canvasDiff * grid.pixelsPerUnit;\r
+        Line2D line = new Line2D.Double();\r
+        line.setLine(0, 3, controlWidth, 3);\r
+        g.draw(line);\r
+               \r
+        while (controlX <= controlWidth + 0.1) {\r
+               line.setLine(controlX, 3, controlX, 8);\r
+               g.draw(line);\r
+            controlX += grid.pixelsPerSegment;\r
+        }\r
+\r
+        // Labels\r
+        Font font = RULER_FONT;\r
+        g.setFont(RULER_FONT);\r
+        FontMetrics fm = g.getFontMetrics(font);\r
+\r
+       canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment);\r
+       double canvasStart = canvasX = xMin + canvasDiff;\r
+        controlX = canvasDiff * grid.pixelsPerUnit;\r
+                \r
+        int i = 0;\r
+        while (controlX <= controlWidth + 0.1) {\r
+               String value = labelFormat.format( canvasX );\r
+               double labelCenter = fm.getStringBounds(value, g).getCenterX();\r
+               g.drawString(value, (float) (controlX-labelCenter), (float) 20);\r
+            controlX += grid.pixelsPerSegment;\r
+            canvasX = canvasStart + grid.segment * (++i);\r
+        }\r
+        \r
+    }\r
+    \r
+    public static void paintVerticalRuler(\r
+               GridSpacing grid, \r
+               Graphics2D g, \r
+               double yMin, \r
+               double controlHeight, \r
+               Format labelFormat) {\r
+       \r
+       g.setStroke(RULER_LINE_STROKE);\r
+       \r
+        // Draw ticks\r
+       double canvasDiff = GridUtils.distanceToNextGridCoord(yMin+grid.segment, grid.segment);\r
+        double controlY = controlHeight - canvasDiff * grid.pixelsPerUnit;\r
+        Line2D line = new Line2D.Double();\r
+        line.setLine(3, 0, 3, controlHeight);\r
+        g.draw(line);\r
+        \r
+        while (controlY >= -0.1) {\r
+               line.setLine(3, controlY, 8, controlY);\r
+               g.draw( line );\r
+            controlY -= grid.pixelsPerSegment;\r
+        }\r
+        \r
+        // Labels\r
+        g.setFont(RULER_FONT);\r
+        FontMetrics fm = g.getFontMetrics(RULER_FONT);\r
+       canvasDiff = GridUtils.distanceToNextGridCoord(yMin, grid.segment);\r
+       double canvasY = yMin + canvasDiff;\r
+       double canvasStart = canvasY;\r
+        controlY = controlHeight - canvasDiff * grid.pixelsPerUnit;\r
+        int i=0;\r
+        while (controlY >= -0.1) {\r
+               String value = labelFormat.format( canvasY );\r
+               LineMetrics lm = fm.getLineMetrics(value, g);\r
+     \r
+               g.drawString(value, (float) 13, (float) (controlY+lm.getAscent()/2)-1);\r
+            controlY -= grid.pixelsPerSegment;\r
+            canvasY = canvasStart + grid.segment * (++i);\r
+        }\r
+    }\r
+\r
+    public static void paintVerticalSlaveRuler(\r
+               GridSpacing masterGrid, \r
+               GridSpacing slaveGrid, \r
+               Graphics2D g, \r
+               double yMinMaster, double yMinSlave, \r
+               double controlHeight, \r
+               Format labelFormat) {\r
+       \r
+       g.setStroke(RULER_LINE_STROKE);\r
+       \r
+        // Draw ticks\r
+       double canvasDiff = GridUtils.distanceToNextGridCoord(yMinMaster+masterGrid.segment, masterGrid.segment);\r
+       double controlDiff = canvasDiff * masterGrid.pixelsPerUnit;\r
+        double startY = controlHeight - controlDiff;\r
+        double controlY = startY;\r
+        Line2D line = new Line2D.Double();\r
+        line.setLine(3, 0, 3, controlHeight);\r
+        g.draw(line);\r
+        \r
+        while (controlY >= -0.1) {\r
+               line.setLine(3, controlY, 8, controlY);\r
+               g.draw( line );\r
+            controlY -= masterGrid.pixelsPerSegment;\r
+        }\r
+        \r
+        // Labels\r
+        g.setFont(RULER_FONT);\r
+        FontMetrics fm = g.getFontMetrics(RULER_FONT);\r
+       canvasDiff = GridUtils.distanceToNextGridCoord(yMinMaster, masterGrid.segment);\r
+       double masterY = yMinMaster + canvasDiff;\r
+       double canvasStart = masterY;\r
+        controlY = controlHeight - canvasDiff * masterGrid.pixelsPerUnit;\r
+//        double slaveGridSegment = masterGrid.pixelsPerSegment * slaveGrid.unitsPerPixel;\r
+        int i=0;\r
+        while (controlY >= -0.1) {\r
+//            System.out.println("controlY="+controlY+", canvasY="+masterY);\r
+            // Convert value from master coordinates to slave            \r
+            double slaveY = (masterY - yMinMaster) * masterGrid.pixelsPerUnit * slaveGrid.unitsPerPixel + yMinSlave;\r
+            if (Math.abs(slaveY) < 1e-5) slaveY=0.0;\r
+               String value = labelFormat.format( slaveY );\r
+               LineMetrics lm = fm.getLineMetrics(value, g);\r
+     \r
+               g.drawString(value, (float) 13, (float) (controlY+lm.getAscent()/2)-1);\r
+            controlY -= masterGrid.pixelsPerSegment;\r
+            masterY = canvasStart + masterGrid.segment * (++i);\r
+        }\r
+    }\r
+    \r
+    public static int getTickCount(GridSpacing grid, double yMin, double controlHeight)\r
+    {\r
+       double canvasDiff = GridUtils.distanceToNextGridCoord(yMin+grid.segment, grid.segment);\r
+        double startY = controlHeight - canvasDiff * grid.pixelsPerUnit;\r
+        double x = startY / grid.pixelsPerSegment;\r
+       return (int) Math.ceil( x );\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Estimate label width, by sampling values from xMin to xMax\r
+     * using given font and format.\r
+     * \r
+     * @param xMin\r
+     * @param xMax\r
+     * @param format\r
+     * @return\r
+     */\r
+    public static double calcLabelWidth(double xMin, double xMax, Format format, GridSpacing grid)\r
+    { \r
+       double width = 0.0;     \r
+       double canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment);\r
+       int c = 0;\r
+       for (double x=xMin + canvasDiff; x<xMax; x+=grid.segment) {\r
+               boolean nearZero = (x < 0.000000000001) && (x > -0.000000000001);\r
+               if (nearZero) x = 0.0;\r
+               String label = format.format(x);\r
+               if (label==null || label.equals("")) continue;\r
+               GlyphVector glyphVector;\r
+                       glyphVector = RULER_FONT.createGlyphVector(frc, label);\r
+            double labelWidth = glyphVector.getVisualBounds().getWidth();\r
+            width = Math.max( width, labelWidth );\r
+            if (c++ > 100) break;            \r
+       }\r
+       return width * 1.05;\r
+    }\r
+    \r
+       \r
+}\r