mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1457 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1457 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			Java
		
	
	
	
/* StyleSheet.java --
 | 
						|
   Copyright (C) 2005 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.html;
 | 
						|
 | 
						|
import gnu.javax.swing.text.html.css.BorderWidth;
 | 
						|
import gnu.javax.swing.text.html.css.CSSColor;
 | 
						|
import gnu.javax.swing.text.html.css.CSSParser;
 | 
						|
import gnu.javax.swing.text.html.css.CSSParserCallback;
 | 
						|
import gnu.javax.swing.text.html.css.FontSize;
 | 
						|
import gnu.javax.swing.text.html.css.FontStyle;
 | 
						|
import gnu.javax.swing.text.html.css.FontWeight;
 | 
						|
import gnu.javax.swing.text.html.css.Length;
 | 
						|
import gnu.javax.swing.text.html.css.Selector;
 | 
						|
 | 
						|
import java.awt.Color;
 | 
						|
import java.awt.Font;
 | 
						|
import java.awt.Graphics;
 | 
						|
import java.awt.Rectangle;
 | 
						|
import java.awt.Shape;
 | 
						|
import java.awt.font.FontRenderContext;
 | 
						|
import java.awt.geom.Rectangle2D;
 | 
						|
import java.io.BufferedReader;
 | 
						|
import java.io.IOException;
 | 
						|
import java.io.InputStream;
 | 
						|
import java.io.InputStreamReader;
 | 
						|
import java.io.Reader;
 | 
						|
import java.io.Serializable;
 | 
						|
import java.io.StringReader;
 | 
						|
import java.net.URL;
 | 
						|
import java.util.ArrayList;
 | 
						|
import java.util.Collections;
 | 
						|
import java.util.Enumeration;
 | 
						|
import java.util.HashMap;
 | 
						|
import java.util.Iterator;
 | 
						|
import java.util.List;
 | 
						|
import java.util.Map;
 | 
						|
 | 
						|
import javax.swing.border.Border;
 | 
						|
import javax.swing.event.ChangeListener;
 | 
						|
import javax.swing.text.AttributeSet;
 | 
						|
import javax.swing.text.Element;
 | 
						|
import javax.swing.text.MutableAttributeSet;
 | 
						|
import javax.swing.text.SimpleAttributeSet;
 | 
						|
import javax.swing.text.Style;
 | 
						|
import javax.swing.text.StyleConstants;
 | 
						|
import javax.swing.text.StyleContext;
 | 
						|
import javax.swing.text.View;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * This class adds support for defining the visual characteristics of HTML views
 | 
						|
 * being rendered. This enables views to be customized by a look-and-feel, mulitple
 | 
						|
 * views over the same model can be rendered differently. Each EditorPane has its
 | 
						|
 * own StyleSheet, but by default one sheet will be shared by all of the HTMLEditorKit
 | 
						|
 * instances. An HTMLDocument can also have a StyleSheet, which holds specific CSS
 | 
						|
 * specs.
 | 
						|
 *
 | 
						|
 *  In order for Views to store less state and therefore be more lightweight,
 | 
						|
 *  the StyleSheet can act as a factory for painters that handle some of the
 | 
						|
 *  rendering tasks. Since the StyleSheet may be used by views over multiple
 | 
						|
 *  documents the HTML attributes don't effect the selector being used.
 | 
						|
 *
 | 
						|
 *  The rules are stored as named styles, and other information is stored to
 | 
						|
 *  translate the context of an element to a rule.
 | 
						|
 *
 | 
						|
 * @author Lillian Angel (langel@redhat.com)
 | 
						|
 */
 | 
						|
