commit-classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commit-cp] classpath javax/swing/text/htmlHTMLEditorKit.ja...


From: Audrius Meskauskas
Subject: [commit-cp] classpath javax/swing/text/htmlHTMLEditorKit.ja...
Date: Mon, 05 Jun 2006 12:38:32 +0000

CVSROOT:        /sources/classpath
Module name:    classpath
Changes by:     Audrius Meskauskas <audriusa>   06/06/05 12:38:32

Modified files:
        javax/swing/text/html: HTMLEditorKit.java 
        .              : ChangeLog 
Added files:
        javax/swing/text/html: ImageView.java 
        gnu/javax/swing/text/html: CombinedAttributes.java 

Log message:
        2006-06-05  Audrius Meskauskas  <address@hidden>
        
                * javax/swing/text/html/HTMLEditorKit.java (HTMLFactory.create):
                Create the ImageView, when applicable.
                * gnu/javax/swing/text/html/CombinedAttributes.java,
                javax/swing/text/html/ImageView.java: New files.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/text/html/HTMLEditorKit.java?cvsroot=classpath&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/classpath/javax/swing/text/html/ImageView.java?cvsroot=classpath&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpath&r1=1.7654&r2=1.7655
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/javax/swing/text/html/CombinedAttributes.java?cvsroot=classpath&rev=1.1

Patches:
Index: javax/swing/text/html/HTMLEditorKit.java
===================================================================
RCS file: 
/sources/classpath/classpath/javax/swing/text/html/HTMLEditorKit.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- javax/swing/text/html/HTMLEditorKit.java    23 Mar 2006 00:30:14 -0000      
1.27
+++ javax/swing/text/html/HTMLEditorKit.java    5 Jun 2006 12:38:30 -0000       
1.28
@@ -548,6 +548,8 @@
                    || tag.equals(HTML.Tag.BLOCKQUOTE)
                    || tag.equals(HTML.Tag.PRE))
             view = new BlockView(element, View.Y_AXIS);
+          else if (tag.equals(HTML.Tag.IMG))
+            view = new ImageView(element);
           
           // FIXME: Uncomment when the views have been implemented
           else if (tag.equals(HTML.Tag.CONTENT))
@@ -559,12 +561,11 @@
           else if (tag.equals(HTML.Tag.TD))
             view = new ParagraphView(element);
 
