| 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 |