001/* 002 * $Id: Rectangle.java 4871 2011-05-13 19:05:12Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text; 045 046import java.util.List; 047import java.util.ArrayList; 048 049import com.itextpdf.text.pdf.GrayColor; 050 051/** 052 * A <CODE>Rectangle</CODE> is the representation of a geometric figure. 053 * 054 * Rectangles support constant width borders using 055 * {@link #setBorderWidth(float)}and {@link #setBorder(int)}. 056 * They also support borders that vary in width/color on each side using 057 * methods like {@link #setBorderWidthLeft(float)}or 058 * {@link #setBorderColorLeft(BaseColor)}. 059 * 060 * @see Element 061 */ 062public class Rectangle implements Element { 063 064 // CONSTANTS: 065 066 /** This is the value that will be used as <VAR>undefined </VAR>. */ 067 public static final int UNDEFINED = -1; 068 069 /** This represents one side of the border of the <CODE>Rectangle</CODE>. */ 070 public static final int TOP = 1; 071 072 /** This represents one side of the border of the <CODE>Rectangle</CODE>. */ 073 public static final int BOTTOM = 2; 074 075 /** This represents one side of the border of the <CODE>Rectangle</CODE>. */ 076 public static final int LEFT = 4; 077 078 /** This represents one side of the border of the <CODE>Rectangle</CODE>. */ 079 public static final int RIGHT = 8; 080 081 /** This represents a rectangle without borders. */ 082 public static final int NO_BORDER = 0; 083 084 /** This represents a type of border. */ 085 public static final int BOX = TOP + BOTTOM + LEFT + RIGHT; 086 087 // MEMBER VARIABLES: 088 089 /** the lower left x-coordinate. */ 090 protected float llx; 091 092 /** the lower left y-coordinate. */ 093 protected float lly; 094 095 /** the upper right x-coordinate. */ 096 protected float urx; 097 098 /** the upper right y-coordinate. */ 099 protected float ury; 100 101 /** The rotation of the Rectangle */ 102 protected int rotation = 0; 103 104 /** This is the color of the background of this rectangle. */ 105 protected BaseColor backgroundColor = null; 106 107 /** This represents the status of the 4 sides of the rectangle. */ 108 protected int border = UNDEFINED; 109 110 /** Whether variable width/color borders are used. */ 111 protected boolean useVariableBorders = false; 112 113 /** This is the width of the border around this rectangle. */ 114 protected float borderWidth = UNDEFINED; 115 116 /** The width of the left border of this rectangle. */ 117 protected float borderWidthLeft = UNDEFINED; 118 119 /** The width of the right border of this rectangle. */ 120 protected float borderWidthRight = UNDEFINED; 121 122 /** The width of the top border of this rectangle. */ 123 protected float borderWidthTop = UNDEFINED; 124 125 /** The width of the bottom border of this rectangle. */ 126 protected float borderWidthBottom = UNDEFINED; 127 128 /** The color of the border of this rectangle. */ 129 protected BaseColor borderColor = null; 130 131 /** The color of the left border of this rectangle. */ 132 protected BaseColor borderColorLeft = null; 133 134 /** The color of the right border of this rectangle. */ 135 protected BaseColor borderColorRight = null; 136 137 /** The color of the top border of this rectangle. */ 138 protected BaseColor borderColorTop = null; 139 140 /** The color of the bottom border of this rectangle. */ 141 protected BaseColor borderColorBottom = null; 142 143 // CONSTRUCTORS: 144 145 /** 146 * Constructs a <CODE>Rectangle</CODE> -object. 147 * 148 * @param llx lower left x 149 * @param lly lower left y 150 * @param urx upper right x 151 * @param ury upper right y 152 */ 153 public Rectangle(final float llx, final float lly, final float urx, final float ury) { 154 this.llx = llx; 155 this.lly = lly; 156 this.urx = urx; 157 this.ury = ury; 158 } 159 160 /** 161 * Constructs a <CODE>Rectangle</CODE>-object. 162 * 163 * @param llx lower left x 164 * @param lly lower left y 165 * @param urx upper right x 166 * @param ury upper right y 167 * @param rotation the rotation (0, 90, 180, or 270) 168 * @since iText 5.0.6 169 */ 170 public Rectangle(final float llx, final float lly, final float urx, final float ury, final int rotation) { 171 this(llx, lly, urx, ury); 172 setRotation(rotation); 173 } 174 175 /** 176 * Constructs a <CODE>Rectangle</CODE> -object starting from the origin 177 * (0, 0). 178 * 179 * @param urx upper right x 180 * @param ury upper right y 181 */ 182 public Rectangle(final float urx, final float ury) { 183 this(0, 0, urx, ury); 184 } 185 186 /** 187 * Constructs a <CODE>Rectangle</CODE>-object starting from the origin 188 * (0, 0) and with a specific rotation (valid values are 0, 90, 180, 270). 189 * 190 * @param urx upper right x 191 * @param ury upper right y 192 * @param rotation the rotation of the rectangle 193 * @since iText 5.0.6 194 */ 195 public Rectangle(final float urx, final float ury, final int rotation) { 196 this(0, 0, urx, ury, rotation); 197 } 198 199 /** 200 * Constructs a <CODE>Rectangle</CODE> -object. 201 * 202 * @param rect another <CODE>Rectangle</CODE> 203 */ 204 public Rectangle(final Rectangle rect) { 205 this(rect.llx, rect.lly, rect.urx, rect.ury); 206 cloneNonPositionParameters(rect); 207 } 208 209 // IMPLEMENTATION OF THE ELEMENT INTERFACE:e 210 211 /** 212 * Processes the element by adding it (or the different parts) to an 213 * <CODE>ElementListener</CODE>. 214 * 215 * @param listener an <CODE>ElementListener</CODE> 216 * @return <CODE>true</CODE> if the element was processed successfully 217 */ 218 public boolean process(final ElementListener listener) { 219 try { 220 return listener.add(this); 221 } 222 catch (DocumentException de) { 223 return false; 224 } 225 } 226 227 /** 228 * Gets the type of the text element. 229 * 230 * @return a type 231 */ 232 public int type() { 233 return Element.RECTANGLE; 234 } 235 236 /** 237 * Gets all the chunks in this element. 238 * 239 * @return an <CODE>ArrayList</CODE> 240 */ 241 public List<Chunk> getChunks() { 242 return new ArrayList<Chunk>(); 243 } 244 245 /** 246 * @see com.itextpdf.text.Element#isContent() 247 * @since iText 2.0.8 248 */ 249 public boolean isContent() { 250 return true; 251 } 252 253 /** 254 * @see com.itextpdf.text.Element#isNestable() 255 * @since iText 2.0.8 256 */ 257 public boolean isNestable() { 258 return false; 259 } 260 261 // METHODS TO GET/SET THE DIMENSIONS: 262 263 /** 264 * Sets the lower left x-coordinate. 265 * 266 * @param llx the new value 267 */ 268 public void setLeft(final float llx) { 269 this.llx = llx; 270 } 271 272 /** 273 * Returns the lower left x-coordinate. 274 * 275 * @return the lower left x-coordinate 276 */ 277 public float getLeft() { 278 return llx; 279 } 280 281 /** 282 * Returns the lower left x-coordinate, considering a given margin. 283 * 284 * @param margin a margin 285 * @return the lower left x-coordinate 286 */ 287 public float getLeft(final float margin) { 288 return llx + margin; 289 } 290 291 /** 292 * Sets the upper right x-coordinate. 293 * 294 * @param urx the new value 295 */ 296 public void setRight(final float urx) { 297 this.urx = urx; 298 } 299 300 /** 301 * Returns the upper right x-coordinate. 302 * 303 * @return the upper right x-coordinate 304 */ 305 public float getRight() { 306 return urx; 307 } 308 309 /** 310 * Returns the upper right x-coordinate, considering a given margin. 311 * 312 * @param margin a margin 313 * @return the upper right x-coordinate 314 */ 315 public float getRight(final float margin) { 316 return urx - margin; 317 } 318 319 /** 320 * Returns the width of the rectangle. 321 * 322 * @return the width 323 */ 324 public float getWidth() { 325 return urx - llx; 326 } 327 328 /** 329 * Sets the upper right y-coordinate. 330 * 331 * @param ury the new value 332 */ 333 public void setTop(final float ury) { 334 this.ury = ury; 335 } 336 337 /** 338 * Returns the upper right y-coordinate. 339 * 340 * @return the upper right y-coordinate 341 */ 342 public float getTop() { 343 return ury; 344 } 345 346 /** 347 * Returns the upper right y-coordinate, considering a given margin. 348 * 349 * @param margin a margin 350 * @return the upper right y-coordinate 351 */ 352 public float getTop(final float margin) { 353 return ury - margin; 354 } 355 356 /** 357 * Sets the lower left y-coordinate. 358 * 359 * @param lly the new value 360 */ 361 public void setBottom(final float lly) { 362 this.lly = lly; 363 } 364 365 /** 366 * Returns the lower left y-coordinate. 367 * 368 * @return the lower left y-coordinate 369 */ 370 public float getBottom() { 371 return lly; 372 } 373 374 /** 375 * Returns the lower left y-coordinate, considering a given margin. 376 * 377 * @param margin a margin 378 * @return the lower left y-coordinate 379 */ 380 public float getBottom(final float margin) { 381 return lly + margin; 382 } 383 384 /** 385 * Returns the height of the rectangle. 386 * 387 * @return the height 388 */ 389 public float getHeight() { 390 return ury - lly; 391 } 392 393 /** 394 * Normalizes the rectangle. 395 * Switches lower left with upper right if necessary. 396 */ 397 public void normalize() { 398 if (llx > urx) { 399 float a = llx; 400 llx = urx; 401 urx = a; 402 } 403 if (lly > ury) { 404 float a = lly; 405 lly = ury; 406 ury = a; 407 } 408 } 409 410 // METHODS TO GET/SET THE ROTATION: 411 412 /** 413 * Gets the rotation of the rectangle 414 * 415 * @return a rotation value 416 */ 417 public int getRotation() { 418 return rotation; 419 } 420 421 /** 422 * Sets the rotation of the rectangle. Valid values are 0, 90, 180, and 270. 423 * @param rotation the new rotation value 424 * @since iText 5.0.6 425 */ 426 public void setRotation(final int rotation) { 427 this.rotation = rotation % 360; 428 switch (this.rotation) { 429 case 90: 430 case 180: 431 case 270: 432 break; 433 default: 434 this.rotation = 0; 435 } 436 } 437 438 /** 439 * Rotates the rectangle. 440 * Swaps the values of llx and lly and of urx and ury. 441 * 442 * @return the rotated <CODE>Rectangle</CODE> 443 */ 444 public Rectangle rotate() { 445 Rectangle rect = new Rectangle(lly, llx, ury, urx); 446 rect.setRotation(rotation + 90); 447 return rect; 448 } 449 450 // METHODS TO GET/SET THE BACKGROUND COLOR: 451 452 /** 453 * Gets the backgroundcolor. 454 * 455 * @return a <CODE>BaseColor</CODE> 456 */ 457 public BaseColor getBackgroundColor() { 458 return backgroundColor; 459 } 460 461 /** 462 * Sets the backgroundcolor of the rectangle. 463 * 464 * @param backgroundColor a <CODE>BaseColor</CODE> 465 */ 466 467 public void setBackgroundColor(final BaseColor backgroundColor) { 468 this.backgroundColor = backgroundColor; 469 } 470 471 /** 472 * Gets the grayscale. 473 * 474 * @return the grayscale color of the background 475 * or 0 if the background has no grayscale color. 476 */ 477 public float getGrayFill() { 478 if (backgroundColor instanceof GrayColor) 479 return ((GrayColor)backgroundColor).getGray(); 480 return 0; 481 } 482 483 /** 484 * Sets the the background color to a grayscale value. 485 * 486 * @param value the new grayscale value 487 */ 488 public void setGrayFill(final float value) { 489 backgroundColor = new GrayColor(value); 490 } 491 492// METHODS TO GET/SET THE BORDER: 493 494 /** 495 * Returns the exact type of the border. 496 * 497 * @return a value 498 */ 499 public int getBorder() { 500 return border; 501 } 502 503 /** 504 * Indicates whether some type of border is set. 505 * 506 * @return a boolean 507 */ 508 public boolean hasBorders() { 509 switch (border) { 510 case UNDEFINED: 511 case NO_BORDER: 512 return false; 513 default: 514 return borderWidth > 0 || borderWidthLeft > 0 515 || borderWidthRight > 0 || borderWidthTop > 0 || borderWidthBottom > 0; 516 } 517 } 518 519 /** 520 * Indicates whether the specified type of border is set. 521 * 522 * @param type the type of border 523 * @return a boolean 524 */ 525 public boolean hasBorder(final int type) { 526 if (border == UNDEFINED) 527 return false; 528 return (border & type) == type; 529 } 530 531 /** 532 * Enables/Disables the border on the specified sides. 533 * The border is specified as an integer bitwise combination of 534 * the constants: <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE>. 535 * 536 * @see #enableBorderSide(int) 537 * @see #disableBorderSide(int) 538 * @param border the new value 539 */ 540 public void setBorder(final int border) { 541 this.border = border; 542 } 543 544 /** 545 * Indicates whether variable width borders are being used. 546 * Returns true if <CODE>setBorderWidthLeft, setBorderWidthRight, 547 * setBorderWidthTop, or setBorderWidthBottom</CODE> has been called. 548 * 549 * @return true if variable width borders are in use 550 */ 551 public boolean isUseVariableBorders() { 552 return useVariableBorders; 553 } 554 555 /** 556 * Sets a parameter indicating if the rectangle has variable borders 557 * 558 * @param useVariableBorders indication if the rectangle has variable borders 559 */ 560 public void setUseVariableBorders(final boolean useVariableBorders) { 561 this.useVariableBorders = useVariableBorders; 562 } 563 564 /** 565 * Enables the border on the specified side. 566 * 567 * @param side the side to enable. 568 * One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE> 569 */ 570 public void enableBorderSide(final int side) { 571 if (border == UNDEFINED) 572 border = 0; 573 border |= side; 574 } 575 576 /** 577 * Disables the border on the specified side. 578 * 579 * @param side the side to disable. 580 * One of <CODE>LEFT, RIGHT, TOP, BOTTOM</CODE> 581 */ 582 public void disableBorderSide(final int side) { 583 if (border == UNDEFINED) 584 border = 0; 585 border &= ~side; 586 } 587 588 // METHODS TO GET/SET THE BORDER WIDTH: 589 590 /** 591 * Gets the borderwidth. 592 * 593 * @return a value 594 */ 595 public float getBorderWidth() { 596 return borderWidth; 597 } 598 599 /** 600 * Sets the borderwidth of the table. 601 * 602 * @param borderWidth the new value 603 */ 604 public void setBorderWidth(final float borderWidth) { 605 this.borderWidth = borderWidth; 606 } 607 608 /** 609 * Helper function returning the border width of a specific side. 610 * 611 * @param variableWidthValue a variable width (could be undefined) 612 * @param side the border you want to check 613 * @return the variableWidthValue if not undefined, otherwise the borderWidth 614 */ 615 private float getVariableBorderWidth(final float variableWidthValue, final int side) { 616 if ((border & side) != 0) 617 return variableWidthValue != UNDEFINED ? variableWidthValue : borderWidth; 618 return 0; 619 } 620 621 /** 622 * Helper function updating the border flag for a side 623 * based on the specified width. 624 * A width of 0 will disable the border on that side. 625 * Any other width enables it. 626 * 627 * @param width width of border 628 * @param side border side constant 629 */ 630 private void updateBorderBasedOnWidth(final float width, final int side) { 631 useVariableBorders = true; 632 if (width > 0) 633 enableBorderSide(side); 634 else 635 disableBorderSide(side); 636 } 637 638 /** 639 * Gets the width of the left border. 640 * 641 * @return a width 642 */ 643 public float getBorderWidthLeft() { 644 return getVariableBorderWidth(borderWidthLeft, LEFT); 645 } 646 647 /** 648 * Sets the width of the left border. 649 * 650 * @param borderWidthLeft a width 651 */ 652 public void setBorderWidthLeft(final float borderWidthLeft) { 653 this.borderWidthLeft = borderWidthLeft; 654 updateBorderBasedOnWidth(borderWidthLeft, LEFT); 655 } 656 657 /** 658 * Gets the width of the right border. 659 * 660 * @return a width 661 */ 662 public float getBorderWidthRight() { 663 return getVariableBorderWidth(borderWidthRight, RIGHT); 664 } 665 666 /** 667 * Sets the width of the right border. 668 * 669 * @param borderWidthRight a width 670 */ 671 public void setBorderWidthRight(final float borderWidthRight) { 672 this.borderWidthRight = borderWidthRight; 673 updateBorderBasedOnWidth(borderWidthRight, RIGHT); 674 } 675 676 /** 677 * Gets the width of the top border. 678 * 679 * @return a width 680 */ 681 public float getBorderWidthTop() { 682 return getVariableBorderWidth(borderWidthTop, TOP); 683 } 684 685 /** 686 * Sets the width of the top border. 687 * 688 * @param borderWidthTop a width 689 */ 690 public void setBorderWidthTop(final float borderWidthTop) { 691 this.borderWidthTop = borderWidthTop; 692 updateBorderBasedOnWidth(borderWidthTop, TOP); 693 } 694 695 /** 696 * Gets the width of the bottom border. 697 * 698 * @return a width 699 */ 700 public float getBorderWidthBottom() { 701 return getVariableBorderWidth(borderWidthBottom, BOTTOM); 702 } 703 704 /** 705 * Sets the width of the bottom border. 706 * 707 * @param borderWidthBottom a width 708 */ 709 public void setBorderWidthBottom(final float borderWidthBottom) { 710 this.borderWidthBottom = borderWidthBottom; 711 updateBorderBasedOnWidth(borderWidthBottom, BOTTOM); 712 } 713 714 // METHODS TO GET/SET THE BORDER COLOR: 715 716 /** 717 * Gets the color of the border. 718 * 719 * @return a <CODE>BaseColor</CODE> 720 */ 721 public BaseColor getBorderColor() { 722 return borderColor; 723 } 724 725 /** 726 * Sets the color of the border. 727 * 728 * @param borderColor a <CODE>BaseColor</CODE> 729 */ 730 public void setBorderColor(final BaseColor borderColor) { 731 this.borderColor = borderColor; 732 } 733 734 /** 735 * Gets the color of the left border. 736 * 737 * @return a <CODE>BaseColor</CODE> 738 */ 739 public BaseColor getBorderColorLeft() { 740 if (borderColorLeft == null) 741 return borderColor; 742 return borderColorLeft; 743 } 744 745 /** 746 * Sets the color of the left border. 747 * 748 * @param borderColorLeft a <CODE>BaseColor</CODE> 749 */ 750 public void setBorderColorLeft(final BaseColor borderColorLeft) { 751 this.borderColorLeft = borderColorLeft; 752 } 753 754 /** 755 * Gets the color of the right border. 756 * 757 * @return a <CODE>BaseColor</CODE> 758 */ 759 public BaseColor getBorderColorRight() { 760 if (borderColorRight == null) 761 return borderColor; 762 return borderColorRight; 763 } 764 765 /** 766 * Sets the color of the right border. 767 * 768 * @param borderColorRight a <CODE>BaseColor</CODE> 769 */ 770 public void setBorderColorRight(final BaseColor borderColorRight) { 771 this.borderColorRight = borderColorRight; 772 } 773 774 /** 775 * Gets the color of the top border. 776 * 777 * @return a <CODE>BaseColor</CODE> 778 */ 779 public BaseColor getBorderColorTop() { 780 if (borderColorTop == null) 781 return borderColor; 782 return borderColorTop; 783 } 784 785 /** 786 * Sets the color of the top border. 787 * 788 * @param borderColorTop a <CODE>BaseColor</CODE> 789 */ 790 public void setBorderColorTop(final BaseColor borderColorTop) { 791 this.borderColorTop = borderColorTop; 792 } 793 794 /** 795 * Gets the color of the bottom border. 796 * 797 * @return a <CODE>BaseColor</CODE> 798 */ 799 public BaseColor getBorderColorBottom() { 800 if (borderColorBottom == null) 801 return borderColor; 802 return borderColorBottom; 803 } 804 805 /** 806 * Sets the color of the bottom border. 807 * 808 * @param borderColorBottom a <CODE>BaseColor</CODE> 809 */ 810 public void setBorderColorBottom(final BaseColor borderColorBottom) { 811 this.borderColorBottom = borderColorBottom; 812 } 813 814 // SPECIAL METHODS: 815 816 /** 817 * Gets a Rectangle that is altered to fit on the page. 818 * 819 * @param top the top position 820 * @param bottom the bottom position 821 * @return a <CODE>Rectangle</CODE> 822 */ 823 public Rectangle rectangle(final float top, final float bottom) { 824 Rectangle tmp = new Rectangle(this); 825 if (getTop() > top) { 826 tmp.setTop(top); 827 tmp.disableBorderSide(TOP); 828 } 829 if (getBottom() < bottom) { 830 tmp.setBottom(bottom); 831 tmp.disableBorderSide(BOTTOM); 832 } 833 return tmp; 834 } 835 836 /** 837 * Copies each of the parameters, except the position, from a 838 * <CODE>Rectangle</CODE> object 839 * 840 * @param rect <CODE>Rectangle</CODE> to copy from 841 */ 842 public void cloneNonPositionParameters(final Rectangle rect) { 843 this.rotation = rect.rotation; 844 this.backgroundColor = rect.backgroundColor; 845 this.border = rect.border; 846 this.useVariableBorders = rect.useVariableBorders; 847 this.borderWidth = rect.borderWidth; 848 this.borderWidthLeft = rect.borderWidthLeft; 849 this.borderWidthRight = rect.borderWidthRight; 850 this.borderWidthTop = rect.borderWidthTop; 851 this.borderWidthBottom = rect.borderWidthBottom; 852 this.borderColor = rect.borderColor; 853 this.borderColorLeft = rect.borderColorLeft; 854 this.borderColorRight = rect.borderColorRight; 855 this.borderColorTop = rect.borderColorTop; 856 this.borderColorBottom = rect.borderColorBottom; 857 } 858 859 /** 860 * Copies each of the parameters, except the position, from a 861 * <CODE>Rectangle</CODE> object if the value is set there 862 * 863 * @param rect <CODE>Rectangle</CODE> to copy from 864 */ 865 public void softCloneNonPositionParameters(final Rectangle rect) { 866 if (rect.rotation != 0) 867 this.rotation = rect.rotation; 868 if (rect.backgroundColor != null) 869 this.backgroundColor = rect.backgroundColor; 870 if (rect.border != UNDEFINED) 871 this.border = rect.border; 872 if (useVariableBorders) 873 this.useVariableBorders = rect.useVariableBorders; 874 if (rect.borderWidth != UNDEFINED) 875 this.borderWidth = rect.borderWidth; 876 if (rect.borderWidthLeft != UNDEFINED) 877 this.borderWidthLeft = rect.borderWidthLeft; 878 if (rect.borderWidthRight != UNDEFINED) 879 this.borderWidthRight = rect.borderWidthRight; 880 if (rect.borderWidthTop != UNDEFINED) 881 this.borderWidthTop = rect.borderWidthTop; 882 if (rect.borderWidthBottom != UNDEFINED) 883 this.borderWidthBottom = rect.borderWidthBottom; 884 if (rect.borderColor != null) 885 this.borderColor = rect.borderColor; 886 if (rect.borderColorLeft != null) 887 this.borderColorLeft = rect.borderColorLeft; 888 if (rect.borderColorRight != null) 889 this.borderColorRight = rect.borderColorRight; 890 if (rect.borderColorTop != null) 891 this.borderColorTop = rect.borderColorTop; 892 if (rect.borderColorBottom != null) 893 this.borderColorBottom = rect.borderColorBottom; 894 } 895 896 /** 897 * @return a String representation of the rectangle 898 * @see java.lang.Object#toString() 899 */ 900 @Override 901 public String toString() { 902 StringBuffer buf = new StringBuffer("Rectangle: "); 903 buf.append(getWidth()); 904 buf.append('x'); 905 buf.append(getHeight()); 906 buf.append(" (rot: "); 907 buf.append(rotation); 908 buf.append(" degrees)"); 909 return buf.toString(); 910 } 911 912}