+
           /*
           else if (tag.equals(HTML.Tag.MENU) || tag.equals(HTML.Tag.DIR)
                    || tag.equals(HTML.Tag.UL) || tag.equals(HTML.Tag.OL))
             view = new ListView(element);
-          else if (tag.equals(HTML.Tag.IMG))
-            view = new ImageView(element);
           else if (tag.equals(HTML.Tag.HR))
             view = new HRuleView(element);
           else if (tag.equals(HTML.Tag.BR))

Index: ChangeLog
===================================================================
RCS file: /sources/classpath/classpath/ChangeLog,v
retrieving revision 1.7654
retrieving revision 1.7655
diff -u -b -r1.7654 -r1.7655
--- ChangeLog   5 Jun 2006 11:44:51 -0000       1.7654
+++ ChangeLog   5 Jun 2006 12:38:30 -0000       1.7655
@@ -1,3 +1,10 @@
+2006-06-05  Audrius Meskauskas  <address@hidden>
+
+       * javax/swing/text/html/HTMLEditorKit.java (HTMLFactory.create):
+       Create the ImageView, when applicable.
+       * gnu/javax/swing/text/html/CombinedAttributes.java,
+       javax/swing/text/html/ImageView.java: New files.
+
 2006-06-05  Roman Kennke  <address@hidden>
 
        PR 27834

Index: javax/swing/text/html/ImageView.java
===================================================================
RCS file: javax/swing/text/html/ImageView.java
diff -N javax/swing/text/html/ImageView.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/html/ImageView.java        5 Jun 2006 12:38:30 -0000       
1.1
@@ -0,0 +1,441 @@
+package javax.swing.text.html;
+
+import gnu.javax.swing.text.html.CombinedAttributes;
+import gnu.javax.swing.text.html.ImageViewIconFactory;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+import javax.swing.text.Position.Bias;
+import javax.swing.text.html.HTML.Attribute;
+
+/**
+ * A view, representing a single image, represented by the HTML IMG tag.
+ * 
+ * @author Audrius Meskauskas (address@hidden) 
+ */
+public class ImageView extends View
+{
+  /**
+   * True if the image loads synchronuosly (on demand). By default, the image
+   * loads asynchronuosly.
+   */
+  boolean loadOnDemand;
+  
+  /**
+   * The image icon, wrapping the image,
+   */
+  ImageIcon imageIcon;
+ 
+  /**
+   * The image state.
+   */
+  byte imageState = MediaTracker.LOADING;
+
+  /**
+   * Creates the image view that represents the given element.
+   * 
+   * @param element the element, represented by this image view.
+   */
+  public ImageView(Element element)
+  {
+    super(element);
+  }
+ 
+  /**
+   * Load or reload the image. This method initiates the image reloading. After
+   * the image is ready, the repaint event will be scheduled. The current 
image,
+   * if it already exists, will be discarded.
+   * 
+   * @param itsTime
+   *          also load if the "on demand" property is set
+   */
+  void reloadImage(boolean itsTime)
+  {
+    URL url = getImageURL();
+    if (url == null)
+      imageState = (byte) MediaTracker.ERRORED;
+    else if (!(loadOnDemand && !itsTime))
+      imageIcon = new ImageIcon(url);
+    else
+      imageState = (byte) MediaTracker.LOADING;
+  }
+  
+  /**
+   * Get the image alignment. This method works handling standart alignment
+   * attributes in the HTML IMG tag (align = top bottom middle left right).
+   * Depending from the parameter, either horizontal or vertical alingment
+   * information is returned.
+   * 
+   * @param axis -
+   *          either X_AXIS or Y_AXIS
+   */
+  public float getAlignment(int axis)
+  {
+    AttributeSet attrs = getAttributes();
+    Object al = attrs.getAttribute(Attribute.ALIGN);
+    
+    // Default is top left aligned.
+    if (al == null)
+      return 0.0f;
+
+    String align = al.toString();
+
+    if (axis == View.X_AXIS)
+      {
+        if (align.equals("middle"))
+          return 0.5f;
+        else if (align.equals("left"))
+          return 0.0f;
+        else if (align.equals("right"))
+          return 1.0f;
+        else
+          return 0.0f;
+      }
+    else if (axis == View.Y_AXIS)
+      {
+        if (align.equals("middle"))
+          return 0.5f;
+        else if (align.equals("top"))
+          return 0.0f;
+        else if (align.equals("bottom"))
+          return 1.0f;
+        else
+          return 0.0f;
+      }
+    else
+      throw new IllegalArgumentException("axis " + axis);
+  }
+  
+  /**
+   * Get the text that should be shown as the image replacement and also as the
+   * image tool tip text. The method returns the value of the attribute, having
+   * the name address@hidden Attribute#ALT}. If there is no such attribute, 
the image
+   * name from the url is returned. If the URL is not available, the empty
+   * string is returned.
+   */
+  public String getAltText()
+  {
+    Object rt = getAttributes().getAttribute(Attribute.ALT);
+    if (rt != null)
+      return rt.toString();
+    else
+      {
+        URL u = getImageURL();
+        if (u == null)
+          return "";
+        else
+          return u.getFile();
+      }
+  }
+  
+  /**
+   * Returns the combination of the document and the style sheet attributes.
+   */
+  public AttributeSet getAttributes()
+  {
+    StyleSheet styles = getStyleSheet();
+    if (styles == null)
+      return super.getAttributes();
+    else
+      return CombinedAttributes.combine(super.getAttributes(),
+                                        styles.getViewAttributes(this));
+  }
+  
+  /**
+   * Get the image to render. May return null if the image is not yet loaded.
+   */
+  public Image getImage()
+  {
+    if (imageIcon == null)
+      return null;
+    else
+      return imageIcon.getImage();
+  }
+  
+  /**
+   * Get the URL location of the image to render. If this method returns null,
+   * the "no image" icon is rendered instead. By defaul, url must be present as
+   * the "src" property of the IMG tag. If it is missing, null is returned and
+   * the "no image" icon is rendered.
+   * 
+   * @return the URL location of the image to render.
+   */
+  public URL getImageURL()
+  {
+    Object url = getAttributes().getAttribute(Attribute.SRC);
+    if (url == null)
+      return null;
+
+    try
+      {
+        return new URL(url.toString());
+      }
+    catch (MalformedURLException e)
+      {
+        // The URL is malformed - no image.
+        return null;
+      }
+  }
+
+  /**
+   * Get the icon that should be displayed while the image is loading and hence
+   * not yet available.
+   * 
+   * @return an icon, showing a non broken sheet of paper with image.
+   */
+  public Icon getLoadingImageIcon()
+  {
+    return ImageViewIconFactory.getLoadingImageIcon();
+  }
+  
+  /**
+   * Get the image loading strategy.
+   * 
+   * @return false (default) if the image is loaded when the view is
+   *         constructed, true if the image is only loaded on demand when
+   *         rendering.
+   */
+  public boolean getLoadsSynchronously()
+  {
+    return loadOnDemand;
+  }
+
+  /**
+   * Get the icon that should be displayed when the image is not available.
+   * 
+   * @return an icon, showing a broken sheet of paper with image.
+   */
+  public Icon getNoImageIcon()
+  {
+    return ImageViewIconFactory.getNoImageIcon();
+  }
+  
+  /**
+   * Get the preferred span of the image along the axis. The image size is 
first
+   * requested to the attributes address@hidden Attribute#WIDTH} and
+   * address@hidden Attribute#HEIGHT}. If they are missing, and the image is 
already
+   * loaded, the image size is returned. If there are no attributes, and the
+   * image is not loaded, zero is returned.
+   * 
+   * @param axis -
+   *          either X_AXIS or Y_AXIS
+   * @return either width of height of the image, depending on the axis.
+   */
+  public float getPreferredSpan(int axis)
+  {
+    AttributeSet attrs = getAttributes();
+    
+    Image image = getImage();
+
+    if (axis == View.X_AXIS)
+      {
+        Object w = attrs.getAttribute(Attribute.WIDTH);
+        if (w != null)
+          return Integer.parseInt(w.toString());
+        else if (image != null)
+          return image.getWidth(getContainer());
+        else
+          return getNoImageIcon().getIconWidth();
+      }
+    else if (axis == View.Y_AXIS)
+      {
+        Object w = attrs.getAttribute(Attribute.HEIGHT);
+        if (w != null)
+          return Integer.parseInt(w.toString());
+        else if (image != null)
+          return image.getHeight(getContainer());
+        else
+          return getNoImageIcon().getIconHeight();
+      }
+    else
+      throw new IllegalArgumentException("axis " + axis);
+  }
+  
+  /**
+   * Get the associated style sheet from the document.
+   * 
+   * @return the associated style sheet.
+   */
+  protected StyleSheet getStyleSheet()
+  {
+    Document d = getElement().getDocument();
+    if (d instanceof HTMLDocument)
+      return ((HTMLDocument) d).getStyleSheet();
+    else
+      return null;
+  }
+
+  /**
+   * Get the tool tip text. This is overridden to return the value of the
+   * address@hidden #getAltText()}. The parameters are ignored.
+   * 
+   * @return that is returned by getAltText().
+   */
+  public String getToolTipText(float x, float y, Shape shape)
+  {
+    return getAltText();
+  }
+  
+  /**
+   * Paints the image or one of the two image state icons. The image is resized
+   * to the shape bounds. If there is no image available, the alternative text
+   * is displayed besides the image state icon.
+   * 
+   * @param g
+   *          the Graphics, used for painting.
+   * @param bounds
+   *          the bounds of the region where the image or replacing icon must 
be
+   *          painted.
+   */
+  public void paint(Graphics g, Shape bounds)
+  {
+    Rectangle r = bounds.getBounds();
+
+    if (imageIcon == null)
+
+      {
+        // Loading image on demand, rendering the loading icon so far.
+        reloadImage(true);
+         
+        // The reloadImage sets the imageIcon, unless the URL is broken 
+        // or malformed.
+        if (imageIcon != null)
+          {
+            if (imageIcon.getImageLoadStatus() != MediaTracker.COMPLETE)
+              {
+                // Render "not ready" icon, unless the image is ready
+                // immediately.
+                renderIcon(g, r, getLoadingImageIcon());
+                // Add the listener to repaint when the icon will be ready.
+                imageIcon.setImageObserver(getContainer());
+                return;
+              }
+          }
+        else
+          {
+            renderIcon(g, r, getNoImageIcon());
+            return;
+          }
+      }
+
+    imageState = (byte) imageIcon.getImageLoadStatus();
+
+    switch (imageState)
+      {
+      case MediaTracker.ABORTED:
+      case MediaTracker.ERRORED:
+        renderIcon(g, r, getNoImageIcon());
+        break;
+      case MediaTracker.LOADING:
+      // If the image is not loaded completely, we still render it, as the
+      // partial image may be available.
+      case MediaTracker.COMPLETE:
+      {
+        // Paint the scaled image.
+        Image scaled = imageIcon.getImage().getScaledInstance(
+                                                              r.width,
+                                                              r.height,
+                                                              
Image.SCALE_DEFAULT);
+        ImageIcon painter = new ImageIcon(scaled);
+        painter.paintIcon(getContainer(), g, r.x, r.y);
+      }
+        break;
+      }
+  }
+  
+  /**
+   * Render "no image" icon and the alternative "no image" text. The text is
+   * rendered right from the icon and is aligned to the icon bottom.
+   */
+  private void renderIcon(Graphics g, Rectangle bounds, Icon icon)
+  {
+    Shape current = g.getClip();
+    try
+      {
+        g.setClip(bounds);
+        if (icon != null)
+          {
+            icon.paintIcon(getContainer(), g, bounds.x, bounds.y);
+            g.drawString(getAltText(), bounds.x + icon.getIconWidth(),
+                         bounds.y + icon.getIconHeight());
+          }
+      }
+    finally
+      {
+        g.setClip(current);
+      }
+  }
+  
+  /**
+   * Set if the image should be loaded only when needed (synchronuosly). By
+   * default, the image loads asynchronuosly. If the image is not yet ready, 
the
+   * icon, returned by the address@hidden #getLoadingImageIcon()}, is 
displayed.
+   */
+  public void setLoadsSynchronously(boolean load_on_demand)
+  {
+    loadOnDemand = load_on_demand;
+  }
+ 
+  /**
+   * Update all cached properties from the attribute set, returned by the
+   * address@hidden #getAttributes}.
+   */
+  protected void setPropertiesFromAttributes()
+  {
+    // In the current implementation, nothing is cached yet, unless the image
+    // itself.
+    imageIcon = null;
+  }
+  
+  /**
+   * Maps the picture co-ordinates into the image position in the model. As the
+   * image is not divideable, this is currently implemented always to return 
the
+   * start offset.
+   */
+  public int viewToModel(float x, float y, Shape shape, Bias[] bias)
+  {
+    return getStartOffset();
+  }
+  
+  /**
+   * This is currently implemented always to return the area of the image view,
+   * as the image is not divideable by character positions.
+   * 
+   * @param pos character position
+   * @param area of the image view
+   * @param bias bias
+   * 
+   * @return the shape, where the given character position should be mapped.
+   */
+  public Shape modelToView(int pos, Shape area, Bias bias)
+      throws BadLocationException
+  {
+    return area;
+  }
+  
+  /**
+   * Starts loading the image asynchronuosly. If the image must be loaded
+   * synchronuosly instead, the address@hidden #setLoadsSynchronously} must be
+   * called before calling this method. The passed parameters are not used.
+   */
+  public void setSize(float width, float height)
+  {
+    if (imageIcon == null)
+      reloadImage(false);
+  }  
+  
+
+}

