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:
042: package org.netbeans.modules.visualweb.designer;
043:
044: import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
045: import org.netbeans.modules.visualweb.api.designer.cssengine.CssValue;
046: import java.awt.Font;
047: import java.awt.FontMetrics;
048: import java.util.Hashtable;
049: import java.util.Map;
050: import org.w3c.dom.Element;
051:
052: /**
053: * Utilites for css box visual formatting.
054: *
055: * @author Peter Zavadsky
056: * @author Tor Norbye (the old font stuff)
057: */
058: public final class CssUtilities {
059:
060: // XXX Copied form CssBox.
061: // XXX Copy also in designer/jsf/../DomDocumentImpl.
062: // FIXME This is very suspicious, and should be revisited.
063: // public static final int AUTO = Integer.MAX_VALUE - 1;
064: public static final int AUTO = CssValue.AUTO;
065:
066: /** Creates a new instance of CssBoxUtilities */
067: private CssUtilities() {
068: }
069:
070: // /** Gets <code>FontMetrics</code> for the designer <code>Font</code> used for specified
071: // * <code>Element</code> and text in its value attribute.
072: // * @param element <code>Element</code> which used font's metrics is gonna be provided
073: // * @see #getDesignerFontForElement */
074: // public static FontMetrics getDesignerFontMetricsForElement(Element element) {
075: // return getDesignerFontMetricsForElement(element, element.getAttribute(HtmlAttribute.VALUE));
076: // }
077:
078: /** Gets <code>FontMetrics</code> for the designer <code>Font</code> used for specified
079: * <code>Element</code> and text.
080: * @param element <code>Element</code> which used font's metrics is gonna be provided
081: * @param text text based on which the font is selected (according the priority list
082: * and the ability to show all its characters).
083: * @see #getDesignerFontForElement */
084: public static FontMetrics getDesignerFontMetricsForElement(
085: Element element, String text, int defaultFontSize) {
086: Font font = getDesignerFontForElement(element, text,
087: defaultFontSize);
088: // return Toolkit.getDefaultToolkit().getFontMetrics(font);
089: return DesignerUtils.getFontMetrics(font);
090: }
091:
092: // /** Gets designer <code>Font</code> used for <code>element</code> and text in its value attribute.
093: // * @param element <code>Element</code> for which the <code>Font</code> is provided */
094: // public static Font getDesignerFontForElement(Element element) {
095: // return getDesignerFontForElement(element, element.getAttribute(HtmlAttribute.VALUE));
096: // }
097:
098: /** Gets designer <code>Font</code> for specified <code>element</code> and text.
099: * @param element <code>Element</code> for which the <code>Font</code> is provided
100: * @param text text based on which the font is selected (according the priority list
101: * and the ability to show all its characters. */
102: public static Font getDesignerFontForElement(Element element,
103: String text, int defaultFontSize) {
104: String[] fontFamilyNames = CssProvider.getValueService()
105: .getFontFamilyNamesForElement(element);
106:
107: int style = CssProvider.getValueService()
108: .getFontStyleForElement(element, Font.PLAIN);
109: // int size = Math.round(CssProvider.getValueService().getFontSizeForElement(element, DesignerSettings.getInstance().getDefaultFontSize()));
110: int size = Math.round(CssProvider.getValueService()
111: .getFontSizeForElement(element, defaultFontSize));
112:
113: for (String fontFamilyName : fontFamilyNames) {
114: Font font = getFont(fontFamilyName, style, size);
115: // #6461942 Needs to check whether the font is able to show the text.
116: if (text == null || text.length() == 0
117: || font.canDisplayUpTo(text) == -1) {
118: return font;
119: }
120: }
121:
122: // XXX This shouldn't happen, anyway fall back to the last font family name specified.
123: return getFont(fontFamilyNames[fontFamilyNames.length - 1],
124: style, size);
125: }
126:
127: // >>> XXX Moved from CssValueServiceImpl
128: private static FontKey fontSearch = new FontKey(null, 0, 0);
129: private static Map<FontKey, Font> fontTable = new Hashtable<FontKey, Font>();
130:
131: /**
132: * Gets a new font. This returns a Font from a cache
133: * if a cached font exists. If not, a Font is added to
134: * the cache. This is basically a low-level cache for
135: * 1.1 font features.
136: *
137: * @param family the font family (such as "Monospaced")
138: * @param style the style of the font (such as Font.PLAIN)
139: * @param size the point size >= 1
140: * @return the new font
141: */
142: private static Font getFont(String family, int style, int size) {
143: fontSearch.setValue(family, style, size);
144:
145: Font f = fontTable.get(fontSearch);
146:
147: if (f == null) {
148: // haven't seen this one yet.
149: f = new Font(family, style, size);
150:
151: FontKey key = new FontKey(family, style, size);
152: fontTable.put(key, f);
153: }
154:
155: return f;
156: }
157:
158: /** Key for a font table */
159: private static class FontKey {
160: private String family;
161: private int style;
162: private int size;
163:
164: /**
165: * Constructs a font key.
166: */
167: public FontKey(String family, int style, int size) {
168: setValue(family, style, size);
169: }
170:
171: public void setValue(String family, int style, int size) {
172: this .family = (family != null) ? family.intern() : null;
173: this .style = style;
174: this .size = size;
175: }
176:
177: /**
178: * Returns a hashcode for this font.
179: * @return a hashcode value for this font.
180: */
181: public int hashCode() {
182: int fhash = (family != null) ? family.hashCode() : 0;
183:
184: return fhash ^ style ^ size;
185: }
186:
187: /**
188: * Compares this object to the specifed object.
189: * The result is <code>true</code> if and only if the argument is not
190: * <code>null</code> and is a <code>Font</code> object with the same
191: * name, style, and point size as this font.
192: * @param obj the object to compare this font with.
193: * @return <code>true</code> if the objects are equal;
194: * <code>false</code> otherwise.
195: */
196: public boolean equals(Object obj) {
197: if (obj instanceof FontKey) {
198: FontKey font = (FontKey) obj;
199:
200: return (size == font.size) && (style == font.style)
201: && (family == font.family);
202: }
203:
204: return false;
205: }
206: } // End of FontKey
207:
208: // <<< XXX Moved from CssValueServiceImpl
209:
210: /** XXX Copy also in insync/FacesDnDSupport.
211: * XXX Copy also in designer/jsf/../DomDocumentImpl
212: * XXX Provides the auto value as <code>AUTO</code>, revise that, it looks very dangerous.
213: * TODO At least move into designer/cssengine.
214: */
215: public static int getCssLength(Element element, int property) {
216: //// Value val = getValue(element, property);
217: // CssValue cssValue = CssProvider.getEngineService().getComputedValueForElement(element, property);
218: //
219: // // XXX #6460007 Possible NPE.
220: // if (cssValue == null) {
221: // // XXX What value to return?
222: // return 0;
223: // }
224: //
225: //// if (val == CssValueConstants.AUTO_VALUE) {
226: // if (CssProvider.getValueService().isAutoValue(cssValue)) {
227: // return AUTO;
228: // }
229: //
230: //// return (int)val.getFloatValue();
231: // return (int)cssValue.getFloatValue();
232: return CssProvider.getValueService().getCssLength(element,
233: property);
234: }
235:
236: }
|