X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Futils%2FGridUtil.java;h=5114f1a660656771595a6a5375e1465d96c82e78;hp=b8caadb9ffab1ff79ac36b1de87bf41117f65acf;hb=78d831a19c254d829e45d04c5ec6a3057680b7d7;hpb=969bd23cab98a79ca9101af33334000879fb60c5 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 index b8caadb9f..5114f1a66 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/utils/GridUtil.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/utils/GridUtil.java @@ -1,247 +1,260 @@ -/******************************************************************************* - * Copyright (c) 2007, 2011 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.g2d.utils; - -import java.awt.BasicStroke; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.LineMetrics; -import java.awt.geom.Line2D; -import java.text.Format; - -import org.simantics.scenegraph.utils.GridUtils; - -public class GridUtil { - - public static final BasicStroke GRID_LINE_STROKE; - public static final BasicStroke RULER_LINE_STROKE; - public static final Font RULER_FONT; - public static final Font RULER_FONT_BOLD; - public static final FontRenderContext frc = new FontRenderContext(null, true, true); - - static { - RULER_LINE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f); - GRID_LINE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f); - RULER_FONT = new Font("Tahoma", Font.PLAIN, 12); - RULER_FONT_BOLD = new Font("Tahoma", Font.BOLD, 12); - } - - public GridUtil() { - } - - public static void paintGridLines( - GridSpacing xgrid, GridSpacing ygrid, - Graphics2D g, - double xMin, double yMax, - double controlWidth, - double controlHeightForVerticalLines, - double controlHeightForHorizLines) { - - g.setStroke(GRID_LINE_STROKE); - Line2D line = new Line2D.Double(); - - if (xgrid != null) { - // Vertical lines - double controlX = GridUtils.distanceToNextGridCoordScaled(xMin, xgrid.segment, xgrid.pixelsPerUnit); - - while (controlX <= controlWidth+0.1) { - line.setLine(controlX, 0, controlX, (int) (controlHeightForVerticalLines - 1)); - g.draw(line); - controlX += xgrid.pixelsPerSegment; - } - } - - // Horizontal lines - if (ygrid != null) { - double canvasDiff = GridUtils.distanceToNextGridCoord(yMax, ygrid.segment); - double controlY = controlHeightForHorizLines - canvasDiff * ygrid.pixelsPerUnit; - - while (controlY >= -0.1) { - line.setLine(0, controlY, (int) (controlWidth - 1), controlY); - g.draw(line); - controlY -= ygrid.pixelsPerSegment; - } - } - } - - public static void paintHorizontalRuler( - GridSpacing grid, - Graphics2D g, - double xMin, - double controlWidth, - Format labelFormat) { - g.setStroke(RULER_LINE_STROKE); - - // Draw ticks - double canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment); - double canvasX = xMin + canvasDiff; - double controlX = canvasDiff * grid.pixelsPerUnit; - Line2D line = new Line2D.Double(); - line.setLine(0, 3, controlWidth, 3); - g.draw(line); - - while (controlX <= controlWidth + 0.1) { - line.setLine(controlX, 3, controlX, 8); - g.draw(line); - controlX += grid.pixelsPerSegment; - } - - // Labels - Font font = RULER_FONT; - g.setFont(RULER_FONT); - FontMetrics fm = g.getFontMetrics(font); - - canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment); - double canvasStart = canvasX = xMin + canvasDiff; - controlX = canvasDiff * grid.pixelsPerUnit; - - int i = 0; - while (controlX <= controlWidth + 0.1) { - String value = labelFormat.format( canvasX ); - double labelCenter = fm.getStringBounds(value, g).getCenterX(); - g.drawString(value, (float) (controlX-labelCenter), (float) 20); - controlX += grid.pixelsPerSegment; - canvasX = canvasStart + grid.segment * (++i); - } - - } - - public static void paintVerticalRuler( - GridSpacing grid, - Graphics2D g, - double yMin, - double controlHeight, - Format labelFormat) { - - g.setStroke(RULER_LINE_STROKE); - - // Draw ticks - double canvasDiff = GridUtils.distanceToNextGridCoord(yMin+grid.segment, grid.segment); - double controlY = controlHeight - canvasDiff * grid.pixelsPerUnit; - Line2D line = new Line2D.Double(); - line.setLine(3, 0, 3, controlHeight); - g.draw(line); - - while (controlY >= -0.1) { - line.setLine(3, controlY, 8, controlY); - g.draw( line ); - controlY -= grid.pixelsPerSegment; - } - - // Labels - g.setFont(RULER_FONT); - FontMetrics fm = g.getFontMetrics(RULER_FONT); - canvasDiff = GridUtils.distanceToNextGridCoord(yMin, grid.segment); - double canvasY = yMin + canvasDiff; - double canvasStart = canvasY; - controlY = controlHeight - canvasDiff * grid.pixelsPerUnit; - int i=0; - while (controlY >= -0.1) { - String value = labelFormat.format( canvasY ); - LineMetrics lm = fm.getLineMetrics(value, g); - - g.drawString(value, (float) 13, (float) (controlY+lm.getAscent()/2)-1); - controlY -= grid.pixelsPerSegment; - canvasY = canvasStart + grid.segment * (++i); - } - } - - public static void paintVerticalSlaveRuler( - GridSpacing masterGrid, - GridSpacing slaveGrid, - Graphics2D g, - double yMinMaster, double yMinSlave, - double controlHeight, - Format labelFormat) { - - g.setStroke(RULER_LINE_STROKE); - - // Draw ticks - double canvasDiff = GridUtils.distanceToNextGridCoord(yMinMaster+masterGrid.segment, masterGrid.segment); - double controlDiff = canvasDiff * masterGrid.pixelsPerUnit; - double startY = controlHeight - controlDiff; - double controlY = startY; - Line2D line = new Line2D.Double(); - line.setLine(3, 0, 3, controlHeight); - g.draw(line); - - while (controlY >= -0.1) { - line.setLine(3, controlY, 8, controlY); - g.draw( line ); - controlY -= masterGrid.pixelsPerSegment; - } - - // Labels - g.setFont(RULER_FONT); - FontMetrics fm = g.getFontMetrics(RULER_FONT); - canvasDiff = GridUtils.distanceToNextGridCoord(yMinMaster, masterGrid.segment); - double masterY = yMinMaster + canvasDiff; - double canvasStart = masterY; - controlY = controlHeight - canvasDiff * masterGrid.pixelsPerUnit; -// double slaveGridSegment = masterGrid.pixelsPerSegment * slaveGrid.unitsPerPixel; - int i=0; - while (controlY >= -0.1) { -// System.out.println("controlY="+controlY+", canvasY="+masterY); - // Convert value from master coordinates to slave - double slaveY = (masterY - yMinMaster) * masterGrid.pixelsPerUnit * slaveGrid.unitsPerPixel + yMinSlave; - if (Math.abs(slaveY) < 1e-5) slaveY=0.0; - String value = labelFormat.format( slaveY ); - LineMetrics lm = fm.getLineMetrics(value, g); - - g.drawString(value, (float) 13, (float) (controlY+lm.getAscent()/2)-1); - controlY -= masterGrid.pixelsPerSegment; - masterY = canvasStart + masterGrid.segment * (++i); - } - } - - public static int getTickCount(GridSpacing grid, double yMin, double controlHeight) - { - double canvasDiff = GridUtils.distanceToNextGridCoord(yMin+grid.segment, grid.segment); - double startY = controlHeight - canvasDiff * grid.pixelsPerUnit; - double x = startY / grid.pixelsPerSegment; - return (int) Math.ceil( x ); - } - - - /** - * Estimate label width, by sampling values from xMin to xMax - * using given font and format. - * - * @param xMin - * @param xMax - * @param format - * @return - */ - public static double calcLabelWidth(double xMin, double xMax, Format format, GridSpacing grid) - { - double width = 0.0; - double canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment); - int c = 0; - for (double x=xMin + canvasDiff; x -0.000000000001); - if (nearZero) x = 0.0; - String label = format.format(x); - if (label==null || label.equals("")) continue; - GlyphVector glyphVector; - glyphVector = RULER_FONT.createGlyphVector(frc, label); - double labelWidth = glyphVector.getVisualBounds().getWidth(); - width = Math.max( width, labelWidth ); - if (c++ > 100) break; - } - return width * 1.05; - } - - -} +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.g2d.utils; + +import java.awt.BasicStroke; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.Line2D; +import java.text.Format; + +import org.simantics.scenegraph.utils.GridUtils; + +public class GridUtil { + + public static final BasicStroke GRID_LINE_STROKE; + public static final BasicStroke RULER_LINE_STROKE; + public static final Font RULER_FONT; + public static final Font RULER_FONT_BOLD; + public static final FontRenderContext frc = new FontRenderContext(null, true, true); + + static { + RULER_LINE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f); + GRID_LINE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.CAP_SQUARE, 10.0f, null, 0.0f); + RULER_FONT = new Font("Tahoma", Font.PLAIN, 12); + RULER_FONT_BOLD = new Font("Tahoma", Font.BOLD, 12); + } + + public GridUtil() { + } + + public static void paintGridLines( + GridSpacing xgrid, GridSpacing ygrid, + Graphics2D g, + double xMin, double yMax, + double controlWidth, + double controlHeightForVerticalLines, + double controlHeightForHorizLines) { + + g.setStroke(GRID_LINE_STROKE); + Line2D line = new Line2D.Double(); + + if (xgrid != null) { + // Vertical lines + double controlX = GridUtils.distanceToNextGridCoordScaled(xMin, xgrid.segment, xgrid.pixelsPerUnit); + + while (controlX <= controlWidth+0.1) { + line.setLine(controlX, 0, controlX, (int) (controlHeightForVerticalLines - 1)); + g.draw(line); + controlX += xgrid.pixelsPerSegment; + } + } + + // Horizontal lines + if (ygrid != null) { + double canvasDiff = GridUtils.distanceToNextGridCoord(yMax, ygrid.segment); + double controlY = controlHeightForHorizLines - canvasDiff * ygrid.pixelsPerUnit; + + while (controlY >= -0.1) { + line.setLine(0, controlY, (int) (controlWidth - 1), controlY); + g.draw(line); + controlY -= ygrid.pixelsPerSegment; + } + } + } + + public static void paintHorizontalRuler( + GridSpacing grid, + Graphics2D g, + double xMin, + double controlWidth, + Format labelFormat) { + g.setStroke(RULER_LINE_STROKE); + + // Draw ticks + double canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment); + double canvasX = xMin + canvasDiff; + double controlX = canvasDiff * grid.pixelsPerUnit; + Line2D line = new Line2D.Double(); + line.setLine(0, 3, controlWidth, 3); + g.draw(line); + + while (controlX <= controlWidth + 0.1) { + line.setLine(controlX, 3, controlX, 8); + g.draw(line); + controlX += grid.pixelsPerSegment; + } + + // Labels + Font font = RULER_FONT; + g.setFont(RULER_FONT); + FontMetrics fm = g.getFontMetrics(font); + + canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment); + double canvasStart = canvasX = xMin + canvasDiff; + controlX = canvasDiff * grid.pixelsPerUnit; + + int i = 0; + while (controlX <= controlWidth + 0.1) { + String value = labelFormat.format( canvasX ); + double labelCenter = fm.getStringBounds(value, g).getCenterX(); + g.drawString(value, (float) (controlX-labelCenter), (float) 20); + controlX += grid.pixelsPerSegment; + canvasX = canvasStart + grid.segment * (++i); + } + + } + + public static void paintVerticalRuler( + GridSpacing grid, + Graphics2D g, + double yMin, + double controlHeight, + Format labelFormat) { + + g.setStroke(RULER_LINE_STROKE); + + // Draw ticks + double canvasDiff = GridUtils.distanceToNextGridCoord(yMin+grid.segment, grid.segment); + double controlY = controlHeight - canvasDiff * grid.pixelsPerUnit; + Line2D line = new Line2D.Double(); + line.setLine(3, 0, 3, controlHeight); + g.draw(line); + + while (controlY >= -0.1) { + line.setLine(3, controlY, 8, controlY); + g.draw( line ); + controlY -= grid.pixelsPerSegment; + } + + // Labels + g.setFont(RULER_FONT); + FontMetrics fm = g.getFontMetrics(RULER_FONT); + canvasDiff = GridUtils.distanceToNextGridCoord(yMin, grid.segment); + double canvasY = yMin + canvasDiff; + double canvasStart = canvasY; + controlY = controlHeight - canvasDiff * grid.pixelsPerUnit; + int i=0; + while (controlY >= -0.1) { + String value = labelFormat.format( canvasY ); + LineMetrics lm = fm.getLineMetrics(value, g); + + g.drawString(value, (float) 13, (float) (controlY+lm.getAscent()/2)-1); + controlY -= grid.pixelsPerSegment; + canvasY = canvasStart + grid.segment * (++i); + } + } + + public static void paintVerticalSlaveRuler( + GridSpacing masterGrid, + GridSpacing slaveGrid, + Graphics2D g, + double yMinMaster, double yMinSlave, + double controlHeight, + Format labelFormat) { + + g.setStroke(RULER_LINE_STROKE); + + // Draw ticks + double canvasDiff = GridUtils.distanceToNextGridCoord(yMinMaster+masterGrid.segment, masterGrid.segment); + double controlDiff = canvasDiff * masterGrid.pixelsPerUnit; + double startY = controlHeight - controlDiff; + double controlY = startY; + Line2D line = new Line2D.Double(); + line.setLine(3, 0, 3, controlHeight); + g.draw(line); + + while (controlY >= -0.1) { + line.setLine(3, controlY, 8, controlY); + g.draw( line ); + controlY -= masterGrid.pixelsPerSegment; + } + + // Labels + g.setFont(RULER_FONT); + FontMetrics fm = g.getFontMetrics(RULER_FONT); + canvasDiff = GridUtils.distanceToNextGridCoord(yMinMaster, masterGrid.segment); + double masterY = yMinMaster + canvasDiff; + double canvasStart = masterY; + controlY = controlHeight - canvasDiff * masterGrid.pixelsPerUnit; +// double slaveGridSegment = masterGrid.pixelsPerSegment * slaveGrid.unitsPerPixel; + int i=0; + while (controlY >= -0.1) { +// System.out.println("controlY="+controlY+", canvasY="+masterY); + // Convert value from master coordinates to slave + double slaveY = (masterY - yMinMaster) * masterGrid.pixelsPerUnit * slaveGrid.unitsPerPixel + yMinSlave; + if (Math.abs(slaveY) < 1e-5) slaveY=0.0; + String value = labelFormat.format( slaveY ); + LineMetrics lm = fm.getLineMetrics(value, g); + + g.drawString(value, (float) 13, (float) (controlY+lm.getAscent()/2)-1); + controlY -= masterGrid.pixelsPerSegment; + masterY = canvasStart + masterGrid.segment * (++i); + } + } + + public static int getTickCount(GridSpacing grid, double yMin, double controlHeight) + { + double canvasDiff = GridUtils.distanceToNextGridCoord(yMin+grid.segment, grid.segment); + double startY = controlHeight - canvasDiff * grid.pixelsPerUnit; + double x = startY / grid.pixelsPerSegment; + return (int) Math.ceil( x ); + } + + /** + * Estimate label width, by sampling values from xMin to xMax + * using given font and format. + * + * @param xMin + * @param xMax + * @param format + * @return + */ + public static double calcLabelWidth(double xMin, double xMax, Format format, GridSpacing grid) + { + double width = 0.0; + double canvasDiff = GridUtils.distanceToNextGridCoord(xMin, grid.segment); + int c = 0; + double canvasStart = xMin + canvasDiff; + for (double x=canvasStart; x -0.000000000001); +// if (nearZero) x = 0.0; + + String label = format.format(x); + if (label==null || label.equals("")) continue; + GlyphVector glyphVector; + glyphVector = RULER_FONT.createGlyphVector(frc, label); + double labelWidth = glyphVector.getVisualBounds().getWidth(); + //System.out.format("calcLabelWidth[%d](%s, %f, %f)%n", c, label, labelWidth, width); + width = Math.max( width, labelWidth ); + if (c++ > 100) break; + + // It is floating-point-wise more precise to calculate x like this than + // accumulating x += grid.segment. + // Also, this is how paintVerticalRuler does it and we want to match that + // in order to calculate the label width from the exact same values that + // paintVerticalRuler will draw. + x = canvasStart + grid.segment * c; + } + return width * 1.05; + } + +}