001: /* ****************************************************************************
002: * FontInfo.java
003: * ****************************************************************************/
004:
005: /* J_LZ_COPYRIGHT_BEGIN *******************************************************
006: * Copyright 2001-2006 Laszlo Systems, Inc. All Rights Reserved. *
007: * Use is subject to license terms. *
008: * J_LZ_COPYRIGHT_END *********************************************************/
009:
010: package org.openlaszlo.compiler;
011:
012: import org.openlaszlo.utils.ChainedException;
013: import java.io.Serializable;
014: import java.util.*;
015:
016: /**
017: * Font information used for measuring text.
018: *
019: * @author <a href="mailto:bloch@laszlosystems.com">Eric Bloch</a>
020: */
021: public class FontInfo implements java.io.Serializable {
022:
023: public static final String NULL_FONT = null;
024: public static final int NULL_SIZE = -1;
025: public static final int NULL_STYLE = -1;
026:
027: /** bit fields for text style */
028: public final static int PLAIN = 0x0;
029: /** bit fields for text style */
030: public final static int BOLD = 0x1;
031: /** bit fields for text style */
032: public final static int ITALIC = 0x2;
033: /** bit fields for text style */
034: public final static int BOLDITALIC = 0x3;
035:
036: /** font face */
037: private String mName = null;
038: /** font size */
039: private int mSize;
040:
041: /** used for compile-time width/height cascading */
042: private int mWidth = NULL_SIZE;
043: private int mHeight = NULL_SIZE;
044:
045: /** font style bits */
046: public int styleBits = 0;
047:
048: /** This can have three values:
049: -1 = unset
050: 0 = false
051: 1 = true
052: */
053: public final static int FONTINFO_NULL = -1;
054: public final static int FONTINFO_FALSE = 0;
055: public final static int FONTINFO_TRUE = 1;
056:
057: // resizable defaults to false
058: public int resizable = FONTINFO_NULL;
059:
060: // multiline default to false
061: public int multiline = FONTINFO_NULL;
062:
063: public String toString() {
064: return "FontInfo: name=" + mName + ", size=" + mSize
065: + ", style=" + getStyle();
066: }
067:
068: public String toStringLong() {
069: return "FontInfo: name=" + mName + ", size=" + mSize
070: + ", style=" + getStyle() + ", width=" + mWidth
071: + ", height=" + mHeight + ", resizable=" + resizable
072: + ", multiline=" + multiline;
073: }
074:
075: /**
076: * Create a new FontInfo
077: * @param name name
078: * @param sz size
079: * @param st style
080: */
081: public FontInfo(String name, String sz, String st) {
082: mName = name;
083: setSize(sz);
084: setStyle(st);
085: }
086:
087: public FontInfo(FontInfo i) {
088: this .mName = i.mName;
089: this .mSize = i.mSize;
090: this .styleBits = i.styleBits;
091:
092: // static text optimization params
093: this .resizable = i.resizable;
094: this .multiline = i.multiline;
095: this .mWidth = i.getWidth();
096: this .mHeight = i.getHeight();
097: }
098:
099: public FontInfo(String name, int sz, int st) {
100: mName = name;
101: mSize = sz;
102: styleBits = st;
103: }
104:
105: /** Extra params for static textfield optimization.
106: Tracks width and height of a view.
107: */
108: public int getWidth() {
109: return mWidth;
110: }
111:
112: public int getHeight() {
113: return mHeight;
114: }
115:
116: public void setWidth(int w) {
117: mWidth = w;
118: }
119:
120: public void setHeight(int w) {
121: mHeight = w;
122: }
123:
124: /**
125: * Set the name
126: * @param f the name
127: */
128: public void setName(String f) {
129: mName = f;
130: }
131:
132: /**
133: * Set the style
134: * @param st style
135: */
136: public void setStyle(String st) {
137: styleBits = styleBitsFromString(st);
138: }
139:
140: /**
141: * Set the style bits directly
142: * @param st stylebits
143: */
144: public void setStyleBits(int st) {
145: styleBits = st;
146: }
147:
148: /**
149: * Set the size
150: * @param sz the size
151: */
152: public void setSize(String sz) {
153: mSize = Integer.parseInt(sz);
154: }
155:
156: /**
157: * Set the size
158: * @param sz the size
159: */
160: public void setSize(int sz) {
161: mSize = sz;
162: }
163:
164: /**
165: * @return the size
166: */
167: public int getSize() {
168: return mSize;
169: }
170:
171: /**
172: * @return the stylebits
173: */
174: public int getStyleBits() {
175: return styleBits;
176: }
177:
178: /**
179: * @return the name
180: */
181: public String getName() {
182: return mName;
183: }
184:
185: public static FontInfo blankFontInfo() {
186: FontInfo fi = new FontInfo(FontInfo.NULL_FONT,
187: FontInfo.NULL_SIZE, FontInfo.NULL_STYLE);
188: return fi;
189: }
190:
191: /** Does this font spec contain a known font name,size,style ?
192: */
193: public boolean isFullySpecified() {
194: return ((mSize != NULL_SIZE) && (styleBits != NULL_STYLE)
195: && (mName != NULL_FONT) &&
196: // we don't understand constraint expressions, just string literals
197: (mName.charAt(0) != '$'));
198: }
199:
200: /** If OTHER has non-null fields, copy
201: them from OTHER to us.
202:
203: null fields are indicated by:
204: name == null,
205: size == -1,
206: stylebits == -1,
207: */
208: public void mergeFontInfoFrom(FontInfo other) {
209: if (other.getSize() != NULL_SIZE) {
210: mSize = other.getSize();
211: }
212:
213: if (other.getStyleBits() != NULL_STYLE) {
214: styleBits = other.getStyleBits();
215: }
216:
217: if (other.getName() != NULL_FONT) {
218: mName = other.getName();
219: }
220:
221: if (other.resizable != FONTINFO_NULL) {
222: resizable = other.resizable;
223: }
224:
225: if (other.multiline != FONTINFO_NULL) {
226: multiline = other.multiline;
227: }
228:
229: if (other.getWidth() != NULL_SIZE) {
230: mWidth = other.getWidth();
231: }
232:
233: if (other.getHeight() != NULL_SIZE) {
234: mHeight = other.getHeight();
235: }
236: }
237:
238: /**
239: * @return the name
240: */
241: public final String getStyle() {
242: return styleBitsToString(styleBits);
243: }
244:
245: /**
246: * @return the name
247: */
248: public final String getStyle(boolean whitespace) {
249: return styleBitsToString(styleBits, whitespace);
250: }
251:
252: /**
253: * Return the string representation of the style.
254: *
255: * @param styleBits an <code>int</code> encoding the style
256: * @param whitespace whether to separate style names by spaces; e.g. true for "bold italic", false for "bolditalic"
257: */
258: public static String styleBitsToString(int styleBits,
259: boolean whitespace) {
260: switch (styleBits) {
261: case PLAIN:
262: return "plain";
263: case BOLD:
264: return "bold";
265: case ITALIC:
266: return "italic";
267: case BOLDITALIC:
268: if (whitespace) {
269: return "bold italic";
270: } else {
271: return "bolditalic";
272: }
273: default:
274: return null;
275: }
276: }
277:
278: /**
279: * Return the string representation of the style, e.g. "bold italic".
280: *
281: * @param styleBits an <code>int</code> value
282: */
283: public static String styleBitsToString(int styleBits) {
284: return styleBitsToString(styleBits, true);
285: }
286:
287: /**
288: /**
289: * @return the bits for a style
290: */
291: public static int styleBitsFromString(String name) {
292: int style = PLAIN;
293: if (name != null) {
294: StringTokenizer st = new StringTokenizer(name);
295: while (st.hasMoreTokens()) {
296: String token = st.nextToken();
297: if (token.equals("bold")) {
298: style |= BOLD;
299: } else if (token.equals("italic")) {
300: style |= ITALIC;
301: } else if (token.equals("plain")) {
302: style |= PLAIN;
303: } else if (token.equals("bolditalic")) {
304: style |= ITALIC | BOLD;
305: } else {
306: throw new CompilationError(
307: /* (non-Javadoc)
308: * @i18n.test
309: * @org-mes="Unknown style " + p[0]
310: */
311: org.openlaszlo.i18n.LaszloMessages.getMessage(
312: FontInfo.class.getName(), "051018-315",
313: new Object[] { name }));
314: }
315: }
316: }
317: return style;
318: }
319:
320: /**
321: * "bold italic", "italic bold" -> "bold italic" or "bolditalic"
322: * (depending on the value of <code>whitespace</code>
323: *
324: * @param style a <code>String</code> value
325: * @return a <code>String</code> value
326: */
327: public static String normalizeStyleString(String style,
328: boolean whitespace) {
329: if (style.matches("^\\s*\\$(\\w*)\\{(.*)}\\s*")) {
330: return style;
331: } else {
332: return styleBitsToString(styleBitsFromString(style),
333: whitespace);
334: }
335: }
336: }
|