Clover coverage report -
Coverage timestamp: Sun Apr 18 2004 21:32:30 EDT
file stats: LOC: 474   Methods: 18
NCLOC: 203   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
SHTMLBlockView.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
 3   
  *
 4   
  * This software is the proprietary information of Sun Microsystems, Inc.
 5   
  * Use is subject to license terms.
 6   
  *
 7   
  */
 8   
 import java.awt.*;
 9   
 import javax.swing.*;
 10   
 import javax.swing.event.*;
 11   
 import javax.swing.text.*;
 12   
 import javax.swing.text.html.*;
 13   
 
 14   
 /**
 15   
  * HTML block view copied from javax.swing.text.html.BlockView.java
 16   
  *
 17   
  * The original class is only changed in the way that it now uses
 18   
  * a com.lightdev.app.shtm.SHTMLBoxPainter instead of
 19   
  * javax.swing.text.html.StyleSheet.BoxPainter
 20   
  *
 21   
  * Admittedly ugly solution which hopefully can be corrected
 22   
  * once Sun decided to tidy up the CSS part of Swing.
 23   
  *
 24   
  * @version stage 11, April 27, 2003
 25   
  */
 26   
 
 27   
 public class SHTMLBlockView extends BoxView {
 28   
 
 29   
   private SHTMLBoxPainter painter;
 30   
   private AttributeSet attr;
 31   
 
 32   
 
 33   
   /**
 34   
    * Creates a new view that represents an
 35   
    * html box.  This can be used for a number
 36   
    * of elements.
 37   
    *
 38   
    * @param elem the element to create a view for
 39   
    * @param axis either View.X_AXIS or View.Y_AXIS
 40   
    */
 41  0
   public SHTMLBlockView(Element elem, int axis) {
 42  0
     super(elem, axis);
 43   
   }
 44   
 
 45   
   /**
 46   
    * Establishes the parent view for this view.  This is
 47   
    * guaranteed to be called before any other methods if the
 48   
    * parent view is functioning properly.
 49   
    * <p>
 50   
    * This is implemented
 51   
    * to forward to the superclass as well as call the
 52   
    * {@link #setPropertiesFromAttributes()}
 53   
    * method to set the paragraph properties from the css
 54   
    * attributes.  The call is made at this time to ensure
 55   
    * the ability to resolve upward through the parents
 56   
    * view attributes.
 57   
    *
 58   
    * @param parent the new parent, or null if the view is
 59   
    *  being removed from a parent it was previously added
 60   
    *  to
 61   
    */
 62  0
   public void setParent(View parent) {
 63  0
     super.setParent(parent);
 64  0
     if (parent != null) {
 65  0
       setPropertiesFromAttributes();
 66   
     }
 67   
   }
 68   
 
 69   
   /**
 70   
    * Calculate the requirements of the block along the major
 71   
    * axis (i.e. the axis along with it tiles).  This is implemented
 72   
    * to provide the superclass behavior and then adjust it if the
 73   
    * CSS width or height attribute is specified and applicable to
 74   
    * the axis.
 75   
    */
 76  0
   protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) {
 77  0
     if (r == null) {
 78  0
       r = new SizeRequirements();
 79   
     }
 80  0
     if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {
 81  0
       r = super.calculateMajorAxisRequirements(axis, r);
 82   
     }
 83   
     else {
 84   
       // Offset by the margins so that pref/min/max return the
 85   
       // right value.
 86  0
       SizeRequirements parentR = super.calculateMajorAxisRequirements(
 87   
           axis, null);
 88  0
       int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
 89   
                    getTopInset() + getBottomInset();
 90  0
       r.minimum -= margin;
 91  0
       r.preferred -= margin;
 92  0
       r.maximum -= margin;
 93  0
       constrainSize(axis, r, parentR);
 94   
     }
 95  0
     return r;
 96   
   }
 97   
 
 98   
   /**
 99   
    * Calculate the requirements of the block along the minor
 100   
    * axis (i.e. the axis orthoginal to the axis along with it tiles).
 101   
    * This is implemented
 102   
    * to provide the superclass behavior and then adjust it if the
 103   
    * CSS width or height attribute is specified and applicable to
 104   
    * the axis.
 105   
    */
 106  0
   protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
 107  0
     if (r == null) {
 108  0
       r = new SizeRequirements();
 109   
     }
 110   
 
 111  0
     if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {
 112   
 
 113   
             /*
 114   
       * The requirements were not directly specified by attributes, so
 115   
       * compute the aggregate of the requirements of the children.  The
 116   
       * children that have a percentage value specified will be treated
 117   
       * as completely stretchable since that child is not limited in any
 118   
       * way.
 119   
              */
 120   
 /*
 121   
             int min = 0;
 122   
             long pref = 0;
 123   
             int max = 0;
 124   
             int n = getViewCount();
 125   
             for (int i = 0; i < n; i++) {
 126   
                 View v = getView(i);
 127   
                 min = Math.max((int) v.getMinimumSpan(axis), min);
 128   
                 pref = Math.max((int) v.getPreferredSpan(axis), pref);
 129   
                 if (
 130   
                 max = Math.max((int) v.getMaximumSpan(axis), max);
 131   
 
 132   
             }
 133   
             r.preferred = (int) pref;
 134   
             r.minimum = min;
 135   
             r.maximum = max;
 136   
             */
 137  0
       r = super.calculateMinorAxisRequirements(axis, r);
 138   
     }
 139   
     else {
 140   
       // Offset by the margins so that pref/min/max return the
 141   
       // right value.
 142  0
       SizeRequirements parentR = super.calculateMinorAxisRequirements(
 143   
           axis, null);
 144  0
       int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
 145   
                    getTopInset() + getBottomInset();
 146  0
       r.minimum -= margin;
 147  0
       r.preferred -= margin;
 148  0
       r.maximum -= margin;
 149  0
       constrainSize(axis, r, parentR);
 150   
     }
 151   
 
 152   
         /*
 153   
     * Set the alignment based upon the CSS properties if it is
 154   
     * specified.  For X_AXIS this would be text-align, for
 155   
     * Y_AXIS this would be vertical-align.
 156   
          */
 157  0
     if (axis == X_AXIS) {
 158  0
       Object o = getAttributes().getAttribute(CSS.Attribute.TEXT_ALIGN);
 159  0
       if (o != null) {
 160  0
         String align = o.toString();
 161  0
         if (align.equals("center")) {
 162  0
           r.alignment = 0.5f;
 163  0
         } else if (align.equals("right")) {
 164  0
           r.alignment = 1.0f;
 165   
         } else {
 166  0
           r.alignment = 0.0f;
 167   
         }
 168   
       }
 169   
     }
 170   
     // Y_AXIS TBD
 171  0
     return r;
 172   
   }
 173   
 
 174  0
   boolean isPercentage(int axis, AttributeSet a) {
 175  0
     if (axis == X_AXIS) {
 176  0
       if (cssWidth != null) {
 177  0
         return cssWidth.toString().trim().endsWith("%");
 178   
         //return cssWidth.isPercentage();
 179   
       }
 180   
     } else {
 181  0
       if (cssHeight != null) {
 182  0
         return cssHeight.toString().trim().endsWith("%");
 183   
         //return cssHeight.isPercentage();
 184   
       }
 185   
     }
 186  0
     return false;
 187   
   }
 188   
 
 189   
   /**
 190   
    * Adjust the given requirements to the CSS width or height if
 191   
    * it is specified along the applicable axis.  Return true if the
 192   
    * size is exactly specified, false if the span is not specified
 193   
    * in an attribute or the size specified is a percentage.
 194   
    */
 195   
     /*
 196   
     static boolean spanSetFromAttributes(int axis, SizeRequirements r,
 197   
                                          CSS.LengthValue cssWidth,
 198   
                                          CSS.LengthValue cssHeight) {
 199   
         if (axis == X_AXIS) {
 200   
             if ((cssWidth != null) && (! cssWidth.isPercentage())) {
 201   
                 r.minimum = r.preferred = r.maximum = (int) cssWidth.getValue();
 202   
                 return true;
 203   
             }
 204   
         } else {
 205   
             if ((cssHeight != null) && (! cssHeight.isPercentage())) {
 206   
                 r.minimum = r.preferred = r.maximum = (int) cssHeight.getValue();
 207   
                 return true;
 208   
             }
 209   
         }
 210   
         return false;
 211   
     }
 212   
     */
 213   
 
 214   
    /**
 215   
     * Adjust the given requirements to the CSS width or height if
 216   
     * it is specified along the applicable axis.  Return true if the
 217   
     * size is exactly specified, false if the span is not specified
 218   
     * in an attribute or the size specified is a percentage.
 219   
     *
 220   
     * (copied from javax.swing.text.html.BlockView)
 221   
     */
 222   
 
 223  0
   static boolean spanSetFromAttributes(int axis, SizeRequirements r,
 224   
                                        Object cssWidth,
 225   
                                        Object cssHeight) {
 226  0
     if (axis == X_AXIS) {
 227  0
       if ((cssWidth != null) /*&& (! cssWidth.isPercentage())*/) {
 228   
         //if(!cssWidth.toString().trim().endsWith("%")) {
 229  0
           r.minimum = r.preferred = r.maximum = (int) Util.getPtValue(cssWidth.toString()); /* cssWidth.getValue();*/
 230   
           //System.out.println("spanSetFromAttributes width=r.maximum");
 231   
           //System.out.println("spanSetFromAttributes = true");
 232  0
           return true;
 233   
         //}
 234   
       }
 235   
     } else {
 236  0
       if ((cssHeight != null) /*&& (! cssHeight.isPercentage())*/) {
 237   
         //if(!cssHeight.toString().endsWith("%")) {
 238  0
           r.minimum = r.preferred = r.maximum = (int) Util.getPtValue(cssHeight.toString()); /* cssHeight.getValue();*/
 239   
           //System.out.println("spanSetFromAttributes height=r.maximum");
 240   
           //System.out.println("spanSetFromAttributes = true");
 241  0
           return true;
 242   
         //}
 243   
       }
 244   
     }
 245   
     //System.out.println("spanSetFromAttributes no percentage: " + cssWidth);
 246   
     //System.out.println("spanSetFromAttributes = false");
 247  0
     return false;
 248   
   }
 249   
 
 250   
 
 251   
 
 252   
   /**
 253   
    * Perform layout for the minor axis of the box (i.e. the
 254   
    * axis orthoginal to the axis that it represents).  The results
 255   
    * of the layout should be placed in the given arrays which represent
 256   
    * the allocations to the children along the minor axis.
 257   
    *
 258   
    * @param targetSpan the total span given to the view, which
 259   
    *  whould be used to layout the childre.
 260   
    * @param axis the axis being layed out
 261   
    * @param offsets the offsets from the origin of the view for
 262   
    *  each of the child views; this is a return value and is
 263   
    *  filled in by the implementation of this method
 264   
    * @param spans the span of each child view; this is a return
 265   
    *  value and is filled in by the implementation of this method
 266   
    * @return the offset and span for each child view in the
 267   
    *  offsets and spans parameters
 268   
    */
 269  0
   protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {
 270  0
     int n = getViewCount();
 271  0
     Object key = (axis == X_AXIS) ? CSS.Attribute.WIDTH : CSS.Attribute.HEIGHT;
 272  0
     for (int i = 0; i < n; i++) {
 273  0
       View v = getView(i);
 274  0
       int min = (int) v.getMinimumSpan(axis);
 275  0
       int max = (int) v.getMaximumSpan(axis);
 276   
 
 277   
       // check for percentage span
 278  0
       AttributeSet a = v.getAttributes();
 279   
       //CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(key);
 280  0
       Object lv = a.getAttribute(key);
 281  0
       if ((lv != null) /*&& lv.isPercentage()*/) {
 282  0
         if(lv.toString().trim().endsWith("%")) {
 283   
           // bound the span to the percentage specified
 284  0
           min = (int) (Util.getPtValue(lv.toString()) * new Integer(targetSpan).floatValue());/*lv.getValue(targetSpan);*/
 285  0
           max = min;
 286   
         }
 287   
       }
 288   
 
 289   
       // assign the offset and span for the child
 290  0
       if (max < targetSpan) {
 291   
         // can't make the child this wide, align it
 292  0
         float align = v.getAlignment(axis);
 293  0
         offsets[i] = (int) ((targetSpan - max) * align);
 294  0
         spans[i] = max;
 295   
       } else {
 296   
         // make it the target width, or as small as it can get.
 297  0
         offsets[i] = 0;
 298  0
         spans[i] = Math.max(min, targetSpan);
 299   
       }
 300   
     }
 301   
   }
 302   
 
 303   
 
 304   
   /**
 305   
    * Renders using the given rendering surface and area on that
 306   
    * surface.  This is implemented to delegate to the css box
 307   
    * painter to paint the border and background prior to the
 308   
    * interior.
 309   
    *
 310   
    * @param g the rendering surface to use
 311   
    * @param allocation the allocated region to render into
 312   
    * @see View#paint
 313   
    */
 314  0
   public void paint(Graphics g, Shape allocation) {
 315  0
     Rectangle a = (Rectangle) allocation;
 316  0
     painter.paint(g, a.x, a.y, a.width, a.height, this);
 317  0
     super.paint(g, a);
 318   
   }
 319   
 
 320   
   /**
 321   
    * Fetches the attributes to use when rendering.  This is
 322   
    * implemented to multiplex the attributes specified in the
 323   
    * model with a StyleSheet.
 324   
    */
 325  0
   public AttributeSet getAttributes() {
 326  0
     if (attr == null) {
 327  0
       StyleSheet sheet = getStyleSheet();
 328  0
       attr = sheet.getViewAttributes(this);
 329   
     }
 330  0
     return attr;
 331   
   }
 332   
 
 333   
   /**
 334   
    * Gets the resize weight.
 335   
    *
 336   
    * @param axis may be either X_AXIS or Y_AXIS
 337   
    * @return the weight
 338   
    * @exception IllegalArgumentException for an invalid axis
 339   
    */
 340  0
   public int getResizeWeight(int axis) {
 341  0
     switch (axis) {
 342  0
       case View.X_AXIS:
 343  0
         return 1;
 344  0
       case View.Y_AXIS:
 345  0
         return 0;
 346  0
       default:
 347  0
         throw new IllegalArgumentException("Invalid axis: " + axis);
 348   
     }
 349   
   }
 350   
 
 351   
   /**
 352   
    * Gets the alignment.
 353   
    *
 354   
    * @param axis may be either X_AXIS or Y_AXIS
 355   
    * @return the alignment
 356   
    */
 357  0
   public float getAlignment(int axis) {
 358  0
     switch (axis) {
 359  0
       case View.X_AXIS:
 360  0
         return 0;
 361  0
       case View.Y_AXIS:
 362  0
         if (getViewCount() == 0) {
 363  0
           return 0;
 364   
         }
 365  0
         float span = getPreferredSpan(View.Y_AXIS);
 366  0
         View v = getView(0);
 367  0
         float above = v.getPreferredSpan(View.Y_AXIS);
 368  0
         float a = (((int)span) != 0) ? (above * v.getAlignment(View.Y_AXIS)) / span: 0;
 369  0
         return a;
 370  0
       default:
 371  0
         throw new IllegalArgumentException("Invalid axis: " + axis);
 372   
     }
 373   
   }
 374   
 
 375  0
   public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
 376  0
     super.changedUpdate(changes, a, f);
 377  0
     int pos = changes.getOffset();
 378  0
     if (pos <= getStartOffset() && (pos + changes.getLength()) >=
 379   
         getEndOffset()) {
 380  0
       setPropertiesFromAttributes();
 381   
     }
 382   
   }
 383   
 
 384   
   /**
 385   
    * Determines the preferred span for this view along an
 386   
    * axis.
 387   
    *
 388   
    * @param axis may be either <code>View.X_AXIS</code>
 389   
    *         or <code>View.Y_AXIS</code>
 390   
    * @return   the span the view would like to be rendered into >= 0;
 391   
    *           typically the view is told to render into the span
 392   
    *           that is returned, although there is no guarantee;
 393   
    *           the parent may choose to resize or break the view
 394   
    * @exception IllegalArgumentException for an invalid axis type
 395   
    */
 396  0
   public float getPreferredSpan(int axis) {
 397  0
     return super.getPreferredSpan(axis);
 398   
   }
 399   
 
 400   
   /**
 401   
    * Determines the minimum span for this view along an
 402   
    * axis.
 403   
    *
 404   
    * @param axis may be either <code>View.X_AXIS</code>
 405   
    *         or <code>View.Y_AXIS</code>
 406   
    * @return  the span the view would like to be rendered into >= 0;
 407   
    *           typically the view is told to render into the span
 408   
    *           that is returned, although there is no guarantee;
 409   
    *           the parent may choose to resize or break the view
 410   
    * @exception IllegalArgumentException for an invalid axis type
 411   
    */
 412  0
   public float getMinimumSpan(int axis) {
 413  0
     return super.getMinimumSpan(axis);
 414   
   }
 415   
 
 416   
   /**
 417   
    * Determines the maximum span for this view along an
 418   
    * axis.
 419   
    *
 420   
    * @param axis may be either <code>View.X_AXIS</code>
 421   
    *         or <code>View.Y_AXIS</code>
 422   
    * @return   the span the view would like to be rendered into >= 0;
 423   
    *           typically the view is told to render into the span
 424   
    *           that is returned, although there is no guarantee;
 425   
    *           the parent may choose to resize or break the view
 426   
    * @exception IllegalArgumentException for an invalid axis type
 427   
    */
 428  0
   public float getMaximumSpan(int axis) {
 429  0
     return super.getMaximumSpan(axis);
 430   
   }
 431   
 
 432   
   /**
 433   
    * Update any cached values that come from attributes.
 434   
    */
 435  0
   protected void setPropertiesFromAttributes() {
 436   
 
 437   
     // update attributes
 438  0
     StyleSheet sheet = getStyleSheet();
 439  0
     attr = sheet.getViewAttributes(this);
 440   
 
 441   
     // Reset the painter
 442  0
     painter = new SHTMLBoxPainter(attr); //sheet.getBoxPainter(attr);
 443  0
     if (attr != null) {
 444  0
       setInsets((short) painter.getInset(TOP, this),
 445   
                 (short) painter.getInset(LEFT, this),
 446   
                 (short) painter.getInset(BOTTOM, this),
 447   
                 (short) painter.getInset(RIGHT, this));
 448   
     }
 449   
 
 450   
     // Get the width/height
 451  0
     cssWidth = /* (CSS.LengthValue) */ attr.getAttribute(CSS.Attribute.WIDTH);
 452  0
     cssHeight = /* (CSS.LengthValue) */ attr.getAttribute(CSS.Attribute.HEIGHT);
 453   
   }
 454   
 
 455  0
   protected StyleSheet getStyleSheet() {
 456  0
     HTMLDocument doc = (HTMLDocument) getDocument();
 457  0
     return doc.getStyleSheet();
 458   
   }
 459   
 
 460   
   /**
 461   
    * Constrains <code>want</code> to fit in the minimum size specified
 462   
    * by <code>min</code>.
 463   
    */
 464  0
   private void constrainSize(int axis, SizeRequirements want,
 465   
                              SizeRequirements min) {
 466  0
     if (min.minimum > want.minimum) {
 467  0
       want.minimum = want.preferred = min.minimum;
 468  0
       want.maximum = Math.max(want.maximum, min.maximum);
 469   
     }
 470   
   }
 471   
 
 472   
   private Object /*CSS.LengthValue*/ cssWidth;
 473   
   private Object /*CSS.LengthValue*/ cssHeight;
 474   
 }