gecko-dev/layout/tables/nsTableColFrame.h

327 строки
11 KiB
C++

/* -*- 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
virtual void Init(nsIContent* aContent, nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override {
nsSplittableFrame::Init(aContent, aParent, aPrevInFlow);
if (!aPrevInFlow) {
mWritingMode = GetTableFrame()->GetWritingMode();
}
}
/** @see nsIFrame::DidSetComputedStyle */
virtual void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override;
virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override;
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) override;
#ifdef DEBUG_FRAME_DUMP
virtual 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; }
virtual bool IsFrameOfType(uint32_t aFlags) const override {
if (aFlags & eSupportsContainLayoutAndPaint) {
return false;
}
return nsSplittableFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
}
virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0,
bool aRebuildDisplayItems = true) override;
virtual void InvalidateFrameWithRect(
const nsRect& aRect, uint32_t aDisplayItemKey = 0,
bool aRebuildDisplayItems = true) override;
virtual 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