001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.designer.cssengine;
042:
043: import java.util.HashMap;
044: import java.util.Map;
045: import org.apache.batik.css.engine.CSSEngine;
046: import org.apache.batik.css.engine.value.AbstractValueFactory;
047: import org.apache.batik.css.engine.value.ShorthandManager;
048: import org.apache.batik.css.engine.value.css2.FontSizeManager;
049: import org.apache.batik.css.engine.value.css2.FontStyleManager;
050: import org.apache.batik.css.engine.value.css2.FontVariantManager;
051: import org.apache.batik.css.engine.value.css2.FontWeightManager;
052: import org.openide.util.NbBundle;
053: import org.w3c.css.sac.LexicalUnit;
054: import org.w3c.dom.DOMException;
055:
056: /**
057: * Represents the "font" shorthand property for setting
058: * font-size, font-style, font-variant, font-family, and line-height
059: *
060: * @todo Need to implement reset-semantics for all the properties
061: * that aren't specified
062: * @todo Handle the system font names better than today
063: *
064: * @author Tor Norbye
065: */
066: public class FontShorthandManager extends AbstractValueFactory
067: implements ShorthandManager {
068:
069: public String getPropertyName() {
070: return CssConstants.CSS_FONT_PROPERTY;
071: }
072:
073: // private static HashMap systemFonts = new HashMap(15);
074: private static Map<String, String> systemFonts = new HashMap<String, String>(
075: 15);
076: static {
077: systemFonts.put("caption", "caption"); // NOI18N
078: systemFonts.put("icon", "icon"); // NOI18N
079: systemFonts.put("menu", "menu"); // NOI18N
080: systemFonts.put("message-box", "message-box"); // NOI18N
081: systemFonts.put("small-caption", "small-caption"); // NOI18N
082: systemFonts.put("status-bar", "status-bar"); // NOI18N
083: }
084:
085: public void setValues(CSSEngine eng,
086: ShorthandManager.PropertyHandler ph, LexicalUnit lu,
087: boolean imp) throws DOMException {
088:
089: // The value manager should reset any property which is not set
090: LexicalUnit fontStyle = null, fontVariant = null, fontWeight = null;
091: LexicalUnit fontSize = null, lineHeight = null, fontFamily = null;
092:
093: // The CSS spec says there's a specific property order -- but browsers
094: // seem more lenient than that so we should be too. But we can use
095: // the order to disambiguate.
096: for (; lu != null; lu = lu.getNextLexicalUnit()) {
097: switch (lu.getLexicalUnitType()) {
098: /* How do I handle inherit? Ditto for BackgroundShorthandManager.
099: * Is
100: case LexicalUnit.SAC_INHERIT:
101: return ValueConstants.INHERIT_VALUE;
102: */
103: case LexicalUnit.SAC_EM:
104: case LexicalUnit.SAC_EX:
105: case LexicalUnit.SAC_PIXEL:
106: case LexicalUnit.SAC_CENTIMETER:
107: case LexicalUnit.SAC_MILLIMETER:
108: case LexicalUnit.SAC_INCH:
109: case LexicalUnit.SAC_POINT:
110: case LexicalUnit.SAC_PICA:
111: case LexicalUnit.SAC_REAL:
112: case LexicalUnit.SAC_PERCENTAGE:
113: if (lu.getPreviousLexicalUnit() != null
114: && lu.getPreviousLexicalUnit()
115: .getLexicalUnitType() == LexicalUnit.SAC_OPERATOR_SLASH) {
116: // This is a line height!
117: lineHeight = lu;
118: } else {
119: fontSize = lu;
120: }
121: break;
122: case LexicalUnit.SAC_INTEGER:
123: // If it's 100, 200, ..., 900, then it might be font weight
124: // Else it might be font size or line height
125: int i = lu.getIntegerValue();
126: if (i >= 100 && i % 100 == 0) {
127: fontWeight = lu;
128: } else {
129: fontSize = lu;
130: }
131: break;
132: case LexicalUnit.SAC_IDENT:
133: case LexicalUnit.SAC_STRING_VALUE:
134: String s = lu.getStringValue().toLowerCase().intern();
135: if (s == CssConstants.CSS_NORMAL_VALUE) {
136: // This is defined for multiple properties.
137: // Initially I started to write code here to disambiguate
138: // based on the position to figure out who to assign the
139: // normal to. But then I realized it doesn't matter; we
140: // can ignore it. All 4 properties which support "normal"
141: // (font-style, font-variant, font-weight and line-height)
142: // have "normal" as their default/initial values! And in
143: // the code below, I will reset the values to these defaults
144: // anyway so there's no need to do any work here.
145: } else if (FontStyleManager.values.get(s) != null) {
146: fontStyle = lu;
147: } else if (FontSizeManager.values.get(s) != null) {
148: fontSize = lu;
149: } else if (FontVariantManager.values.get(s) != null) {
150: fontVariant = lu;
151: } else if (FontWeightManager.values.get(s) != null) {
152: fontWeight = lu;
153: } else if (systemFonts.get(s) != null) {
154: // It's one of the system fonts... not sure how to handle this.
155: // Not commonly used luckily.
156: return; // XXX do something better here after Reef!
157: // (don't fall through since these shorthands won't include
158: // a family-name etc. which will generate a warning. The
159: // best we can do is ignore this property.
160: } else {
161: // Must be a font family name!
162: fontFamily = lu;
163: }
164: break;
165: }
166: }
167:
168: if (fontSize == null || fontFamily == null) {
169: // Invalid font setting -- do nothing - but warn the user
170: String msg = NbBundle.getMessage(
171: FontShorthandManager.class, "IllegalFontShorthand"); // NOI18N
172: throw new DOMException(DOMException.SYNTAX_ERR, msg);
173: }
174:
175: if (fontStyle != null) {
176: ph.property(CssConstants.CSS_FONT_STYLE_PROPERTY,
177: fontStyle, imp);
178: }
179: // else {
180: // // Reset property to default value;
181: // // I should add a method for this to the PropertyHandler interface,
182: // // but it will have to be after Reef since we're minimizing
183: // // risk and the number of changes at this point
184: // // XXX TODO
185: // //ph.reset(XhtmlCss.FONT_STYLE_INDEX);
186: // }
187:
188: if (fontVariant != null) {
189: ph.property(CssConstants.CSS_FONT_VARIANT_PROPERTY,
190: fontVariant, imp);
191: }
192: // else {
193: // //ph.reset(XhtmlCss.FONT_VARIANT_INDEX);
194: // }
195:
196: if (fontWeight != null) {
197: ph.property(CssConstants.CSS_FONT_WEIGHT_PROPERTY,
198: fontWeight, imp);
199: }
200:
201: // else {
202: // //ph.reset(XhtmlCss.FONT_WEIGHT_INDEX);
203: // }
204:
205: if (fontSize != null) {
206: ph.property(CssConstants.CSS_FONT_SIZE_PROPERTY, fontSize,
207: imp);
208: }
209:
210: // else {
211: // //ph.reset(XhtmlCss.FONT_SIZE_INDEX);
212: // }
213:
214: if (lineHeight != null) {
215: ph.property(CssConstants.CSS_LINE_HEIGHT_PROPERTY,
216: lineHeight, imp);
217: }
218: // else {
219: // //ph.reset(XhtmlCss.LINE_HEIGHT_INDEX);
220: // }
221:
222: if (fontFamily != null) {
223: ph.property(CssConstants.CSS_FONT_FAMILY_PROPERTY,
224: fontFamily, imp);
225: }
226: // else {
227: // //ph.reset(XhtmlCss.FONT_FAMILY_INDEX);
228: // }
229:
230: }
231: }
|