public class StyleSheet extends StyleContext
 | 
						|
{
 | 
						|
 | 
						|
  /**
 | 
						|
   * Parses CSS stylesheets using the parser in gnu/javax/swing/html/css.
 | 
						|
   *
 | 
						|
   * This is package private to avoid accessor methods.
 | 
						|
   */
 | 
						|
  class CSSStyleSheetParserCallback
 | 
						|
    implements CSSParserCallback
 | 
						|
  {
 | 
						|
    /**
 | 
						|
     * The current styles.
 | 
						|
     */
 | 
						|
    private CSSStyle[] styles;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The precedence of the stylesheet to be parsed.
 | 
						|
     */
 | 
						|
    private int precedence;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a new CSS parser. This parser parses a CSS stylesheet with
 | 
						|
     * the specified precedence.
 | 
						|
     *
 | 
						|
     * @param prec the precedence, according to the constants defined in
 | 
						|
     *        CSSStyle
 | 
						|
     */
 | 
						|
    CSSStyleSheetParserCallback(int prec)
 | 
						|
    {
 | 
						|
      precedence = prec;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called at the beginning of a statement.
 | 
						|
     *
 | 
						|
     * @param sel the selector
 | 
						|
     */
 | 
						|
    public void startStatement(Selector[] sel)
 | 
						|
    {
 | 
						|
      styles = new CSSStyle[sel.length];
 | 
						|
      for (int i = 0; i < sel.length; i++)
 | 
						|
        styles[i] = new CSSStyle(precedence, sel[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called at the end of a statement.
 | 
						|
     */
 | 
						|
    public void endStatement()
 | 
						|
    {
 | 
						|
      for (int i = 0; i < styles.length; i++)
 | 
						|
        css.add(styles[i]);
 | 
						|
      styles = null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Called when a declaration is parsed.
 | 
						|
     *
 | 
						|
     * @param property the property
 | 
						|
     * @param value the value
 | 
						|
     */
 | 
						|
    public void declaration(String property, String value)
 | 
						|
    {
 | 
						|
      CSS.Attribute cssAtt = CSS.getAttribute(property);
 | 
						|
      Object val = CSS.getValue(cssAtt, value);
 | 
						|
      for (int i = 0; i < styles.length; i++)
 | 
						|
        {
 | 
						|
          CSSStyle style = styles[i];
 | 
						|
          CSS.addInternal(style, cssAtt, value);
 | 
						|
          if (cssAtt != null)
 | 
						|
            style.addAttribute(cssAtt, val);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Represents a style that is defined by a CSS rule.
 | 
						|
   */
 | 
						|
  private class CSSStyle
 | 
						|
    extends SimpleAttributeSet
 | 
						|
    implements Style, Comparable<CSSStyle>
 | 
						|
  {
 | 
						|
 | 
						|
    static final int PREC_UA = 0;
 | 
						|
    static final int PREC_NORM = 100000;
 | 
						|
    static final int PREC_AUTHOR_NORMAL = 200000;
 | 
						|
    static final int PREC_AUTHOR_IMPORTANT = 300000;
 | 
						|
    static final int PREC_USER_IMPORTANT = 400000;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The priority of this style when matching CSS selectors.
 | 
						|
     */
 | 
						|
    private int precedence;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The selector for this rule.
 | 
						|
     *
 | 
						|
     * This is package private to avoid accessor methods.
 | 
						|
     */
 | 
						|
    Selector selector;
 | 
						|
 | 
						|
    CSSStyle(int prec, Selector sel)
 | 
						|
    {
 | 
						|
      precedence = prec;
 | 
						|
      selector = sel;
 | 
						|
    }
 | 
						|
 | 
						|
    public String getName()
 | 
						|
    {
 | 
						|
      // TODO: Implement this for correctness.
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
 | 
						|
    public void addChangeListener(ChangeListener listener)
 | 
						|
    {
 | 
						|
      // TODO: Implement this for correctness.
 | 
						|
    }
 | 
						|
 | 
						|
    public void removeChangeListener(ChangeListener listener)
 | 
						|
    {
 | 
						|
      // TODO: Implement this for correctness.
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sorts the rule according to the style's precedence and the
 | 
						|
     * selectors specificity.
 | 
						|
     */
 | 
						|
    public int compareTo(CSSStyle other)
 | 
						|
    {
 | 
						|
      return other.precedence + other.selector.getSpecificity()
 | 
						|
             - precedence - selector.getSpecificity();
 | 
						|
    }
 | 
						|
 | 
						|
  }
 | 
						|
 | 
						|
  /** The base URL */
 | 
						|
  URL base;
 | 
						|
 | 
						|
  /** Base font size (int) */
 | 
						|
  int baseFontSize;
 | 
						|
 | 
						|
  /**
 | 
						|
   * The linked style sheets stored.
 | 
						|
   */
 | 
						|
  private ArrayList<StyleSheet> linked;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Maps element names (selectors) to AttributSet (the corresponding style
 | 
						|
   * information).
 | 
						|
   */
 | 
						|
  ArrayList<CSSStyle> css = new ArrayList<CSSStyle>();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Maps selectors to their resolved styles.
 | 
						|
   */
 | 
						|
  private HashMap<String,Style> resolvedStyles;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constructs a StyleSheet.
 | 
						|
   */
 | 
						|
  public StyleSheet()
 | 
						|
  {
 | 
						|
    super();
 | 
						|
    baseFontSize = 4; // Default font size from CSS
 | 
						|
    resolvedStyles = new HashMap<String,Style>();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the style used to render the given tag. The element represents the tag
 | 
						|
   * and can be used to determine the nesting, where the attributes will differ
 | 
						|
   * if there is nesting inside of elements.
 | 
						|
   *
 | 
						|
   * @param t - the tag to translate to visual attributes
 | 
						|
   * @param e - the element representing the tag
 | 
						|
   * @return the set of CSS attributes to use to render the tag.
 | 
						|
   */
 | 
						|
  public Style getRule(HTML.Tag t, Element e)
 | 
						|
  {
 | 
						|
    // Create list of the element and all of its parents, starting
 | 
						|
    // with the bottommost element.
 | 
						|
    ArrayList<Element> path = new ArrayList<Element>();
 | 
						|
    Element el;
 | 
						|
    AttributeSet atts;
 | 
						|
    for (el = e; el != null; el = el.getParentElement())
 | 
						|
      path.add(el);
 | 
						|
 | 
						|
    // Create fully qualified selector.
 | 
						|
    StringBuilder selector = new StringBuilder();
 | 
						|
    int count = path.size();
 | 
						|
    // We append the actual element after this loop.
 | 
						|
    for (int i = count - 1; i > 0; i--)
 | 
						|
      {
 | 
						|
        el = path.get(i);
 | 
						|
        atts = el.getAttributes();
 | 
						|
        Object name = atts.getAttribute(StyleConstants.NameAttribute);
 | 
						|
        selector.append(name.toString());
 | 
						|
        if (atts.isDefined(HTML.Attribute.ID))
 | 
						|
          {
 | 
						|
            selector.append('#');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.ID));
 | 
						|
          }
 | 
						|
        if (atts.isDefined(HTML.Attribute.CLASS))
 | 
						|
          {
 | 
						|
            selector.append('.');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.CLASS));
 | 
						|
          }
 | 
						|
        if (atts.isDefined(HTML.Attribute.DYNAMIC_CLASS))
 | 
						|
          {
 | 
						|
            selector.append(':');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.DYNAMIC_CLASS));
 | 
						|
          }
 | 
						|
        if (atts.isDefined(HTML.Attribute.PSEUDO_CLASS))
 | 
						|
          {
 | 
						|
            selector.append(':');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.PSEUDO_CLASS));
 | 
						|
          }
 | 
						|
        selector.append(' ');
 | 
						|
      }
 | 
						|
    selector.append(t.toString());
 | 
						|
    el = path.get(0);
 | 
						|
    atts = el.getAttributes();
 | 
						|
    // For leaf elements, we have to fetch the tag specific attributes.
 | 
						|
    if (el.isLeaf())
 | 
						|
      {
 | 
						|
        Object o = atts.getAttribute(t);
 | 
						|
        if (o instanceof AttributeSet)
 | 
						|
          atts = (AttributeSet) o;
 | 
						|
        else
 | 
						|
          atts = null;
 | 
						|
      }
 | 
						|
    if (atts != null)
 | 
						|
      {
 | 
						|
        if (atts.isDefined(HTML.Attribute.ID))
 | 
						|
          {
 | 
						|
            selector.append('#');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.ID));
 | 
						|
          }
 | 
						|
        if (atts.isDefined(HTML.Attribute.CLASS))
 | 
						|
          {
 | 
						|
            selector.append('.');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.CLASS));
 | 
						|
          }
 | 
						|
        if (atts.isDefined(HTML.Attribute.DYNAMIC_CLASS))
 | 
						|
          {
 | 
						|
            selector.append(':');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.DYNAMIC_CLASS));
 | 
						|
          }
 | 
						|
        if (atts.isDefined(HTML.Attribute.PSEUDO_CLASS))
 | 
						|
          {
 | 
						|
            selector.append(':');
 | 
						|
            selector.append(atts.getAttribute(HTML.Attribute.PSEUDO_CLASS));
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return getResolvedStyle(selector.toString(), path, t);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Fetches a resolved style. If there is no resolved style for the
 | 
						|
   * specified selector, the resolve the style using
 | 
						|
   * {@link #resolveStyle(String, List, HTML.Tag)}.
 | 
						|
   *
 | 
						|
   * @param selector the selector for which to resolve the style
 | 
						|
   * @param path the Element path, used in the resolving algorithm
 | 
						|
   * @param tag the tag for which to resolve
 | 
						|
   *
 | 
						|
   * @return the resolved style
 | 
						|
   */
 | 
						|
  private Style getResolvedStyle(String selector, List<Element> path, HTML.Tag tag)
 | 
						|
  {
 | 
						|
    Style style = resolvedStyles.get(selector);
 | 
						|
    if (style == null)
 | 
						|
      style = resolveStyle(selector, path, tag);
 | 
						|
    return style;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Resolves a style. This creates arrays that hold the tag names,
 | 
						|
   * class and id attributes and delegates the work to
 | 
						|
   * {@link #resolveStyle(String, String[], List<Map<String,String>>)}.
 | 
						|
   *
 | 
						|
   * @param selector the selector
 | 
						|
   * @param path the Element path
 | 
						|
   * @param tag the tag
 | 
						|
   *
 | 
						|
   * @return the resolved style
 | 
						|
   */
 | 
						|
  private Style resolveStyle(String selector, List<Element> path, HTML.Tag tag)
 | 
						|
  {
 | 
						|
    int count = path.size();
 | 
						|
    String[] tags = new String[count];
 | 
						|
    List<Map<String,String>> attributes =
 | 
						|
      new ArrayList<Map<String,String>>(count);
 | 
						|
    for (int i = 0; i < count; i++)
 | 
						|
      {
 | 
						|
        Element el = path.get(i);
 | 
						|
        AttributeSet atts = el.getAttributes();
 | 
						|
        if (i == 0 && el.isLeaf())
 | 
						|
          {
 | 
						|
            Object o = atts.getAttribute(tag);
 | 
						|
            if (o instanceof AttributeSet)
 | 
						|
              atts = (AttributeSet) o;
 | 
						|
            else
 | 
						|
              atts = null;
 | 
						|
          }
 | 
						|
        if (atts != null)
 | 
						|
          {
 | 
						|
            HTML.Tag t =
 | 
						|
              (HTML.Tag) atts.getAttribute(StyleConstants.NameAttribute);
 | 
						|
            if (t != null)
 | 
						|
              tags[i] = t.toString();
 | 
						|
            else
 | 
						|
              tags[i] = null;
 | 
						|
            attributes.add(attributeSetToMap(atts));
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            tags[i] = null;
 | 
						|
            attributes.add(null);
 | 
						|
          }
 | 
						|
      }
 | 
						|
    tags[0] = tag.toString();
 | 
						|
    return resolveStyle(selector, tags, attributes);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Performs style resolving.
 | 
						|
   *
 | 
						|
   * @param selector the selector
 | 
						|
   * @param tags the tags
 | 
						|
   * @param attributes the attributes of the tags
 | 
						|
   *
 | 
						|
   * @return the resolved style
 | 
						|
   */
 | 
						|
  private Style resolveStyle(String selector, String[] tags,
 | 
						|
                             List<Map<String,String>> attributes)
 | 
						|
  {
 | 
						|
    // FIXME: This style resolver is not correct. But it works good enough for
 | 
						|
    // the default.css.
 | 
						|
    ArrayList<CSSStyle> styles = new ArrayList<CSSStyle>();
 | 
						|
    for (CSSStyle style : css)
 | 
						|
      {
 | 
						|
        if (style.selector.matches(tags, attributes))
 | 
						|
          styles.add(style);
 | 
						|
      }
 | 
						|
 | 
						|
    // Add styles from linked stylesheets.
 | 
						|
    if (linked != null)
 | 
						|
      {
 | 
						|
        for (int i = linked.size() - 1; i >= 0; i--)
 | 
						|
          {
 | 
						|
            StyleSheet ss = linked.get(i);
 | 
						|
            for (int j = ss.css.size() - 1; j >= 0; j--)
 | 
						|
              {
 | 
						|
                CSSStyle style = ss.css.get(j);
 | 
						|
                if (style.selector.matches(tags, attributes))
 | 
						|
                  styles.add(style);
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
 | 
						|
    // Sort selectors.
 | 
						|
    Collections.sort(styles);
 | 
						|
    Style[] styleArray = styles.toArray(new Style[styles.size()]);
 | 
						|
    Style resolved = new MultiStyle(selector, styleArray);
 | 
						|
    resolvedStyles.put(selector, resolved);
 | 
						|
    return resolved;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the rule that best matches the selector. selector is a space
 | 
						|
   * separated String of element names. The attributes of the returned
 | 
						|
   * Style will change as rules are added and removed.
 | 
						|
   *
 | 
						|
   * @param selector - the element names separated by spaces
 | 
						|
   * @return the set of CSS attributes to use to render
 | 
						|
   */
 | 
						|
  public Style getRule(String selector)
 | 
						|
  {
 | 
						|
    CSSStyle best = null;
 | 
						|
    for (Iterator<CSSStyle> i = css.iterator(); i.hasNext();)
 | 
						|
      {
 | 
						|
        CSSStyle style = i.next();
 | 
						|
        if (style.compareTo(best) < 0)
 | 
						|
          best = style;
 | 
						|
      }
 | 
						|
    return best;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds a set of rules to the sheet. The rules are expected to be in valid
 | 
						|
   * CSS format. This is called as a result of parsing a <style> tag
 | 
						|
   *
 | 
						|
   * @param rule - the rule to add to the sheet
 | 
						|
   */
 | 
						|
  public void addRule(String rule)
 | 
						|
  {
 | 
						|
    CSSStyleSheetParserCallback cb =
 | 
						|
      new CSSStyleSheetParserCallback(CSSStyle.PREC_AUTHOR_NORMAL);
 | 
						|
    // FIXME: Handle ref.
 | 
						|
    StringReader in = new StringReader(rule);
 | 
						|
    CSSParser parser = new CSSParser(in, cb);
 | 
						|
    try
 | 
						|
      {
 | 
						|
        parser.parse();
 | 
						|
      }
 | 
						|
    catch (IOException ex)
 | 
						|
      {
 | 
						|
        // Shouldn't happen. And if, then don't let it bork the outside code.
 | 
						|
      }
 | 
						|
    // Clean up resolved styles cache so that the new styles are recognized
 | 
						|
    // on next stylesheet request.
 | 
						|
    resolvedStyles.clear();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Translates a CSS declaration into an AttributeSet. This is called
 | 
						|
   * as a result of encountering an HTML style attribute.
 | 
						|
   *
 | 
						|
   * @param decl - the declaration to get
 | 
						|
   * @return the AttributeSet representing the declaration
 | 
						|
   */
 | 
						|
  public AttributeSet getDeclaration(String decl)
 | 
						|
  {
 | 
						|
    if (decl == null)
 | 
						|
      return SimpleAttributeSet.EMPTY;
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return null;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Loads a set of rules that have been specified in terms of CSS grammar.
 | 
						|
   * If there are any conflicts with existing rules, the new rule is added.
 | 
						|
   *
 | 
						|
   * @param in - the stream to read the CSS grammar from.
 | 
						|
   * @param ref - the reference URL. It is the location of the stream, it may
 | 
						|
   * be null. All relative URLs specified in the stream will be based upon this
 | 
						|
   * parameter.
 | 
						|
   * @throws IOException - For any IO error while reading
 | 
						|
   */
 | 
						|
  public void loadRules(Reader in, URL ref)
 | 
						|
    throws IOException
 | 
						|
  {
 | 
						|
    CSSStyleSheetParserCallback cb =
 | 
						|
      new CSSStyleSheetParserCallback(CSSStyle.PREC_UA);
 | 
						|
    // FIXME: Handle ref.
 | 
						|
    CSSParser parser = new CSSParser(in, cb);
 | 
						|
    parser.parse();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets a set of attributes to use in the view. This is a set of
 | 
						|
   * attributes that can be used for View.getAttributes
 | 
						|
   *
 | 
						|
   * @param v - the view to get the set for
 | 
						|
   * @return the AttributeSet to use in the view.
 | 
						|
   */
 | 
						|
  public AttributeSet getViewAttributes(View v)
 | 
						|
  {
 | 
						|
    return new ViewAttributeSet(v, this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes a style previously added.
 | 
						|
   *
 | 
						|
   * @param nm - the name of the style to remove
 | 
						|
   */
 | 
						|
  public void removeStyle(String nm)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    super.removeStyle(nm);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds the rules from ss to those of the receiver. ss's rules will
 | 
						|
   * override the old rules. An added StyleSheet will never override the rules
 | 
						|
   * of the receiving style sheet.
 | 
						|
   *
 | 
						|
   * @param ss - the new StyleSheet.
 | 
						|
   */
 | 
						|
  public void addStyleSheet(StyleSheet ss)
 | 
						|
  {
 | 
						|
    if (linked == null)
 | 
						|
      linked = new ArrayList<StyleSheet>();
 | 
						|
    linked.add(ss);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes ss from those of the receiver
 | 
						|
   *
 | 
						|
   * @param ss - the StyleSheet to remove.
 | 
						|
   */
 | 
						|
  public void removeStyleSheet(StyleSheet ss)
 | 
						|
  {
 | 
						|
    if (linked != null)
 | 
						|
      {
 | 
						|
        linked.remove(ss);
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an array of the linked StyleSheets. May return null.
 | 
						|
   *
 | 
						|
   * @return - An array of the linked StyleSheets.
 | 
						|
   */
 | 
						|
  public StyleSheet[] getStyleSheets()
 | 
						|
  {
 | 
						|
    StyleSheet[] linkedSS;
 | 
						|
    if (linked != null)
 | 
						|
      {
 | 
						|
        linkedSS = new StyleSheet[linked.size()];
 | 
						|
        linkedSS = linked.toArray(linkedSS);
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        linkedSS = null;
 | 
						|
      }
 | 
						|
    return linkedSS;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Imports a style sheet from the url. The rules are directly added to the
 | 
						|
   * receiver. This is usually called when a <link> tag is resolved in an
 | 
						|
   * HTML document.
 | 
						|
   *
 | 
						|
   * @param url the URL to import the StyleSheet from
 | 
						|
   */
 | 
						|
  public void importStyleSheet(URL url)
 | 
						|
  {
 | 
						|
    try
 | 
						|
      {
 | 
						|
        InputStream in = url.openStream();
 | 
						|
        Reader r = new BufferedReader(new InputStreamReader(in));
 | 
						|
        CSSStyleSheetParserCallback cb =
 | 
						|
          new CSSStyleSheetParserCallback(CSSStyle.PREC_AUTHOR_NORMAL);
 | 
						|
        CSSParser parser = new CSSParser(r, cb);
 | 
						|
        parser.parse();
 | 
						|
      }
 | 
						|
    catch (IOException ex)
 | 
						|
      {
 | 
						|
        // We can't do anything about it I guess.
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the base url. All import statements that are relative, will be
 | 
						|
   * relative to base.
 | 
						|
   *
 | 
						|
   * @param base -
 | 
						|
   *          the base URL.
 | 
						|
   */
 | 
						|
  public void setBase(URL base)
 | 
						|
  {
 | 
						|
    this.base = base;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the base url.
 | 
						|
   *
 | 
						|
   * @return - the base
 | 
						|
   */
 | 
						|
  public URL getBase()
 | 
						|
  {
 | 
						|
    return base;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds a CSS attribute to the given set.
 | 
						|
   *
 | 
						|
   * @param attr - the attribute set
 | 
						|
   * @param key - the attribute to add
 | 
						|
   * @param value - the value of the key
 | 
						|
   */
 | 
						|
  public void addCSSAttribute(MutableAttributeSet attr, CSS.Attribute key,
 | 
						|
                              String value)
 | 
						|
  {
 | 
						|
    Object val = CSS.getValue(key, value);
 | 
						|
    CSS.addInternal(attr, key, value);
 | 
						|
    attr.addAttribute(key, val);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds a CSS attribute to the given set.
 | 
						|
   * This method parses the value argument from HTML based on key.
 | 
						|
   * Returns true if it finds a valid value for the given key,
 | 
						|
   * and false otherwise.
 | 
						|
   *
 | 
						|
   * @param attr - the attribute set
 | 
						|
   * @param key - the attribute to add
 | 
						|
   * @param value - the value of the key
 | 
						|
   * @return true if a valid value was found.
 | 
						|
   */
 | 
						|
  public boolean addCSSAttributeFromHTML(MutableAttributeSet attr, CSS.Attribute key,
 | 
						|
                                         String value)
 | 
						|
  {
 | 
						|
    // FIXME: Need to parse value from HTML based on key.
 | 
						|
    attr.addAttribute(key, value);
 | 
						|
    return attr.containsAttribute(key, value);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Converts a set of HTML attributes to an equivalent set of CSS attributes.
 | 
						|
   *
 | 
						|
   * @param htmlAttrSet - the set containing the HTML attributes.
 | 
						|
   * @return the set of CSS attributes
 | 
						|
   */
 | 
						|
  public AttributeSet translateHTMLToCSS(AttributeSet htmlAttrSet)
 | 
						|
  {
 | 
						|
    AttributeSet cssAttr = htmlAttrSet.copyAttributes();
 | 
						|
 | 
						|
    // The HTML align attribute maps directly to the CSS text-align attribute.
 | 
						|
    Object o = htmlAttrSet.getAttribute(HTML.Attribute.ALIGN);
 | 
						|
    if (o != null)
 | 
						|
      cssAttr = addAttribute(cssAttr, CSS.Attribute.TEXT_ALIGN, o);
 | 
						|
 | 
						|
    // The HTML width attribute maps directly to CSS width.
 | 
						|
    o = htmlAttrSet.getAttribute(HTML.Attribute.WIDTH);
 | 
						|
    if (o != null)
 | 
						|
      cssAttr = addAttribute(cssAttr, CSS.Attribute.WIDTH,
 | 
						|
                             new Length(o.toString()));
 | 
						|
 | 
						|
    // The HTML height attribute maps directly to CSS height.
 | 
						|
    o = htmlAttrSet.getAttribute(HTML.Attribute.HEIGHT);
 | 
						|
    if (o != null)
 | 
						|
      cssAttr = addAttribute(cssAttr, CSS.Attribute.HEIGHT,
 | 
						|
                             new Length(o.toString()));
 | 
						|
 | 
						|
    o = htmlAttrSet.getAttribute(HTML.Attribute.NOWRAP);
 | 
						|
    if (o != null)
 | 
						|
      cssAttr = addAttribute(cssAttr, CSS.Attribute.WHITE_SPACE, "nowrap");
 | 
						|
 | 
						|
    // Map cellspacing attr of tables to CSS border-spacing.
 | 
						|
    o = htmlAttrSet.getAttribute(HTML.Attribute.CELLSPACING);
 | 
						|
    if (o != null)
 | 
						|
      cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_SPACING,
 | 
						|
                             new Length(o.toString()));
 | 
						|
 | 
						|
    // For table cells and headers, fetch the cellpadding value from the
 | 
						|
    // parent table and set it as CSS padding attribute.
 | 
						|
    HTML.Tag tag = (HTML.Tag)
 | 
						|
                   htmlAttrSet.getAttribute(StyleConstants.NameAttribute);
 | 
						|
    if ((tag == HTML.Tag.TD || tag == HTML.Tag.TH)
 | 
						|
        && htmlAttrSet instanceof Element)
 | 
						|
      {
 | 
						|
        Element el = (Element) htmlAttrSet;
 | 
						|
        AttributeSet tableAttrs = el.getParentElement().getParentElement()
 | 
						|
                                  .getAttributes();
 | 
						|
        o = tableAttrs.getAttribute(HTML.Attribute.CELLPADDING);
 | 
						|
        if (o != null)
 | 
						|
          {
 | 
						|
            Length l = new Length(o.toString());
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_BOTTOM, l);
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_LEFT, l);
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_RIGHT, l);
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_TOP, l);
 | 
						|
          }
 | 
						|
        o = tableAttrs.getAttribute(HTML.Attribute.BORDER);
 | 
						|
        cssAttr = translateBorder(cssAttr, o);
 | 
						|
      }
 | 
						|
 | 
						|
    // Translate border attribute.
 | 
						|
    o = cssAttr.getAttribute(HTML.Attribute.BORDER);
 | 
						|
    cssAttr = translateBorder(cssAttr, o);
 | 
						|
 | 
						|
    // TODO: Add more mappings.
 | 
						|
    return cssAttr;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Translates a HTML border attribute to a corresponding set of CSS
 | 
						|
   * attributes.
 | 
						|
   *
 | 
						|
   * @param cssAttr the original set of CSS attributes to add to
 | 
						|
   * @param o the value of the border attribute
 | 
						|
   *
 | 
						|
   * @return the new set of CSS attributes
 | 
						|
   */
 | 
						|
  private AttributeSet translateBorder(AttributeSet cssAttr, Object o)
 | 
						|
  {
 | 
						|
    if (o != null)
 | 
						|
      {
 | 
						|
        BorderWidth l = new BorderWidth(o.toString());
 | 
						|
        if (l.getValue() > 0)
 | 
						|
          {
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_WIDTH, l);
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_STYLE,
 | 
						|
                                   "solid");
 | 
						|
            cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_COLOR,
 | 
						|
                                   new CSSColor("black"));
 | 
						|
          }
 | 
						|
      }
 | 
						|
    return cssAttr;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds an attribute to the given set and returns a new set. This is implemented
 | 
						|
   * to convert StyleConstants attributes to CSS before forwarding them to the superclass.
 | 
						|
   * The StyleConstants attribute do not have corresponding CSS entry, the attribute
 | 
						|
   * is stored (but will likely not be used).
 | 
						|
   *
 | 
						|
   * @param old - the old set
 | 
						|
   * @param key - the non-null attribute key
 | 
						|
   * @param value - the attribute value
 | 
						|
   * @return the updated set
 | 
						|
   */
 | 
						|
  public AttributeSet addAttribute(AttributeSet old, Object key,
 | 
						|
                                   Object value)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return super.addAttribute(old, key, value);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds a set of attributes to the element. If any of these attributes are
 | 
						|
   * StyleConstants, they will be converted to CSS before forwarding to the
 | 
						|
   * superclass.
 | 
						|
   *
 | 
						|
   * @param old - the old set
 | 
						|
   * @param attr - the attributes to add
 | 
						|
   * @return the updated attribute set
 | 
						|
   */
 | 
						|
  public AttributeSet addAttributes(AttributeSet old, AttributeSet attr)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return super.addAttributes(old, attr);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes an attribute from the set. If the attribute is a
 | 
						|
   * StyleConstants, it will be converted to CSS before forwarding to the
 | 
						|
   * superclass.
 | 
						|
   *
 | 
						|
   * @param old - the old set
 | 
						|
   * @param key - the non-null attribute key
 | 
						|
   * @return the updated set
 | 
						|
   */
 | 
						|
  public AttributeSet removeAttribute(AttributeSet old, Object key)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return super.removeAttribute(old, key);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes an attribute from the set. If any of the attributes are
 | 
						|
   * StyleConstants, they will be converted to CSS before forwarding to the
 | 
						|
   * superclass.
 | 
						|
   *
 | 
						|
   * @param old - the old set
 | 
						|
   * @param attrs - the attributes to remove
 | 
						|
   * @return the updated set
 | 
						|
   */
 | 
						|
  public AttributeSet removeAttributes(AttributeSet old, AttributeSet attrs)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return super.removeAttributes(old, attrs);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes a set of attributes for the element. If any of the attributes is a
 | 
						|
   * StyleConstants, they will be converted to CSS before forwarding to the
 | 
						|
   * superclass.
 | 
						|
   *
 | 
						|
   * @param old - the old attribute set
 | 
						|
   * @param names - the attribute names
 | 
						|
   * @return the update attribute set
 | 
						|
   */
 | 
						|
  public AttributeSet removeAttributes(AttributeSet old, Enumeration<?> names)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return super.removeAttributes(old, names);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a compact set of attributes that might be shared. This is a hook
 | 
						|
   * for subclasses that want to change the behaviour of SmallAttributeSet.
 | 
						|
   *
 | 
						|
   * @param a - the set of attributes to be represented in the compact form.
 | 
						|
   * @return the set of attributes created
 | 
						|
   */
 | 
						|
  protected StyleContext.SmallAttributeSet createSmallAttributeSet(AttributeSet a)
 | 
						|
  {
 | 
						|
    return super.createSmallAttributeSet(a);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Creates a large set of attributes. This set is not shared. This is a hook
 | 
						|
   * for subclasses that want to change the behaviour of the larger attribute
 | 
						|
   * storage format.
 | 
						|
   *
 | 
						|
   * @param a - the set of attributes to be represented in the larger form.
 | 
						|
   * @return the large set of attributes.
 | 
						|
   */
 | 
						|
  protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
 | 
						|
  {
 | 
						|
    return super.createLargeAttributeSet(a);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the font to use for the given set.
 | 
						|
   *
 | 
						|
   * @param a - the set to get the font for.
 | 
						|
   * @return the font for the set
 | 
						|
   */
 | 
						|
  public Font getFont(AttributeSet a)
 | 
						|
  {
 | 
						|
    int realSize = getFontSize(a);
 | 
						|
 | 
						|
    // Decrement size for subscript and superscript.
 | 
						|
    Object valign = a.getAttribute(CSS.Attribute.VERTICAL_ALIGN);
 | 
						|
    if (valign != null)
 | 
						|
      {
 | 
						|
        String v = valign.toString();
 | 
						|
        if (v.contains("sup") || v.contains("sub"))
 | 
						|
          realSize -= 2;
 | 
						|
      }
 | 
						|
 | 
						|
    // TODO: Convert font family.
 | 
						|
    String family = "SansSerif";
 | 
						|
 | 
						|
    int style = Font.PLAIN;
 | 
						|
    FontWeight weight = (FontWeight) a.getAttribute(CSS.Attribute.FONT_WEIGHT);
 | 
						|
    if (weight != null)
 | 
						|
      style |= weight.getValue();
 | 
						|
    FontStyle fStyle = (FontStyle) a.getAttribute(CSS.Attribute.FONT_STYLE);
 | 
						|
    if (fStyle != null)
 | 
						|
      style |= fStyle.getValue();
 | 
						|
    return new Font(family, style, realSize);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Determines the EM base value based on the specified attributes.
 | 
						|
   *
 | 
						|
   * @param atts the attibutes
 | 
						|
   *
 | 
						|
   * @return the EM base value
 | 
						|
   */
 | 
						|
  float getEMBase(AttributeSet atts)
 | 
						|
  {
 | 
						|
    Font font = getFont(atts);
 | 
						|
    FontRenderContext ctx = new FontRenderContext(null, false, false);
 | 
						|
    Rectangle2D bounds = font.getStringBounds("M", ctx);
 | 
						|
    return (float) bounds.getWidth();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Determines the EX base value based on the specified attributes.
 | 
						|
   *
 | 
						|
   * @param atts the attibutes
 | 
						|
   *
 | 
						|
   * @return the EX base value
 | 
						|
   */
 | 
						|
  float getEXBase(AttributeSet atts)
 | 
						|
  {
 | 
						|
    Font font = getFont(atts);
 | 
						|
    FontRenderContext ctx = new FontRenderContext(null, false, false);
 | 
						|
    Rectangle2D bounds = font.getStringBounds("x", ctx);
 | 
						|
    return (float) bounds.getHeight();
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Resolves the fontsize for a given set of attributes.
 | 
						|
   *
 | 
						|
   * @param atts the attributes
 | 
						|
   *
 | 
						|
   * @return the resolved font size
 | 
						|
   */
 | 
						|
  private int getFontSize(AttributeSet atts)
 | 
						|
  {
 | 
						|
    int size = 12;
 | 
						|
    if (atts.isDefined(CSS.Attribute.FONT_SIZE))
 | 
						|
      {
 | 
						|
        FontSize fs = (FontSize) atts.getAttribute(CSS.Attribute.FONT_SIZE);
 | 
						|
        if (fs.isRelative())
 | 
						|
          {
 | 
						|
            int parSize = 12;
 | 
						|
            AttributeSet resolver = atts.getResolveParent();
 | 
						|
            if (resolver != null)
 | 
						|
              parSize = getFontSize(resolver);
 | 
						|
            size = fs.getValue(parSize);
 | 
						|
          }
 | 
						|
        else
 | 
						|
          {
 | 
						|
            size = fs.getValue();
 | 
						|
          }
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        AttributeSet resolver = atts.getResolveParent();
 | 
						|
        if (resolver != null)
 | 
						|
          size = getFontSize(resolver);
 | 
						|
      }
 | 
						|
    return size;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Takes a set of attributes and turns it into a foreground
 | 
						|
   * color specification. This is used to specify things like, brigher, more hue
 | 
						|
   * etc.
 | 
						|
   *
 | 
						|
   * @param a - the set to get the foreground color for
 | 
						|
   * @return the foreground color for the set
 | 
						|
   */
 | 
						|
  public Color getForeground(AttributeSet a)
 | 
						|
  {
 | 
						|
    CSSColor c = (CSSColor) a.getAttribute(CSS.Attribute.COLOR);
 | 
						|
    Color color = null;
 | 
						|
    if (c != null)
 | 
						|
      color = c.getValue();
 | 
						|
    return color;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Takes a set of attributes and turns it into a background
 | 
						|
   * color specification. This is used to specify things like, brigher, more hue
 | 
						|
   * etc.
 | 
						|
   *
 | 
						|
   * @param a - the set to get the background color for
 | 
						|
   * @return the background color for the set
 | 
						|
   */
 | 
						|
  public Color getBackground(AttributeSet a)
 | 
						|
  {
 | 
						|
    CSSColor c = (CSSColor) a.getAttribute(CSS.Attribute.BACKGROUND_COLOR);
 | 
						|
    Color color = null;
 | 
						|
    if (c != null)
 | 
						|
      color = c.getValue();
 | 
						|
    return color;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the box formatter to use for the given set of CSS attributes.
 | 
						|
   *
 | 
						|
   * @param a - the given set
 | 
						|
   * @return the box formatter
 | 
						|
   */
 | 
						|
  public BoxPainter getBoxPainter(AttributeSet a)
 | 
						|
  {
 | 
						|
    return new BoxPainter(a, this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the list formatter to use for the given set of CSS attributes.
 | 
						|
   *
 | 
						|
   * @param a - the given set
 | 
						|
   * @return the list formatter
 | 
						|
   */
 | 
						|
  public ListPainter getListPainter(AttributeSet a)
 | 
						|
  {
 | 
						|
    return new ListPainter(a, this);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the base font size between 1 and 7.
 | 
						|
   *
 | 
						|
   * @param sz - the new font size for the base.
 | 
						|
   */
 | 
						|
  public void setBaseFontSize(int sz)
 | 
						|
  {
 | 
						|
    if (sz <= 7 && sz >= 1)
 | 
						|
      baseFontSize = sz;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the base font size from the String. It can either identify
 | 
						|
   * a specific font size (between 1 and 7) or identify a relative
 | 
						|
   * font size such as +1 or -2.
 | 
						|
   *
 | 
						|
   * @param size - the new font size as a String.
 | 
						|
   */
 | 
						|
  public void setBaseFontSize(String size)
 | 
						|
  {
 | 
						|
    size = size.trim();
 | 
						|
    int temp = 0;
 | 
						|
    try
 | 
						|
      {
 | 
						|
        if (size.length() == 2)
 | 
						|
          {
 | 
						|
            int i = new Integer(size.substring(1)).intValue();
 | 
						|
            if (size.startsWith("+"))
 | 
						|
              temp = baseFontSize + i;
 | 
						|
            else if (size.startsWith("-"))
 | 
						|
              temp = baseFontSize - i;
 | 
						|
          }
 | 
						|
        else if (size.length() == 1)
 | 
						|
          temp = new Integer(size.substring(0)).intValue();
 | 
						|
 | 
						|
        if (temp <= 7 && temp >= 1)
 | 
						|
          baseFontSize = temp;
 | 
						|
      }
 | 
						|
    catch (NumberFormatException nfe)
 | 
						|
      {
 | 
						|
        // Do nothing here
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * TODO
 | 
						|
   *
 | 
						|
   * @param pt - TODO
 | 
						|
   * @return TODO
 | 
						|
   */
 | 
						|
  public static int getIndexOfSize(float pt)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the point size, given a size index.
 | 
						|
   *
 | 
						|
   * @param index - the size index
 | 
						|
   * @return the point size.
 | 
						|
   */
 | 
						|
  public float getPointSize(int index)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Given the string of the size, returns the point size value.
 | 
						|
   *
 | 
						|
   * @param size - the string representation of the size.
 | 
						|
   * @return - the point size value.
 | 
						|
   */
 | 
						|
  public float getPointSize(String size)
 | 
						|
  {
 | 
						|
    // FIXME: Not implemented.
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Convert the color string represenation into java.awt.Color. The valid
 | 
						|
   * values are like "aqua" , "#00FFFF" or "rgb(1,6,44)".
 | 
						|
   *
 | 
						|
   * @param colorName the color to convert.
 | 
						|
   * @return the matching java.awt.color
 | 
						|
   */
 | 
						|
  public Color stringToColor(String colorName)
 | 
						|
  {
 | 
						|
    return CSSColor.convertValue(colorName);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class carries out some of the duties of CSS formatting. This enables views
 | 
						|
   * to present the CSS formatting while not knowing how the CSS values are cached.
 | 
						|
   *
 | 
						|
   * This object is reponsible for the insets of a View and making sure
 | 
						|
   * the background is maintained according to the CSS attributes.
 | 
						|
   *
 | 
						|
   * @author Lillian Angel (langel@redhat.com)
 | 
						|
   */
 | 
						|
  public static class BoxPainter extends Object implements Serializable
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * The left inset.
 | 
						|
     */
 | 
						|
    private float leftInset;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The right inset.
 | 
						|
     */
 | 
						|
    private float rightInset;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The top inset.
 | 
						|
     */
 | 
						|
    private float topInset;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The bottom inset.
 | 
						|
     */
 | 
						|
    private float bottomInset;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The border of the box.
 | 
						|
     */
 | 
						|
    private Border border;
 | 
						|
 | 
						|
    private float leftPadding;
 | 
						|
    private float rightPadding;
 | 
						|
    private float topPadding;
 | 
						|
    private float bottomPadding;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The background color.
 | 
						|
     */
 | 
						|
    private Color background;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Package-private constructor.
 | 
						|
     *
 | 
						|
     * @param as - AttributeSet for painter
 | 
						|
     */
 | 
						|
    BoxPainter(AttributeSet as, StyleSheet ss)
 | 
						|
    {
 | 
						|
      float emBase = ss.getEMBase(as);
 | 
						|
      float exBase = ss.getEXBase(as);
 | 
						|
      // Fetch margins.
 | 
						|
      Length l = (Length) as.getAttribute(CSS.Attribute.MARGIN_LEFT);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          leftInset = l.getValue();
 | 
						|
        }
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.MARGIN_RIGHT);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          rightInset = l.getValue();
 | 
						|
        }
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.MARGIN_TOP);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          topInset = l.getValue();
 | 
						|
        }
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.MARGIN_BOTTOM);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          bottomInset = l.getValue();
 | 
						|
        }
 | 
						|
 | 
						|
      // Fetch padding.
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_LEFT);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          leftPadding = l.getValue();
 | 
						|
        }
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_RIGHT);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          rightPadding = l.getValue();
 | 
						|
        }
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_TOP);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          topPadding = l.getValue();
 | 
						|
        }
 | 
						|
      l = (Length) as.getAttribute(CSS.Attribute.PADDING_BOTTOM);
 | 
						|
      if (l != null)
 | 
						|
        {
 | 
						|
          l.setFontBases(emBase, exBase);
 | 
						|
          bottomPadding = l.getValue();
 | 
						|
        }
 | 
						|
 | 
						|
      // Determine border.
 | 
						|
      border = new CSSBorder(as, ss);
 | 
						|
 | 
						|
      // Determine background.
 | 
						|
      background = ss.getBackground(as);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Gets the inset needed on a given side to account for the margin, border
 | 
						|
     * and padding.
 | 
						|
     *
 | 
						|
     * @param size - the size of the box to get the inset for. View.TOP, View.LEFT,
 | 
						|
     * View.BOTTOM or View.RIGHT.
 | 
						|
     * @param v - the view making the request. This is used to get the AttributeSet,
 | 
						|
     * amd may be used to resolve percentage arguments.
 | 
						|
     * @return the inset
 | 
						|
     * @throws IllegalArgumentException - for an invalid direction.
 | 
						|
     */
 | 
						|
    public float getInset(int size, View v)
 | 
						|
    {
 | 
						|
      float inset;
 | 
						|
      switch (size)
 | 
						|
        {
 | 
						|
        case View.TOP:
 | 
						|
          inset = topInset;
 | 
						|
          if (border != null)
 | 
						|
            inset += border.getBorderInsets(null).top;
 | 
						|
          inset += topPadding;
 | 
						|
          break;
 | 
						|
        case View.BOTTOM:
 | 
						|
          inset = bottomInset;
 | 
						|
          if (border != null)
 | 
						|
            inset += border.getBorderInsets(null).bottom;
 | 
						|
          inset += bottomPadding;
 | 
						|
          break;
 | 
						|
        case View.LEFT:
 | 
						|
          inset = leftInset;
 | 
						|
          if (border != null)
 | 
						|
            inset += border.getBorderInsets(null).left;
 | 
						|
          inset += leftPadding;
 | 
						|
          break;
 | 
						|
        case View.RIGHT:
 | 
						|
          inset = rightInset;
 | 
						|
          if (border != null)
 | 
						|
            inset += border.getBorderInsets(null).right;
 | 
						|
          inset += rightPadding;
 | 
						|
          break;
 | 
						|
        default:
 | 
						|
          inset = 0.0F;
 | 
						|
      }
 | 
						|
      return inset;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Paints the CSS box according to the attributes given. This should
 | 
						|
     * paint the border, padding and background.
 | 
						|
     *
 | 
						|
     * @param g - the graphics configuration
 | 
						|
     * @param x - the x coordinate
 | 
						|
     * @param y - the y coordinate
 | 
						|
     * @param w - the width of the allocated area
 | 
						|
     * @param h - the height of the allocated area
 | 
						|
     * @param v - the view making the request
 | 
						|
     */
 | 
						|
    public void paint(Graphics g, float x, float y, float w, float h, View v)
 | 
						|
    {
 | 
						|
      int inX = (int) (x + leftInset);
 | 
						|
      int inY = (int) (y + topInset);
 | 
						|
      int inW = (int) (w - leftInset - rightInset);
 | 
						|
      int inH = (int) (h - topInset - bottomInset);
 | 
						|
      if (background != null)
 | 
						|
        {
 | 
						|
          g.setColor(background);
 | 
						|
          g.fillRect(inX, inY, inW, inH);
 | 
						|
        }
 | 
						|
      if (border != null)
 | 
						|
        {
 | 
						|
          border.paintBorder(null, g, inX, inY, inW, inH);
 | 
						|
        }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class carries out some of the CSS list formatting duties. Implementations
 | 
						|
   * of this class enable views to present the CSS formatting while not knowing anything
 | 
						|
   * about how the CSS values are being cached.
 | 
						|
   *
 | 
						|
   * @author Lillian Angel (langel@redhat.com)
 | 
						|
   */
 | 
						|
  public static class ListPainter implements Serializable
 | 
						|
  {
 | 
						|
 | 
						|
    /**
 | 
						|
     * Attribute set for painter
 | 
						|
     */
 | 
						|
    private AttributeSet attributes;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The associated style sheet.
 | 
						|
     */
 | 
						|
    private StyleSheet styleSheet;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The bullet type.
 | 
						|
     */
 | 
						|
    private String type;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Package-private constructor.
 | 
						|
     *
 | 
						|
     * @param as - AttributeSet for painter
 | 
						|
     */
 | 
						|
    ListPainter(AttributeSet as, StyleSheet ss)
 | 
						|
    {
 | 
						|
      attributes = as;
 | 
						|
      styleSheet = ss;
 | 
						|
      type = (String) as.getAttribute(CSS.Attribute.LIST_STYLE_TYPE);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Cached rectangle re-used in the paint method below.
 | 
						|
     */
 | 
						|
    private final Rectangle tmpRect = new Rectangle();
 | 
						|
 | 
						|
    /**
 | 
						|
     * Paints the CSS list decoration according to the attributes given.
 | 
						|
     *
 | 
						|
     * @param g - the graphics configuration
 | 
						|
     * @param x - the x coordinate
 | 
						|
     * @param y - the y coordinate
 | 
						|
     * @param w - the width of the allocated area
 | 
						|
     * @param h - the height of the allocated area
 | 
						|
     * @param v - the view making the request
 | 
						|
     * @param item - the list item to be painted >=0.
 | 
						|
     */
 | 
						|
    public void paint(Graphics g, float x, float y, float w, float h, View v,
 | 
						|
                      int item)
 | 
						|
    {
 | 
						|
      // FIXME: This is a very simplistic list rendering. We still need
 | 
						|
      // to implement different bullet types (see type field) and custom
 | 
						|
      // bullets via images.
 | 
						|
      View itemView = v.getView(item);
 | 
						|
      AttributeSet viewAtts = itemView.getAttributes();
 | 
						|
      Object tag = viewAtts.getAttribute(StyleConstants.NameAttribute);
 | 
						|
      // Only paint something here when the child view is an LI tag
 | 
						|
      // and the calling view is some of the list tags then).
 | 
						|
      if (tag != null && tag == HTML.Tag.LI)
 | 
						|
        {
 | 
						|
          g.setColor(Color.BLACK);
 | 
						|
          int centerX = (int) (x - 12);
 | 
						|
          int centerY = -1;
 | 
						|
          // For paragraphs (almost all cases) center bullet vertically
 | 
						|
          // in the middle of the first line.
 | 
						|
          tmpRect.setBounds((int) x, (int) y, (int) w, (int) h);
 | 
						|
          if (itemView.getViewCount() > 0)
 | 
						|
            {
 | 
						|
              View v1 = itemView.getView(0);
 | 
						|
              if (v1 instanceof ParagraphView && v1.getViewCount() > 0)
 | 
						|
                {
 | 
						|
                  Shape a1 = itemView.getChildAllocation(0, tmpRect);
 | 
						|
                  Rectangle r1 = a1 instanceof Rectangle ? (Rectangle) a1
 | 
						|
                                                         : a1.getBounds();
 | 
						|
                  ParagraphView par = (ParagraphView) v1;
 | 
						|
                  Shape a = par.getChildAllocation(0, r1);
 | 
						|
                  if (a != null)
 | 
						|
                    {
 | 
						|
                      Rectangle r = a instanceof Rectangle ? (Rectangle) a
 | 
						|
                                                           : a.getBounds();
 | 
						|
                      centerY = (int) (r.height / 2 + r.y);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
          if (centerY == -1)
 | 
						|
            {
 | 
						|
              centerY =(int) (h / 2 + y);
 | 
						|
            }
 | 
						|
          g.fillOval(centerX - 3, centerY - 3, 6, 6);
 | 
						|
        }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Converts an AttributeSet to a Map. This is used for CSS resolving.
 | 
						|
   *
 | 
						|
   * @param atts the attributes to convert
 | 
						|
   *
 | 
						|
   * @return the converted map
 | 
						|
   */
 | 
						|
  private Map<String,String> attributeSetToMap(AttributeSet atts)
 | 
						|
  {
 | 
						|
    HashMap<String,String> map = new HashMap<String,String>();
 | 
						|
    Enumeration<?> keys = atts.getAttributeNames();
 | 
						|
    while (keys.hasMoreElements())
 | 
						|
      {
 | 
						|
        Object key = keys.nextElement();
 | 
						|
        Object value = atts.getAttribute(key);
 | 
						|
        map.put(key.toString(), value.toString());
 | 
						|
      }
 | 
						|
    return map;
 | 
						|
  }
 | 
						|
}
 |