OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
3 * (C) 1997 Torben Weis (weis@kde.org) | 3 * (C) 1997 Torben Weis (weis@kde.org) |
4 * (C) 1998 Waldo Bastian (bastian@kde.org) | 4 * (C) 1998 Waldo Bastian (bastian@kde.org) |
5 * (C) 1999 Lars Knoll (knoll@kde.org) | 5 * (C) 1999 Lars Knoll (knoll@kde.org) |
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
7 * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010 Apple Inc. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010 Apple Inc. |
8 * All rights reserved. | 8 * All rights reserved. |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // | 120 // |
121 // The following example would have 2 entries [ 3, 2 ] in effectiveColumns(): | 121 // The following example would have 2 entries [ 3, 2 ] in effectiveColumns(): |
122 // <table> | 122 // <table> |
123 // <tr> | 123 // <tr> |
124 // <td colspan="3"></td> | 124 // <td colspan="3"></td> |
125 // <td colspan="2"></td> | 125 // <td colspan="2"></td> |
126 // </tr> | 126 // </tr> |
127 // </table> | 127 // </table> |
128 // | 128 // |
129 // Columns can be split if we add a row with a different colspan structure. | 129 // Columns can be split if we add a row with a different colspan structure. |
130 // See splitEffectiveColumn() and appendEffectiveColumn() for operations | 130 // See SplitEffectiveColumn() and AppendEffectiveColumn() for operations |
131 // over effectiveColumns() and effectiveColumnPositions(). | 131 // over EffectiveColumns() and EffectiveColumnPositions(). |
132 // | 132 // |
133 // See absoluteColumnToEffectiveColumn() for converting an absolute column | 133 // See absoluteColumnToEffectiveColumn() for converting an absolute column |
134 // index into an index into effectiveColumns() and effectiveColumnPositions(). | 134 // index into an index into effectiveColumns() and effectiveColumnPositions(). |
135 | 135 |
136 class CORE_EXPORT LayoutTable final : public LayoutBlock { | 136 class CORE_EXPORT LayoutTable final : public LayoutBlock { |
137 public: | 137 public: |
138 explicit LayoutTable(Element*); | 138 explicit LayoutTable(Element*); |
139 ~LayoutTable() override; | 139 ~LayoutTable() override; |
140 | 140 |
141 // Per CSS 3 writing-mode: "The first and second values of the | 141 // Per CSS 3 writing-mode: "The first and second values of the |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 // 'border-spacing' only applies to separate borders (see 17.6.1 The | 349 // 'border-spacing' only applies to separate borders (see 17.6.1 The |
350 // separated borders model). | 350 // separated borders model). |
351 return BorderStart() + BorderEnd() + | 351 return BorderStart() + BorderEnd() + |
352 (ShouldCollapseBorders() ? LayoutUnit() | 352 (ShouldCollapseBorders() ? LayoutUnit() |
353 : (PaddingStart() + PaddingEnd() + | 353 : (PaddingStart() + PaddingEnd() + |
354 BorderSpacingInRowDirection())); | 354 BorderSpacingInRowDirection())); |
355 } | 355 } |
356 | 356 |
357 // Return the first column or column-group. | 357 // Return the first column or column-group. |
358 LayoutTableCol* FirstColumn() const; | 358 LayoutTableCol* FirstColumn() const; |
| 359 LayoutTableCol* FirstInnermostColumn() const; |
359 | 360 |
360 struct ColAndColGroup { | 361 struct ColAndColGroup { |
361 ColAndColGroup() | 362 ColAndColGroup() |
362 : col(nullptr), | 363 : col(nullptr), |
363 colgroup(nullptr), | 364 colgroup(nullptr), |
364 adjoins_start_border_of_col_group(false), | 365 adjoins_start_border_of_col_group(false), |
365 adjoins_end_border_of_col_group(false) {} | 366 adjoins_end_border_of_col_group(false) {} |
366 LayoutTableCol* col; | 367 LayoutTableCol* col; |
367 LayoutTableCol* colgroup; | 368 LayoutTableCol* colgroup; |
368 bool adjoins_start_border_of_col_group; | 369 bool adjoins_start_border_of_col_group; |
369 bool adjoins_end_border_of_col_group; | 370 bool adjoins_end_border_of_col_group; |
370 LayoutTableCol* InnermostColOrColGroup() { return col ? col : colgroup; } | 371 LayoutTableCol* InnermostColOrColGroup() { return col ? col : colgroup; } |
371 }; | 372 }; |
372 ColAndColGroup ColElementAtAbsoluteColumn( | 373 ColAndColGroup ColAndColGroupAtEffectiveColumn( |
373 unsigned absolute_column_index) const { | 374 unsigned effective_column) const { |
374 // The common case is to not have col/colgroup elements, make that case | 375 if (!cols_at_effective_columns_valid_) |
375 // fast. | 376 UpdateColsAtEffectiveColumns(); |
376 if (!has_col_elements_) | 377 if (!cols_at_effective_columns_ || |
| 378 effective_column >= cols_at_effective_columns_->size()) |
377 return ColAndColGroup(); | 379 return ColAndColGroup(); |
378 return SlowColElementAtAbsoluteColumn(absolute_column_index); | 380 return cols_at_effective_columns_->at(effective_column); |
379 } | 381 } |
380 bool HasColElements() const { return has_col_elements_; } | 382 bool HasColOrColGroups() const { |
| 383 if (!cols_at_effective_columns_valid_) |
| 384 UpdateColsAtEffectiveColumns(); |
| 385 return !!cols_at_effective_columns_; |
| 386 } |
381 | 387 |
382 bool NeedsSectionRecalc() const { return needs_section_recalc_; } | 388 bool NeedsSectionRecalc() const { return needs_section_recalc_; } |
383 void SetNeedsSectionRecalc() { | 389 void SetNeedsSectionRecalc() { |
384 if (DocumentBeingDestroyed()) | 390 if (DocumentBeingDestroyed()) |
385 return; | 391 return; |
386 // For all we know, sections may have been deleted at this point. Don't | 392 // For all we know, sections may have been deleted at this point. Don't |
387 // keep pointers dangling around. | 393 // keep pointers dangling around. |
388 head_ = nullptr; | 394 head_ = nullptr; |
389 foot_ = nullptr; | 395 foot_ = nullptr; |
390 first_body_ = nullptr; | 396 first_body_ = nullptr; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 HitTestAction) override; | 500 HitTestAction) override; |
495 | 501 |
496 int BaselinePosition( | 502 int BaselinePosition( |
497 FontBaseline, | 503 FontBaseline, |
498 bool first_line, | 504 bool first_line, |
499 LineDirectionMode, | 505 LineDirectionMode, |
500 LinePositionMode = kPositionOnContainingLine) const override; | 506 LinePositionMode = kPositionOnContainingLine) const override; |
501 int FirstLineBoxBaseline() const override; | 507 int FirstLineBoxBaseline() const override; |
502 int InlineBlockBaseline(LineDirectionMode) const override; | 508 int InlineBlockBaseline(LineDirectionMode) const override; |
503 | 509 |
504 ColAndColGroup SlowColElementAtAbsoluteColumn(unsigned col) const; | 510 void UpdateColsAtEffectiveColumns() const; |
505 | 511 void InvalidateColsAtEffectiveColumns() const; |
506 void UpdateColumnCache() const; | |
507 void InvalidateCachedColumns(); | |
508 | 512 |
509 void UpdateLogicalWidth() override; | 513 void UpdateLogicalWidth() override; |
510 | 514 |
511 LayoutUnit ConvertStyleLogicalWidthToComputedWidth( | 515 LayoutUnit ConvertStyleLogicalWidthToComputedWidth( |
512 const Length& style_logical_width, | 516 const Length& style_logical_width, |
513 LayoutUnit available_width) const; | 517 LayoutUnit available_width) const; |
514 LayoutUnit ConvertStyleLogicalHeightToComputedHeight( | 518 LayoutUnit ConvertStyleLogicalHeightToComputedHeight( |
515 const Length& style_logical_height) const; | 519 const Length& style_logical_height) const; |
516 | 520 |
517 LayoutRect OverflowClipRect( | 521 LayoutRect OverflowClipRect( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 // Holds the logical layout positions of effective columns, and the last item | 554 // Holds the logical layout positions of effective columns, and the last item |
551 // (whose index is numEffectiveColumns()) holds the position of the imaginary | 555 // (whose index is numEffectiveColumns()) holds the position of the imaginary |
552 // column after the last column. | 556 // column after the last column. |
553 // Because of the last item, m_effectiveColumnPositions.size() is always | 557 // Because of the last item, m_effectiveColumnPositions.size() is always |
554 // numEffectiveColumns() + 1. | 558 // numEffectiveColumns() + 1. |
555 mutable Vector<int> effective_column_positions_; | 559 mutable Vector<int> effective_column_positions_; |
556 | 560 |
557 // The captions associated with this object. | 561 // The captions associated with this object. |
558 mutable Vector<LayoutTableCaption*> captions_; | 562 mutable Vector<LayoutTableCaption*> captions_; |
559 | 563 |
560 // Holds pointers to LayoutTableCol objects for <col>s and <colgroup>s under | 564 // Stores cached ColAndColGroup structures at effective columns. |
561 // this table. | 565 mutable std::unique_ptr<Vector<ColAndColGroup>> cols_at_effective_columns_; |
562 // There is no direct relationship between the size of and index into this | |
563 // vector and those of m_effectiveColumns because they hold different things. | |
564 mutable Vector<LayoutTableCol*> column_layout_objects_; | |
565 | 566 |
566 mutable LayoutTableSection* head_; | 567 mutable LayoutTableSection* head_; |
567 mutable LayoutTableSection* foot_; | 568 mutable LayoutTableSection* foot_; |
568 mutable LayoutTableSection* first_body_; | 569 mutable LayoutTableSection* first_body_; |
569 | 570 |
570 // The layout algorithm used by this table. | 571 // The layout algorithm used by this table. |
571 // | 572 // |
572 // CSS 2.1 defines 2 types of table layouts toggled with 'table-layout': | 573 // CSS 2.1 defines 2 types of table layouts toggled with 'table-layout': |
573 // fixed (TableLayoutAlgorithmFixed) and auto (TableLayoutAlgorithmAuto). | 574 // fixed (TableLayoutAlgorithmFixed) and auto (TableLayoutAlgorithmAuto). |
574 // See http://www.w3.org/TR/CSS21/tables.html#width-layout. | 575 // See http://www.w3.org/TR/CSS21/tables.html#width-layout. |
575 // | 576 // |
576 // The layout algorithm is delegated to TableLayoutAlgorithm. This enables | 577 // The layout algorithm is delegated to TableLayoutAlgorithm. This enables |
577 // changing 'table-layout' without having to reattach the <table>. | 578 // changing 'table-layout' without having to reattach the <table>. |
578 // | 579 // |
579 // As the algorithm is dependent on the style, this field is nullptr before | 580 // As the algorithm is dependent on the style, this field is nullptr before |
580 // the first style is applied in styleDidChange(). | 581 // the first style is applied in styleDidChange(). |
581 std::unique_ptr<TableLayoutAlgorithm> table_layout_; | 582 std::unique_ptr<TableLayoutAlgorithm> table_layout_; |
582 | 583 |
583 // A sorted list of all unique border values that we want to paint. | 584 // A sorted list of all unique border values that we want to paint. |
584 // | 585 // |
585 // Collapsed borders are SUPER EXPENSIVE to compute. The reason is that we | 586 // Collapsed borders are SUPER EXPENSIVE to compute. The reason is that we |
586 // need to compare a cells border against all the adjoining cells, rows, | 587 // need to compare a cells border against all the adjoining cells, rows, |
587 // row groups, column, column groups and table. Thus we cache them in this | 588 // row groups, column, column groups and table. Thus we cache them in this |
588 // field. | 589 // field. |
589 CollapsedBorderValues collapsed_borders_; | 590 CollapsedBorderValues collapsed_borders_; |
590 bool collapsed_borders_valid_ : 1; | 591 bool collapsed_borders_valid_ : 1; |
591 bool needs_invalidate_collapsed_borders_for_all_cells_ : 1; | 592 bool needs_invalidate_collapsed_borders_for_all_cells_ : 1; |
592 | 593 |
593 mutable bool has_col_elements_ : 1; | |
594 mutable bool needs_section_recalc_ : 1; | 594 mutable bool needs_section_recalc_ : 1; |
595 | 595 |
596 bool column_logical_width_changed_ : 1; | 596 bool column_logical_width_changed_ : 1; |
597 mutable bool column_layout_objects_valid_ : 1; | 597 mutable bool cols_at_effective_columns_valid_ : 1; |
598 mutable unsigned no_cell_colspan_at_least_; | 598 mutable unsigned no_cell_colspan_at_least_; |
599 unsigned CalcNoCellColspanAtLeast() const { | 599 unsigned CalcNoCellColspanAtLeast() const { |
600 for (unsigned c = 0; c < NumEffectiveColumns(); c++) { | 600 for (unsigned c = 0; c < NumEffectiveColumns(); c++) { |
601 if (effective_columns_[c].span > 1) | 601 if (effective_columns_[c].span > 1) |
602 return c; | 602 return c; |
603 } | 603 } |
604 return NumEffectiveColumns(); | 604 return NumEffectiveColumns(); |
605 } | 605 } |
606 | 606 |
607 short h_spacing_; | 607 short h_spacing_; |
(...skipping 13 matching lines...) Expand all Loading... |
621 if (first_body_) | 621 if (first_body_) |
622 return first_body_; | 622 return first_body_; |
623 return foot_; | 623 return foot_; |
624 } | 624 } |
625 | 625 |
626 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTable, IsTable()); | 626 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutTable, IsTable()); |
627 | 627 |
628 } // namespace blink | 628 } // namespace blink |
629 | 629 |
630 #endif // LayoutTable_h | 630 #endif // LayoutTable_h |
OLD | NEW |