diff options
Diffstat (limited to 'layout/tables/nsTableColFrame.h')
-rw-r--r-- | layout/tables/nsTableColFrame.h | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h new file mode 100644 index 0000000000..1c56060044 --- /dev/null +++ b/layout/tables/nsTableColFrame.h @@ -0,0 +1,324 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef nsTableColFrame_h__ +#define nsTableColFrame_h__ + +#include "mozilla/Attributes.h" +#include "celldata.h" +#include "nscore.h" +#include "nsContainerFrame.h" +#include "nsTArray.h" +#include "nsTableColGroupFrame.h" +#include "mozilla/WritingModes.h" + +namespace mozilla { +class PresShell; +} // namespace mozilla + +class nsTableColFrame final : public nsSplittableFrame { + public: + NS_DECL_FRAMEARENA_HELPERS(nsTableColFrame) + + enum { + eWIDTH_SOURCE_NONE = 0, // no cell has contributed to the width style + eWIDTH_SOURCE_CELL = 1, // a cell specified a width + eWIDTH_SOURCE_CELL_WITH_SPAN = 2 // a cell implicitly specified a width via + // colspan + }; + + nsTableColType GetColType() const; + void SetColType(nsTableColType aType); + + /** + * instantiate a new instance of nsTableRowFrame. + * + * @param aPresShell the pres shell for this frame + * + * @return the frame that was created + */ + friend nsTableColFrame* NS_NewTableColFrame(mozilla::PresShell* aPresShell, + ComputedStyle* aContext); + + // nsIFrame overrides + void Init(nsIContent* aContent, nsContainerFrame* aParent, + nsIFrame* aPrevInFlow) override { + nsSplittableFrame::Init(aContent, aParent, aPrevInFlow); + if (!aPrevInFlow) { + mWritingMode = GetTableFrame()->GetWritingMode(); + } + } + + /** @see nsIFrame::DidSetComputedStyle */ + void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; + + void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, + const ReflowInput& aReflowInput, + nsReflowStatus& aStatus) override; + + void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists) override; + +#ifdef DEBUG_FRAME_DUMP + nsresult GetFrameName(nsAString& aResult) const override; +#endif + + nsTableColGroupFrame* GetTableColGroupFrame() const { + nsIFrame* parent = GetParent(); + MOZ_ASSERT(parent && parent->IsTableColGroupFrame()); + return static_cast<nsTableColGroupFrame*>(parent); + } + + nsTableFrame* GetTableFrame() const { + return GetTableColGroupFrame()->GetTableFrame(); + } + + int32_t GetColIndex() const; + + void SetColIndex(int32_t aColIndex); + + nsTableColFrame* GetNextCol() const; + + /** return the number of the columns the col represents. always >= 1 */ + int32_t GetSpan(); + + /** convenience method, calls into cellmap */ + int32_t Count() const; + + BCPixelSize GetIStartBorderWidth() const { return mIStartBorderWidth; } + BCPixelSize GetIEndBorderWidth() const { return mIEndBorderWidth; } + void SetIStartBorderWidth(BCPixelSize aWidth) { mIStartBorderWidth = aWidth; } + void SetIEndBorderWidth(BCPixelSize aWidth) { mIEndBorderWidth = aWidth; } + + /** + * Gets inner border widths before collapsing with cell borders + * Caller must get istart border from previous column or from table + * GetContinuousBCBorderWidth will not overwrite aBorder.IStart + * see nsTablePainter about continuous borders + * + * @return outer iend border width (istart inner for next column) + */ + nscoord GetContinuousBCBorderWidth(mozilla::WritingMode aWM, + mozilla::LogicalMargin& aBorder); + /** + * Set full border widths before collapsing with cell borders + * @param aForSide - side to set; only valid for bstart, iend, and bend + */ + void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide, + BCPixelSize aPixelValue); +#ifdef DEBUG + void Dump(int32_t aIndent); +#endif + + /** + * Restore the default values of the intrinsic widths, so that we can + * re-accumulate intrinsic widths from the cells in the column. + */ + void ResetIntrinsics() { + mMinCoord = 0; + mPrefCoord = 0; + mPrefPercent = 0.0f; + mHasSpecifiedCoord = false; + } + + /** + * Restore the default value of the preferred percentage width (the + * only intrinsic width used by FixedTableLayoutStrategy. + */ + void ResetPrefPercent() { mPrefPercent = 0.0f; } + + /** + * Restore the default values of the temporary buffer for + * spanning-cell intrinsic widths (as we process spanning cells). + */ + void ResetSpanIntrinsics() { + mSpanMinCoord = 0; + mSpanPrefCoord = 0; + mSpanPrefPercent = 0.0f; + } + + /** + * Add the widths for a cell or column element, or the contribution of + * the widths from a column-spanning cell: + * @param aMinCoord The minimum intrinsic width + * @param aPrefCoord The preferred intrinsic width or, if there is a + * specified non-percentage width, max(specified width, minimum intrinsic + * width). + * @param aHasSpecifiedCoord Whether there is a specified + * non-percentage width. + * + * Note that the implementation of this functions is a bit tricky + * since mPrefCoord means different things depending on + * whether mHasSpecifiedCoord is true (and likewise for aPrefCoord and + * aHasSpecifiedCoord). If mHasSpecifiedCoord is false, then + * all widths added had aHasSpecifiedCoord false and mPrefCoord is the + * largest of the pref widths. But if mHasSpecifiedCoord is true, + * then mPrefCoord is the largest of (1) the pref widths for cells + * with aHasSpecifiedCoord true and (2) the min widths for cells with + * aHasSpecifiedCoord false. + */ + void AddCoords(nscoord aMinCoord, nscoord aPrefCoord, + bool aHasSpecifiedCoord) { + NS_ASSERTION(aMinCoord <= aPrefCoord, "intrinsic widths out of order"); + + if (aHasSpecifiedCoord && !mHasSpecifiedCoord) { + mPrefCoord = mMinCoord; + mHasSpecifiedCoord = true; + } + if (!aHasSpecifiedCoord && mHasSpecifiedCoord) { + aPrefCoord = aMinCoord; // NOTE: modifying argument + } + + if (aMinCoord > mMinCoord) mMinCoord = aMinCoord; + if (aPrefCoord > mPrefCoord) mPrefCoord = aPrefCoord; + + NS_ASSERTION(mMinCoord <= mPrefCoord, "min larger than pref"); + } + + /** + * Add a percentage width specified on a cell or column element or the + * contribution to this column of a percentage width specified on a + * column-spanning cell. + */ + void AddPrefPercent(float aPrefPercent) { + if (aPrefPercent > mPrefPercent) mPrefPercent = aPrefPercent; + } + + /** + * Get the largest minimum intrinsic width for this column. + */ + nscoord GetMinCoord() const { return mMinCoord; } + /** + * Get the largest preferred width for this column, or, if there were + * any specified non-percentage widths (see GetHasSpecifiedCoord), the + * largest minimum intrinsic width or specified width. + */ + nscoord GetPrefCoord() const { return mPrefCoord; } + /** + * Get whether there were any specified widths contributing to this + * column. + */ + bool GetHasSpecifiedCoord() const { return mHasSpecifiedCoord; } + + /** + * Get the largest specified percentage width contributing to this + * column (returns 0 if there were none). + */ + float GetPrefPercent() const { return mPrefPercent; } + + /** + * Like AddCoords, but into a temporary buffer used for groups of + * column-spanning cells. + */ + void AddSpanCoords(nscoord aSpanMinCoord, nscoord aSpanPrefCoord, + bool aSpanHasSpecifiedCoord) { + NS_ASSERTION(aSpanMinCoord <= aSpanPrefCoord, + "intrinsic widths out of order"); + + if (!aSpanHasSpecifiedCoord && mHasSpecifiedCoord) { + aSpanPrefCoord = aSpanMinCoord; // NOTE: modifying argument + } + + if (aSpanMinCoord > mSpanMinCoord) mSpanMinCoord = aSpanMinCoord; + if (aSpanPrefCoord > mSpanPrefCoord) mSpanPrefCoord = aSpanPrefCoord; + + NS_ASSERTION(mSpanMinCoord <= mSpanPrefCoord, "min larger than pref"); + } + + /* + * Accumulate percentage widths on column spanning cells into + * temporary variables. + */ + void AddSpanPrefPercent(float aSpanPrefPercent) { + if (aSpanPrefPercent > mSpanPrefPercent) + mSpanPrefPercent = aSpanPrefPercent; + } + + /* + * Accumulate the temporary variables for column spanning cells into + * the primary variables. + */ + void AccumulateSpanIntrinsics() { + AddCoords(mSpanMinCoord, mSpanPrefCoord, mHasSpecifiedCoord); + AddPrefPercent(mSpanPrefPercent); + } + + // Used to adjust a column's pref percent so that the table's total + // never exceeeds 100% (by only allowing percentages to be used, + // starting at the first column, until they reach 100%). + void AdjustPrefPercent(float* aTableTotalPercent) { + float allowed = 1.0f - *aTableTotalPercent; + if (mPrefPercent > allowed) mPrefPercent = allowed; + *aTableTotalPercent += mPrefPercent; + } + + // The final width of the column. + void ResetFinalISize() { + mFinalISize = nscoord_MIN; // so we detect that it changed + } + void SetFinalISize(nscoord aFinalISize) { mFinalISize = aFinalISize; } + nscoord GetFinalISize() { return mFinalISize; } + + bool IsFrameOfType(uint32_t aFlags) const override { + if (aFlags & (eSupportsContainLayoutAndPaint | eSupportsAspectRatio)) { + return false; + } + + return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart)); + } + + void InvalidateFrame(uint32_t aDisplayItemKey = 0, + bool aRebuildDisplayItems = true) override; + void InvalidateFrameWithRect(const nsRect& aRect, + uint32_t aDisplayItemKey = 0, + bool aRebuildDisplayItems = true) override; + void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); } + + protected: + explicit nsTableColFrame(ComputedStyle* aStyle, nsPresContext* aPresContext); + ~nsTableColFrame(); + + nscoord mMinCoord; + nscoord mPrefCoord; + nscoord mSpanMinCoord; // XXX... + nscoord mSpanPrefCoord; // XXX... + float mPrefPercent; + float mSpanPrefPercent; // XXX... + // ...XXX the four members marked above could be allocated as part of + // a separate array allocated only during + // BasicTableLayoutStrategy::ComputeColumnIntrinsicISizes (and only + // when colspans were present). + nscoord mFinalISize; + + // the index of the column with respect to the whole table (starting at 0) + // it should never be smaller then the start column index of the parent + // colgroup + uint32_t mColIndex; + + // border width in pixels of the inner half of the border only + BCPixelSize mIStartBorderWidth; + BCPixelSize mIEndBorderWidth; + BCPixelSize mBStartContBorderWidth; + BCPixelSize mIEndContBorderWidth; + BCPixelSize mBEndContBorderWidth; + + bool mHasSpecifiedCoord; +}; + +inline int32_t nsTableColFrame::GetColIndex() const { return mColIndex; } + +inline void nsTableColFrame::SetColIndex(int32_t aColIndex) { + mColIndex = aColIndex; +} + +inline nscoord nsTableColFrame::GetContinuousBCBorderWidth( + mozilla::WritingMode aWM, mozilla::LogicalMargin& aBorder) { + int32_t d2a = PresContext()->AppUnitsPerDevPixel(); + aBorder.BStart(aWM) = BC_BORDER_END_HALF_COORD(d2a, mBStartContBorderWidth); + aBorder.IEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, mIEndContBorderWidth); + aBorder.BEnd(aWM) = BC_BORDER_START_HALF_COORD(d2a, mBEndContBorderWidth); + return BC_BORDER_END_HALF_COORD(d2a, mIEndContBorderWidth); +} + +#endif |