All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.intarsys.pdf.cds.CDSRectangle Maven / Gradle / Ivy

Go to download

This is a fork of http://sourceforge.net/projects/jpodlib/ as development seems to be frozen. We're providing some bug fixes along with deployments to maven.

There is a newer version: 2.0
Show newest version
/*
 * Copyright (c) 2007, intarsys consulting GmbH
 *
 * 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 intarsys 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 de.intarsys.pdf.cds;

import de.intarsys.pdf.cos.COSArray;
import de.intarsys.pdf.cos.COSFixed;
import de.intarsys.pdf.cos.COSNumber;

import java.awt.geom.Rectangle2D;

/**
 * The implementation of the pdf rectangle data type.
 * 

*

* The specification of the data type is found in [PDF} chapter 3.8.3. *

*

*

*

*

 *              A rectangle is defined by
 *                   [llx, lly, urx, ury ]
 *              where
 *                   llx = lower left x coordinate
 *                   lly = lower left y coordinate
 *                   urx = upper right x coordinate
 *                   ury = upper right y coordinate
 *
 *                          urx
 *                           |
 *                           v
 *                     +-----+  <-ury
 *                     |     |
 *              lly -> +-----+
 *                     ˆ
 *                     |
 *                    llx
 *
 *
 * 
*

* An application should be prepared to get any two diagonally opposite corners * in the rectangle specification. Use "normalize()" to ensure a rectangle that * conforms to the above picture. *

*/ public class CDSRectangle extends CDSBase { /** * Some common constants in rectangle */ private static final float INCH_2_CM = 2.54f; private static final float A4_WIDTH = 21.0f; private static final float A4_HEIGHT = 29.7f; private static final float DPI = 72.0f; /* * paper sizes in mm A0 841 × 1189 B0 1000 × 1414 C0 17 × 1297 A1 594 × 841 * B1 707 × 1000 C1 648 × 917 A2 420 × 594 B2 500 × 707 C2 458 × 648 A3 297 × * 420 B3 353 × 500 C3 324 × 458 A4 210 × 297 B4 250 × 353 C4 229 × 324 A5 * 148 × 210 B5 176 × 250 C5 162 × 229 A6 105 × 148 B6 125 × 176 C6 114 × * 162 A7 74 × 105 B7 88 × 125 C7 81 × 114 A8 52 × 74 B8 62 × 88 C8 57 × 81 * A9 37 × 52 B9 44 × 62 C9 40 × 57 A10 26 × 37 B10 31 × 44 C10 28 × 40 */ // todo 4 add some common paper sizes public static final float[] SIZE_A4 = {0, 0, (A4_WIDTH / INCH_2_CM * DPI), (A4_HEIGHT / INCH_2_CM * DPI)}; /** * Create a {@link CDSRectangle} from an {@code array} holding the * rectangle coordinates. * * @param array The base {@link COSArray} * @return Create a {@link CDSRectangle} from {@code array} */ public static CDSRectangle createFromCOS(COSArray array) { if (array == null) { return null; } CDSRectangle rect = (CDSRectangle) array.getAttribute(CDSRectangle.class); if (rect == null) { rect = new CDSRectangle(array); array.setAttribute(CDSRectangle.class, rect); } return rect; } private Rectangle2D cachedRectangle; private Rectangle2D cachedNormalizedRectangle; /** * CDTRectangle constructor comment. */ public CDSRectangle() { super(COSArray.createWith(0, 0, 0, 0)); } /** * CDTRectangle constructor. Create a new rectangle with given array. * * @param newR A four dimensional COSArray defining llx,lly, urx, ury. */ protected CDSRectangle(COSArray newR) { super(newR); } /** * CDTRectangle constructor. Create a new rectangle with given size. * * @param llx the lower left x * @param lly the lower left y * @param urx the upper right x * @param ury the upper right y */ public CDSRectangle(float llx, float lly, float urx, float ury) { super(COSArray.createWith(llx, lly, urx, ury)); } /** * CDTRectangle constructor. Create a new rectangle with given array. The * array must have 4 elements of type float. * * @param rectArray A four dimensional array defining llx,lly, urx, ury. * @see CDSRectangle#CDSRectangle(float llx, float lly, float urx, float * ury) */ public CDSRectangle(float[] rectArray) { this(rectArray[0], rectArray[1], rectArray[2], rectArray[3]); } public CDSRectangle(Rectangle2D rect) { super(COSArray.createWith((float) rect.getMinX(), (float) rect.getMinY(), (float) rect.getMaxX(), (float) rect.getMaxY())); } /** * {@code true} if x/y lies within this. * * @param x x coordinate to be checked. * @param y y coordinate to be checked. * @return {@code true} if x/y lies within this. */ public boolean contains(double x, double y) { COSArray array = cosGetArray(); float x0 = ((COSNumber) array.get(0)).floatValue(); float x1 = ((COSNumber) array.get(2)).floatValue(); if (x0 < x1) { if ((x < x0) || (x > x1)) { return false; } } else { if ((x > x0) || (x < x1)) { return false; } } float y0 = ((COSNumber) array.get(1)).floatValue(); float y1 = ((COSNumber) array.get(3)).floatValue(); if (y0 < y1) { return ((y >= y0) && (y <= y1)); } else { return ((y >= y1) && (y <= y0)); } } /** * {@code true} if x/y lies within this, with a "uncertainty" of * epsilon. * * @param x x coordinate to be checked. * @param y y coordinate to be checked. * @param epsilon The allowed range of uncertainty * @return {@code true} if x/y lies within this. */ public boolean contains(double x, double y, double epsilon) { COSArray array = cosGetArray(); float x0 = ((COSNumber) array.get(0)).floatValue(); float x1 = ((COSNumber) array.get(2)).floatValue(); if (x0 < x1) { if ((x < (x0 - epsilon)) || (x > (x1 + epsilon))) { return false; } } else { if ((x > (x0 + epsilon)) || (x < (x1 - epsilon))) { return false; } } float y0 = ((COSNumber) array.get(1)).floatValue(); float y1 = ((COSNumber) array.get(3)).floatValue(); if (y0 < y1) { return ((y >= (y0 - epsilon)) && (y <= (y1 + epsilon))); } else { return ((y >= (y1 - epsilon)) && (y <= (y0 + epsilon))); } } /** * Create a copy of the receiver * * @return a new copy of the receiver */ public CDSRectangle copy() { return new CDSRectangle((COSArray) cosGetArray().copyShallow()); } /** * Return the height (an absolute value) of the rectangle. * * @return Return the height (an absolute value) of the rectangle. */ public float getHeight() { return Math.abs(getUpperRightY() - getLowerLeftY()); } /** * The lower left x coordinate. * * @return The lower left x coordinate. */ public float getLowerLeftX() { return ((COSNumber) cosGetArray().get(0)).floatValue(); } /** * The lower left y coordinate. * * @return The lower left y coordinate. */ public float getLowerLeftY() { return ((COSNumber) cosGetArray().get(1)).floatValue(); } /** * The upper right x coordinate. * * @return The upper right x coordinate. */ public float getUpperRightX() { return ((COSNumber) cosGetArray().get(2)).floatValue(); } /** * The upper right y coordinate. * * @return The upper right y coordinate. */ public float getUpperRightY() { return ((COSNumber) cosGetArray().get(3)).floatValue(); } /** * Get the width (an absolute value) of the rectangle. * * @return Get the width (an absolute value) of the rectangle. */ public float getWidth() { return Math.abs(getUpperRightX() - getLowerLeftX()); } /* * (non-Javadoc) * * @see de.intarsys.pdf.cos.COSBasedObject#invalidateCaches() */ @Override public void invalidateCaches() { super.invalidateCaches(); cachedNormalizedRectangle = null; cachedRectangle = null; } /** * Move the rectangle by a relative offset. The relationship of the opposite * corners is preserved by this method. * * @param dx The offset by which we move in x direction. * @param dy The offset by which we move in y direction. */ public void move(float dx, float dy) { setLowerLeftX(getLowerLeftX() + dx); setLowerLeftY(getLowerLeftY() + dy); setUpperRightX(getUpperRightX() + dx); setUpperRightY(getUpperRightY() + dy); } /** * Move the rectangle to a new absolute position. The relationship of the * opposite corners is preserved by this method. The receiver is modified. * * @param x The new x position of the lower left corner. * @param y The new y position of the lower left corner. * @return {@code this} */ public CDSRectangle moveTo(float x, float y) { float width = getUpperRightX() - getLowerLeftX(); float height = getUpperRightY() - getLowerLeftY(); setLowerLeftX(x); setLowerLeftY(y); setUpperRightX(width + x); setUpperRightY(height + y); return this; } /** * Adjust the corner coordinates so that lower left is really in the lower * left (this means returns the smallest coordinate values). *

*

* This method changes {@code this} in place! *

* * @return {@code this} */ public CDSRectangle normalize() { float t1; float t2; if ((t1 = getLowerLeftX()) > (t2 = getUpperRightX())) { setLowerLeftX(t2); setUpperRightX(t1); } if ((t1 = getLowerLeftY()) > (t2 = getUpperRightY())) { setLowerLeftY(t2); setUpperRightY(t1); } return this; } /** * Resize the rectangle by moving the upper right corner. * * @param dx The distance we move the upper right x coordinate. * @param dy The distance we move the upper right y coordinate. */ public void resize(float dx, float dy) { setUpperRightX(getUpperRightX() + dx); setUpperRightY(getUpperRightY() + dy); } /** * Resize the rectangle to a new width and heigth. The new width and heigth * are defined relative to the lower left corner as signed values. * * @param width The new width of the rectangle. * @param height The new height of the rectangle. */ public void resizeTo(float width, float height) { setUpperRightX(getLowerLeftX() + width); setUpperRightY(getLowerLeftY() + height); } /** * Set the corners of this. * * @param llx The lower left x coordinate * @param lly The lower left y coordinate * @param urx The upper right x coordinate * @param ury The upper right y coordinate */ public void setCorners(float llx, float lly, float urx, float ury) { cosGetArray().set(0, COSFixed.create(llx)); cosGetArray().set(1, COSFixed.create(lly)); cosGetArray().set(2, COSFixed.create(urx)); cosGetArray().set(3, COSFixed.create(ury)); } /** * Set the height of this. * * @param height THe new height */ public void setHeight(float height) { setUpperRightY(getLowerLeftY() + height); } /** * Set the lower left x coordinate. * * @param num The lower left x coordinate. */ public void setLowerLeftX(float num) { cosGetArray().set(0, COSFixed.create(num)); } /** * Set the lower left y coordinate. * * @param num The lower left y coordinate. */ public void setLowerLeftY(float num) { cosGetArray().set(1, COSFixed.create(num)); } /** * Set the upper right x coordinate. * * @param num The upper right x coordinate. */ public void setUpperRightX(float num) { cosGetArray().set(2, COSFixed.create(num)); } /** * Set the upper right y coordinate. * * @param num The upper right y coordinate. */ public void setUpperRightY(float num) { cosGetArray().set(3, COSFixed.create(num)); } /** * Set the width of this. * * @param width The new width. */ public void setWidth(float width) { setUpperRightX(getLowerLeftX() + width); } public float[] toArray() { return new float[]{getLowerLeftX(), getLowerLeftY(), getUpperRightX(), getUpperRightY()}; } /** * Construct a {@link Rectangle2D} object from the receiver. The rectangle * will be normalized before construction. * * @return The Rectangle2D created from the receiver. */ public Rectangle2D toNormalizedRectangle() { if (cachedNormalizedRectangle == null) { float llx = getLowerLeftX(); float lly = getLowerLeftY(); float urx = getUpperRightX(); float ury = getUpperRightY(); float temp; if (llx > urx) { temp = llx; llx = urx; urx = temp; } if (lly > ury) { temp = lly; lly = ury; ury = temp; } cachedNormalizedRectangle = new Rectangle2D.Float(llx, lly, urx - llx, ury - lly); } return (Rectangle2D) cachedNormalizedRectangle.clone(); } /** * Construct a {@link Rectangle2D} object from the receiver. The resulting * rectangle is not normalized, that means it may return a negative width or * height. * * @return The Rectangle2D created from the receiver. */ public Rectangle2D toRectangle() { if (cachedRectangle == null) { float llx = getLowerLeftX(); float lly = getLowerLeftY(); float urx = getUpperRightX(); float ury = getUpperRightY(); cachedRectangle = new Rectangle2D.Float(llx, lly, urx - llx, ury - lly); } return (Rectangle2D) cachedRectangle.clone(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy