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

Subversion Repositories openrisc

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* TableView.java -- A table view for HTML tables
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 java.awt.Graphics;
42
import java.awt.Rectangle;
43
import java.awt.Shape;
44
 
45
import gnu.javax.swing.text.html.css.Length;
46
 
47
import javax.swing.SizeRequirements;
48
import javax.swing.event.DocumentEvent;
49
import javax.swing.text.AttributeSet;
50
import javax.swing.text.Element;
51
import javax.swing.text.StyleConstants;
52
import javax.swing.text.View;
53
import javax.swing.text.ViewFactory;
54
 
55
/**
56
 * A view implementation that renders HTML tables.
57
 *
58
 * This is basically a vertical BoxView that contains the rows of the table
59
 * and the rows are horizontal BoxViews that contain the actual columns.
60
 */
61
class TableView
62
  extends BlockView
63
  implements ViewFactory
64
{
65
 
66
  /**
67
   * Represents a single table row.
68
   */
69
  class RowView
70
    extends BlockView
71
  {
72
    /**
73
     * Has true at column positions where an above row's cell overlaps into
74
     * this row.
75
     */
76
    boolean[] overlap;
77
 
78
    /**
79
     * Stores the row index of this row.
80
     */
81
    int rowIndex;
82
 
83
    /**
84
     * Creates a new RowView.
85
     *
86
     * @param el the element for the row view
87
     */
88
    RowView(Element el)
89
    {
90
      super(el, X_AXIS);
91
    }
92
 
93
    public void replace(int offset, int len, View[] views)
94
    {
95
      gridValid = false;
96
      super.replace(offset, len, views);
97
    }
98
 
99
    /**
100
     * Overridden to make rows not resizable along the Y axis.
101
     */
102
    public float getMaximumSpan(int axis)
103
    {
104
      float span;
105
      if (axis == Y_AXIS)
106
        span = super.getPreferredSpan(axis);
107
      else
108
        span = Integer.MAX_VALUE;
109
      return span;
110
    }
111
 
112
    public float getMinimumSpan(int axis)
113
    {
114
      float span;
115
      if (axis == X_AXIS)
116
        span = totalColumnRequirements.minimum;
117
      else
118
        span = super.getMinimumSpan(axis);
119
      return span;
120
    }
121
 
122
    public float getPreferredSpan(int axis)
123
    {
124
      float span;
125
      if (axis == X_AXIS)
126
        span = totalColumnRequirements.preferred;
127
      else
128
        span = super.getPreferredSpan(axis);
129
      return span;
130
    }
131
 
132
    /**
133
     * Calculates the overall size requirements for the row along the
134
     * major axis. This will be the sum of the column requirements.
135
     */
136
    protected SizeRequirements calculateMajorAxisRequirements(int axis,
137
                                                            SizeRequirements r)
138
    {
139
      if (r == null)
140
        r = new SizeRequirements();
141
      int adjust = (columnRequirements.length + 1) * cellSpacing;
142
      r.minimum = totalColumnRequirements.minimum + adjust;
143
      r.preferred = totalColumnRequirements.preferred + adjust;
144
      r.maximum = totalColumnRequirements.maximum + adjust;
145
      r.alignment = 0.0F;
146
      return r;
147
    }
148
 
149
    /**
150
     * Lays out the columns in this row.
151
     */
152
    protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets,
153
                                   int spans[])
154
    {
155
      super.layoutMinorAxis(targetSpan, axis, offsets, spans);
156
 
157
      // Adjust columns that have rowSpan > 1.
158
      int numCols = getViewCount();
159
      for (int i = 0; i < numCols; i++)
160
        {
161
          View v = getView(i);
162
          if (v instanceof CellView)
163
            {
164
              CellView cell = (CellView) v;
165
              if (cell.rowSpan > 1)
166
                {
167
                  for (int r = 1; r < cell.rowSpan; r++)
168
                    {
169
                      spans[i] += TableView.this.getSpan(axis, rowIndex + r);
170
                      spans[i] += cellSpacing;
171
                    }
172
                }
173
            }
174
        }
175
    }
176
 
177
    /**
178
     * Lays out the columns in this row.
179
     */
180
    protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
181
                                   int spans[])
