OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [text/] [html/] [BlockView.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* BlockView.java --
2
   Copyright (C) 2005 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
import java.util.HashMap;
47
 
48
import javax.swing.SizeRequirements;
49
import javax.swing.event.DocumentEvent;
50
import javax.swing.text.AttributeSet;
51
import javax.swing.text.BoxView;
52
import javax.swing.text.Element;
53
import javax.swing.text.View;
54
import javax.swing.text.ViewFactory;
55
 
56
/**
57
 * @author Lillian Angel <langel@redhat.com>
58
 */
59
public class BlockView extends BoxView
60
{
61
 
62
  /**
63
   * Stores information about child positioning according to the
64
   * CSS attributes position, left, right, top and bottom.
65
   */
66
  private static class PositionInfo
67
  {
68
    // TODO: Use enums when available.
69
 
70
    /**
71
     * Static positioning. This is the default and is thus rarely really
72
     * used.
73
     */
74
    static final int STATIC = 0;
75
 
76
    /**
77
     * Relative positioning. The box is teaked relative to its static
78
     * computed bounds.
79
     */
80
    static final int RELATIVE = 1;
81
 
82
    /**
83
     * Absolute positioning. The box is moved relative to the parent's box.
84
     */
85
    static final int ABSOLUTE = 2;
86
 
87
    /**
88
     * Like ABSOLUTE, with some fixation against the viewport (not yet
89
     * implemented).
90
     */
91
    static final int FIXED = 3;
92
 
93
    /**
94
     * The type according to the constants of this class.
95
     */
96
    int type;
97
 
98
    /**
99
     * The left constraint, null if not set.
100
     */
101
    Length left;
102
 
103
    /**
104
     * The right constraint, null if not set.
105
     */
106
    Length right;
107
 
108
    /**
109
     * The top constraint, null if not set.
110
     */
111
    Length top;
112
 
113
    /**
114
     * The bottom constraint, null if not set.
115
     */
116
    Length bottom;
117
 
118
    /**
119
     * Creates a new PositionInfo object.
120
     *
121
     * @param typ the type to set
122
     * @param l the left constraint
123
     * @param r the right constraint
124
     * @param t the top constraint
125
     * @param b the bottom constraint
126
     */
127
    PositionInfo(int typ, Length l, Length r, Length t, Length b)
128
    {
129
      type = typ;
130
      left = l;
131
      right = r;
132
      top = t;
133
      bottom = b;
134
    }
135
  }
136
 
137
  /**
138
   * The attributes for this view.
139
   */
140
  private AttributeSet attributes;
141
 
142
  /**
143
   * The box painter for this view.
144
   *
145
   * This is package private because the TableView needs access to it.
146
   */
147
  StyleSheet.BoxPainter painter;
148
 
149
  /**
150
   * The width and height as specified in the stylesheet, null if not
151
   * specified. The first value is the X_AXIS, the second the Y_AXIS. You
152
   * can index this directly by the X_AXIS and Y_AXIS constants.
153
   */
154
  private Length[] cssSpans;
155
 
156
  /**
157
   * Stores additional CSS layout information.
158
   */
159
  private HashMap positionInfo;
160
 
161
  /**
162
   * Creates a new view that represents an html box.
163
   * This can be used for a number of elements.
164
   *
165
   * @param elem - the element to create a view for
166
   * @param axis - either View.X_AXIS or View.Y_AXIS
167
   */
168
  public BlockView(Element elem, int axis)
169
  {
170
    super(elem, axis);
171
    cssSpans = new Length[2];
172
    positionInfo = new HashMap();
173
  }
174
 
175
  /**
176
   * Creates the parent view for this. It is called before
177
   * any other methods, if the parent view is working properly.
178
   * Implemented to forward to the superclass and call
179
   * setPropertiesFromAttributes to set the paragraph
180
   * properties.
181
   *
182
   * @param parent - the new parent, or null if the view
183
   * is being removed from a parent it was added to.
184
   */
185
  public void setParent(View parent)
186
  {
187
    super.setParent(parent);
188
 
189
    if (parent != null)
190
      setPropertiesFromAttributes();
191
  }
192
 
193
  /**
194
   * Calculates the requirements along the major axis.
195
   * This is implemented to call the superclass and then
196
   * adjust it if the CSS width or height attribute is specified
197
   * and applicable.
198
   *
199
   * @param axis - the axis to check the requirements for.
200
   * @param r - the SizeRequirements. If null, one is created.
201
   * @return the new SizeRequirements object.
202
   */
203
  protected SizeRequirements calculateMajorAxisRequirements(int axis,
204
                                                            SizeRequirements r)
205
  {
206
    if (r == null)
207
      r = new SizeRequirements();
208
 
209
    if (setCSSSpan(r, axis))
210
      {
211
        // If we have set the span from CSS, then we need to adjust
212
        // the margins.
213
        SizeRequirements parent = super.calculateMajorAxisRequirements(axis,
214
                                                                       null);
215
        int margin = axis == X_AXIS ? getLeftInset() + getRightInset()
216
                                    : getTopInset() + getBottomInset();
217
        r.minimum -= margin;
218
        r.preferred -= margin;
219
        r.maximum -= margin;
220
        constrainSize(axis, r, parent);
221
      }
222
    else
223
      r = super.calculateMajorAxisRequirements(axis, r);
224
    return r;
225
  }
226
 
227
  /**
228
   * Calculates the requirements along the minor axis.
229
   * This is implemented to call the superclass and then
230
   * adjust it if the CSS width or height attribute is specified
231
   * and applicable.
232
   *
233
   * @param axis - the axis to check the requirements for.
234
   * @param r - the SizeRequirements. If null, one is created.
235
   * @return the new SizeRequirements object.
236
   */
237
  protected SizeRequirements calculateMinorAxisRequirements(int axis,
238
                                                            SizeRequirements r)
239
  {
240
    if (r == null)
241
      r = new SizeRequirements();
242
 
243
    if (setCSSSpan(r, axis))
244
      {
245
        // If we have set the span from CSS, then we need to adjust
246
        // the margins.
247
        SizeRequirements parent = super.calculateMinorAxisRequirements(axis,
248
                                                                       null);
249
        int margin = axis == X_AXIS ? getLeftInset() + getRightInset()
250
                                    : getTopInset() + getBottomInset();
251
        r.minimum -= margin;
252
        r.preferred -= margin;
253
        r.maximum -= margin;
254
        constrainSize(axis, r, parent);
255
      }
256
    else
257
      r = super.calculateMinorAxisRequirements(axis, r);
258
 
259
    // Apply text alignment if appropriate.
260
    if (axis == X_AXIS)
261
      {
262
        Object o = getAttributes().getAttribute(CSS.Attribute.TEXT_ALIGN);
263
        if (o != null)
264
          {
265
            String al = o.toString().trim();
266
            if (al.equals("center"))
267
              r.alignment = 0.5f;
268
            else if (al.equals("right"))
269
              r.alignment = 1.0f;
270
            else
271
              r.alignment = 0.0f;
272
          }
273
      }
274
    return r;
275
  }
276
 
277
  /**
278
   * Sets the span on the SizeRequirements object according to the
279
   * according CSS span value, when it is set.
280
   *
281
   * @param r the size requirements
282
   * @param axis the axis
283
   *
284
   * @return <code>true</code> when the CSS span has been set,
285
   *         <code>false</code> otherwise
286
   */
287
  private boolean setCSSSpan(SizeRequirements r, int axis)
288
  {
289
    boolean ret = false;
290
    Length span = cssSpans[axis];
291
    // We can't set relative CSS spans here because we don't know
292
    // yet about the allocated span. Instead we use the view's
293
    // normal requirements.
294
    if (span != null && ! span.isPercentage())
295
      {
296
        r.minimum = (int) span.getValue();
297
        r.preferred = (int) span.getValue();
298
        r.maximum = (int) span.getValue();
299
        ret = true;
300
      }
301
    return ret;
302
  }
303
 
304
  /**
305
   * Constrains the <code>r</code> requirements according to
306
   * <code>min</code>.
307
   *
308
   * @param axis the axis
309
   * @param r the requirements to constrain
310
   * @param min the constraining requirements
311
   */
312
  private void constrainSize(int axis, SizeRequirements r,
313
                             SizeRequirements min)
314
  {
315
    if (min.minimum > r.minimum)
316
      {
317
        r.minimum = min.minimum;
318
        r.preferred = min.minimum;
319
        r.maximum = Math.max(r.maximum, min.maximum);
320
      }
321
  }
322
 
323
  /**
324
   * Lays out the box along the minor axis (the axis that is
325
   * perpendicular to the axis that it represents). The results
326
   * of the layout are placed in the given arrays which are
327
   * the allocations to the children along the minor axis.
328
   *
329
   * @param targetSpan - the total span given to the view, also
330
   * used to layout the children.
331
   * @param axis - the minor axis
332
   * @param offsets - the offsets from the origin of the view for
333
   * all the child views. This is a return value and is filled in by this
334
   * function.
335
   * @param spans - the span of each child view. This is a return value and is
336
   * filled in by this function.
337
   */
338
  protected void layoutMinorAxis(int targetSpan, int axis,
339
                                 int[] offsets, int[] spans)
340
  {
341
    int viewCount = getViewCount();
342
    for (int i = 0; i < viewCount; i++)
343
      {
344
        View view = getView(i);
345
        int min = (int) view.getMinimumSpan(axis);
346
        int max;
347
        // Handle CSS span value of child.
348
        Length length = cssSpans[axis];
349
        if (length != null)
350
          {
351
            min = Math.max((int) length.getValue(targetSpan), min);
352
            max = min;
353
          }
354
        else
355
          max = (int) view.getMaximumSpan(axis);
356
 
357
        if (max < targetSpan)
358
          {
359
            // Align child.
360
            float align = view.getAlignment(axis);
361
            offsets[i] = (int) ((targetSpan - max) * align);
362
            spans[i] = max;
363
          }
364
        else
365
          {
366
            offsets[i] = 0;
367
            spans[i] = Math.max(min, targetSpan);
368
          }
369
 
370
        // Adjust according to CSS position info.
371
        positionView(targetSpan, axis, i, offsets, spans);
372
      }
373
  }
374
 
375
  /**
376
   * Overridden to perform additional CSS layout (absolute/relative
377
   * positioning).
378
   */
379
  protected void layoutMajorAxis(int targetSpan, int axis,
380
                                 int[] offsets, int[] spans)
381
  {
382
    super.layoutMajorAxis(targetSpan, axis, offsets, spans);
383
 
384
    // Adjust according to CSS position info.
385
    int viewCount = getViewCount();
386
    for (int i = 0; i < viewCount; i++)
387
      {
388
        positionView(targetSpan, axis, i, offsets, spans);
389
      }
390
  }
391
 
392
  /**
393
   * Positions a view according to any additional CSS constraints.
394
   *
395
   * @param targetSpan the target span
396
   * @param axis the axis
397
   * @param i the index of the view
398
   * @param offsets the offsets get placed here
399
   * @param spans the spans get placed here
400
   */
401
  private void positionView(int targetSpan, int axis, int i, int[] offsets,
402
                            int[] spans)
403
  {
404
    View view = getView(i);
405
    PositionInfo pos = (PositionInfo) positionInfo.get(view);
406
    if (pos != null)
407
      {
408
        int p0 = -1;
409
        int p1 = -1;
410
        if (axis == X_AXIS)
411
          {
412
            Length l = pos.left;
413
            if (l != null)
414
              p0 = (int) l.getValue(targetSpan);
415
            l = pos.right;
416
            if (l != null)
417
              p1 = (int) l.getValue(targetSpan);
418
          }
419
        else
420
          {
421
            Length l = pos.top;
422
            if (l != null)
423
              p0 = (int) l.getValue(targetSpan);
424
            l = pos.bottom;
425
            if (l != null)
426
              p1 = (int) l.getValue(targetSpan);
427
          }
428
        if (pos.type == PositionInfo.ABSOLUTE
429
            || pos.type == PositionInfo.FIXED)
430
          {
431
            if (p0 != -1)
432
              {
433
                offsets[i] = p0;
434
                if (p1 != -1)
435
                  {
436
                    // Overrides computed width. (Possibly overconstrained
437
                    // when the width attribute was set too.)
438
                    spans[i] = targetSpan - p1 - offsets[i];
439
                  }
440
              }
441
            else if (p1 != -1)
442
              {
443
                // Preserve any computed width.
444
                offsets[i] = targetSpan - p1 - spans[i];
445
              }
446
          }
447
        else if (pos.type == PositionInfo.RELATIVE)
448
          {
449
            if (p0 != -1)
450
              {
451
                offsets[i] += p0;
452
                if (p1 != -1)
453
                  {
454
                    // Overrides computed width. (Possibly overconstrained
455
                    // when the width attribute was set too.)
456
                    spans[i] = spans[i] - p0 - p1 - offsets[i];
457
                  }
458
              }
459
            else if (p1 != -1)
460
              {
461
                // Preserve any computed width.
462
                offsets[i] -= p1;
463
              }
464
          }
465
      }
466
  }
467
 
468
  /**
469
   * Paints using the given graphics configuration and shape.
470
   * This delegates to the css box painter to paint the
471
   * border and background prior to the interior.
472
   *
473
   * @param g - Graphics configuration
474
   * @param a - the Shape to render into.
475
   */
476
  public void paint(Graphics g, Shape a)
477
  {
478
    Rectangle rect = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
479
 
480
    // Debug output. Shows blocks in green rectangles.
481
    // g.setColor(Color.GREEN);
482
    // g.drawRect(rect.x, rect.y, rect.width, rect.height);
483
 
484
    painter.paint(g, rect.x, rect.y, rect.width, rect.height, this);
485
    super.paint(g, a);
486
  }
487
 
488
  /**
489
   * Fetches the attributes to use when painting.
490
   *
491
   * @return the attributes of this model.
492
   */
493
  public AttributeSet getAttributes()
494
  {
495
    if (attributes == null)
496
      attributes = getStyleSheet().getViewAttributes(this);
497
    return attributes;
498
  }
499
 
500
  /**
501
   * Gets the resize weight.
502
   *
503
   * @param axis - the axis to get the resize weight for.
504
   * @return the resize weight.
505
   * @throws IllegalArgumentException - for an invalid axis
506
   */
507
  public int getResizeWeight(int axis) throws IllegalArgumentException
508
  {
509
    // Can't resize the Y_AXIS
510
    if (axis == Y_AXIS)
511
      return 0;
512
    if (axis == X_AXIS)
513
      return 1;
514
    throw new IllegalArgumentException("Invalid Axis");
515
  }
516
 
517
  /**
518
   * Gets the alignment.
519
   *
520
   * @param axis - the axis to get the alignment for.
521
   * @return the alignment.
522
   */
523
  public float getAlignment(int axis)
524
  {
525
    if (axis == X_AXIS)
526
      return super.getAlignment(axis);
527
    if (axis == Y_AXIS)
528
      {
529
        if (getViewCount() == 0)
530
          return 0.0F;
531
        float prefHeight = getPreferredSpan(Y_AXIS);
532
        View first = getView(0);
533
        float firstRowHeight = first.getPreferredSpan(Y_AXIS);
534
        return prefHeight != 0 ? (firstRowHeight * first.getAlignment(Y_AXIS))
535
                                 / prefHeight
536
                               : 0;
537
      }
538
    throw new IllegalArgumentException("Invalid Axis");
539
  }
540
 
541
  /**
542
   * Gives notification from the document that attributes were
543
   * changed in a location that this view is responsible for.
544
   *
545
   * @param ev - the change information
546
   * @param a - the current shape of the view
547
   * @param f - the factory to use to rebuild if the view has children.
548
   */
549
  public void changedUpdate(DocumentEvent ev,
550
                            Shape a, ViewFactory f)
551
  {
552
    super.changedUpdate(ev, a, f);
553
 
554
    // If more elements were added, then need to set the properties for them
555
    int currPos = ev.getOffset();
556
    if (currPos <= getStartOffset()
557
        && (currPos + ev.getLength()) >= getEndOffset())
558
        setPropertiesFromAttributes();
559
  }
560
 
561
  /**
562
   * Determines the preferred span along the axis.
563
   *
564
   * @param axis - the view to get the preferred span for.
565
   * @return the span the view would like to be painted into >=0/
566
   * The view is usually told to paint into the span that is returned,
567
   * although the parent may choose to resize or break the view.
568
   * @throws IllegalArgumentException - for an invalid axis
569
   */
570
  public float getPreferredSpan(int axis) throws IllegalArgumentException
571
  {
572
    if (axis == X_AXIS || axis == Y_AXIS)
573
      return super.getPreferredSpan(axis);
574
    throw new IllegalArgumentException("Invalid Axis");
575
  }
576
 
577
  /**
578
   * Determines the minimum span along the axis.
579
   *
580
   * @param axis - the axis to get the minimum span for.
581
   * @return the span the view would like to be painted into >=0/
582
   * The view is usually told to paint into the span that is returned,
583
   * although the parent may choose to resize or break the view.
584
   * @throws IllegalArgumentException - for an invalid axis
585
   */
586
  public float getMinimumSpan(int axis) throws IllegalArgumentException
587
  {
588
    if (axis == X_AXIS || axis == Y_AXIS)
589
      return super.getMinimumSpan(axis);
590
    throw new IllegalArgumentException("Invalid Axis");
591
  }
592
 
593
  /**
594
   * Determines the maximum span along the axis.
595
   *
596
   * @param axis - the axis to get the maximum span for.
597
   * @return the span the view would like to be painted into >=0/
598
   * The view is usually told to paint into the span that is returned,
599
   * although the parent may choose to resize or break the view.
600
   * @throws IllegalArgumentException - for an invalid axis
601
   */
602
  public float getMaximumSpan(int axis) throws IllegalArgumentException
603
  {
604
    if (axis == X_AXIS || axis == Y_AXIS)
605
      return super.getMaximumSpan(axis);
606
    throw new IllegalArgumentException("Invalid Axis");
607
  }
608
 
609
  /**
610
   * Updates any cached values that come from attributes.
611
   */
612
  protected void setPropertiesFromAttributes()
613
  {
614
    // Fetch attributes.
615
    StyleSheet ss = getStyleSheet();
616
    attributes = ss.getViewAttributes(this);
617
 
618
    // Fetch painter.
619
    painter = ss.getBoxPainter(attributes);
620
 
621
    // Update insets.
622
    if (attributes != null)
623
      {
624
        setInsets((short) painter.getInset(TOP, this),
625
                  (short) painter.getInset(LEFT, this),
626
                  (short) painter.getInset(BOTTOM, this),
627
                  (short) painter.getInset(RIGHT, this));
628
      }
629
 
630
    // Fetch width and height.
631
    float emBase = ss.getEMBase(attributes);
632
    float exBase = ss.getEXBase(attributes);
633
    cssSpans[X_AXIS] = (Length) attributes.getAttribute(CSS.Attribute.WIDTH);
634
    if (cssSpans[X_AXIS] != null)
635
      cssSpans[X_AXIS].setFontBases(emBase, exBase);
636
    cssSpans[Y_AXIS] = (Length) attributes.getAttribute(CSS.Attribute.HEIGHT);
637
    if (cssSpans[Y_AXIS] != null)
638
      cssSpans[Y_AXIS].setFontBases(emBase, exBase);
639
  }
640
 
641
  /**
642
   * Gets the default style sheet.
643
   *
644
   * @return the style sheet
645
   */
646
  protected StyleSheet getStyleSheet()
647
  {
648
    HTMLDocument doc = (HTMLDocument) getDocument();
649
    return doc.getStyleSheet();
650
  }
651
 
652
  /**
653
   * Overridden to fetch additional CSS layout information.
654
   */
655
  public void replace(int offset, int length, View[] views)
656
  {
657
    // First remove unneeded stuff.
658
    for (int i = 0; i < length; i++)
659
      {
660
        View child = getView(i + offset);
661
        positionInfo.remove(child);
662
      }
663
 
664
    // Call super to actually replace the views.
665
    super.replace(offset, length, views);
666
 
667
    // Now fetch the position infos for the new views.
668
    for (int i = 0; i < views.length; i++)
669
      {
670
        fetchLayoutInfo(views[i]);
671
      }
672
  }
673
 
674
  /**
675
   * Fetches and stores the layout info for the specified view.
676
   *
677
   * @param view the view for which the layout info is stored
678
   */
679
  private void fetchLayoutInfo(View view)
680
  {
681
    AttributeSet atts = view.getAttributes();
682
    Object o = atts.getAttribute(CSS.Attribute.POSITION);
683
    if (o != null && o instanceof String && ! o.equals("static"))
684
      {
685
        int type;
686
        if (o.equals("relative"))
687
          type = PositionInfo.RELATIVE;
688
        else if (o.equals("absolute"))
689
          type = PositionInfo.ABSOLUTE;
690
        else if (o.equals("fixed"))
691
          type = PositionInfo.FIXED;
692
        else
693
          type = PositionInfo.STATIC;
694
 
695
        if (type != PositionInfo.STATIC)
696
          {
697
            StyleSheet ss = getStyleSheet();
698
            float emBase = ss.getEMBase(atts);
699
            float exBase = ss.getEXBase(atts);
700
            Length left = (Length) atts.getAttribute(CSS.Attribute.LEFT);
701
            if (left != null)
702
              left.setFontBases(emBase, exBase);
703
            Length right = (Length) atts.getAttribute(CSS.Attribute.RIGHT);
704
            if (right != null)
705
              right.setFontBases(emBase, exBase);
706
            Length top = (Length) atts.getAttribute(CSS.Attribute.TOP);
707
            if (top != null)
708
              top.setFontBases(emBase, exBase);
709
            Length bottom = (Length) atts.getAttribute(CSS.Attribute.BOTTOM);
710
            if (bottom != null)
711
              bottom.setFontBases(emBase, exBase);
712
            if (left != null || right != null || top != null || bottom != null)
713
              {
714
                PositionInfo pos = new PositionInfo(type, left, right, top,
715
                                                    bottom);
716
                positionInfo.put(view, pos);
717
              }
718
          }
719
      }
720
  }
721
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.