001package net.gdface.sdk;
002
003import java.io.ByteArrayOutputStream;
004import java.io.PrintStream;
005import java.io.Serializable;
006
007/**
008 * 通用矩形定义对象
009 * @author guyadong
010 */
011public class FRect implements Serializable{
012        private static final FRect NULL=new FRect();
013        
014        /**
015         * {@code rect}为{@code null}或所有字段为0时返回{@code true}
016         * @param rect
017         * @return
018         */
019        public static final boolean isNull(FRect rect){
020                return null == rect || rect.isZeroAll();
021        }
022        /**
023         * 
024         */
025        private static final long serialVersionUID = 1L;
026        private int left;
027        private int top;
028        private int width;
029        private int height;
030
031        public FRect() {
032                this(0,0,0,0);
033        }
034
035        public FRect(int left, int top, int width, int height) {
036                this.left = left;
037                this.top = top;
038                this.width = width;
039                this.height = height;
040        }
041
042        public int getLeft() {
043                return this.left;
044        }
045
046        public void setLeft(int left) {
047                this.left = left;
048        }
049
050        public int getTop() {
051                return this.top;
052        }
053
054        public void setTop(int top) {
055                this.top = top;
056        }
057
058        public int getWidth() {
059                return this.width;
060        }
061
062        public void setWidth(int width) {
063                this.width = width;
064        }
065
066        public int getHeight() {
067                return this.height;
068        }
069
070        public void setHeight(int height) {
071                this.height = height;
072        }
073
074        @Override
075        public String toString() {
076                ByteArrayOutputStream bo = new ByteArrayOutputStream();
077                toStream(new PrintStream(bo));
078                return bo.toString();
079        }
080        /**
081         * 以文本形式向{@link PrintStream}输出对象内容 
082         * @param stream
083         */
084        public void toStream(PrintStream stream) {
085                stream.printf("[%d,%d,%d,%d]",this.left,this.top, this.width,this.height);
086        }
087
088        @Override
089        public int hashCode() {
090                final int prime = 31;
091                int result = 1;
092                result = prime * result + height;
093                result = prime * result + left;
094                result = prime * result + top;
095                result = prime * result + width;
096                return result;
097        }
098
099        @Override
100        public boolean equals(Object obj) {
101                if (this == obj) {
102                        return true;
103                }
104                if (obj == null) {
105                        return false;
106                }
107                if (!(obj instanceof FRect)) {
108                        return false;
109                }
110                FRect other = (FRect) obj;
111                if (height != other.height) {
112                        return false;
113                }
114                if (left != other.left) {
115                        return false;
116                }
117                if (top != other.top) {
118                        return false;
119                }
120                if (width != other.width) {
121                        return false;
122                }
123                return true;
124        }
125        public boolean isZeroAll(){
126                return this.equals(NULL);
127        }
128        public boolean contains(FRect rectangle) {
129                return this.contains(rectangle.left, rectangle.top, rectangle.width, rectangle.height);
130        }
131
132        public boolean contains(int n, int n2, int n3, int n4) {
133                int n5 = this.width;
134                int n6 = this.height;
135                if ((n5 | n6 | n3 | n4) < 0) {
136                        return false;
137                }
138                int n7 = this.left;
139                int n8 = this.top;
140                if (n < n7 || n2 < n8) {
141                        return false;
142                }
143                n5 += n7;
144                if ((n3 += n) <= n ? n5 >= n7 || n3 > n5 : n5 >= n7 && n3 > n5) {
145                        return false;
146                }
147                n6 += n8;
148                if ((n4 += n2) <= n2 ? n6 >= n8 || n4 > n6 : n6 >= n8 && n4 > n6) {
149                        return false;
150                }
151                return true;
152        }
153        /**
154         * 将指定的矩形对象以中心向外长宽扩展指定的比例
155         * @param imageWidth 图像宽度
156         * @param imageHeight 图像高度
157         * @param ratio 扩展比例(大于0)
158         * @return 扩展后的新矩形对象
159         */
160        public final FRect grow(int imageWidth,int imageHeight,float ratio){
161                if(ratio <= 0){
162                        throw new  IllegalArgumentException("INVALID ratio,>0 required");
163                }
164                int gw = (int) (getWidth()*ratio);
165                int gh = (int) (getHeight()*ratio);
166                return grow(imageWidth,imageHeight,gw,gh,gw,gh);
167        }
168        /**
169         * 将矩形{@code frect}对象上下左右扩充指定的像素,如果超出图像尺寸,则以图像尺寸为边界<br>
170         * @param imageWidth 图像尺寸:宽度
171         * @param imageHeight 图像尺寸:高度
172         * @param gleft 左边扩展尺寸
173         * @param gtop 顶边扩展尺寸
174         * @param gright 右边扩展尺寸
175         * @param gbottom 底边扩展尺寸
176         * @return 扩展后的新矩形对象
177         */
178        public FRect grow(int imageWidth,int imageHeight,int gleft,int gtop,int gright,int gbottom){
179                if(imageWidth<0 || imageHeight < 0 || gleft<0 || gtop <0 || gright <0 || gbottom <0){
180                        throw new  IllegalArgumentException("INVALID input argument,>=0 required");
181                }
182                int newLeft = Math.max(getLeft() - gleft, 0);
183                int newTop = Math.max(getTop() - gtop, 0);
184                int newRight= Math.min(getLeft() + getWidth() + gright, imageWidth);
185                int newBottom= Math.min(getTop() + getHeight() + gbottom, imageHeight);
186                return new FRect(newLeft,newTop,newRight - newLeft,newBottom - newTop); 
187        }
188}