182
    {
183
      updateGrid();
184
      int realColumn = 0;
185
      int colCount = getViewCount();
186
      for (int i = 0; i < numColumns;)
187
        {
188
          if (! overlap[i] && realColumn < colCount)
189
            {
190
              View v = getView(realColumn);
191
              if (v instanceof CellView)
192
                {
193
                  CellView cv = (CellView) v;
194
                  offsets[realColumn] = columnOffsets[i];
195
                  spans[realColumn] = 0;
196
                  for (int j = 0; j < cv.colSpan; j++, i++)
197
                    {
198
                      spans[realColumn] += columnSpans[i];
199
                      if (j < cv.colSpan - 1)
200
                        spans[realColumn] += cellSpacing;
201
                    }
202
                }
203
              realColumn++;
204
            }
205
          else
206
            {
207
              i++;
208
            }
209
        }
210
    }
211
  }
212
 
213
  /**
214
   * A view that renders HTML table cells (TD and TH tags).
215
   */
216
  class CellView
217
    extends BlockView
218
  {
219
 
220
    /**
221
     * The number of columns that this view spans.
222
     */
223
    int colSpan;
224
 
225
    /**
226
     * The number of rows that this cell spans.
227
     */
228
    int rowSpan;
229
 
230
    /**
231
     * Creates a new CellView for the specified element.
232
     *
233
     * @param el the element for which to create the colspan
234
     */
235
    CellView(Element el)
236
    {
237
      super(el, Y_AXIS);
238
    }
239
 
240
    protected SizeRequirements calculateMajorAxisRequirements(int axis,
241
                                                            SizeRequirements r)
242
    {
243
      r = super.calculateMajorAxisRequirements(axis, r);
244
      r.maximum = Integer.MAX_VALUE;
245
      return r;
246
    }
247
 
248
    /**
249
     * Overridden to fetch the columnSpan attibute.
250
     */
251
    protected void setPropertiesFromAttributes()
252
    {
253
      super.setPropertiesFromAttributes();
254
      colSpan = 1;
255
      AttributeSet atts = getAttributes();
256
      Object o = atts.getAttribute(HTML.Attribute.COLSPAN);
257
      if (o != null)
258
        {
259
          try
260
            {
261
              colSpan = Integer.parseInt(o.toString());
262
            }
263
          catch (NumberFormatException ex)
264
            {
265
              // Couldn't parse the colspan, assume 1.
266
              colSpan = 1;
267
            }
268
        }
269
      rowSpan = 1;
270
      o = atts.getAttribute(HTML.Attribute.ROWSPAN);
271
      if (o != null)
272
        {
273
          try
274
            {
275
              rowSpan = Integer.parseInt(o.toString());
276
            }
277
          catch (NumberFormatException ex)
278
            {
279
              // Couldn't parse the colspan, assume 1.
280
              rowSpan = 1;
281
            }
282
        }
283
    }
284
  }
285
 
286
 
287
  /**
288
   * The attributes of this view.
289
   */
290
  private AttributeSet attributes;
291
 
292
  /**
293
   * The column requirements.
294
   *
295
   * Package private to avoid accessor methods.
296
   */
297
  SizeRequirements[] columnRequirements;
298
 
299
  /**
300
   * The overall requirements across all columns.
301
   *
302
   * Package private to avoid accessor methods.
303
   */
304
  SizeRequirements totalColumnRequirements;
305
 
306
  /**
307
   * The column layout, offsets.
308
   *
309
   * Package private to avoid accessor methods.
310
   */
311
  int[] columnOffsets;
312
 
313
  /**
314
   * The column layout, spans.
315
   *
316
   * Package private to avoid accessor methods.
317
   */
318
  int[] columnSpans;
319
 
320
  /**
321
   * The widths of the columns that have been explicitly specified.
322
   */
323
  Length[] columnWidths;
324
 
325
  /**
326
   * The total number of columns.
327
   */
328
  int numColumns;
329
 
330
  /**
331
   * The table width.
332
   */
333
  private Length width;
334
 
335
  /**
336
   * Indicates if the grid setup is ok.
337
   */
338
  boolean gridValid = false;
339
 
340
  /**
341
   * Additional space that is added _between_ table cells.
342
   *
343
   * This is package private to avoid accessor methods.
344
   */
345
  int cellSpacing;
346
 
347
  /**
348
   * A cached Rectangle object for reuse in paint().
349
   */
350
  private Rectangle tmpRect;
351
 
352
  /**
353
   * Creates a new HTML table view for the specified element.
354
   *
355
   * @param el the element for the table view
356
   */
