michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #ifndef nsTableCellFrame_h__ michael@0: #define nsTableCellFrame_h__ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "celldata.h" michael@0: #include "nsITableCellLayout.h" michael@0: #include "nscore.h" michael@0: #include "nsContainerFrame.h" michael@0: #include "nsStyleContext.h" michael@0: #include "nsIPercentHeightObserver.h" michael@0: #include "nsGkAtoms.h" michael@0: #include "nsLayoutUtils.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class nsTableFrame; michael@0: michael@0: /** michael@0: * nsTableCellFrame michael@0: * data structure to maintain information about a single table cell's frame michael@0: * michael@0: * NOTE: frames are not ref counted. We expose addref and release here michael@0: * so we can change that decsion in the future. Users of nsITableCellLayout michael@0: * should refcount correctly as if this object is being ref counted, though michael@0: * no actual support is under the hood. michael@0: * michael@0: * @author sclark michael@0: */ michael@0: class nsTableCellFrame : public nsContainerFrame, michael@0: public nsITableCellLayout, michael@0: public nsIPercentHeightObserver michael@0: { michael@0: public: michael@0: NS_DECL_QUERYFRAME_TARGET(nsTableCellFrame) michael@0: NS_DECL_QUERYFRAME michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: michael@0: // default constructor supplied by the compiler michael@0: michael@0: nsTableCellFrame(nsStyleContext* aContext); michael@0: ~nsTableCellFrame(); michael@0: michael@0: virtual void Init(nsIContent* aContent, michael@0: nsIFrame* aParent, michael@0: nsIFrame* aPrevInFlow) MOZ_OVERRIDE; michael@0: michael@0: virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; michael@0: michael@0: #ifdef ACCESSIBILITY michael@0: virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: virtual nsresult AttributeChanged(int32_t aNameSpaceID, michael@0: nsIAtom* aAttribute, michael@0: int32_t aModType) MOZ_OVERRIDE; michael@0: michael@0: /** @see nsIFrame::DidSetStyleContext */ michael@0: virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; michael@0: michael@0: // table cells contain a block frame which does most of the work, and michael@0: // so these functions should never be called. They assert and return michael@0: // NS_ERROR_NOT_IMPLEMENTED michael@0: virtual nsresult AppendFrames(ChildListID aListID, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: virtual nsresult InsertFrames(ChildListID aListID, michael@0: nsIFrame* aPrevFrame, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: virtual nsresult RemoveFrame(ChildListID aListID, michael@0: nsIFrame* aOldFrame) MOZ_OVERRIDE; michael@0: michael@0: virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE { michael@0: return GetFirstPrincipalChild()->GetContentInsertionFrame(); michael@0: } michael@0: michael@0: virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE; michael@0: michael@0: virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; michael@0: michael@0: virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; michael@0: michael@0: /** instantiate a new instance of nsTableRowFrame. michael@0: * @param aPresShell the pres shell for this frame michael@0: * michael@0: * @return the frame that was created michael@0: */ michael@0: friend nsIFrame* NS_NewTableCellFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); michael@0: michael@0: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) MOZ_OVERRIDE; michael@0: michael@0: void PaintCellBackground(nsRenderingContext& aRenderingContext, michael@0: const nsRect& aDirtyRect, nsPoint aPt, michael@0: uint32_t aFlags); michael@0: michael@0: michael@0: virtual nsresult ProcessBorders(nsTableFrame* aFrame, michael@0: nsDisplayListBuilder* aBuilder, michael@0: const nsDisplayListSet& aLists); michael@0: michael@0: virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; michael@0: virtual IntrinsicWidthOffsetData michael@0: IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; michael@0: michael@0: virtual nsresult Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * Get the "type" of the frame michael@0: * michael@0: * @see nsLayoutAtoms::tableCellFrame michael@0: */ michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: void VerticallyAlignChild(nscoord aMaxAscent); michael@0: michael@0: /* michael@0: * Get the value of vertical-align adjusted for CSS 2's rules for a michael@0: * table cell, which means the result is always michael@0: * NS_STYLE_VERTICAL_ALIGN_{TOP,MIDDLE,BOTTOM,BASELINE}. michael@0: */ michael@0: virtual uint8_t GetVerticalAlign() const; michael@0: michael@0: bool HasVerticalAlignBaseline() const { michael@0: return GetVerticalAlign() == NS_STYLE_VERTICAL_ALIGN_BASELINE; michael@0: } michael@0: michael@0: bool CellHasVisibleContent(nscoord height, michael@0: nsTableFrame* tableFrame, michael@0: nsIFrame* kidFrame); michael@0: michael@0: /** michael@0: * Get the first-line baseline of the cell relative to its top border michael@0: * edge, as if the cell were vertically aligned to the top of the row. michael@0: */ michael@0: nscoord GetCellBaseline() const; michael@0: michael@0: /** michael@0: * return the cell's specified row span. this is what was specified in the michael@0: * content model or in the style info, and is always >= 1. michael@0: * to get the effective row span (the actual value that applies), use GetEffectiveRowSpan() michael@0: * @see nsTableFrame::GetEffectiveRowSpan() michael@0: */ michael@0: virtual int32_t GetRowSpan(); michael@0: michael@0: // there is no set row index because row index depends on the cell's parent row only michael@0: michael@0: /*---------------- nsITableCellLayout methods ------------------------*/ michael@0: michael@0: /** michael@0: * return the cell's starting row index (starting at 0 for the first row). michael@0: * for continued cell frames the row index is that of the cell's first-in-flow michael@0: * and the column index (starting at 0 for the first column michael@0: */ michael@0: NS_IMETHOD GetCellIndexes(int32_t &aRowIndex, int32_t &aColIndex) MOZ_OVERRIDE; michael@0: michael@0: /** return the mapped cell's row index (starting at 0 for the first row) */ michael@0: virtual nsresult GetRowIndex(int32_t &aRowIndex) const MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * return the cell's specified col span. this is what was specified in the michael@0: * content model or in the style info, and is always >= 1. michael@0: * to get the effective col span (the actual value that applies), use GetEffectiveColSpan() michael@0: * @see nsTableFrame::GetEffectiveColSpan() michael@0: */ michael@0: virtual int32_t GetColSpan(); michael@0: michael@0: /** return the cell's column index (starting at 0 for the first column) */ michael@0: virtual nsresult GetColIndex(int32_t &aColIndex) const MOZ_OVERRIDE; michael@0: void SetColIndex(int32_t aColIndex); michael@0: michael@0: /** return the available width given to this frame during its last reflow */ michael@0: inline nscoord GetPriorAvailWidth(); michael@0: michael@0: /** set the available width given to this frame during its last reflow */ michael@0: inline void SetPriorAvailWidth(nscoord aPriorAvailWidth); michael@0: michael@0: /** return the desired size returned by this frame during its last reflow */ michael@0: inline nsSize GetDesiredSize(); michael@0: michael@0: /** set the desired size returned by this frame during its last reflow */ michael@0: inline void SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize); michael@0: michael@0: bool GetContentEmpty(); michael@0: void SetContentEmpty(bool aContentEmpty); michael@0: michael@0: bool HasPctOverHeight(); michael@0: void SetHasPctOverHeight(bool aValue); michael@0: michael@0: nsTableCellFrame* GetNextCell() const; michael@0: michael@0: virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const; michael@0: michael@0: virtual void PaintBackground(nsRenderingContext& aRenderingContext, michael@0: const nsRect& aDirtyRect, michael@0: nsPoint aPt, michael@0: uint32_t aFlags); michael@0: michael@0: void DecorateForSelection(nsRenderingContext& aRenderingContext, michael@0: nsPoint aPt); michael@0: michael@0: virtual bool UpdateOverflow() MOZ_OVERRIDE; michael@0: michael@0: virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE michael@0: { michael@0: return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart)); michael@0: } michael@0: michael@0: virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; michael@0: virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; michael@0: virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); } michael@0: michael@0: protected: michael@0: virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState= nullptr) const MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * GetBorderOverflow says how far the cell's own borders extend michael@0: * outside its own bounds. In the separated borders model this should michael@0: * just be zero (as it is for most frames), but in the collapsed michael@0: * borders model (for which nsBCTableCellFrame overrides this virtual michael@0: * method), it considers the extents of the collapsed border. michael@0: */ michael@0: virtual nsMargin GetBorderOverflow(); michael@0: michael@0: friend class nsTableRowFrame; michael@0: michael@0: uint32_t mColIndex; // the starting column for this cell michael@0: michael@0: nscoord mPriorAvailWidth; // the avail width during the last reflow michael@0: nsSize mDesiredSize; // the last desired width & height michael@0: }; michael@0: michael@0: inline nscoord nsTableCellFrame::GetPriorAvailWidth() michael@0: { return mPriorAvailWidth;} michael@0: michael@0: inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth) michael@0: { mPriorAvailWidth = aPriorAvailWidth;} michael@0: michael@0: inline nsSize nsTableCellFrame::GetDesiredSize() michael@0: { return mDesiredSize; } michael@0: michael@0: inline void nsTableCellFrame::SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize) michael@0: { michael@0: mDesiredSize.width = aDesiredSize.Width(); michael@0: mDesiredSize.height = aDesiredSize.Height(); michael@0: } michael@0: michael@0: inline bool nsTableCellFrame::GetContentEmpty() michael@0: { michael@0: return (mState & NS_TABLE_CELL_CONTENT_EMPTY) == michael@0: NS_TABLE_CELL_CONTENT_EMPTY; michael@0: } michael@0: michael@0: inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty) michael@0: { michael@0: if (aContentEmpty) { michael@0: mState |= NS_TABLE_CELL_CONTENT_EMPTY; michael@0: } else { michael@0: mState &= ~NS_TABLE_CELL_CONTENT_EMPTY; michael@0: } michael@0: } michael@0: michael@0: inline bool nsTableCellFrame::HasPctOverHeight() michael@0: { michael@0: return (mState & NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) == michael@0: NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; michael@0: } michael@0: michael@0: inline void nsTableCellFrame::SetHasPctOverHeight(bool aValue) michael@0: { michael@0: if (aValue) { michael@0: mState |= NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; michael@0: } else { michael@0: mState &= ~NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; michael@0: } michael@0: } michael@0: michael@0: // nsBCTableCellFrame michael@0: class nsBCTableCellFrame : public nsTableCellFrame michael@0: { michael@0: public: michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: michael@0: nsBCTableCellFrame(nsStyleContext* aContext); michael@0: michael@0: ~nsBCTableCellFrame(); michael@0: michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: michael@0: virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE; michael@0: virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE; michael@0: michael@0: // Get the *inner half of the border only*, in twips. michael@0: virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const MOZ_OVERRIDE; michael@0: michael@0: // Get the *inner half of the border only*, in pixels. michael@0: BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const; michael@0: michael@0: // Set the full (both halves) width of the border michael@0: void SetBorderWidth(mozilla::css::Side aSide, BCPixelSize aPixelValue); michael@0: michael@0: virtual nsMargin GetBorderOverflow() MOZ_OVERRIDE; michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: #endif michael@0: michael@0: virtual void PaintBackground(nsRenderingContext& aRenderingContext, michael@0: const nsRect& aDirtyRect, michael@0: nsPoint aPt, michael@0: uint32_t aFlags) MOZ_OVERRIDE; michael@0: michael@0: private: michael@0: michael@0: // These are the entire width of the border (the cell edge contains only michael@0: // the inner half, per the macros in nsTablePainter.h). michael@0: BCPixelSize mTopBorder; michael@0: BCPixelSize mRightBorder; michael@0: BCPixelSize mBottomBorder; michael@0: BCPixelSize mLeftBorder; michael@0: }; michael@0: michael@0: #endif