Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / javax / swing / text / StyleContext.java
blob6c4e299455f6650ba68b0eacf825b631088166d4
1 /* StyleContext.java --
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.text;
41 import java.awt.Color;
42 import java.awt.Font;
43 import java.awt.FontMetrics;
44 import java.awt.Toolkit;
45 import java.io.IOException;
46 import java.io.ObjectInputStream;
47 import java.io.ObjectOutputStream;
48 import java.io.Serializable;
49 import java.util.Enumeration;
50 import java.util.EventListener;
51 import java.util.Hashtable;
53 import javax.swing.event.ChangeEvent;
54 import javax.swing.event.ChangeListener;
55 import javax.swing.event.EventListenerList;
57 public class StyleContext
58 implements Serializable, AbstractDocument.AttributeContext
60 /** The serialization UID (compatible with JDK1.5). */
61 private static final long serialVersionUID = 8042858831190784241L;
63 public class NamedStyle
64 implements Serializable, Style
66 /** The serialization UID (compatible with JDK1.5). */
67 private static final long serialVersionUID = -6690628971806226374L;
69 protected ChangeEvent changeEvent;
70 protected EventListenerList listenerList;
72 AttributeSet attributes;
73 String name;
75 public NamedStyle()
77 this(null, null);
80 public NamedStyle(Style parent)
82 this(null, parent);
85 public NamedStyle(String name, Style parent)
87 this.name = name;
88 this.attributes = getEmptySet();
89 this.changeEvent = new ChangeEvent(this);
90 this.listenerList = new EventListenerList();
91 setResolveParent(parent);
94 public String getName()
96 return name;
99 public void setName(String n)
101 name = n;
102 fireStateChanged();
105 public void addChangeListener(ChangeListener l)
107 listenerList.add(ChangeListener.class, l);
110 public void removeChangeListener(ChangeListener l)
112 listenerList.remove(ChangeListener.class, l);
115 public EventListener[] getListeners(Class listenerType)
117 return listenerList.getListeners(listenerType);
120 public ChangeListener[] getChangeListeners()
122 return (ChangeListener[]) getListeners(ChangeListener.class);
125 protected void fireStateChanged()
127 ChangeListener[] listeners = getChangeListeners();
128 for (int i = 0; i < listeners.length; ++i)
130 listeners[i].stateChanged(changeEvent);
134 public void addAttribute(Object name, Object value)
136 attributes = StyleContext.this.addAttribute(attributes, name, value);
137 fireStateChanged();
140 public void addAttributes(AttributeSet attr)
142 attributes = StyleContext.this.addAttributes(attributes, attr);
143 fireStateChanged();
146 public boolean containsAttribute(Object name, Object value)
148 return attributes.containsAttribute(name, value);
151 public boolean containsAttributes(AttributeSet attrs)
153 return attributes.containsAttributes(attrs);
156 public AttributeSet copyAttributes()
158 return attributes.copyAttributes();
161 public Object getAttribute(Object attrName)
163 return attributes.getAttribute(attrName);
166 public int getAttributeCount()
168 return attributes.getAttributeCount();
171 public Enumeration getAttributeNames()
173 return attributes.getAttributeNames();
176 public boolean isDefined(Object attrName)
178 return attributes.isDefined(attrName);
181 public boolean isEqual(AttributeSet attr)
183 return attributes.isEqual(attr);
186 public void removeAttribute(Object name)
188 attributes = StyleContext.this.removeAttribute(attributes, name);
189 fireStateChanged();
192 public void removeAttributes(AttributeSet attrs)
194 attributes = StyleContext.this.removeAttributes(attributes, attrs);
195 fireStateChanged();
198 public void removeAttributes(Enumeration names)
200 attributes = StyleContext.this.removeAttributes(attributes, names);
201 fireStateChanged();
205 public AttributeSet getResolveParent()
207 return attributes.getResolveParent();
210 public void setResolveParent(AttributeSet parent)
212 if (parent != null)
214 attributes = StyleContext.this.addAttribute
215 (attributes, ResolveAttribute, parent);
217 fireStateChanged();
220 public String toString()
222 return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() + "]");
226 public class SmallAttributeSet
227 implements AttributeSet
229 final Object [] attrs;
230 public SmallAttributeSet(AttributeSet a)
232 if (a == null)
233 attrs = new Object[0];
234 else
236 int n = a.getAttributeCount();
237 int i = 0;
238 attrs = new Object[n * 2];
239 Enumeration e = a.getAttributeNames();
240 while (e.hasMoreElements())
242 Object name = e.nextElement();
243 attrs[i++] = name;
244 attrs[i++] = a.getAttribute(name);
249 public SmallAttributeSet(Object [] a)
251 if (a == null)
252 attrs = new Object[0];
253 else
255 attrs = new Object[a.length];
256 System.arraycopy(a, 0, attrs, 0, a.length);
260 public Object clone()
262 return new SmallAttributeSet(this.attrs);
265 public boolean containsAttribute(Object name, Object value)
267 for (int i = 0; i < attrs.length; i += 2)
269 if (attrs[i].equals(name) &&
270 attrs[i+1].equals(value))
271 return true;
273 return false;
276 public boolean containsAttributes(AttributeSet a)
278 Enumeration e = a.getAttributeNames();
279 while (e.hasMoreElements())
281 Object name = e.nextElement();
282 Object val = a.getAttribute(name);
283 if (!containsAttribute(name, val))
284 return false;
286 return true;
289 public AttributeSet copyAttributes()
291 return (AttributeSet) clone();
294 public boolean equals(Object obj)
296 return
297 (obj instanceof AttributeSet)
298 && this.isEqual((AttributeSet)obj);
301 public Object getAttribute(Object key)
303 for (int i = 0; i < attrs.length; i += 2)
305 if (attrs[i].equals(key))
306 return attrs[i+1];
309 // Check the resolve parent, unless we're looking for the
310 // ResolveAttribute, which would cause an infinite loop
311 if (!(key.equals(ResolveAttribute)))
313 Object p = getResolveParent();
314 if (p != null && p instanceof AttributeSet)
315 return (((AttributeSet)p).getAttribute(key));
318 return null;
321 public int getAttributeCount()
323 return attrs.length / 2;
326 public Enumeration getAttributeNames()
328 return new Enumeration()
330 int i = 0;
331 public boolean hasMoreElements()
333 return i < attrs.length;
335 public Object nextElement()
337 i += 2;
338 return attrs[i-2];
343 public AttributeSet getResolveParent()
345 return (AttributeSet) getAttribute(ResolveAttribute);
348 public int hashCode()
350 return java.util.Arrays.asList(attrs).hashCode();
353 public boolean isDefined(Object key)
355 for (int i = 0; i < attrs.length; i += 2)
357 if (attrs[i].equals(key))
358 return true;
360 return false;
363 public boolean isEqual(AttributeSet attr)
365 return attr != null
366 && attr.containsAttributes(this)
367 && this.containsAttributes(attr);
370 public String toString()
372 StringBuffer sb = new StringBuffer();
373 sb.append("[StyleContext.SmallattributeSet:");
374 for (int i = 0; i < attrs.length; ++i)
376 sb.append(" (");
377 sb.append(attrs[i].toString());
378 sb.append("=");
379 sb.append(attrs[i+1].toString());
380 sb.append(")");
382 sb.append("]");
383 return sb.toString();
387 // FIXME: official javadocs suggest that these might be more usefully
388 // implemented using a WeakHashMap, but not sure if that works most
389 // places or whether it really matters anyways.
391 // FIXME: also not sure if these tables ought to be static (singletons),
392 // shared across all StyleContexts. I think so, but it's not clear in
393 // docs. revert to non-shared if you think it matters.
396 * The name of the default style.
398 public static final String DEFAULT_STYLE = "default";
401 * The default style for this style context.
403 NamedStyle defaultStyle = new NamedStyle(DEFAULT_STYLE, null);
405 static Hashtable sharedAttributeSets = new Hashtable();
406 static Hashtable sharedFonts = new Hashtable();
408 static StyleContext defaultStyleContext = new StyleContext();
409 static final int compressionThreshold = 9;
411 EventListenerList listenerList;
412 Hashtable styleTable;
415 * Creates a new instance of the style context. Add the default style
416 * to the style table.
418 public StyleContext()
420 listenerList = new EventListenerList();
421 styleTable = new Hashtable();
422 styleTable.put(DEFAULT_STYLE, defaultStyle);
425 protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
427 return new SmallAttributeSet(a);
430 protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
432 return new SimpleAttributeSet(a);
435 public void addChangeListener(ChangeListener listener)
437 listenerList.add(ChangeListener.class, listener);
440 public void removeChangeListener(ChangeListener listener)
442 listenerList.remove(ChangeListener.class, listener);
445 public ChangeListener[] getChangeListeners()
447 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
450 public Style addStyle(String name, Style parent)
452 Style newStyle = new NamedStyle(name, parent);
453 if (name != null)
454 styleTable.put(name, newStyle);
455 return newStyle;
458 public void removeStyle(String name)
460 styleTable.remove(name);
464 * Get the style from the style table. If the passed name
465 * matches {@link #DEFAULT_STYLE}, returns the default style.
466 * Otherwise returns the previously defined style of
467 * <code>null</code> if the style with the given name is not defined.
469 * @param name the name of the style.
471 * @return the style with the given name or null if no such defined.
473 public Style getStyle(String name)
475 return (Style) styleTable.get(name);
479 * Get the names of the style. The returned enumeration always
480 * contains at least one member, the default style.
482 public Enumeration getStyleNames()
484 return styleTable.keys();
488 // StyleContexts only understand the "simple" model of fonts present in
489 // pre-java2d systems: fonts are a family name, a size (integral number
490 // of points), and a mask of style parameters (plain, bold, italic, or
491 // bold|italic). We have an inner class here called SimpleFontSpec which
492 // holds such triples.
494 // A SimpleFontSpec can be built for *any* AttributeSet because the size,
495 // family, and style keys in an AttributeSet have default values (defined
496 // over in StyleConstants).
498 // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
499 // that we reuse Fonts between styles and style contexts.
502 private static class SimpleFontSpec
504 String family;
505 int style;
506 int size;
507 public SimpleFontSpec(String family,
508 int style,
509 int size)
511 this.family = family;
512 this.style = style;
513 this.size = size;
515 public boolean equals(Object obj)
517 return (obj != null)
518 && (obj instanceof SimpleFontSpec)
519 && (((SimpleFontSpec)obj).family.equals(this.family))
520 && (((SimpleFontSpec)obj).style == this.style)
521 && (((SimpleFontSpec)obj).size == this.size);
523 public int hashCode()
525 return family.hashCode() + style + size;
529 public Font getFont(AttributeSet attr)
531 String family = StyleConstants.getFontFamily(attr);
532 int style = Font.PLAIN;
533 if (StyleConstants.isBold(attr))
534 style += Font.BOLD;
535 if (StyleConstants.isItalic(attr))
536 style += Font.ITALIC;
537 int size = StyleConstants.getFontSize(attr);
538 return getFont(family, style, size);
541 public Font getFont(String family, int style, int size)
543 SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
544 if (sharedFonts.containsKey(spec))
545 return (Font) sharedFonts.get(spec);
546 else
548 Font tmp = new Font(family, style, size);
549 sharedFonts.put(spec, tmp);
550 return tmp;
554 public FontMetrics getFontMetrics(Font f)
556 return Toolkit.getDefaultToolkit().getFontMetrics(f);
559 public Color getForeground(AttributeSet a)
561 return StyleConstants.getForeground(a);
564 public Color getBackground(AttributeSet a)
566 return StyleConstants.getBackground(a);
569 protected int getCompressionThreshold()
571 return compressionThreshold;
574 public static StyleContext getDefaultStyleContext()
576 return defaultStyleContext;
579 public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
581 if (old instanceof MutableAttributeSet)
583 ((MutableAttributeSet)old).addAttribute(name, value);
584 return old;
586 else
588 MutableAttributeSet mutable = createLargeAttributeSet(old);
589 mutable.addAttribute(name, value);
590 if (mutable.getAttributeCount() >= getCompressionThreshold())
591 return mutable;
592 else
594 SmallAttributeSet small = createSmallAttributeSet(mutable);
595 if (sharedAttributeSets.containsKey(small))
596 small = (SmallAttributeSet) sharedAttributeSets.get(small);
597 else
598 sharedAttributeSets.put(small,small);
599 return small;
604 public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
606 if (old instanceof MutableAttributeSet)
608 ((MutableAttributeSet)old).addAttributes(attributes);
609 return old;
611 else
613 MutableAttributeSet mutable = createLargeAttributeSet(old);
614 mutable.addAttributes(attributes);
615 if (mutable.getAttributeCount() >= getCompressionThreshold())
616 return mutable;
617 else
619 SmallAttributeSet small = createSmallAttributeSet(mutable);
620 if (sharedAttributeSets.containsKey(small))
621 small = (SmallAttributeSet) sharedAttributeSets.get(small);
622 else
623 sharedAttributeSets.put(small,small);
624 return small;
629 public AttributeSet getEmptySet()
631 AttributeSet e = createSmallAttributeSet(null);
632 if (sharedAttributeSets.containsKey(e))
633 e = (AttributeSet) sharedAttributeSets.get(e);
634 else
635 sharedAttributeSets.put(e, e);
636 return e;
639 public void reclaim(AttributeSet attributes)
641 if (sharedAttributeSets.containsKey(attributes))
642 sharedAttributeSets.remove(attributes);
645 public AttributeSet removeAttribute(AttributeSet old, Object name)
647 if (old instanceof MutableAttributeSet)
649 ((MutableAttributeSet)old).removeAttribute(name);
650 if (old.getAttributeCount() < getCompressionThreshold())
652 SmallAttributeSet small = createSmallAttributeSet(old);
653 if (!sharedAttributeSets.containsKey(small))
654 sharedAttributeSets.put(small,small);
655 old = (AttributeSet) sharedAttributeSets.get(small);
657 return old;
659 else
661 MutableAttributeSet mutable = createLargeAttributeSet(old);
662 mutable.removeAttribute(name);
663 SmallAttributeSet small = createSmallAttributeSet(mutable);
664 if (sharedAttributeSets.containsKey(small))
665 small = (SmallAttributeSet) sharedAttributeSets.get(small);
666 else
667 sharedAttributeSets.put(small,small);
668 return small;
672 public AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes)
674 return removeAttributes(old, attributes.getAttributeNames());
677 public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
679 if (old instanceof MutableAttributeSet)
681 ((MutableAttributeSet)old).removeAttributes(names);
682 if (old.getAttributeCount() < getCompressionThreshold())
684 SmallAttributeSet small = createSmallAttributeSet(old);
685 if (!sharedAttributeSets.containsKey(small))
686 sharedAttributeSets.put(small,small);
687 old = (AttributeSet) sharedAttributeSets.get(small);
689 return old;
691 else
693 MutableAttributeSet mutable = createLargeAttributeSet(old);
694 mutable.removeAttributes(names);
695 SmallAttributeSet small = createSmallAttributeSet(mutable);
696 if (sharedAttributeSets.containsKey(small))
697 small = (SmallAttributeSet) sharedAttributeSets.get(small);
698 else
699 sharedAttributeSets.put(small,small);
700 return small;
705 // FIXME: there's some sort of quasi-serialization stuff in here which I
706 // have left incomplete; I'm not sure I understand the intent properly.
708 public static Object getStaticAttribute(Object key)
710 throw new InternalError("not implemented");
713 public static Object getStaticAttributeKey(Object key)
715 throw new InternalError("not implemented");
718 public static void readAttributeSet(ObjectInputStream in, MutableAttributeSet a)
719 throws ClassNotFoundException, IOException
721 throw new InternalError("not implemented");
724 public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
725 throws IOException
727 throw new InternalError("not implemented");
730 public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
731 throws ClassNotFoundException, IOException
733 throw new InternalError("not implemented");
736 public void writeAttributes(ObjectOutputStream out, AttributeSet a)
737 throws IOException
739 throw new InternalError("not implemented");