357
  public TableView(Element el)
358
  {
359
    super(el, Y_AXIS);
360
    totalColumnRequirements = new SizeRequirements();
361
    tmpRect = new Rectangle();
362
  }
363
 
364
  /**
365
   * Implementation of the ViewFactory interface for creating the
366
   * child views correctly.
367
   */
368
  public View create(Element elem)
369
  {
370
    View view = null;
371
    AttributeSet atts = elem.getAttributes();
372
    Object name = atts.getAttribute(StyleConstants.NameAttribute);
373
    AttributeSet pAtts = elem.getParentElement().getAttributes();
374
    Object pName = pAtts.getAttribute(StyleConstants.NameAttribute);
375
 
376
    if (name == HTML.Tag.TR && pName == HTML.Tag.TABLE)
377
      view = new RowView(elem);
378
    else if ((name == HTML.Tag.TD || name == HTML.Tag.TH)
379
             && pName == HTML.Tag.TR)
380
      view = new CellView(elem);
381
    else if (name == HTML.Tag.CAPTION)
382
      view = new ParagraphView(elem);
383
    else
384
      {
385
        // If we haven't mapped the element, then fall back to the standard
386
        // view factory.
387
        View parent = getParent();
388
        if (parent != null)
389
          {
390
            ViewFactory vf = parent.getViewFactory();
391
            if (vf != null)
392
              view = vf.create(elem);
393
          }
394
      }
395
    return view;
396
  }
397
 
398
  /**
399
   * Returns this object as view factory so that we get our TR, TD, TH
400
   * and CAPTION subelements created correctly.
401
   */
402
  public ViewFactory getViewFactory()
403
  {
404
    return this;
405
  }
406
 
407
  /**
408
   * Returns the attributes of this view. This is overridden to provide
409
   * the attributes merged with the CSS stuff.
410
   */
411
  public AttributeSet getAttributes()
412
  {
413
    if (attributes == null)
414
      attributes = getStyleSheet().getViewAttributes(this);
415
    return attributes;
416
  }
417
 
418
  /**
419
   * Returns the stylesheet associated with this view.
420
   *
421
   * @return the stylesheet associated with this view
422
   */
423
  protected StyleSheet getStyleSheet()
424
  {
425
    HTMLDocument doc = (HTMLDocument) getDocument();
426
    return doc.getStyleSheet();
427
  }
428
 
429
  /**
430
   * Overridden to calculate the size requirements according to the
431
   * columns distribution.
432
   */
433
  protected SizeRequirements calculateMinorAxisRequirements(int axis,
434
                                                            SizeRequirements r)
435
  {
436
    updateGrid();
437
    calculateColumnRequirements();
438
 
439
    // Calculate the horizontal requirements according to the superclass.
440
    // This will return the maximum of the row's widths.
441
    r = super.calculateMinorAxisRequirements(axis, r);
442
 
443
    // Try to set the CSS width if it fits.
444
    if (width != null)
445
      {
446
        int w = (int) width.getValue();
447
        if (r.minimum < w)
448
          r.minimum = w;
449
      }
450
 
451
    // Adjust requirements when we have cell spacing.
452
    int adjust = (columnRequirements.length + 1) * cellSpacing;
453
    r.minimum += adjust;
454
    r.preferred += adjust;
455
 
456
    // Apply the alignment.
457
    AttributeSet atts = getAttributes();
458
    Object o = atts.getAttribute(CSS.Attribute.TEXT_ALIGN);
459
    r.alignment = 0.0F;
460
    if (o != null)
461
      {
462
        String al = o.toString();
463
        if (al.equals("left"))
464
          r.alignment = 0.0F;
465
        else if (al.equals("center"))
466
          r.alignment = 0.5F;
467
        else if (al.equals("right"))
468
          r.alignment = 1.0F;
469
      }
470
 
471
    // Make it not resize in the horizontal direction.
472
    r.maximum = r.preferred;
473
    return r;
474
  }
475
 
476
  /**
477
   * Overridden to perform the table layout before calling the super
478
   * implementation.
479
   */
480
  protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets,
481
                                 int[] spans)
482
  {
483
    updateGrid();
484
 
485
    // Mark all rows as invalid along their minor axis to force correct
486
    // layout of multi-row cells.
487
    int n = getViewCount();
488
    for (int i = 0; i < n; i++)
489
      {
490
        View row = getView(i);
491
        if (row instanceof RowView)
492
          ((RowView) row).layoutChanged(axis);
493
      }
494
 
495
    layoutColumns(targetSpan);
496
    super.layoutMinorAxis(targetSpan, axis, offsets, spans);
497
  }
