123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /* -*- 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 nsTableCellFrame_h__
- #define nsTableCellFrame_h__
- #include "mozilla/Attributes.h"
- #include "celldata.h"
- #include "imgIContainer.h"
- #include "nsITableCellLayout.h"
- #include "nscore.h"
- #include "nsContainerFrame.h"
- #include "nsStyleContext.h"
- #include "nsIPercentBSizeObserver.h"
- #include "nsGkAtoms.h"
- #include "nsLayoutUtils.h"
- #include "nsTArray.h"
- #include "nsTableRowFrame.h"
- #include "mozilla/WritingModes.h"
- /**
- * nsTableCellFrame
- * data structure to maintain information about a single table cell's frame
- *
- * NOTE: frames are not ref counted. We expose addref and release here
- * so we can change that decsion in the future. Users of nsITableCellLayout
- * should refcount correctly as if this object is being ref counted, though
- * no actual support is under the hood.
- *
- * @author sclark
- */
- class nsTableCellFrame : public nsContainerFrame,
- public nsITableCellLayout,
- public nsIPercentBSizeObserver
- {
- typedef mozilla::gfx::DrawTarget DrawTarget;
- typedef mozilla::image::DrawResult DrawResult;
- protected:
- typedef mozilla::WritingMode WritingMode;
- typedef mozilla::LogicalSide LogicalSide;
- typedef mozilla::LogicalMargin LogicalMargin;
- public:
- NS_DECL_QUERYFRAME_TARGET(nsTableCellFrame)
- NS_DECL_QUERYFRAME
- NS_DECL_FRAMEARENA_HELPERS
- // default constructor supplied by the compiler
- nsTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame);
- ~nsTableCellFrame();
- nsTableRowFrame* GetTableRowFrame() const
- {
- nsIFrame* parent = GetParent();
- MOZ_ASSERT(parent && parent->GetType() == nsGkAtoms::tableRowFrame);
- return static_cast<nsTableRowFrame*>(parent);
- }
- nsTableFrame* GetTableFrame() const
- {
- return GetTableRowFrame()->GetTableFrame();
- }
- virtual void Init(nsIContent* aContent,
- nsContainerFrame* aParent,
- nsIFrame* aPrevInFlow) override;
- virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
- #ifdef ACCESSIBILITY
- virtual mozilla::a11y::AccType AccessibleType() override;
- #endif
- virtual nsresult AttributeChanged(int32_t aNameSpaceID,
- nsIAtom* aAttribute,
- int32_t aModType) override;
- /** @see nsIFrame::DidSetStyleContext */
- virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
- #ifdef DEBUG
- // Our anonymous block frame is the content insertion frame so these
- // methods should never be called:
- virtual void AppendFrames(ChildListID aListID,
- nsFrameList& aFrameList) override;
- virtual void InsertFrames(ChildListID aListID,
- nsIFrame* aPrevFrame,
- nsFrameList& aFrameList) override;
- virtual void RemoveFrame(ChildListID aListID,
- nsIFrame* aOldFrame) override;
- #endif
- virtual nsContainerFrame* GetContentInsertionFrame() override {
- return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
- }
- virtual nsMargin GetUsedMargin() const override;
- virtual void NotifyPercentBSize(const ReflowInput& aReflowInput) override;
- virtual bool NeedsToObserve(const ReflowInput& aReflowInput) override;
- virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
- const nsDisplayListSet& aLists) override;
- virtual nsresult ProcessBorders(nsTableFrame* aFrame,
- nsDisplayListBuilder* aBuilder,
- const nsDisplayListSet& aLists);
- virtual nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
- virtual nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
- IntrinsicISizeOffsetData IntrinsicISizeOffsets(nscoord aPercentageBasis =
- NS_UNCONSTRAINEDSIZE) override;
- virtual void Reflow(nsPresContext* aPresContext,
- ReflowOutput& aDesiredSize,
- const ReflowInput& aReflowInput,
- nsReflowStatus& aStatus) override;
- /**
- * Get the "type" of the frame
- *
- * @see nsLayoutAtoms::tableCellFrame
- */
- virtual nsIAtom* GetType() const override;
- #ifdef DEBUG_FRAME_DUMP
- virtual nsresult GetFrameName(nsAString& aResult) const override;
- #endif
- // Although the spec doesn't say that writing-mode is not applied to
- // table-cells, we still override this method here because we want to
- // make effective writing mode of table structure frames consistent
- // within a table. The content inside table cells is reflowed by an
- // anonymous block, hence their writing mode is not affected.
- virtual mozilla::WritingMode GetWritingMode() const override
- { return GetTableFrame()->GetWritingMode(); }
- void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent);
- /*
- * Get the value of vertical-align adjusted for CSS 2's rules for a
- * table cell, which means the result is always
- * NS_STYLE_VERTICAL_ALIGN_{TOP,MIDDLE,BOTTOM,BASELINE}.
- */
- virtual uint8_t GetVerticalAlign() const;
- bool HasVerticalAlignBaseline() const {
- return GetVerticalAlign() == NS_STYLE_VERTICAL_ALIGN_BASELINE;
- }
- bool CellHasVisibleContent(nscoord aBSize,
- nsTableFrame* tableFrame,
- nsIFrame* kidFrame);
- /**
- * Get the first-line baseline of the cell relative to its block-start border
- * edge, as if the cell were vertically aligned to the top of the row.
- */
- nscoord GetCellBaseline() const;
- /**
- * return the cell's specified row span. this is what was specified in the
- * content model or in the style info, and is always >= 0.
- * to get the effective row span (the actual value that applies), use GetEffectiveRowSpan()
- * @see nsTableFrame::GetEffectiveRowSpan()
- */
- int32_t GetRowSpan();
- // there is no set row index because row index depends on the cell's parent row only
- /*---------------- nsITableCellLayout methods ------------------------*/
- /**
- * return the cell's starting row index (starting at 0 for the first row).
- * for continued cell frames the row index is that of the cell's first-in-flow
- * and the column index (starting at 0 for the first column
- */
- NS_IMETHOD GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex) override;
- /** return the mapped cell's row index (starting at 0 for the first row) */
- uint32_t RowIndex() const
- {
- return static_cast<nsTableRowFrame*>(GetParent())->GetRowIndex();
- }
- /**
- * return the cell's specified col span. this is what was specified in the
- * content model or in the style info, and is always >= 1.
- * to get the effective col span (the actual value that applies), use GetEffectiveColSpan()
- * @see nsTableFrame::GetEffectiveColSpan()
- */
- int32_t GetColSpan();
- /** return the cell's column index (starting at 0 for the first column) */
- uint32_t ColIndex() const
- {
- // NOTE: We copy this from previous continuations, and we don't ever have
- // dynamic updates when tables split, so our mColIndex always matches our
- // first continuation's.
- MOZ_ASSERT(static_cast<nsTableCellFrame*>(FirstContinuation())->mColIndex ==
- mColIndex,
- "mColIndex out of sync with first continuation");
- return mColIndex;
- }
- void SetColIndex(int32_t aColIndex);
- /** return the available isize given to this frame during its last reflow */
- inline nscoord GetPriorAvailISize();
- /** set the available isize given to this frame during its last reflow */
- inline void SetPriorAvailISize(nscoord aPriorAvailISize);
- /** return the desired size returned by this frame during its last reflow */
- inline mozilla::LogicalSize GetDesiredSize();
- /** set the desired size returned by this frame during its last reflow */
- inline void SetDesiredSize(const ReflowOutput & aDesiredSize);
- bool GetContentEmpty() const;
- void SetContentEmpty(bool aContentEmpty);
- bool HasPctOverBSize();
- void SetHasPctOverBSize(bool aValue);
- nsTableCellFrame* GetNextCell() const
- {
- nsIFrame* sibling = GetNextSibling();
- #ifdef DEBUG
- if (sibling) {
- nsTableCellFrame* cellFrame = do_QueryFrame(sibling);
- MOZ_ASSERT(cellFrame, "How do we have a non-cell sibling?");
- }
- #endif // DEBUG
- return static_cast<nsTableCellFrame*>(sibling);
- }
- virtual LogicalMargin GetBorderWidth(WritingMode aWM) const;
- virtual DrawResult PaintBackground(nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsPoint aPt,
- uint32_t aFlags);
- void DecorateForSelection(DrawTarget* aDrawTarget, nsPoint aPt);
- virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;
- virtual bool IsFrameOfType(uint32_t aFlags) const override
- {
- return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart));
- }
-
- virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
- virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) override;
- virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
- bool ShouldPaintBordersAndBackgrounds() const;
- bool ShouldPaintBackground(nsDisplayListBuilder* aBuilder);
- protected:
- virtual LogicalSides
- GetLogicalSkipSides(const ReflowInput* aReflowInput = nullptr) const override;
- /**
- * GetBorderOverflow says how far the cell's own borders extend
- * outside its own bounds. In the separated borders model this should
- * just be zero (as it is for most frames), but in the collapsed
- * borders model (for which nsBCTableCellFrame overrides this virtual
- * method), it considers the extents of the collapsed border.
- */
- virtual nsMargin GetBorderOverflow();
- friend class nsTableRowFrame;
- uint32_t mColIndex; // the starting column for this cell
- nscoord mPriorAvailISize; // the avail isize during the last reflow
- mozilla::LogicalSize mDesiredSize; // the last desired inline and block size
- };
- inline nscoord nsTableCellFrame::GetPriorAvailISize()
- { return mPriorAvailISize; }
- inline void nsTableCellFrame::SetPriorAvailISize(nscoord aPriorAvailISize)
- { mPriorAvailISize = aPriorAvailISize; }
- inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize()
- { return mDesiredSize; }
- inline void nsTableCellFrame::SetDesiredSize(const ReflowOutput & aDesiredSize)
- {
- mozilla::WritingMode wm = aDesiredSize.GetWritingMode();
- mDesiredSize = aDesiredSize.Size(wm).ConvertTo(GetWritingMode(), wm);
- }
- inline bool nsTableCellFrame::GetContentEmpty() const
- {
- return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
- }
- inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty)
- {
- if (aContentEmpty) {
- AddStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
- } else {
- RemoveStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
- }
- }
- inline bool nsTableCellFrame::HasPctOverBSize()
- {
- return HasAnyStateBits(NS_TABLE_CELL_HAS_PCT_OVER_BSIZE);
- }
- inline void nsTableCellFrame::SetHasPctOverBSize(bool aValue)
- {
- if (aValue) {
- AddStateBits(NS_TABLE_CELL_HAS_PCT_OVER_BSIZE);
- } else {
- RemoveStateBits(NS_TABLE_CELL_HAS_PCT_OVER_BSIZE);
- }
- }
- // nsBCTableCellFrame
- class nsBCTableCellFrame final : public nsTableCellFrame
- {
- typedef mozilla::image::DrawResult DrawResult;
- public:
- NS_DECL_FRAMEARENA_HELPERS
- nsBCTableCellFrame(nsStyleContext* aContext, nsTableFrame* aTableFrame);
- ~nsBCTableCellFrame();
- virtual nsIAtom* GetType() const override;
- virtual nsMargin GetUsedBorder() const override;
- // Get the *inner half of the border only*, in twips.
- virtual LogicalMargin GetBorderWidth(WritingMode aWM) const override;
- // Get the *inner half of the border only*, in pixels.
- BCPixelSize GetBorderWidth(LogicalSide aSide) const;
- // Set the full (both halves) width of the border
- void SetBorderWidth(LogicalSide aSide, BCPixelSize aPixelValue);
- virtual nsMargin GetBorderOverflow() override;
- #ifdef DEBUG_FRAME_DUMP
- virtual nsresult GetFrameName(nsAString& aResult) const override;
- #endif
- virtual DrawResult PaintBackground(nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsPoint aPt,
- uint32_t aFlags) override;
- private:
- // These are the entire width of the border (the cell edge contains only
- // the inner half, per the macros in nsTablePainter.h).
- BCPixelSize mBStartBorder;
- BCPixelSize mIEndBorder;
- BCPixelSize mBEndBorder;
- BCPixelSize mIStartBorder;
- };
- // Implemented here because that's a sane-ish way to make the includes work out.
- inline nsTableCellFrame* nsTableRowFrame::GetFirstCell() const
- {
- nsIFrame* firstChild = mFrames.FirstChild();
- #ifdef DEBUG
- if (firstChild) {
- nsTableCellFrame* cellFrame = do_QueryFrame(firstChild);
- MOZ_ASSERT(cellFrame, "How do we have a non-cell sibling?");
- }
- #endif // DEBUG
- return static_cast<nsTableCellFrame*>(firstChild);
- }
- #endif
|