001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: BorderProps.java 474225 2006-11-13 10:08:19Z jeremias $ */
019:
020: package org.apache.fop.traits;
021:
022: import java.awt.Color;
023: import java.io.Serializable;
024: import java.util.StringTokenizer;
025:
026: import org.apache.fop.apps.FOUserAgent;
027: import org.apache.fop.fo.Constants;
028: import org.apache.fop.fo.expr.PropertyException;
029: import org.apache.fop.util.ColorUtil;
030:
031: /**
032: * Border properties.
033: * Class to store border trait propties for the area tree.
034: */
035: public class BorderProps implements Serializable {
036:
037: /** Separate border model */
038: public static final int SEPARATE = 0;
039: /** Collapsing border model, for borders inside a table */
040: public static final int COLLAPSE_INNER = 1;
041: /** Collapsing border model, for borders at the table's outer border */
042: public static final int COLLAPSE_OUTER = 2;
043:
044: /** Border style (one of EN_*) */
045: public int style; // Enum for border style
046: /** Border color */
047: public Color color;
048: /** Border width */
049: public int width;
050: /** Border mode (one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER) */
051: public int mode;
052:
053: /**
054: * Constructs a new BorderProps instance.
055: * @param style border style (one of EN_*)
056: * @param width border width
057: * @param color border color
058: * @param mode border mode ((one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER)
059: */
060: public BorderProps(int style, int width, Color color, int mode) {
061: this .style = style;
062: this .width = width;
063: this .color = color;
064: this .mode = mode;
065: }
066:
067: /**
068: * Constructs a new BorderProps instance.
069: * @param style border style (one of the XSL enum values for border style)
070: * @param width border width
071: * @param color border color
072: * @param mode border mode ((one of SEPARATE, COLLAPSE_INNER and COLLAPSE_OUTER)
073: */
074: public BorderProps(String style, int width, Color color, int mode) {
075: this (getConstantForStyle(style), width, color, mode);
076: }
077:
078: /**
079: * @param bp the border properties or null
080: * @return the effective width of the clipped part of the border
081: */
082: public static int getClippedWidth(BorderProps bp) {
083: if ((bp != null) && (bp.mode != SEPARATE)) {
084: return bp.width / 2;
085: } else {
086: return 0;
087: }
088: }
089:
090: private String getStyleString() {
091: switch (style) {
092: case Constants.EN_NONE:
093: return "none";
094: case Constants.EN_HIDDEN:
095: return "hidden";
096: case Constants.EN_DOTTED:
097: return "dotted";
098: case Constants.EN_DASHED:
099: return "dashed";
100: case Constants.EN_SOLID:
101: return "solid";
102: case Constants.EN_DOUBLE:
103: return "double";
104: case Constants.EN_GROOVE:
105: return "groove";
106: case Constants.EN_RIDGE:
107: return "ridge";
108: case Constants.EN_INSET:
109: return "inset";
110: case Constants.EN_OUTSET:
111: return "outset";
112: default:
113: throw new IllegalStateException("Illegal border style: "
114: + style);
115: }
116: }
117:
118: private static int getConstantForStyle(String style) {
119: if ("none".equalsIgnoreCase(style)) {
120: return Constants.EN_NONE;
121: } else if ("hidden".equalsIgnoreCase(style)) {
122: return Constants.EN_HIDDEN;
123: } else if ("dotted".equalsIgnoreCase(style)) {
124: return Constants.EN_DOTTED;
125: } else if ("dashed".equalsIgnoreCase(style)) {
126: return Constants.EN_DASHED;
127: } else if ("solid".equalsIgnoreCase(style)) {
128: return Constants.EN_SOLID;
129: } else if ("double".equalsIgnoreCase(style)) {
130: return Constants.EN_DOUBLE;
131: } else if ("groove".equalsIgnoreCase(style)) {
132: return Constants.EN_GROOVE;
133: } else if ("ridge".equalsIgnoreCase(style)) {
134: return Constants.EN_RIDGE;
135: } else if ("inset".equalsIgnoreCase(style)) {
136: return Constants.EN_INSET;
137: } else if ("outset".equalsIgnoreCase(style)) {
138: return Constants.EN_OUTSET;
139: } else {
140: throw new IllegalStateException("Illegal border style: "
141: + style);
142: }
143: }
144:
145: /** @see java.lang.Object#hashCode() */
146: public int hashCode() {
147: return toString().hashCode();
148: }
149:
150: /** @see java.lang.Object#equals(java.lang.Object) */
151: public boolean equals(Object obj) {
152: if (obj == null) {
153: return false;
154: } else if (obj == this ) {
155: return true;
156: } else {
157: if (obj instanceof BorderProps) {
158: BorderProps other = (BorderProps) obj;
159: return (style == other.style)
160: && color.equals(other.color)
161: && width == other.width && mode == other.mode;
162: }
163: }
164: return false;
165: }
166:
167: /**
168: * Returns a BorderProps represtation of a string of the format as written by
169: * BorderProps.toString().
170: * @param foUserAgent FOP user agent caching ICC profiles
171: * @param s the string
172: * @return a BorderProps instance
173: */
174: public static BorderProps valueOf(FOUserAgent foUserAgent, String s) {
175: if (s.startsWith("(") && s.endsWith(")")) {
176: s = s.substring(1, s.length() - 1);
177: StringTokenizer st = new StringTokenizer(s, ",");
178: String style = st.nextToken();
179: String color = st.nextToken();
180: int width = Integer.parseInt(st.nextToken());
181: int mode = SEPARATE;
182: if (st.hasMoreTokens()) {
183: String ms = st.nextToken();
184: if ("collapse-inner".equalsIgnoreCase(ms)) {
185: mode = COLLAPSE_INNER;
186: } else if ("collapse-outer".equalsIgnoreCase(ms)) {
187: mode = COLLAPSE_OUTER;
188: }
189: }
190: Color c;
191: try {
192: c = ColorUtil.parseColorString(foUserAgent, color);
193: } catch (PropertyException e) {
194: throw new IllegalArgumentException(e.getMessage());
195: }
196:
197: return new BorderProps(style, width, c, mode);
198: } else {
199: throw new IllegalArgumentException(
200: "BorderProps must be surrounded by parentheses");
201: }
202: }
203:
204: /** @see java.lang.Object#toString() */
205: public String toString() {
206: StringBuffer sbuf = new StringBuffer();
207: sbuf.append('(');
208: sbuf.append(getStyleString());
209: sbuf.append(',');
210: sbuf.append(ColorUtil.colorToString(color));
211: sbuf.append(',');
212: sbuf.append(width);
213: if (mode != SEPARATE) {
214: sbuf.append(',');
215: if (mode == COLLAPSE_INNER) {
216: sbuf.append("collapse-inner");
217: } else {
218: sbuf.append("collapse-outer");
219: }
220: }
221: sbuf.append(')');
222: return sbuf.toString();
223: }
224:
225: }
|