498
 
499
  /**
500
   * Calculates the size requirements for the columns.
501
   */
502
  private void calculateColumnRequirements()
503
  {
504
    int numRows = getViewCount();
505
    totalColumnRequirements.minimum = 0;
506
    totalColumnRequirements.preferred = 0;
507
    totalColumnRequirements.maximum = 0;
508
 
509
    // In this first pass we find out a suitable total width to fit in
510
    // all columns of all rows.
511
    for (int r = 0; r < numRows; r++)
512
      {
513
        View rowView = getView(r);
514
        int numCols;
515
        if (rowView instanceof RowView)
516
          numCols = ((RowView) rowView).getViewCount();
517
        else
518
          numCols = 0;
519
 
520
        // We collect the normal (non-relative) column requirements in the
521
        // total variable and the relative requirements in the relTotal
522
        // variable. In the end we create the maximum of both to get the
523
        // real requirements.
524
        SizeRequirements total = new SizeRequirements();
525
        SizeRequirements relTotal = new SizeRequirements();
526
        float totalPercent = 0.F;
527
        int realCol = 0;
528
        for (int c = 0; c < numCols; c++)
529
          {
530
            View v = rowView.getView(c);
531
            if (v instanceof CellView)
532
              {
533
                CellView cellView = (CellView) v;
534
                int colSpan = cellView.colSpan;
535
                if (colSpan > 1)
536
                  {
537
                    int cellMin = (int) cellView.getMinimumSpan(X_AXIS);
538
                    int cellPref = (int) cellView.getPreferredSpan(X_AXIS);
539
                    int cellMax = (int) cellView.getMaximumSpan(X_AXIS);
540
                    int currentMin = 0;
541
                    int currentPref = 0;
542
                    long currentMax = 0;
543
                    for (int i = 0; i < colSpan; i++)
544
                      {
545
                        SizeRequirements req = columnRequirements[realCol];
546
                        currentMin += req.minimum;
547
                        currentPref += req.preferred;
548
                        currentMax += req.maximum;
549
                      }
550
                    int deltaMin = cellMin - currentMin;
551
                    int deltaPref = cellPref - currentPref;
552
                    int deltaMax = (int) (cellMax - currentMax);
553
                    // Distribute delta.
554
                    for (int i = 0; i < colSpan; i++)
555
                      {
556
                        SizeRequirements req = columnRequirements[realCol];
557
                        if (deltaMin > 0)
558
                          req.minimum += deltaMin / colSpan;
559
                        if (deltaPref > 0)
560
                          req.preferred += deltaPref / colSpan;
561
                        if (deltaMax > 0)
562
                          req.maximum += deltaMax / colSpan;
563
                        if (columnWidths[realCol] == null
564
                            || ! columnWidths[realCol].isPercentage())
565
                          {
566
                            total.minimum += req.minimum;
567
                            total.preferred += req.preferred;
568
                            total.maximum += req.maximum;
569
                          }
570
                        else
571
                          {
572
                            relTotal.minimum =
573
                              Math.max(relTotal.minimum,
574
                                     (int) (req.minimum
575
                                          * columnWidths[realCol].getValue()));
576
                            relTotal.preferred =
577
                              Math.max(relTotal.preferred,
578
                                     (int) (req.preferred
579
                                          * columnWidths[realCol].getValue()));
580
                            relTotal.maximum =
581
                              Math.max(relTotal.maximum,
582
                                     (int) (req.maximum
583
                                          * columnWidths[realCol].getValue()));
584
                            totalPercent += columnWidths[realCol].getValue();
585
                          }
586
                      }
587
                    realCol += colSpan;
588
                  }
589
                else
590
                  {
591
                    // Shortcut for colSpan == 1.
592
                    SizeRequirements req = columnRequirements[realCol];
593
                    req.minimum = Math.max(req.minimum,
594
                                        (int) cellView.getMinimumSpan(X_AXIS));
595
                    req.preferred = Math.max(req.preferred,
596
                                      (int) cellView.getPreferredSpan(X_AXIS));
597
                    req.maximum = Math.max(req.maximum,
598
                                        (int) cellView.getMaximumSpan(X_AXIS));
599
                    if (columnWidths[realCol] == null
600
                        || ! columnWidths[realCol].isPercentage())
601
                      {
602
                        total.minimum += columnRequirements[realCol].minimum;
603
                        total.preferred +=
604
                          columnRequirements[realCol].preferred;
605
                        total.maximum += columnRequirements[realCol].maximum;
606
                      }
607
                    else
608
                      {
609
                        relTotal.minimum =
610
                          Math.max(relTotal.minimum,
611
                                 (int) (req.minimum
612
                                        / columnWidths[c].getValue()));
613
                        relTotal.preferred =
614
                          Math.max(relTotal.preferred,
615
                                 (int) (req.preferred
616
                                        / columnWidths[c].getValue()));
617
                        relTotal.maximum =
618
                          Math.max(relTotal.maximum,
619
                                 (int) (req.maximum
620
                                        / columnWidths[c].getValue()));
621
                        totalPercent += columnWidths[c].getValue();
622
                      }
623
                    realCol += 1;
624
                  }
625
              }
626
          }
627
 
628
        // Update the total requirements as follows:
629
        // 1. Multiply the absolute requirements with 1 - totalPercent. This
630
        //    gives the total requirements based on the wishes of the absolute
631
        //    cells.
632
        // 2. Take the maximum of this value and the total relative
633
        //    requirements. Now we should have enough space for whatever cell
634
        //    in this column.
635
        // 3. Take the maximum of this value and the previous maximum value.
636
        total.minimum *= 1.F / (1.F - totalPercent);
637
        total.preferred *= 1.F / (1.F - totalPercent);
638
        total.maximum *= 1.F / (1.F - totalPercent);
639
 
640
        int rowTotalMin = Math.max(total.minimum, relTotal.minimum);
641
        int rowTotalPref = Math.max(total.preferred, relTotal.preferred);
642
        int rowTotalMax = Math.max(total.maximum, relTotal.maximum);
643
        totalColumnRequirements.minimum =
644
          Math.max(totalColumnRequirements.minimum, rowTotalMin);
645
        totalColumnRequirements.preferred =
646
          Math.max(totalColumnRequirements.preferred, rowTotalPref);
647
        totalColumnRequirements.maximum =
648
          Math.max(totalColumnRequirements.maximum, rowTotalMax);
649
      }
650
 
651
    // Now we know what we want and can fix up the actual relative
652
    // column requirements.
653
    int numCols = columnRequirements.length;
654
    for (int i = 0; i < numCols; i++)
655
      {
656
        if (columnWidths[i] != null)
657
          {
658
            columnRequirements[i].minimum = (int)
659
              columnWidths[i].getValue(totalColumnRequirements.minimum);
660
            columnRequirements[i].preferred = (int)
661
              columnWidths[i].getValue(totalColumnRequirements.preferred);
662
            columnRequirements[i].maximum = (int)
663
              columnWidths[i].getValue(totalColumnRequirements.maximum);
664
          }
665
      }
666
  }
