From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- .../classpath/javax/swing/text/StyleContext.java | 990 +++++++++++++++++++++ 1 file changed, 990 insertions(+) create mode 100644 libjava/classpath/javax/swing/text/StyleContext.java (limited to 'libjava/classpath/javax/swing/text/StyleContext.java') diff --git a/libjava/classpath/javax/swing/text/StyleContext.java b/libjava/classpath/javax/swing/text/StyleContext.java new file mode 100644 index 000000000..295398835 --- /dev/null +++ b/libjava/classpath/javax/swing/text/StyleContext.java @@ -0,0 +1,990 @@ +/* StyleContext.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.swing.text; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Toolkit; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.WeakHashMap; + +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; + +public class StyleContext + implements Serializable, AbstractDocument.AttributeContext +{ + /** The serialization UID (compatible with JDK1.5). */ + private static final long serialVersionUID = 8042858831190784241L; + + public class NamedStyle + implements Serializable, Style + { + /** The serialization UID (compatible with JDK1.5). */ + private static final long serialVersionUID = -6690628971806226374L; + + protected transient ChangeEvent changeEvent; + protected EventListenerList listenerList; + + private transient AttributeSet attributes; + + public NamedStyle() + { + this(null, null); + } + + public NamedStyle(Style parent) + { + this(null, parent); + } + + public NamedStyle(String name, Style parent) + { + attributes = getEmptySet(); + listenerList = new EventListenerList(); + if (name != null) + setName(name); + if (parent != null) + setResolveParent(parent); + } + + public String getName() + { + String name = null; + if (isDefined(StyleConstants.NameAttribute)) + name = getAttribute(StyleConstants.NameAttribute).toString(); + return name; + } + + public void setName(String n) + { + if (n != null) + addAttribute(StyleConstants.NameAttribute, n); + } + + public void addChangeListener(ChangeListener l) + { + listenerList.add(ChangeListener.class, l); + } + + public void removeChangeListener(ChangeListener l) + { + listenerList.remove(ChangeListener.class, l); + } + + public T[] getListeners(Class listenerType) + { + return listenerList.getListeners(listenerType); + } + + public ChangeListener[] getChangeListeners() + { + return (ChangeListener[]) getListeners(ChangeListener.class); + } + + protected void fireStateChanged() + { + ChangeListener[] listeners = getChangeListeners(); + for (int i = 0; i < listeners.length; ++i) + { + // Lazily create event. + if (changeEvent == null) + changeEvent = new ChangeEvent(this); + listeners[i].stateChanged(changeEvent); + } + } + + public void addAttribute(Object name, Object value) + { + attributes = StyleContext.this.addAttribute(attributes, name, value); + fireStateChanged(); + } + + public void addAttributes(AttributeSet attr) + { + attributes = StyleContext.this.addAttributes(attributes, attr); + fireStateChanged(); + } + + public boolean containsAttribute(Object name, Object value) + { + return attributes.containsAttribute(name, value); + } + + public boolean containsAttributes(AttributeSet attrs) + { + return attributes.containsAttributes(attrs); + } + + public AttributeSet copyAttributes() + { + // The RI returns a NamedStyle as copy, so do we. + NamedStyle copy = new NamedStyle(); + copy.attributes = attributes.copyAttributes(); + return copy; + } + + public Object getAttribute(Object attrName) + { + return attributes.getAttribute(attrName); + } + + public int getAttributeCount() + { + return attributes.getAttributeCount(); + } + + public Enumeration getAttributeNames() + { + return attributes.getAttributeNames(); + } + + public boolean isDefined(Object attrName) + { + return attributes.isDefined(attrName); + } + + public boolean isEqual(AttributeSet attr) + { + return attributes.isEqual(attr); + } + + public void removeAttribute(Object name) + { + attributes = StyleContext.this.removeAttribute(attributes, name); + fireStateChanged(); + } + + public void removeAttributes(AttributeSet attrs) + { + attributes = StyleContext.this.removeAttributes(attributes, attrs); + fireStateChanged(); + } + + public void removeAttributes(Enumeration names) + { + attributes = StyleContext.this.removeAttributes(attributes, names); + fireStateChanged(); + } + + + public AttributeSet getResolveParent() + { + return attributes.getResolveParent(); + } + + public void setResolveParent(AttributeSet parent) + { + if (parent != null) + addAttribute(StyleConstants.ResolveAttribute, parent); + else + removeAttribute(StyleConstants.ResolveAttribute); + } + + public String toString() + { + return "NamedStyle:" + getName() + " " + attributes; + } + + private void writeObject(ObjectOutputStream s) + throws IOException + { + s.defaultWriteObject(); + writeAttributeSet(s, attributes); + } + + private void readObject(ObjectInputStream s) + throws ClassNotFoundException, IOException + { + s.defaultReadObject(); + attributes = SimpleAttributeSet.EMPTY; + readAttributeSet(s, this); + } + } + + public class SmallAttributeSet + implements AttributeSet + { + final Object [] attrs; + private AttributeSet resolveParent; + public SmallAttributeSet(AttributeSet a) + { + int n = a.getAttributeCount(); + int i = 0; + attrs = new Object[n * 2]; + Enumeration e = a.getAttributeNames(); + while (e.hasMoreElements()) + { + Object name = e.nextElement(); + Object value = a.getAttribute(name); + if (name == ResolveAttribute) + resolveParent = (AttributeSet) value; + attrs[i++] = name; + attrs[i++] = value; + } + } + + public SmallAttributeSet(Object [] a) + { + attrs = a; + for (int i = 0; i < attrs.length; i += 2) + { + if (attrs[i] == ResolveAttribute) + resolveParent = (AttributeSet) attrs[i + 1]; + } + } + + public Object clone() + { + return this; + } + + public boolean containsAttribute(Object name, Object value) + { + return value.equals(getAttribute(name)); + } + + public boolean containsAttributes(AttributeSet a) + { + boolean res = true; + Enumeration e = a.getAttributeNames(); + while (e.hasMoreElements() && res) + { + Object name = e.nextElement(); + res = a.getAttribute(name).equals(getAttribute(name)); + } + return res; + } + + public AttributeSet copyAttributes() + { + return this; + } + + public boolean equals(Object obj) + { + boolean eq = false; + if (obj instanceof AttributeSet) + { + AttributeSet atts = (AttributeSet) obj; + eq = getAttributeCount() == atts.getAttributeCount() + && containsAttributes(atts); + } + return eq; + } + + public Object getAttribute(Object key) + { + Object att = null; + if (key == StyleConstants.ResolveAttribute) + att = resolveParent; + + for (int i = 0; i < attrs.length && att == null; i += 2) + { + if (attrs[i].equals(key)) + att = attrs[i + 1]; + } + + // Check the resolve parent, unless we're looking for the + // ResolveAttribute, which must not be looked up + if (att == null) + { + AttributeSet parent = getResolveParent(); + if (parent != null) + att = parent.getAttribute(key); + } + + return att; + } + + public int getAttributeCount() + { + return attrs.length / 2; + } + + public Enumeration getAttributeNames() + { + return new Enumeration() + { + int i = 0; + public boolean hasMoreElements() + { + return i < attrs.length; + } + public Object nextElement() + { + i += 2; + return attrs[i-2]; + } + }; + } + + public AttributeSet getResolveParent() + { + return resolveParent; + } + + public int hashCode() + { + return java.util.Arrays.asList(attrs).hashCode(); + } + + public boolean isDefined(Object key) + { + for (int i = 0; i < attrs.length; i += 2) + { + if (attrs[i].equals(key)) + return true; + } + return false; + } + + public boolean isEqual(AttributeSet attr) + { + boolean eq; + // If the other one is also a SmallAttributeSet, it is only considered + // equal if it's the same instance. + if (attr instanceof SmallAttributeSet) + eq = attr == this; + else + eq = getAttributeCount() == attr.getAttributeCount() + && this.containsAttributes(attr); + return eq; + } + + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append('{'); + for (int i = 0; i < attrs.length; i += 2) + { + if (attrs[i + 1] instanceof AttributeSet) + { + sb.append(attrs[i]); + sb.append("=AttributeSet,"); + } + else + { + sb.append(attrs[i]); + sb.append('='); + sb.append(attrs[i + 1]); + sb.append(','); + } + } + sb.append("}"); + return sb.toString(); + } + } + + /** + * Register StyleConstant keys as static attribute keys for serialization. + */ + static + { + // Don't let problems while doing this prevent class loading. + try + { + for (Iterator i = StyleConstants.keys.iterator(); i.hasNext();) + registerStaticAttributeKey(i.next()); + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + + /** + * The name of the default style. + */ + public static final String DEFAULT_STYLE = "default"; + + static Hashtable sharedAttributeSets = new Hashtable(); + static Hashtable sharedFonts = new Hashtable(); + + static StyleContext defaultStyleContext; + static final int compressionThreshold = 9; + + /** + * These attribute keys are handled specially in serialization. + */ + private static Hashtable writeAttributeKeys; + private static Hashtable readAttributeKeys; + + private NamedStyle styles; + + /** + * Used for searching attributes in the pool. + */ + private transient MutableAttributeSet search = new SimpleAttributeSet(); + + /** + * A pool of immutable AttributeSets. + */ + private transient Map attributeSetPool = + Collections.synchronizedMap(new WeakHashMap()); + + /** + * Creates a new instance of the style context. Add the default style + * to the style table. + */ + public StyleContext() + { + styles = new NamedStyle(null); + addStyle(DEFAULT_STYLE, null); + } + + protected SmallAttributeSet createSmallAttributeSet(AttributeSet a) + { + return new SmallAttributeSet(a); + } + + protected MutableAttributeSet createLargeAttributeSet(AttributeSet a) + { + return new SimpleAttributeSet(a); + } + + public void addChangeListener(ChangeListener listener) + { + styles.addChangeListener(listener); + } + + public void removeChangeListener(ChangeListener listener) + { + styles.removeChangeListener(listener); + } + + public ChangeListener[] getChangeListeners() + { + return styles.getChangeListeners(); + } + + public Style addStyle(String name, Style parent) + { + Style newStyle = new NamedStyle(name, parent); + if (name != null) + styles.addAttribute(name, newStyle); + return newStyle; + } + + public void removeStyle(String name) + { + styles.removeAttribute(name); + } + + /** + * Get the style from the style table. If the passed name + * matches {@link #DEFAULT_STYLE}, returns the default style. + * Otherwise returns the previously defined style of + * null if the style with the given name is not defined. + * + * @param name the name of the style. + * + * @return the style with the given name or null if no such defined. + */ + public Style getStyle(String name) + { + return (Style) styles.getAttribute(name); + } + + /** + * Get the names of the style. The returned enumeration always + * contains at least one member, the default style. + */ + public Enumeration getStyleNames() + { + return styles.getAttributeNames(); + } + + private void readObject(ObjectInputStream in) + throws ClassNotFoundException, IOException + { + search = new SimpleAttributeSet(); + attributeSetPool = Collections.synchronizedMap(new WeakHashMap()); + in.defaultReadObject(); + } + + private void writeObject(ObjectOutputStream out) + throws IOException + { + cleanupPool(); + out.defaultWriteObject(); + } + + // + // StyleContexts only understand the "simple" model of fonts present in + // pre-java2d systems: fonts are a family name, a size (integral number + // of points), and a mask of style parameters (plain, bold, italic, or + // bold|italic). We have an inner class here called SimpleFontSpec which + // holds such triples. + // + // A SimpleFontSpec can be built for *any* AttributeSet because the size, + // family, and style keys in an AttributeSet have default values (defined + // over in StyleConstants). + // + // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so + // that we reuse Fonts between styles and style contexts. + // + + private static class SimpleFontSpec + { + String family; + int style; + int size; + public SimpleFontSpec(String family, + int style, + int size) + { + this.family = family; + this.style = style; + this.size = size; + } + public boolean equals(Object obj) + { + return (obj != null) + && (obj instanceof SimpleFontSpec) + && (((SimpleFontSpec)obj).family.equals(this.family)) + && (((SimpleFontSpec)obj).style == this.style) + && (((SimpleFontSpec)obj).size == this.size); + } + public int hashCode() + { + return family.hashCode() + style + size; + } + } + + public Font getFont(AttributeSet attr) + { + String family = StyleConstants.getFontFamily(attr); + int style = Font.PLAIN; + if (StyleConstants.isBold(attr)) + style += Font.BOLD; + if (StyleConstants.isItalic(attr)) + style += Font.ITALIC; + int size = StyleConstants.getFontSize(attr); + return getFont(family, style, size); + } + + public Font getFont(String family, int style, int size) + { + SimpleFontSpec spec = new SimpleFontSpec(family, style, size); + if (sharedFonts.containsKey(spec)) + return (Font) sharedFonts.get(spec); + else + { + Font tmp = new Font(family, style, size); + sharedFonts.put(spec, tmp); + return tmp; + } + } + + public FontMetrics getFontMetrics(Font f) + { + return Toolkit.getDefaultToolkit().getFontMetrics(f); + } + + public Color getForeground(AttributeSet a) + { + return StyleConstants.getForeground(a); + } + + public Color getBackground(AttributeSet a) + { + return StyleConstants.getBackground(a); + } + + protected int getCompressionThreshold() + { + return compressionThreshold; + } + + public static StyleContext getDefaultStyleContext() + { + if (defaultStyleContext == null) + defaultStyleContext = new StyleContext(); + return defaultStyleContext; + } + + public synchronized AttributeSet addAttribute(AttributeSet old, Object name, + Object value) + { + AttributeSet ret; + if (old.getAttributeCount() + 1 < getCompressionThreshold()) + { + search.removeAttributes(search); + search.addAttributes(old); + search.addAttribute(name, value); + reclaim(old); + ret = searchImmutableSet(); + } + else + { + MutableAttributeSet mas = getMutableAttributeSet(old); + mas.addAttribute(name, value); + ret = mas; + } + return ret; + } + + public synchronized AttributeSet addAttributes(AttributeSet old, + AttributeSet attributes) + { + AttributeSet ret; + if (old.getAttributeCount() + attributes.getAttributeCount() + < getCompressionThreshold()) + { + search.removeAttributes(search); + search.addAttributes(old); + search.addAttributes(attributes); + reclaim(old); + ret = searchImmutableSet(); + } + else + { + MutableAttributeSet mas = getMutableAttributeSet(old); + mas.addAttributes(attributes); + ret = mas; + } + return ret; + } + + public AttributeSet getEmptySet() + { + return SimpleAttributeSet.EMPTY; + } + + public void reclaim(AttributeSet attributes) + { + cleanupPool(); + } + + public synchronized AttributeSet removeAttribute(AttributeSet old, + Object name) + { + AttributeSet ret; + if (old.getAttributeCount() - 1 <= getCompressionThreshold()) + { + search.removeAttributes(search); + search.addAttributes(old); + search.removeAttribute(name); + reclaim(old); + ret = searchImmutableSet(); + } + else + { + MutableAttributeSet mas = getMutableAttributeSet(old); + mas.removeAttribute(name); + ret = mas; + } + return ret; + } + + public synchronized AttributeSet removeAttributes(AttributeSet old, + AttributeSet attributes) + { + AttributeSet ret; + if (old.getAttributeCount() <= getCompressionThreshold()) + { + search.removeAttributes(search); + search.addAttributes(old); + search.removeAttributes(attributes); + reclaim(old); + ret = searchImmutableSet(); + } + else + { + MutableAttributeSet mas = getMutableAttributeSet(old); + mas.removeAttributes(attributes); + ret = mas; + } + return ret; + } + + public synchronized AttributeSet removeAttributes(AttributeSet old, + Enumeration names) + { + AttributeSet ret; + if (old.getAttributeCount() <= getCompressionThreshold()) + { + search.removeAttributes(search); + search.addAttributes(old); + search.removeAttributes(names); + reclaim(old); + ret = searchImmutableSet(); + } + else + { + MutableAttributeSet mas = getMutableAttributeSet(old); + mas.removeAttributes(names); + ret = mas; + } + return ret; + } + + /** + * Gets the object previously registered with registerStaticAttributeKey. + * + * @param key - the key that was registered. + * @return the object previously registered with registerStaticAttributeKey. + */ + public static Object getStaticAttribute(Object key) + { + if (key == null) + return null; + return readAttributeKeys.get(key); + } + + /** + * Returns the String that key will be registered with + * registerStaticAttributeKey. + * + * @param key - the key that will be registered. + * @return the string the key will be registered with. + */ + public static Object getStaticAttributeKey(Object key) + { + return key.getClass().getName() + "." + key.toString(); + } + + /** + * Reads a set of attributes from the given object input stream. This will + * attempt to restore keys that were static objects by considering only the + * keys that have were registered with registerStaticAttributeKey. The + * attributes retrieved will be placed into the given set. + * + * @param in - the stream to read from + * @param a - the set of attributes + * @throws ClassNotFoundException - may be encountered when reading from + * stream + * @throws IOException - any I/O error + */ + public static void readAttributeSet(ObjectInputStream in, + MutableAttributeSet a) + throws ClassNotFoundException, IOException + { + int count = in.readInt(); + for (int i = 0; i < count; i++) + { + Object key = in.readObject(); + Object val = in.readObject(); + if (readAttributeKeys != null) + { + Object staticKey = readAttributeKeys.get(key); + if (staticKey != null) + key = staticKey; + Object staticVal = readAttributeKeys.get(val); + if (staticVal != null) + val = staticVal; + } + a.addAttribute(key, val); + } + } + + /** + * Serialize an attribute set in a way that is compatible with it + * being read in again by {@link #readAttributeSet(ObjectInputStream, MutableAttributeSet)}. + * In particular registered static keys are transformed properly. + * + * @param out - stream to write to + * @param a - the attribute set + * @throws IOException - any I/O error + */ + public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a) + throws IOException + { + int count = a.getAttributeCount(); + out.writeInt(count); + Enumeration e = a.getAttributeNames(); + while (e.hasMoreElements()) + { + Object key = e.nextElement(); + // Write key. + if (key instanceof Serializable) + out.writeObject(key); + else + { + Object io = writeAttributeKeys.get(key); + if (io == null) + throw new NotSerializableException(key.getClass().getName() + + ", key: " + key); + out.writeObject(io); + } + // Write value. + Object val = a.getAttribute(key); + Object io = writeAttributeKeys.get(val); + if (val instanceof Serializable) + out.writeObject(io != null ? io : val); + else + { + if (io == null) + throw new NotSerializableException(val.getClass().getName()); + out.writeObject(io); + } + } + } + + /** + * Handles reading in the attributes. + * @see #readAttributeSet(ObjectInputStream, MutableAttributeSet) + * + * @param in - the stream to read from + * @param a - the set of attributes + * @throws ClassNotFoundException - may be encountered when reading from stream + * @throws IOException - any I/O error + */ + public void readAttributes(ObjectInputStream in, MutableAttributeSet a) + throws ClassNotFoundException, IOException + { + readAttributeSet(in, a); + } + + /** + * Handles writing of the given attributes. + * @see #writeAttributeSet(ObjectOutputStream, AttributeSet) + * + * @param out - stream to write to + * @param a - the attribute set + * @throws IOException - any I/O error + */ + public void writeAttributes(ObjectOutputStream out, AttributeSet a) + throws IOException + { + writeAttributeSet(out, a); + } + + /** + * Registers an attribute key as a well-known keys. When an attribute with + * such a key is written to a stream, a special syntax is used so that it + * can be recognized when it is read back in. All attribute keys defined + * in StyleContext are registered as static keys. If you define + * additional attribute keys that you want to exist as nonreplicated objects, + * then you should register them using this method. + * + * @param key the key to register as static attribute key + */ + public static void registerStaticAttributeKey(Object key) + { + String io = key.getClass().getName() + "." + key.toString(); + if (writeAttributeKeys == null) + writeAttributeKeys = new Hashtable(); + if (readAttributeKeys == null) + readAttributeKeys = new Hashtable(); + writeAttributeKeys.put(key, io); + readAttributeKeys.put(io, key); + } + + /** + * Returns a string representation of this StyleContext. + * + * @return a string representation of this StyleContext + */ + public String toString() + { + cleanupPool(); + StringBuilder b = new StringBuilder(); + Iterator i = attributeSetPool.keySet().iterator(); + while (i.hasNext()) + { + Object att = i.next(); + b.append(att); + b.append('\n'); + } + return b.toString(); + } + + /** + * Searches the AttributeSet pool and returns a pooled instance if available, + * or pool a new one. + * + * @return an immutable attribute set that equals the current search key + */ + private AttributeSet searchImmutableSet() + { + SmallAttributeSet k = createSmallAttributeSet(search); + WeakReference ref = (WeakReference) attributeSetPool.get(k); + SmallAttributeSet a; + if (ref == null || (a = (SmallAttributeSet) ref.get()) == null) + { + a = k; + attributeSetPool.put(a, new WeakReference(a)); + } + return a; + } + + /** + * Cleans up the attribute set pool from entries that are no longer + * referenced. + */ + private void cleanupPool() + { + // TODO: How else can we force cleaning up the WeakHashMap? + attributeSetPool.size(); + } + + /** + * Returns a MutableAttributeSet that holds a. If a itself is mutable, + * this returns a itself, otherwise it creates a new SimpleAtttributeSet + * via {@link #createLargeAttributeSet(AttributeSet)}. + * + * @param a the AttributeSet to create a mutable set for + * + * @return a mutable attribute set that corresponds to a + */ + private MutableAttributeSet getMutableAttributeSet(AttributeSet a) + { + MutableAttributeSet mas; + if (a instanceof MutableAttributeSet) + mas = (MutableAttributeSet) a; + else + mas = createLargeAttributeSet(a); + return mas; + } +} -- cgit v1.2.3