WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Idea patch (if someone wants to look into that): Unfortunately doesn't handle border-spacing properly
distribution.diff (text/plain), 11.17 KB, created by
Julien Chaffraix
on 2012-06-15 17:59:43 PDT
(
hide
)
Description:
Idea patch (if someone wants to look into that): Unfortunately doesn't handle border-spacing properly
Filename:
MIME Type:
Creator:
Julien Chaffraix
Created:
2012-06-15 17:59:43 PDT
Size:
11.17 KB
patch
obsolete
>From 837c69ca68f41eecabb1188c35ea81d3989e2780 Mon Sep 17 00:00:00 2001 >From: Julien Chaffraix <jchaffraix@google.com> >Date: Wed, 21 Mar 2012 11:47:39 -0700 >Subject: [PATCH] Better distribution algorithm. > >Issues: >* does not guarantee that a 50% will be actually 50% (several pixel diff due to border-spacing & border & padding) :( >--- > Source/WebCore/rendering/RenderTable.cpp | 124 ++++++++++++++++++++++- > Source/WebCore/rendering/RenderTable.h | 81 +++++++++++++++ > Source/WebCore/rendering/RenderTableSection.cpp | 8 +- > Source/WebCore/rendering/RenderTableSection.h | 2 + > 4 files changed, 208 insertions(+), 7 deletions(-) > >diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp >index 71364ec..a9a3ece 100644 >--- a/Source/WebCore/rendering/RenderTable.cpp >+++ b/Source/WebCore/rendering/RenderTable.cpp >@@ -48,6 +48,87 @@ namespace WebCore { > > using namespace HTMLNames; > >+// This should be moved in a new file. >+SectionDistributionInfo::SectionDistributionInfo(RenderTableSection* section) >+ : m_section(section) >+ , m_autoRowsCount(0) >+ , m_totalRowPercent(0) >+{ >+ // FIXME: isFixed() is missing isCalculated. >+ if (sectionLogicalHeight().isFixed()) >+ return; >+ >+ for (unsigned row = 0; row < m_section->numRows(); ++row) { >+ Length rowLogicalHeight = m_section->rowLogicalHeight(row); >+ if (rowLogicalHeight.isAuto()) >+ m_autoRowsCount++; >+ else if (rowLogicalHeight.isPercent()) >+ m_totalRowPercent += rowLogicalHeight.percent(); >+ } >+} >+ >+Length SectionDistributionInfo::sectionLogicalHeight() const >+{ >+ return m_section->style()->height(); >+} >+ >+TableDistributionInfo::TableDistributionInfo(const RenderTable* table) >+ : m_autoSizedSectionCount(0) >+ , m_percentSizedSectionCount(0) >+ , m_fixedSizedSectionCount(0) >+ , m_totalPercentSection(0) >+{ >+ // We skip any empty sections as they should not receive any extra logical height to match other browser. >+ for (RenderTableSection* section = table->topSection(); section; section = table->sectionBelow(section, SkipEmptySections)) { >+ SectionDistributionInfo currentSectionInfo(section); >+ m_sectionsInfo.append(currentSectionInfo); >+ if (currentSectionInfo.sectionLogicalHeight().isAuto()) >+ ++m_autoSizedSectionCount; >+ else if (currentSectionInfo.sectionLogicalHeight().isPercent()) { >+ ++m_percentSizedSectionCount; >+ m_totalPercentSection += currentSectionInfo.sectionLogicalHeight().percent(); >+ } else if (currentSectionInfo.sectionLogicalHeight().isFixed()) >+ ++m_fixedSizedSectionCount; >+ } >+ >+ // We are comparing against 100% or the maximum given so that we always fit in our table. >+ // This matches IE9 and our old behavior but not FF that allows the percent >+ // to go over 100% in which case we overflow from our table. >+ m_totalPercentSection = max(m_totalPercentSection, 100.f); >+} >+ >+void TableDistributionInfo::distributeRemainingLogicalHeight(int& extraLogicalHeight) >+{ >+ for (unsigned i = 0; i < m_sectionsInfo.size(); ++i) { >+ int extraLogicalHeightForSection = extraLogicalHeight / (m_sectionsInfo.size() - i); >+ extraLogicalHeight -= m_sectionsInfo[i].section()->distributeExtraLogicalHeightToRows(extraLogicalHeightForSection); >+ } >+} >+ >+template<LengthType type> >+const SectionDistributionInfo* TableSectionDistributionIterator<type>::next() >+{ >+ if (!m_remainingCandidates) >+ return 0; >+ >+ m_remainingCandidates--; >+ >+ for (; m_position < m_tableInfo.m_sectionsInfo.size(); ++m_position) { >+ const SectionDistributionInfo* sectionInfo = &m_tableInfo.m_sectionsInfo[m_position]; >+ if (sectionInfo->sectionLogicalHeight().type() != type) >+ continue; >+ >+ // Ensure that the iterator was increased for the next time next() is called. >+ ++m_position; >+ return sectionInfo; >+ } >+ >+ ASSERT_NOT_REACHED(); >+ return 0; >+} >+ >+ >+ > RenderTable::RenderTable(Node* node) > : RenderBlock(node) > , m_head(0) >@@ -304,9 +385,46 @@ void RenderTable::distributeExtraLogicalHeight(int extraLogicalHeight) > if (extraLogicalHeight <= 0) > return; > >- // FIXME: Distribute the extra logical height between all table sections instead of giving it all to the first one. >- if (RenderTableSection* section = topSection()) >- extraLogicalHeight -= section->distributeExtraLogicalHeightToRows(extraLogicalHeight); >+ TableDistributionInfo tableInfo(this); >+ >+ // 1. Make sure we properly inflate fixed table section. >+ TableSectionDistributionIterator<Fixed> fixedTableSectionsIterator(tableInfo); >+ while (const SectionDistributionInfo* sectionInfo = fixedTableSectionsIterator.next()) { >+ // We only grow if we are below our fixed size. >+ int diffSectionvsRowsLogicaLHeight = sectionInfo->sectionLogicalHeight().value() - sectionInfo->section()->sectionRowsLogicalHeight(); >+ if (diffSectionvsRowsLogicaLHeight <= 0) >+ break; >+ >+ extraLogicalHeight -= sectionInfo->section()->distributeExtraLogicalHeightToRows(diffSectionvsRowsLogicaLHeight); >+ } >+ >+ if (extraLogicalHeight <= 0) >+ return; >+ >+ // 2. Handle percent table sections. >+ TableSectionDistributionIterator<Percent> percentTableSectionsIterator(tableInfo); >+ int consumedLogicalHeight = 0; >+ while (const SectionDistributionInfo* sectionInfo = percentTableSectionsIterator.next()) { >+ int extraLogicalHeightForSection = (extraLogicalHeight * sectionInfo->sectionLogicalHeight().percent()) / tableInfo.totalPercentSection(); >+ consumedLogicalHeight += sectionInfo->section()->distributeExtraLogicalHeightToRows(extraLogicalHeightForSection); >+ } >+ extraLogicalHeight -= consumedLogicalHeight; >+ >+ if (extraLogicalHeight <= 0) >+ return; >+ >+ // 3. Handle auto table sections. >+ TableSectionDistributionIterator<Auto> autoTableSectionsIterator(tableInfo); >+ while (const SectionDistributionInfo* sectionInfo = autoTableSectionsIterator.next()) { >+ int extraLogicalHeightForSection = extraLogicalHeight / (autoTableSectionsIterator.remainingCandidates() + 1); >+ extraLogicalHeight -= sectionInfo->section()->distributeExtraLogicalHeightToRows(extraLogicalHeightForSection); >+ } >+ >+ if (extraLogicalHeight <= 0) >+ return; >+ >+ // 4. Spread the remaining logical height on all the sections. >+ tableInfo.distributeRemainingLogicalHeight(extraLogicalHeight); > > // FIXME: We really would like to enable this ASSERT to ensure that all the extra space has been distributed. > // However our current distribution algorithm does not round properly and thus we can have some remaining height. >diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h >index 5fda200..f21686a 100644 >--- a/Source/WebCore/rendering/RenderTable.h >+++ b/Source/WebCore/rendering/RenderTable.h >@@ -40,6 +40,87 @@ class TableLayout; > > enum SkipEmptySectionsValue { DoNotSkipEmptySections, SkipEmptySections }; > >+ >+// FIXME: Those classes should be moved to a new file. >+class SectionDistributionInfo { >+ //WTF_MAKE_NONCOPYABLE(SectionDistributionInfo); >+public: >+ SectionDistributionInfo(RenderTableSection*); >+ >+ RenderTableSection* section() const { return m_section; } >+ >+ int totalRowPercent() const { return m_totalRowPercent; } >+ unsigned autoRowsCount() const { return m_autoRowsCount; } >+ >+ Length sectionLogicalHeight() const; >+ >+private: >+ RenderTableSection* m_section; >+ >+ unsigned m_autoRowsCount; >+ // Total percent is uncapped so that we can properly handle > 100% over several sections. >+ // FIXME: Length::percent returns a float, our legacy code handled it as |int| so we kept it but it should be fixed. >+ int m_totalRowPercent; >+}; >+ >+template <LengthType> class TableSectionDistributionIterator; >+ >+class TableDistributionInfo { >+ WTF_MAKE_NONCOPYABLE(TableDistributionInfo); >+public: >+ TableDistributionInfo(const RenderTable*); >+ >+ // FIXME: Better naming. >+ float totalPercentSection() const { return m_totalPercentSection; } >+ unsigned autoSizedSectionCount() const { return m_autoSizedSectionCount; } >+ >+ void distributeRemainingLogicalHeight(int& extraLogicalHeight); >+private: >+ template <LengthType> friend class TableSectionDistributionIterator; >+ >+ Vector<SectionDistributionInfo> m_sectionsInfo; >+ >+ unsigned m_autoSizedSectionCount; >+ unsigned m_percentSizedSectionCount; >+ unsigned m_fixedSizedSectionCount; >+ // FIXME: Calculated? >+ >+ float m_totalPercentSection; >+}; >+ >+template<LengthType type> >+class TableSectionDistributionIterator { >+ WTF_MAKE_NONCOPYABLE(TableSectionDistributionIterator); >+public: >+ TableSectionDistributionIterator(const TableDistributionInfo& tableInfo) >+ : m_tableInfo(tableInfo) >+ , m_position(0) >+ { >+ switch (type) { >+ case Fixed: >+ m_remainingCandidates = m_tableInfo.m_fixedSizedSectionCount; >+ break; >+ case Percent: >+ m_remainingCandidates = m_tableInfo.m_percentSizedSectionCount; >+ break; >+ case Auto: >+ m_remainingCandidates = m_tableInfo.m_autoSizedSectionCount; >+ break; >+ default: >+ // Not handled. >+ ASSERT_NOT_REACHED(); >+ } >+ } >+ >+ const SectionDistributionInfo* next(); >+ unsigned remainingCandidates() { return m_remainingCandidates; } >+ >+private: >+ const TableDistributionInfo& m_tableInfo; >+ unsigned m_position; >+ unsigned m_remainingCandidates; >+}; >+ > class RenderTable : public RenderBlock { > public: > explicit RenderTable(Node*); >diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp >index e85e80b..bb2bcc3 100644 >--- a/Source/WebCore/rendering/RenderTableSection.cpp >+++ b/Source/WebCore/rendering/RenderTableSection.cpp >@@ -402,7 +402,7 @@ int RenderTableSection::calcRowLogicalHeight() > > statePusher.pop(); > >- return m_rowPos[m_grid.size()]; >+ return sectionRowsLogicalHeight(); > } > > void RenderTableSection::layout() >@@ -493,14 +493,14 @@ void RenderTableSection::distributeRemainingExtraLogicalHeight(int& extraLogical > int RenderTableSection::distributeExtraLogicalHeightToRows(int extraLogicalHeight) > { > if (!extraLogicalHeight) >- return extraLogicalHeight; >+ return 0; > > unsigned totalRows = m_grid.size(); > if (!totalRows) >- return extraLogicalHeight; >+ return 0; > > if (!m_rowPos[totalRows] && nextSibling()) >- return extraLogicalHeight; >+ return 0; > > unsigned autoRowsCount = 0; > int totalPercent = 0; >diff --git a/Source/WebCore/rendering/RenderTableSection.h b/Source/WebCore/rendering/RenderTableSection.h >index 9c6869d..6ccd693 100644 >--- a/Source/WebCore/rendering/RenderTableSection.h >+++ b/Source/WebCore/rendering/RenderTableSection.h >@@ -73,6 +73,8 @@ public: > > void setCellLogicalWidths(); > int calcRowLogicalHeight(); >+ Length rowLogicalHeight(unsigned row) { return m_grid[row].logicalHeight; } >+ int sectionRowsLogicalHeight() const { return m_rowPos[m_grid.size()]; } > void layoutRows(); > > RenderTable* table() const { return toRenderTable(parent()); } >-- >1.7.7.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 81824
:
133095
| 147928 |
163212