667
 
668
  /**
669
   * Lays out the columns.
670
   *
671
   * @param targetSpan the target span into which the table is laid out
672
   */
673
  private void layoutColumns(int targetSpan)
674
  {
675
    // Set the spans to the preferred sizes. Determine the space
676
    // that we have to adjust the sizes afterwards.
677
    long sumPref = 0;
678
    int n = columnRequirements.length;
679
    for (int i = 0; i < n; i++)
680
      {
681
        SizeRequirements col = columnRequirements[i];
682
        if (columnWidths[i] != null)
683
          columnSpans[i] = (int) columnWidths[i].getValue(targetSpan);
684
        else
685
          columnSpans[i] = col.preferred;
686
        sumPref += columnSpans[i];
687
      }
688
 
689
    // Try to adjust the spans so that we fill the targetSpan.
690
    // For adjustments we have to use the targetSpan minus the cumulated
691
    // cell spacings.
692
    long diff = targetSpan - (n + 1) * cellSpacing - sumPref;
693
    float factor = 0.0F;
694
    int[] diffs = null;
695
    if (diff != 0)
696
      {
697
        long total = 0;
698
        diffs = new int[n];
699
        for (int i = 0; i < n; i++)
700
          {
701
            // Only adjust the width if we haven't set a column width here.
702
            if (columnWidths[i] == null)
703
              {
704
                SizeRequirements col = columnRequirements[i];
705
                int span;
706
                if (diff < 0)
707
                  {
708
                    span = col.minimum;
709
                    diffs[i] = columnSpans[i] - span;
710
                  }
711
                else
712
                  {
713
                    span = col.maximum;
714
                    diffs[i] = span - columnSpans[i];
715
                  }
716
                total += span;
717
              }
718
            else
719
              total += columnSpans[i];
720
          }
721
 
722
        float maxAdjust = Math.abs(total - sumPref);
723
        factor = diff / maxAdjust;
724
        factor = Math.min(factor, 1.0F);
725
        factor = Math.max(factor, -1.0F);
726
      }
727
 
728
    // Actually perform adjustments.
729
    int totalOffs = cellSpacing;
730
    for (int i = 0; i < n; i++)
731
      {
732
        columnOffsets[i] = totalOffs;
733
        if (diff != 0)
734
          {
735
            float adjust = factor * diffs[i];
736
            columnSpans[i] += Math.round(adjust);
737
          }
738
        // Avoid overflow here.
739
        totalOffs = (int) Math.min((long) totalOffs + (long) columnSpans[i]
740
                                   + (long) cellSpacing, Integer.MAX_VALUE);
741
      }
742
  }
