1 /*
2  * $Id$
3  *
4  * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
5  *
6  * The contents of this file are subject to the Mozilla Public License Version 1.1
7  * (the "License"); you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the License.
13  *
14  * The Original Code is 'iText, a free JAVA-PDF library'.
15  *
16  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18  * All Rights Reserved.
19  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source code
23  * where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above.  If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the MPL as stated above or under the terms of the GNU
37  * Library General Public License as published by the Free Software Foundation;
38  * either version 2 of the License, or any later version.
39  *
40  * This library is distributed in the hope that it will be useful, but WITHOUT
41  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43  * details.
44  *
45  * If you didn't download this code from the following link, you should check if
46  * you aren't using an obsolete version:
47  * http://www.lowagie.com/iText/
48  */
49 
50 package com.lowagie.text;
51 
52 import java.awt.Color;
53 import java.util.ArrayList;
54 
55 import com.lowagie.text.pdf.GrayColor;
56 
57 /**
58  * A <CODE>Rectangle</CODE> is the representation of a geometric figure.
59  *
60  * Rectangles support constant width borders using
61  * {@link #setBorderWidth(float)}and {@link #setBorder(int)}.
62  * They also support borders that vary in width/color on each side using
63  * methods like {@link #setBorderWidthLeft(float)}or
64  * {@link #setBorderColorLeft(java.awt.Color)}.
65  *
66  * @see Element
67  * @see Table
68  * @see Cell
69  * @see HeaderFooter
70  */
71 public class Rectangle implements Element {
72 
73 	// CONSTANTS:
74 
75 	/** This is the value that will be used as <VAR>undefined </VAR>. */
76 	public static final int UNDEFINED = -1;
77 
78 	/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
79 	public static final int TOP = 1;
80 
81 	/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
82 	public static final int BOTTOM = 2;
83 
84 	/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
85 	public static final int LEFT = 4;
86 
87 	/** This represents one side of the border of the <CODE>Rectangle</CODE>. */
88 	public static final int RIGHT = 8;
89 
90 	/** This represents a rectangle without borders. */
91 	public static final int NO_BORDER = 0;
92 
93 	/** This represents a type of border. */
94 	public static final int BOX = TOP + BOTTOM + LEFT + RIGHT;
95 
96 	// MEMBER VARIABLES:
97 
98 	/** the lower left x-coordinate. */
99 	protected float llx;
100 
101 	/** the lower left y-coordinate. */
102 	protected float lly;
103 
104 	/** the upper right x-coordinate. */
105 	protected float urx;
106 
107 	/** the upper right y-coordinate. */
108 	protected float ury;
109 
110 	/** The rotation of the Rectangle */
111 	protected int rotation = 0;
112 
113 	/** This is the color of the background of this rectangle. */
114 	protected Color backgroundColor = null;
115 
116 	/** This represents the status of the 4 sides of the rectangle. */
117 	protected int border = UNDEFINED;
118 
119 	/** Whether variable width/color borders are used. */
120 	protected boolean useVariableBorders = false;
121 
122 	/** This is the width of the border around this rectangle. */
123 	protected float borderWidth = UNDEFINED;
124 
125 	/** The width of the left border of this rectangle. */
126 	protected float borderWidthLeft = UNDEFINED;
127 
128 	/** The width of the right border of this rectangle. */
129 	protected float borderWidthRight = UNDEFINED;
130 
131 	/** The width of the top border of this rectangle. */
132 	protected float borderWidthTop = UNDEFINED;
133 
134 	/** The width of the bottom border of this rectangle. */
135 	protected float borderWidthBottom = UNDEFINED;
136 
137 	/** The color of the border of this rectangle. */
138 	protected Color borderColor = null;
139 
140 	/** The color of the left border of this rectangle. */
141 	protected Color borderColorLeft = null;
142 
143 	/** The color of the right border of this rectangle. */
144 	protected Color borderColorRight = null;
145 
146 	/** The color of the top border of this rectangle. */
147 	protected Color borderColorTop = null;
148 
149 	/** The color of the bottom border of this rectangle. */
150 	protected Color borderColorBottom = null;
151 
152 	// CONSTRUCTORS:
153 
154 	/**
155 	 * Constructs a <CODE>Rectangle</CODE> -object.
156 	 *
157 	 * @param llx	lower left x
158 	 * @param lly	lower left y
159 	 * @param urx	upper right x
160 	 * @param ury	upper right y
161 	 */
Rectangle(float llx, float lly, float urx, float ury)162 	public Rectangle(float llx, float lly, float urx, float ury) {
163 		this.llx = llx;
164 		this.lly = lly;
165 		this.urx = urx;
166 		this.ury = ury;
167 	}
168 
169 	/**
170 	 * Constructs a <CODE>Rectangle</CODE> -object starting from the origin
171 	 * (0, 0).
172 	 *
173 	 * @param urx	upper right x
174 	 * @param ury	upper right y
175 	 */
Rectangle(float urx, float ury)176 	public Rectangle(float urx, float ury) {
177 		this(0, 0, urx, ury);
178 	}
179 
180 	/**
181 	 * Constructs a <CODE>Rectangle</CODE> -object.
182 	 *
183 	 * @param rect	another <CODE>Rectangle</CODE>
184 	 */
Rectangle(Rectangle rect)185 	public Rectangle(Rectangle rect) {
186 		this(rect.llx, rect.lly, rect.urx, rect.ury);
187 		cloneNonPositionParameters(rect);
188 	}
189 
190 	// IMPLEMENTATION OF THE ELEMENT INTERFACE:e
191 
192 	/**
193 	 * Processes the element by adding it (or the different parts) to an
194 	 * <CODE>ElementListener</CODE>.
195 	 *
196 	 * @param listener	an <CODE>ElementListener</CODE>
197 	 * @return <CODE>true</CODE> if the element was processed successfully
198 	 */
process(ElementListener listener)199 	public boolean process(ElementListener listener) {
200 		try {
201 			return listener.add(this);
202 		}
203 		catch (DocumentException de) {
204 			return false;
205 		}
206 	}
207 
208 	/**
209 	 * Gets the type of the text element.
210 	 *
211 	 * @return a type
212 	 */
type()213 	public int type() {
214 		return Element.RECTANGLE;
215 	}
216 
217 	/**
218 	 * Gets all the chunks in this element.
219 	 *
220 	 * @return an <CODE>ArrayList</CODE>
221 	 */
getChunks()222 	public ArrayList getChunks() {
223 		return new ArrayList();
224 	}
225 
226 	/**
227 	 * @see com.lowagie.text.Element#isContent()
228 	 * @since	iText 2.0.8
229 	 */
isContent()230 	public boolean isContent() {
231 		return true;
232 	}
233 
234 	/**
235 	 * @see com.lowagie.text.Element#isNestable()
236 	 * @since	iText 2.0.8
237 	 */
isNestable()238 	public boolean isNestable() {
239 		return false;
240 	}
241 
242 	// METHODS TO GET/SET THE DIMENSIONS:
243 
244 	/**
245 	 * Sets the lower left x-coordinate.
246 	 *
247 	 * @param llx	the new value
248 	 */
setLeft(float llx)249 	public void setLeft(float llx) {
250 		this.llx = llx;
251 	}
252 
253 	/**
254 	 * Returns the lower left x-coordinate.
255 	 *
256 	 * @return the lower left x-coordinate
257 	 */
getLeft()258 	public float getLeft() {
259 		return llx;
260 	}
261 
262 	/**
263 	 * Returns the lower left x-coordinate, considering a given margin.
264 	 *
265 	 * @param margin	a margin
266 	 * @return the lower left x-coordinate
267 	 */
getLeft(float margin)268 	public float getLeft(float margin) {
269 		return llx + margin;
270 	}
271 
272 	/**
273 	 * Sets the upper right x-coordinate.
274 	 *
275 	 * @param urx	the new value
276 	 */
setRight(float urx)277 	public void setRight(float urx) {
278 		this.urx = urx;
279 	}
280 
281 	/**
282 	 * Returns the upper right x-coordinate.
283 	 *
284 	 * @return the upper right x-coordinate
285 	 */
getRight()286 	public float getRight() {
287 		return urx;
288 	}
289 
290 	/**
291 	 * Returns the upper right x-coordinate, considering a given margin.
292 	 *
293 	 * @param margin	a margin
294 	 * @return the upper right x-coordinate
295 	 */
getRight(float margin)296 	public float getRight(float margin) {
297 		return urx - margin;
298 	}
299 
300 	/**
301 	 * Returns the width of the rectangle.
302 	 *
303 	 * @return	the width
304 	 */
getWidth()305 	public float getWidth() {
306 		return urx - llx;
307 	}
308 
309 	/**
310 	 * Sets the upper right y-coordinate.
311 	 *
312 	 * @param ury	the new value
313 	 */
setTop(float ury)314 	public void setTop(float ury) {
315 		this.ury = ury;
316 	}
317 
318 	/**
319 	 * Returns the upper right y-coordinate.
320 	 *
321 	 * @return the upper right y-coordinate
322 	 */
getTop()323 	public float getTop() {
324 		return ury;
325 	}
326 
327 	/**
328 	 * Returns the upper right y-coordinate, considering a given margin.
329 	 *
330 	 * @param margin	a margin
331 	 * @return the upper right y-coordinate
332 	 */
getTop(float margin)333 	public float getTop(float margin) {
334 		return ury - margin;
335 	}
336 
337 	/**
338 	 * Sets the lower left y-coordinate.
339 	 *
340 	 * @param lly	the new value
341 	 */
setBottom(float lly)342 	public void setBottom(float lly) {
343 		this.lly = lly;
344 	}
345 
346 	/**
347 	 * Returns the lower left y-coordinate.
348 	 *
349 	 * @return the lower left y-coordinate
350 	 */
getBottom()351 	public float getBottom() {
352 		return lly;
353 	}
354 
355 	/**
356 	 * Returns the lower left y-coordinate, considering a given margin.
357 	 *
358 	 * @param margin	a margin
359 	 * @return the lower left y-coordinate
360 	 */
getBottom(float margin)361 	public float getBottom(float margin) {
362 		return lly + margin;
363 	}
364 
365 	/**
366 	 * Returns the height of the rectangle.
367 	 *
368 	 * @return the height
369 	 */
getHeight()370 	public float getHeight() {
371 		return ury - lly;
372 	}
373 
374 	/**
375 	 * Normalizes the rectangle.
376 	 * Switches lower left with upper right if necessary.
377 	 */
normalize()378 	public void normalize() {
379 		if (llx > urx) {
380 			float a = llx;
381 			llx = urx;
382 			urx = a;
383 		}
384 		if (lly > ury) {
385 			float a = lly;
386 			lly = ury;
387 			ury = a;
388 		}
389 	}
390 
391 	// METHODS TO GET/SET THE ROTATION:
392 
393 	/**
394 	 * Gets the rotation of the rectangle
395 	 *
396 	 * @return a rotation value
397 	 */
getRotation()398 	public int getRotation() {
399 		return rotation;
400 	}
401 
402 	/**
403 	 * Rotates the rectangle.
404 	 * Swaps the values of llx and lly and of urx and ury.
405 	 *
406 	 * @return the rotated <CODE>Rectangle</CODE>
407 	 */
rotate()408 	public Rectangle rotate() {
409 		Rectangle rect = new Rectangle(lly, llx, ury, urx);
410 		rect.rotation = rotation + 90;
411 		rect.rotation %= 360;
412 		return rect;
413 	}
414 
415 	// METHODS TO GET/SET THE BACKGROUND COLOR:
416 
417 	/**
418 	 * Gets the backgroundcolor.
419 	 *
420 	 * @return a <CODE>Color</CODE>
421 	 */
getBackgroundColor()422 	public Color getBackgroundColor() {
423 		return backgroundColor;
424 	}
425 
426 	/**
427 	 * Sets the backgroundcolor of the rectangle.
428 	 *
429 	 * @param backgroundColor	a <CODE>Color</CODE>
430 	 */
431 
setBackgroundColor(Color backgroundColor)432 	public void setBackgroundColor(Color backgroundColor) {
433 		this.backgroundColor = backgroundColor;
434 	}
435 
436 	/**
437 	 * Gets the grayscale.
438 	 *
439 	 * @return the grayscale color of the background
440      * or 0 if the background has no grayscale color.
441 	 */
getGrayFill()442 	public float getGrayFill() {
443         if (backgroundColor instanceof GrayColor)
444             return ((GrayColor)backgroundColor).getGray();
445         return 0;
446 	}
447 
448 	/**
449 	 * Sets the the background color to a grayscale value.
450 	 *
451 	 * @param value	the new grayscale value
452 	 */
setGrayFill(float value)453 	public void setGrayFill(float value) {
454         backgroundColor = new GrayColor(value);
455 	}
456 
457 //	 METHODS TO GET/SET THE BORDER:
458 
459 	/**
460 	 * Returns the exact type of the border.
461 	 *
462 	 * @return a value
463 	 */
getBorder()464 	public int getBorder() {
465 		return border;
466 	}
467 
468 	/**
469 	 * Indicates whether some type of border is set.
470 	 *
471 	 * @return a boolean
472 	 */
hasBorders()473 	public boolean hasBorders() {
474 		switch (border) {
475 			case UNDEFINED:
476 			case NO_BORDER:
477 				return false;
478 			default:
479 				return borderWidth > 0 || borderWidthLeft > 0
480 						|| borderWidthRight > 0 || borderWidthTop > 0 || borderWidthBottom > 0;
481 		}
482 	}
483 
484 	/**
485 	 * Indicates whether the specified type of border is set.
486 	 *
487 	 * @param type	the type of border
488 	 * @return a boolean
489 	 */
hasBorder(int type)490 	public boolean hasBorder(int type) {
491 		if (border == UNDEFINED)
492 			return false;
493 		return (border & type) == type;
494 	}
495 
496 	/**
497 	 * Enables/Disables the border on the specified sides.
498 	 * The border is specified as an integer bitwise combination of
499 	 * the constants: <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>.
500 	 *
501 	 * @see #enableBorderSide(int)
502 	 * @see #disableBorderSide(int)
503 	 * @param border	the new value
504 	 */
setBorder(int border)505 	public void setBorder(int border) {
506 		this.border = border;
507 	}
508 
509 	/**
510 	 * Indicates whether variable width borders are being used.
511 	 * Returns true if <CODE>setBorderWidthLeft, setBorderWidthRight,
512 	 * setBorderWidthTop, or setBorderWidthBottom</CODE> has been called.
513 	 *
514 	 * @return true if variable width borders are in use
515 	 */
isUseVariableBorders()516 	public boolean isUseVariableBorders() {
517 		return useVariableBorders;
518 	}
519 
520 	/**
521 	 * Sets a parameter indicating if the rectangle has variable borders
522 	 *
523 	 * @param useVariableBorders indication if the rectangle has variable borders
524 	 */
setUseVariableBorders(boolean useVariableBorders)525 	public void setUseVariableBorders(boolean useVariableBorders) {
526 		this.useVariableBorders = useVariableBorders;
527 	}
528 
529 	/**
530 	 * Enables the border on the specified side.
531 	 *
532 	 * @param side	the side to enable.
533 	 * One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>
534 	 */
enableBorderSide(int side)535 	public void enableBorderSide(int side) {
536 		if (border == UNDEFINED)
537 			border = 0;
538 		border |= side;
539 	}
540 
541 	/**
542 	 * Disables the border on the specified side.
543 	 *
544 	 * @param side	the side to disable.
545 	 * One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>
546 	 */
disableBorderSide(int side)547 	public void disableBorderSide(int side) {
548 		if (border == UNDEFINED)
549 			border = 0;
550 		border &= ~side;
551 	}
552 
553 	// METHODS TO GET/SET THE BORDER WIDTH:
554 
555 	/**
556 	 * Gets the borderwidth.
557 	 *
558 	 * @return a value
559 	 */
getBorderWidth()560 	public float getBorderWidth() {
561 		return borderWidth;
562 	}
563 
564 	/**
565 	 * Sets the borderwidth of the table.
566 	 *
567 	 * @param borderWidth the new value
568 	 */
setBorderWidth(float borderWidth)569 	public void setBorderWidth(float borderWidth) {
570 		this.borderWidth = borderWidth;
571 	}
572 
573 	/**
574 	 * Helper function returning the border width of a specific side.
575 	 *
576 	 * @param	variableWidthValue	a variable width (could be undefined)
577 	 * @param	side	the border you want to check
578 	 * @return	the variableWidthValue if not undefined, otherwise the borderWidth
579 	 */
getVariableBorderWidth(float variableWidthValue, int side)580 	private float getVariableBorderWidth(float variableWidthValue, int side) {
581 		if ((border & side) != 0)
582 			return variableWidthValue != UNDEFINED ? variableWidthValue : borderWidth;
583 		return 0;
584 	}
585 
586 	/**
587 	 * Helper function updating the border flag for a side
588 	 * based on the specified width.
589 	 * A width of 0 will disable the border on that side.
590 	 * Any other width enables it.
591 	 *
592 	 * @param width	width of border
593 	 * @param side	border side constant
594 	 */
updateBorderBasedOnWidth(float width, int side)595 	private void updateBorderBasedOnWidth(float width, int side) {
596 		useVariableBorders = true;
597 		if (width > 0)
598 			enableBorderSide(side);
599 		else
600 			disableBorderSide(side);
601 	}
602 
603 	/**
604 	 * Gets the width of the left border.
605 	 *
606 	 * @return a width
607 	 */
getBorderWidthLeft()608 	public float getBorderWidthLeft() {
609 		return getVariableBorderWidth(borderWidthLeft, LEFT);
610 	}
611 
612 	/**
613 	 * Sets the width of the left border.
614 	 *
615 	 * @param borderWidthLeft a width
616 	 */
setBorderWidthLeft(float borderWidthLeft)617 	public void setBorderWidthLeft(float borderWidthLeft) {
618 		this.borderWidthLeft = borderWidthLeft;
619 		updateBorderBasedOnWidth(borderWidthLeft, LEFT);
620 	}
621 
622 	/**
623 	 * Gets the width of the right border.
624 	 *
625 	 * @return a width
626 	 */
getBorderWidthRight()627 	public float getBorderWidthRight() {
628 		return getVariableBorderWidth(borderWidthRight, RIGHT);
629 	}
630 
631 	/**
632 	 * Sets the width of the right border.
633 	 *
634 	 * @param borderWidthRight a width
635 	 */
setBorderWidthRight(float borderWidthRight)636 	public void setBorderWidthRight(float borderWidthRight) {
637 		this.borderWidthRight = borderWidthRight;
638 		updateBorderBasedOnWidth(borderWidthRight, RIGHT);
639 	}
640 
641 	/**
642 	 * Gets the width of the top border.
643 	 *
644 	 * @return a width
645 	 */
getBorderWidthTop()646 	public float getBorderWidthTop() {
647 		return getVariableBorderWidth(borderWidthTop, TOP);
648 	}
649 
650 	/**
651 	 * Sets the width of the top border.
652 	 *
653 	 * @param borderWidthTop a width
654 	 */
setBorderWidthTop(float borderWidthTop)655 	public void setBorderWidthTop(float borderWidthTop) {
656 		this.borderWidthTop = borderWidthTop;
657 		updateBorderBasedOnWidth(borderWidthTop, TOP);
658 	}
659 
660 	/**
661 	 * Gets the width of the bottom border.
662 	 *
663 	 * @return a width
664 	 */
getBorderWidthBottom()665 	public float getBorderWidthBottom() {
666 		return getVariableBorderWidth(borderWidthBottom, BOTTOM);
667 	}
668 
669 	/**
670 	 * Sets the width of the bottom border.
671 	 *
672 	 * @param borderWidthBottom a width
673 	 */
setBorderWidthBottom(float borderWidthBottom)674 	public void setBorderWidthBottom(float borderWidthBottom) {
675 		this.borderWidthBottom = borderWidthBottom;
676 		updateBorderBasedOnWidth(borderWidthBottom, BOTTOM);
677 	}
678 
679 	// METHODS TO GET/SET THE BORDER COLOR:
680 
681 	/**
682 	 * Gets the color of the border.
683 	 *
684 	 * @return	a <CODE>Color</CODE>
685 	 */
getBorderColor()686 	public Color getBorderColor() {
687 		return borderColor;
688 	}
689 
690 	/**
691 	 * Sets the color of the border.
692 	 *
693 	 * @param borderColor a <CODE>Color</CODE>
694 	 */
setBorderColor(Color borderColor)695 	public void setBorderColor(Color borderColor) {
696 		this.borderColor = borderColor;
697 	}
698 
699 	/**
700 	 * Gets the color of the left border.
701 	 *
702 	 * @return a <CODE>Color</CODE>
703 	 */
getBorderColorLeft()704 	public Color getBorderColorLeft() {
705 		if (borderColorLeft == null)
706 			return borderColor;
707 		return borderColorLeft;
708 	}
709 
710 	/**
711 	 * Sets the color of the left border.
712 	 *
713 	 * @param borderColorLeft a <CODE>Color</CODE>
714 	 */
setBorderColorLeft(Color borderColorLeft)715 	public void setBorderColorLeft(Color borderColorLeft) {
716 		this.borderColorLeft = borderColorLeft;
717 	}
718 
719 	/**
720 	 * Gets the color of the right border.
721 	 *
722 	 * @return a <CODE>Color</CODE>
723 	 */
getBorderColorRight()724 	public Color getBorderColorRight() {
725 		if (borderColorRight == null)
726 			return borderColor;
727 		return borderColorRight;
728 	}
729 
730 	/**
731 	 * Sets the color of the right border.
732 	 *
733 	 * @param borderColorRight a <CODE>Color</CODE>
734 	 */
setBorderColorRight(Color borderColorRight)735 	public void setBorderColorRight(Color borderColorRight) {
736 		this.borderColorRight = borderColorRight;
737 	}
738 
739 	/**
740 	 * Gets the color of the top border.
741 	 *
742 	 * @return a <CODE>Color</CODE>
743 	 */
getBorderColorTop()744 	public Color getBorderColorTop() {
745 		if (borderColorTop == null)
746 			return borderColor;
747 		return borderColorTop;
748 	}
749 
750 	/**
751 	 * Sets the color of the top border.
752 	 *
753 	 * @param borderColorTop a <CODE>Color</CODE>
754 	 */
setBorderColorTop(Color borderColorTop)755 	public void setBorderColorTop(Color borderColorTop) {
756 		this.borderColorTop = borderColorTop;
757 	}
758 
759 	/**
760 	 * Gets the color of the bottom border.
761 	 *
762 	 * @return a <CODE>Color</CODE>
763 	 */
getBorderColorBottom()764 	public Color getBorderColorBottom() {
765 		if (borderColorBottom == null)
766 			return borderColor;
767 		return borderColorBottom;
768 	}
769 
770 	/**
771 	 * Sets the color of the bottom border.
772 	 *
773 	 * @param borderColorBottom a <CODE>Color</CODE>
774 	 */
setBorderColorBottom(Color borderColorBottom)775 	public void setBorderColorBottom(Color borderColorBottom) {
776 		this.borderColorBottom = borderColorBottom;
777 	}
778 
779 	// SPECIAL METHODS:
780 
781 	/**
782 	 * Gets a Rectangle that is altered to fit on the page.
783 	 *
784 	 * @param top		the top position
785 	 * @param bottom	the bottom position
786 	 * @return a <CODE>Rectangle</CODE>
787 	 */
rectangle(float top, float bottom)788 	public Rectangle rectangle(float top, float bottom) {
789 		Rectangle tmp = new Rectangle(this);
790 		if (getTop() > top) {
791 			tmp.setTop(top);
792 			tmp.disableBorderSide(TOP);
793 		}
794 		if (getBottom() < bottom) {
795 			tmp.setBottom(bottom);
796 			tmp.disableBorderSide(BOTTOM);
797 		}
798 		return tmp;
799 	}
800 
801 	/**
802 	 * Copies each of the parameters, except the position, from a
803 	 * <CODE>Rectangle</CODE> object
804 	 *
805 	 * @param rect	<CODE>Rectangle</CODE> to copy from
806 	 */
cloneNonPositionParameters(Rectangle rect)807 	public void cloneNonPositionParameters(Rectangle rect) {
808 		this.rotation = rect.rotation;
809 		this.backgroundColor = rect.backgroundColor;
810 		this.border = rect.border;
811 		this.useVariableBorders = rect.useVariableBorders;
812 		this.borderWidth = rect.borderWidth;
813 		this.borderWidthLeft = rect.borderWidthLeft;
814 		this.borderWidthRight = rect.borderWidthRight;
815 		this.borderWidthTop = rect.borderWidthTop;
816 		this.borderWidthBottom = rect.borderWidthBottom;
817 		this.borderColor = rect.borderColor;
818 		this.borderColorLeft = rect.borderColorLeft;
819 		this.borderColorRight = rect.borderColorRight;
820 		this.borderColorTop = rect.borderColorTop;
821 		this.borderColorBottom = rect.borderColorBottom;
822 	}
823 
824 	/**
825 	 * Copies each of the parameters, except the position, from a
826 	 * <CODE>Rectangle</CODE> object if the value is set there
827 	 *
828 	 * @param rect <CODE>Rectangle</CODE> to copy from
829 	 */
softCloneNonPositionParameters(Rectangle rect)830 	public void softCloneNonPositionParameters(Rectangle rect) {
831 		if (rect.rotation != 0)
832 			this.rotation = rect.rotation;
833 		if (rect.backgroundColor != null)
834 			this.backgroundColor = rect.backgroundColor;
835 		if (rect.border != UNDEFINED)
836 			this.border = rect.border;
837 		if (useVariableBorders)
838 			this.useVariableBorders = rect.useVariableBorders;
839 		if (rect.borderWidth != UNDEFINED)
840 			this.borderWidth = rect.borderWidth;
841 		if (rect.borderWidthLeft != UNDEFINED)
842 			this.borderWidthLeft = rect.borderWidthLeft;
843 		if (rect.borderWidthRight != UNDEFINED)
844 			this.borderWidthRight = rect.borderWidthRight;
845 		if (rect.borderWidthTop != UNDEFINED)
846 			this.borderWidthTop = rect.borderWidthTop;
847 		if (rect.borderWidthBottom != UNDEFINED)
848 			this.borderWidthBottom = rect.borderWidthBottom;
849 		if (rect.borderColor != null)
850 			this.borderColor = rect.borderColor;
851 		if (rect.borderColorLeft != null)
852 			this.borderColorLeft = rect.borderColorLeft;
853 		if (rect.borderColorRight != null)
854 			this.borderColorRight = rect.borderColorRight;
855 		if (rect.borderColorTop != null)
856 			this.borderColorTop = rect.borderColorTop;
857 		if (rect.borderColorBottom != null)
858 			this.borderColorBottom = rect.borderColorBottom;
859 	}
860 
861 	/**
862 	 * @return	a String representation of the rectangle
863 	 * @see java.lang.Object#toString()
864 	 */
toString()865 	public String toString() {
866 		StringBuffer buf = new StringBuffer("Rectangle: ");
867 		buf.append(getWidth());
868 		buf.append('x');
869 		buf.append(getHeight());
870 		buf.append(" (rot: ");
871 		buf.append(rotation);
872 		buf.append(" degrees)");
873 		return buf.toString();
874 	}
875 
876 }