Source for javax.swing.text.html.ParagraphView

   1: /* ParagraphView.java -- Renders a paragraph in HTML
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   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.
  10: 
  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.
  15: 
  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.
  20: 
  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.
  25: 
  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. */
  37: 
  38: 
  39: package javax.swing.text.html;
  40: 
  41: import gnu.javax.swing.text.html.css.Length;
  42: 
  43: import java.awt.Graphics;
  44: import java.awt.Rectangle;
  45: import java.awt.Shape;
  46: 
  47: import javax.swing.SizeRequirements;
  48: import javax.swing.text.AttributeSet;
  49: import javax.swing.text.Document;
  50: import javax.swing.text.Element;
  51: import javax.swing.text.StyleConstants;
  52: import javax.swing.text.View;
  53: 
  54: /**
  55:  * Renders a paragraph in HTML. This is a subclass of
  56:  * {@link javax.swing.text.ParagraphView} with some adjustments for
  57:  * understanding stylesheets.
  58:  *
  59:  * @author Roman Kennke (kennke@aicas.com)
  60:  */
  61: public class ParagraphView
  62:   extends javax.swing.text.ParagraphView
  63: {
  64: 
  65:   /**
  66:    * The attributes used by this view.
  67:    */
  68:   private AttributeSet attributes;
  69: 
  70:   /**
  71:    * The stylesheet's box painter.
  72:    */
  73:   private StyleSheet.BoxPainter painter;
  74: 
  75:   /**
  76:    * The width as specified in the stylesheet or null if not specified.
  77:    */
  78:   private Length cssWidth;
  79: 
  80:   /**
  81:    * The height as specified in the stylesheet or null if not specified.
  82:    */
  83:   private Length cssHeight;
  84: 
  85:   /**
  86:    * Creates a new ParagraphView for the specified element.
  87:    *
  88:    * @param element the element
  89:    */
  90:   public ParagraphView(Element element)
  91:   {
  92:     super(element);
  93:   }
  94: 
  95:   /**
  96:    * Sets the parent of this view. This is implemented to call the parent
  97:    * functionality and then trigger {@link #setPropertiesFromAttributes} in
  98:    * order to load the stylesheet attributes.
  99:    *
 100:    * @param parent the parent view to set
 101:    */
 102:   public void setParent(View parent)
 103:   {
 104:     super.setParent(parent);
 105:     if (parent != null)
 106:       setPropertiesFromAttributes();
 107:   }
 108: 
 109:   /**
 110:    * Returns the attributes used by this view. This is implemented to multiplex
 111:    * the attributes of the model with the attributes of the stylesheet.
 112:    */
 113:   public AttributeSet getAttributes()
 114:   {
 115:     if (attributes == null)
 116:       {
 117:         attributes = getStyleSheet().getViewAttributes(this);
 118:       }
 119:     return attributes;
 120:   }
 121: 
 122:   /**
 123:    * Loads the visual properties of the ParagraphView from the element's
 124:    * attributes and the stylesheet of the HTML document.
 125:    */
 126:   protected void setPropertiesFromAttributes()
 127:   {
 128:     super.setPropertiesFromAttributes();
 129: 
 130:     // Fetch CSS attributes.
 131:     attributes = getAttributes();
 132:     if (attributes != null)
 133:       {
 134:         super.setPropertiesFromAttributes();
 135:         Object o = attributes.getAttribute(CSS.Attribute.TEXT_ALIGN);
 136:         if (o != null)
 137:           {
 138:             String align = o.toString();
 139:             if (align.equals("left"))
 140:               setJustification(StyleConstants.ALIGN_LEFT);
 141:             else if (align.equals("right"))
 142:               setJustification(StyleConstants.ALIGN_RIGHT);
 143:             else if (align.equals("center"))
 144:               setJustification(StyleConstants.ALIGN_CENTER);
 145:             else if (align.equals("justify"))
 146:               setJustification(StyleConstants.ALIGN_JUSTIFIED);
 147:           }
 148: 
 149:         // Fetch StyleSheet's box painter.
 150:         painter = getStyleSheet().getBoxPainter(attributes);
 151:         setInsets((short) painter.getInset(TOP, this),
 152:                   (short) painter.getInset(LEFT, this),
 153:                   (short) painter.getInset(BOTTOM, this),
 154:                   (short) painter.getInset(RIGHT, this));
 155: 
 156:         StyleSheet ss = getStyleSheet();
 157:         float emBase = ss.getEMBase(attributes);
 158:         float exBase = ss.getEXBase(attributes);
 159:         cssWidth = (Length) attributes.getAttribute(CSS.Attribute.WIDTH);
 160:         if (cssWidth != null)
 161:           cssWidth.setFontBases(emBase, exBase);
 162:         cssHeight = (Length) attributes.getAttribute(CSS.Attribute.WIDTH);
 163:         if (cssHeight != null)
 164:           cssHeight.setFontBases(emBase, exBase);
 165:       }
 166:   }
 167: 
 168:   /**
 169:    * Returns the stylesheet used by this view.
 170:    *
 171:    * @return the stylesheet used by this view
 172:    */
 173:   protected StyleSheet getStyleSheet()
 174:   {
 175:     Document doc = getDocument();
 176:     StyleSheet styleSheet = null;
 177:     if (doc instanceof HTMLDocument)
 178:       styleSheet = ((HTMLDocument) doc).getStyleSheet();
 179:     return styleSheet;
 180:   }
 181: 
 182:   /**
 183:    * Calculates the minor axis requirements of this view. This is implemented
 184:    * to return the super class'es requirements and modifies the minimumSpan
 185:    * slightly so that it is not smaller than the length of the longest word.
 186:    *
 187:    * @param axis the axis
 188:    * @param r the SizeRequirements object to be used as return parameter;
 189:    *        if <code>null</code> a new one will be created
 190:    *
 191:    * @return the requirements along the minor layout axis
 192:    */
 193:   protected SizeRequirements calculateMinorAxisRequirements(int axis,
 194:                                                             SizeRequirements r)
 195:   {
 196:     r = super.calculateMinorAxisRequirements(axis, r);
 197:     if (! setCSSSpan(r, axis))
 198:       {
 199:         int margin = axis == X_AXIS ? getLeftInset() + getRightInset()
 200:                                     : getTopInset() + getBottomInset();
 201:         r.minimum -= margin;
 202:         r.preferred -= margin;
 203:         r.maximum -= margin;
 204:       }
 205:     return r;
 206:   }
 207: 
 208:   /**
 209:    * Sets the span on the SizeRequirements object according to the
 210:    * according CSS span value, when it is set.
 211:    * 
 212:    * @param r the size requirements
 213:    * @param axis the axis
 214:    *
 215:    * @return <code>true</code> when the CSS span has been set,
 216:    *         <code>false</code> otherwise
 217:    */
 218:   private boolean setCSSSpan(SizeRequirements r, int axis)
 219:   {
 220:     boolean ret = false;
 221:     if (axis == X_AXIS)
 222:       {
 223:         if (cssWidth != null && ! cssWidth.isPercentage())
 224:           {
 225:             r.minimum = (int) cssWidth.getValue();
 226:             r.preferred = (int) cssWidth.getValue();
 227:             r.maximum = (int) cssWidth.getValue();
 228:             ret = true;
 229:           }
 230:       }
 231:     else
 232:       {
 233:         if (cssHeight != null && ! cssWidth.isPercentage())
 234:           {
 235:             r.minimum = (int) cssHeight.getValue();
 236:             r.preferred = (int) cssHeight.getValue();
 237:             r.maximum = (int) cssHeight.getValue();
 238:             ret = true;
 239:           }
 240:       }
 241:     return ret;
 242:   }
 243: 
 244:   /**
 245:    * Determines if this view is visible or not. If none of the children is
 246:    * visible and the only visible child is the break that ends the paragraph,
 247:    * this paragraph is not considered to be visible.
 248:    *
 249:    * @return the visibility of this paragraph
 250:    */
 251:   public boolean isVisible()
 252:   {
 253:     // FIXME: Implement the above specified behaviour.
 254:     return super.isVisible();
 255:   }
 256: 
 257:   /**
 258:    * Paints this view. This paints the box using the stylesheet's
 259:    * box painter for this view and delegates to the super class paint()
 260:    * afterwards.
 261:    *
 262:    * @param g the graphics object
 263:    * @param a the current allocation of this view
 264:    */
 265:   public void paint(Graphics g, Shape a)
 266:   {
 267:     if (a != null)
 268:       {
 269:         Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
 270:         painter.paint(g, r.x, r.y, r.width, r.height, this);
 271:       }
 272:     super.paint(g, a);
 273:   }
 274: 
 275:   /**
 276:    * Returns the preferred span of this view. If this view is not visible,
 277:    * we return <code>0</code>, otherwise the super class is called.
 278:    *
 279:    * @param axis the axis
 280:    *
 281:    * @return the preferred span of this view
 282:    */
 283:   public float getPreferredSpan(int axis)
 284:   {
 285:     float span = 0;
 286:     if (isVisible())
 287:       span = super.getPreferredSpan(axis);
 288:     return span;
 289:   }
 290: 
 291:   /**
 292:    * Returns the minimum span of this view. If this view is not visible,
 293:    * we return <code>0</code>, otherwise the super class is called.
 294:    *
 295:    * @param axis the axis
 296:    *
 297:    * @return the minimum span of this view
 298:    */
 299:   public float getMinimumSpan(int axis)
 300:   {
 301:     float span = 0;
 302:     if (isVisible())
 303:       span = super.getMinimumSpan(axis);
 304:     return span;
 305:   }
 306: 
 307:   /**
 308:    * Returns the maximum span of this view. If this view is not visible,
 309:    * we return <code>0</code>, otherwise the super class is called.
 310:    *
 311:    * @param axis the axis
 312:    *
 313:    * @return the maximum span of this view
 314:    */
 315:   public float getMaximumSpan(int axis)
 316:   {
 317:     float span = 0;
 318:     if (isVisible())
 319:       span = super.getMaximumSpan(axis);
 320:     return span;
 321:   }
 322: }