743
 
744
  /**
745
   * Updates the arrays that contain the row and column data in response
746
   * to a change to the table structure.
747
   *
748
   * Package private to avoid accessor methods.
749
   */
750
  void updateGrid()
751
  {
752
    if (! gridValid)
753
      {
754
        AttributeSet atts = getAttributes();
755
        StyleSheet ss = getStyleSheet();
756
        float emBase = ss.getEMBase(atts);
757
        float exBase = ss.getEXBase(atts);
758
        int maxColumns = 0;
759
        int numRows = getViewCount();
760
        for (int r = 0; r < numRows; r++)
761
          {
762
            View rowView = getView(r);
763
            int numCols = 0;
764
            if (rowView instanceof RowView)
765
              {
766
                int numCells = ((RowView) rowView).getViewCount();
767
                for (int i = 0; i < numCells; i++)
768
                  {
769
                    View v = rowView.getView(i);
770
                    if (v instanceof CellView)
771
                      numCols += ((CellView) v).colSpan;
772
                  }
773
              }
774
            maxColumns = Math.max(numCols, maxColumns);
775
          }
776
        numColumns = maxColumns;
777
        columnWidths = new Length[maxColumns];
778
        int[] rowSpans = new int[maxColumns];
779
        for (int r = 0; r < numRows; r++)
780
          {
781
            View view = getView(r);
782
            if (view instanceof RowView)
783
              {
784
                RowView rowView = (RowView) view;
785
                rowView.rowIndex = r;
786
                rowView.overlap = new boolean[maxColumns];
787
                int colIndex = 0;
788
                int colCount = rowView.getViewCount();
789
                for (int c = 0; c < maxColumns;)
790
                  {
791
                    if (rowSpans[c] > 0)
792
                      {
793
                        rowSpans[c]--;
794
                        rowView.overlap[c] = true;
795
                        c++;
796
                      }
797
                    else if (colIndex < colCount)
798
                      {
799
                        View v = rowView.getView(colIndex);
800
                        colIndex++;
801
                        if (v instanceof CellView)
802
                          {
803
                            CellView cv = (CellView) v;
804
                            Object o =
805
                              cv.getAttributes().getAttribute(CSS.Attribute.WIDTH);
806
                            if (o != null && columnWidths[c] == null
807
                                && o instanceof Length)
808
                              {
809
                                columnWidths[c]= (Length) o;
810
                                columnWidths[c].setFontBases(emBase, exBase);
811
                              }
812
                            int rs = cv.rowSpan - 1;
813
                            for (int col = cv.colSpan - 1; col >= 0; col--)
814
                              {
815
                                rowSpans[c] = rs;
816
                                c++;
817
                              }
818
                          }
819
                      }
820
                    else
821
                      {
822
                        c++;
823
                      }
824
                  }
825
              }
826
          }
827
        columnRequirements = new SizeRequirements[maxColumns];
828
        for (int i = 0; i < maxColumns; i++)
829
          columnRequirements[i] = new SizeRequirements();
830
        columnOffsets = new int[maxColumns];
831
        columnSpans = new int[maxColumns];
832
 
833
        gridValid = true;
834
      }
835
  }
836
 
837
  /**
838
   * Overridden to restrict the table width to the preferred size.
839
   */
