/* * Line.java * Transform * * Copyright (c) 2001-2010 Flagstone Software Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Flagstone Software Ltd. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package com.flagstone.transform.shape; import java.io.IOException; import com.flagstone.transform.coder.Coder; import com.flagstone.transform.coder.Context; import com.flagstone.transform.coder.SWFDecoder; import com.flagstone.transform.coder.SWFEncoder; import com.flagstone.transform.exception.IllegalArgumentRangeException; /** * Line defines a straight line. The line is drawn from the current drawing * point to the end point specified in the Line object which is specified * relative to the current drawing point. Once the line is drawn, the end of the * line is now the current drawing point. */ public final class Line implements ShapeRecord { /** Format string used in toString() method. */ private static final String FORMAT = "Line: (%d, %d)"; /** x-coordinate of the end of the line. */ private transient int xCoord; /** y-coordinate of the end of the line. */ private transient int yCoord; /** Is the line vertical. */ private transient boolean vertical; /** Is the line horizontal. */ private transient boolean general; /** Number of bits used to encode the x and y coordinates. */ private transient int size; /** * Creates and initialises a Line object using values encoded * in the Flash binary format. * * @param coder * an SWFDecoder object that contains the encoded Flash data. * * @throws IOException * if an error occurs while decoding the data. */ public Line(final SWFDecoder coder) throws IOException { // CHECKSTYLE IGNORE MagicNumberCheck FOR NEXT 1 LINES size = coder.readBits(4, false) + 2; if (coder.readBits(1, false) == 0) { if (coder.readBits(1, false) == 0) { xCoord = coder.readBits(size, true); yCoord = 0; } else { xCoord = 0; yCoord = coder.readBits(size, true); } } else { xCoord = coder.readBits(size, true); yCoord = coder.readBits(size, true); } } /** * Creates a Line with the specified relative coordinates. * * @param coordX * the x-coordinate of the end point, specified relative to the * current drawing point. Must be in the range -65536..65535. * @param coordY * the y-coordinate of the end point, specified relative to the * current drawing point. Must be in the range -65536..65535. */ public Line(final int coordX, final int coordY) { setPoint(coordX, coordY); } /** * Creates and initialises a Line object using the values copied * from another Line object. * * @param object * a Line object from which the values will be * copied. */ public Line(final Line object) { xCoord = object.xCoord; yCoord = object.yCoord; } /** * Get the relative x-coordinate of the end-point of the line. * * @return the x-coordinate of the line end. */ public int getX() { return xCoord; } /** * Get the relative y-coordinate of the end-point of the line. * * @return the y-coordinate of the line end. */ public int getY() { return yCoord; } /** * Sets the relative x and y coordinates. * * @param coordX * the x-coordinate of the end point. Must be in the range * -65536..65535. * @param coordY * the y-coordinate of the end point. Must be in the range * -65536..65535. */ public void setPoint(final int coordX, final int coordY) { if ((coordX < Shape.MIN_COORD) || (coordX > Shape.MAX_COORD)) { throw new IllegalArgumentRangeException( Shape.MIN_COORD, Shape.MAX_COORD, coordX); } xCoord = coordX; if ((coordY < Shape.MIN_COORD) || (coordY > Shape.MAX_COORD)) { throw new IllegalArgumentRangeException( Shape.MIN_COORD, Shape.MAX_COORD, coordY); } yCoord = coordY; } /** {@inheritDoc} */ public Line copy() { return new Line(this); } @Override public String toString() { return String.format(FORMAT, xCoord, yCoord); } /** {@inheritDoc} */ public int prepareToEncode(final Context context) { vertical = xCoord == 0; general = (xCoord != 0) && (yCoord != 0); size = Coder.maxSize(xCoord, yCoord, 1); // CHECKSTYLE IGNORE MagicNumberCheck FOR NEXT 1 LINES int numberOfBits = 7; if (general) { numberOfBits += size << 1; } else { numberOfBits += 1 + size; } context.put(Context.SHAPE_SIZE, context.get(Context.SHAPE_SIZE) + numberOfBits); return numberOfBits; } /** {@inheritDoc} */ public void encode(final SWFEncoder coder, final Context context) throws IOException { // CHECKSTYLE IGNORE MagicNumberCheck FOR NEXT 2 LINES coder.writeBits(3, 2); coder.writeBits(size - 2, 4); coder.writeBits(general ? 1 : 0, 1); if (general) { coder.writeBits(xCoord, size); coder.writeBits(yCoord, size); } else { coder.writeBits(vertical ? 1 : 0, 1); coder.writeBits(vertical ? yCoord : xCoord, size); } } }