gwt.g2d.client.graphics.DashedLineRenderer.java Source code

Java tutorial

Introduction

Here is the source code for gwt.g2d.client.graphics.DashedLineRenderer.java

Source

/*
 * Copyright 2011 Hao Nguyen
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package gwt.g2d.client.graphics;

import com.google.gwt.canvas.dom.client.Context2d;

/**
 * Helper class for drawing dashed line.
 * Reference: http://davidowens.wordpress.com/2010/09/07/html-5-canvas-and-dashed-lines/
 * 
 * @author hao1300@gmail.com
 */
public class DashedLineRenderer {

    /**
     * Draw a dashed line from (fromX, fromY) to (toX, toY).
     * 
     * @param context
     * @param fromX x-coordinate of the starting point
     * @param fromY y-coordinate of the starting point
     * @param toX x-coordinate of the ending point
     * @param toY y-coordinate of the ending point
     * @param dashLength length of the dash
     * @param gapLength length of the gap in between dashes
     */
    public static void drawDashedLine(Context2d context, double fromX, double fromY, double toX, double toY,
            double dashLength, double gapLength) {
        DashedLineHelper checkX = GreaterThanHelper.instance;
        DashedLineHelper checkY = GreaterThanHelper.instance;

        if (fromY - toY > 0) {
            checkY = LessThanHelper.instance;
        }
        if (fromX - toX > 0) {
            checkX = LessThanHelper.instance;
        }

        context.moveTo(fromX, fromY);
        double offsetX = fromX;
        double offsetY = fromY;
        boolean dash = true;
        double ang = Math.atan2(toY - fromY, toX - fromX);
        while (!(checkX.isThereYet(offsetX, toX) && checkY.isThereYet(offsetY, toY))) {
            double len = (dash) ? dashLength : gapLength;

            offsetX = checkX.getCap(toX, offsetX + (Math.cos(ang) * len));
            offsetY = checkY.getCap(toY, offsetY + (Math.sin(ang) * len));

            if (dash) {
                context.lineTo(offsetX, offsetY);
            } else {
                context.moveTo(offsetX, offsetY);
            }
            dash = !dash;
        }
    }

    /**
     * Helper class for checking the dash line.
     */
    private interface DashedLineHelper {

        /**
         * Checks whether the point has been reached yet.
         * 
         * @param from
         * @param to
         * @return
         */
        boolean isThereYet(double from, double to);

        /**
         * Gets the cap of the two values. If the line is increasing, this will
         * return max(v1, v2). If the line is decreasing, this will return
         * min(v1, v2).
         * 
         * @param v1
         * @param v2
         * @return
         */
        double getCap(double v1, double v2);
    }

    /**
     * Helper for a decreasing line.
     */
    private static class LessThanHelper implements DashedLineHelper {
        private static DashedLineHelper instance = new LessThanHelper();

        @Override
        public double getCap(double v1, double v2) {
            return Math.max(v1, v2);
        }

        @Override
        public boolean isThereYet(double from, double to) {
            return from <= to;
        }
    }

    /**
     * Helper for an increasing line.
     */
    private static class GreaterThanHelper implements DashedLineHelper {
        private static DashedLineHelper instance = new GreaterThanHelper();

        @Override
        public double getCap(double v1, double v2) {
            return Math.min(v1, v2);
        }

        @Override
        public boolean isThereYet(double from, double to) {
            return from >= to;
        }
    }
}