840
  public float getMaximumSpan(int axis)
841
  {
842
    float span;
843
    if (axis == X_AXIS)
844
      span = super.getPreferredSpan(axis);
845
    else
846
      span = super.getMaximumSpan(axis);
847
    return span;
848
  }
849
 
850
  /**
851
   * Overridden to fetch the CSS attributes when view gets connected.
852
   */
853
  public void setParent(View parent)
854
  {
855
    super.setParent(parent);
856
    if (parent != null)
857
      setPropertiesFromAttributes();
858
  }
859
 
860
  /**
861
   * Fetches CSS and HTML layout attributes.
862
   */
863
  protected void setPropertiesFromAttributes()
864
  {
865
    super.setPropertiesFromAttributes();
866
 
867
    // Fetch and parse cell spacing.
868
    AttributeSet atts = getAttributes();
869
    StyleSheet ss = getStyleSheet();
870
    float emBase = ss.getEMBase(atts);
871
    float exBase = ss.getEXBase(atts);
872
    Object o = atts.getAttribute(CSS.Attribute.BORDER_SPACING);
873
    if (o != null && o instanceof Length)
874
      {
875
        Length l = (Length) o;
876
        l.setFontBases(emBase, exBase);
877
        cellSpacing = (int) l.getValue();
878
      }
879
    o = atts.getAttribute(CSS.Attribute.WIDTH);
880
    if (o != null && o instanceof Length)
881
      {
882
        width = (Length) o;
883
        width.setFontBases(emBase, exBase);
884
      }
885
  }
886
 
887
  /**
888
   * Overridden to adjust for cellSpacing.
889
   */
890
  protected SizeRequirements calculateMajorAxisRequirements(int axis,
891
                                                            SizeRequirements r)
892
  {
893
    r = super.calculateMajorAxisRequirements(axis, r);
894
    int adjust = (getViewCount() + 1) * cellSpacing;
895
    r.minimum += adjust;
896
    r.preferred += adjust;
897
    r.maximum += adjust;
898
    return r;
899
  }
900
 
901
  /**
902
   * Overridden to adjust for cellSpacing.
903
   */
904
  protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets,
905
                                 int spans[])
906
  {
907
    // Mark all rows as invalid along their minor axis to force correct
908
    // layout of multi-row cells.
909
    int n = getViewCount();
910
    for (int i = 0; i < n; i++)
911
      {
912
        View row = getView(i);
913
        if (row instanceof RowView)
914
          ((RowView) row).layoutChanged(axis);
915
      }
916
 
917
    int adjust = (getViewCount() + 1) * cellSpacing;
918
    super.layoutMajorAxis(targetSpan - adjust, axis, offsets, spans);
919
    for (int i = 0; i < offsets.length; i++)
920
      {
921
        offsets[i] += (i + 1) * cellSpacing;
922
      }
923
  }
924
 
925
  /**
926
   * Overridden to replace view factory with this one.
927
   */
928
  public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f)
929
  {
930
    super.insertUpdate(e, a, this);
931
  }
932
 
933
  /**
934
   * Overridden to replace view factory with this one.
935
   */
936
  public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f)
937
  {
938
    super.removeUpdate(e, a, this);
939
  }
940
 
941
  /**
942
   * Overridden to replace view factory with this one.
943
   */
944
  public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f)
945
  {
946
    super.changedUpdate(e, a, this);
947
  }
948
 
949
  public void replace(int offset, int len, View[] views)
950
  {
951
    gridValid = false;
952
    super.replace(offset, len, views);
953
  }
954
 
955
  /**
956
   * We can't use the super class's paint() method because it might cut
957
   * off multi-row children. Instead we trigger painting for all rows
958
   * and let the rows sort out what to paint and what not.
959
   */
960
  public void paint(Graphics g, Shape a)
961
  {
962
    Rectangle rect = a instanceof Rectangle ? (Rectangle) a : a.getBounds();
963
    painter.paint(g, rect.x, rect.y, rect.width, rect.height, this);
964
    int nRows = getViewCount();
965
    Rectangle inside = getInsideAllocation(a);
966
    for (int r = 0; r < nRows; r++)
967
      {
968
        tmpRect.setBounds(inside);
969
        childAllocation(r, tmpRect);
970
        paintChild(g, tmpRect, r);
971
      }
972
  }
973
 
974
}

powered by: WebSVN 2.1.0

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