Index: gnu/javax/swing/text/html/CombinedAttributes.java
===================================================================
RCS file: gnu/javax/swing/text/html/CombinedAttributes.java
diff -N gnu/javax/swing/text/html/CombinedAttributes.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/javax/swing/text/html/CombinedAttributes.java   5 Jun 2006 12:38:31 
-0000       1.1
@@ -0,0 +1,213 @@
+/* CombinedAttributes.java -- A two combined sets of attributes
+   Copyright (C) 2006 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 gnu.javax.swing.text.html;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+
+import javax.swing.text.AttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+
+/**
+ * Contains the two combined attribute sets what are searched subsequently.
+ * This is used to combine style sheet attributes with the HTML view 
attributes.
+ * The parent cannot be used as the view may have its own attribute hierarchy.
+ * 
+ * @author Audrius Meskauskas (address@hidden)  
+ */
+public class CombinedAttributes implements AttributeSet, Serializable
+{
+  /**
+   * Returns the elements from both enumerations.
+   */
+  class CombinedEnumeration implements Enumeration
+  {
+    /**
+     * Create a combined enumeration that enumerates over two enumerations.
+     * 
+     * @param first the first enumeration to enumerate
+     * @param second the second enumeration to enumerate
+     */
+    CombinedEnumeration(Enumeration first, Enumeration second)
+    {
+      a = first;
+      b = second;
+    }
+    
+    /**
+     * The first enumeration (elements returned first)
+     */
+    final Enumeration a;
+    
+    /**
+     * The second enumeration (elements returned later)
+     */
+    final Enumeration b;
+    
+    /** @inheritDoc */
+    public boolean hasMoreElements()
+    {
+      return a.hasMoreElements() || b.hasMoreElements();
+    }
+    
+    /** @inheritDoc */
+    public Object nextElement()
+    {
+      return a.hasMoreElements() ? a.nextElement():b.nextElement();
+    }
+  }
+  
+  
+  /**
+   * The first attribute set.
+   */
+  final AttributeSet a;
+  
+  /**
+   * The second attribute set.
+   */
+  final AttributeSet b;
+  
+  /**
+   * Create the CombinedAttributes what search in the two sets. If any of the
+   * two passed sets is null, another set is returned. Otherwise, the combined
+   * attribute set is returned.
+   * 
+   * @param primary the first set (searched first)
+   * @param secondary the second set (searched later).
+   */
+  public static AttributeSet combine(AttributeSet primary,
+                                     AttributeSet secondary)
+  {
+    if (primary == null)
+      return secondary;
+    else if (secondary == null)
+      return primary;
+    else
+      return new CombinedAttributes(primary, secondary);
+  }
+  
+  /**
+   * Create the CombinedAttributes what search in the two sets.
+   * 
+   * @param primary the first set (searched first)
+   * @param secondary the second set (searched later).
+   */
+  private CombinedAttributes(AttributeSet primary, AttributeSet secondary)
+  {
+    a = primary;
+    b = secondary;
+  }
+
+  /** @inheritDoc */
+  public boolean containsAttribute(Object name, Object value)
+  {
+    return a.containsAttribute(name, value) || b.containsAttribute(name, 
value);
+  }
+
+  /** @inheritDoc */
+  public boolean containsAttributes(AttributeSet attributes)
+  {
+    Enumeration names = attributes.getAttributeNames();
+    Object name;
+    while (names.hasMoreElements())
+      {
+        name = names.nextElement();
+        if (!containsAttribute(name, attributes.getAttribute(name)))
+          return false;
+      }
+    return true;
+  }
+
+  /** @inheritDoc */
+  public AttributeSet copyAttributes()
+  {
+    SimpleAttributeSet copy = new SimpleAttributeSet();
+    copy.addAttributes(a);
+    copy.addAttributes(b);
+    return copy;
+  }
+
+  /** @inheritDoc */
+  public Object getAttribute(Object key)
+  {
+    Object value = a.getAttribute(key);
+    if (value == null)
+      value = b.getAttribute(key);
+    
+    return value;
+  }
+
+  /** @inheritDoc */
+  public int getAttributeCount()
+  {
+    return a.getAttributeCount()+b.getAttributeCount();
+  }
+
+  /** @inheritDoc */
+  public Enumeration getAttributeNames()
+  {
+    return new CombinedEnumeration(a.getAttributeNames(), 
b.getAttributeNames());
+  }
+
+  /**
+   * There is no one.
+   * 
+   * @return null, always.
+   */
+  public AttributeSet getResolveParent()
+  {
+    return null;
+  }
+
+  /** @inheritDoc */
+  public boolean isDefined(Object attrName)
+  {
+    return a.isDefined(attrName) || b.isDefined(attrName);
+  }
+
+  /** @inheritDoc */
+  public boolean isEqual(AttributeSet attr)
+  {
+    if (attr.getAttributeCount() == getAttributeCount())
+      return containsAttributes(attr);
+    else
+      return false;
+  }
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]