diff -r 000000000000 -r 6474c204b198 layout/tables/nsTableCellFrame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/tables/nsTableCellFrame.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,333 @@ +/* -*- 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 "nsITableCellLayout.h" +#include "nscore.h" +#include "nsContainerFrame.h" +#include "nsStyleContext.h" +#include "nsIPercentHeightObserver.h" +#include "nsGkAtoms.h" +#include "nsLayoutUtils.h" +#include "nsTArray.h" + +class nsTableFrame; + +/** + * 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 nsIPercentHeightObserver +{ +public: + NS_DECL_QUERYFRAME_TARGET(nsTableCellFrame) + NS_DECL_QUERYFRAME + NS_DECL_FRAMEARENA_HELPERS + + // default constructor supplied by the compiler + + nsTableCellFrame(nsStyleContext* aContext); + ~nsTableCellFrame(); + + virtual void Init(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame* aPrevInFlow) MOZ_OVERRIDE; + + virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE; + +#ifdef ACCESSIBILITY + virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE; +#endif + + virtual nsresult AttributeChanged(int32_t aNameSpaceID, + nsIAtom* aAttribute, + int32_t aModType) MOZ_OVERRIDE; + + /** @see nsIFrame::DidSetStyleContext */ + virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; + + // table cells contain a block frame which does most of the work, and + // so these functions should never be called. They assert and return + // NS_ERROR_NOT_IMPLEMENTED + virtual nsresult AppendFrames(ChildListID aListID, + nsFrameList& aFrameList) MOZ_OVERRIDE; + virtual nsresult InsertFrames(ChildListID aListID, + nsIFrame* aPrevFrame, + nsFrameList& aFrameList) MOZ_OVERRIDE; + virtual nsresult RemoveFrame(ChildListID aListID, + nsIFrame* aOldFrame) MOZ_OVERRIDE; + + virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE { + return GetFirstPrincipalChild()->GetContentInsertionFrame(); + } + + virtual nsMargin GetUsedMargin() const MOZ_OVERRIDE; + + virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; + + virtual bool NeedsToObserve(const nsHTMLReflowState& aReflowState) MOZ_OVERRIDE; + + /** instantiate a new instance of nsTableRowFrame. + * @param aPresShell the pres shell for this frame + * + * @return the frame that was created + */ + friend nsIFrame* NS_NewTableCellFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); + + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) MOZ_OVERRIDE; + + void PaintCellBackground(nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, nsPoint aPt, + uint32_t aFlags); + + + virtual nsresult ProcessBorders(nsTableFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists); + + virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE; + virtual IntrinsicWidthOffsetData + IntrinsicWidthOffsets(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE; + + virtual nsresult Reflow(nsPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) MOZ_OVERRIDE; + + /** + * Get the "type" of the frame + * + * @see nsLayoutAtoms::tableCellFrame + */ + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; +#endif + + void VerticallyAlignChild(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 height, + nsTableFrame* tableFrame, + nsIFrame* kidFrame); + + /** + * Get the first-line baseline of the cell relative to its top 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 >= 1. + * to get the effective row span (the actual value that applies), use GetEffectiveRowSpan() + * @see nsTableFrame::GetEffectiveRowSpan() + */ + virtual 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) MOZ_OVERRIDE; + + /** return the mapped cell's row index (starting at 0 for the first row) */ + virtual nsresult GetRowIndex(int32_t &aRowIndex) const MOZ_OVERRIDE; + + /** + * 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() + */ + virtual int32_t GetColSpan(); + + /** return the cell's column index (starting at 0 for the first column) */ + virtual nsresult GetColIndex(int32_t &aColIndex) const MOZ_OVERRIDE; + void SetColIndex(int32_t aColIndex); + + /** return the available width given to this frame during its last reflow */ + inline nscoord GetPriorAvailWidth(); + + /** set the available width given to this frame during its last reflow */ + inline void SetPriorAvailWidth(nscoord aPriorAvailWidth); + + /** return the desired size returned by this frame during its last reflow */ + inline nsSize GetDesiredSize(); + + /** set the desired size returned by this frame during its last reflow */ + inline void SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize); + + bool GetContentEmpty(); + void SetContentEmpty(bool aContentEmpty); + + bool HasPctOverHeight(); + void SetHasPctOverHeight(bool aValue); + + nsTableCellFrame* GetNextCell() const; + + virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const; + + virtual void PaintBackground(nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsPoint aPt, + uint32_t aFlags); + + void DecorateForSelection(nsRenderingContext& aRenderingContext, + nsPoint aPt); + + virtual bool UpdateOverflow() MOZ_OVERRIDE; + + virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE + { + return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart)); + } + + virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; + virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; + virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); } + +protected: + virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState= nullptr) const MOZ_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 mPriorAvailWidth; // the avail width during the last reflow + nsSize mDesiredSize; // the last desired width & height +}; + +inline nscoord nsTableCellFrame::GetPriorAvailWidth() +{ return mPriorAvailWidth;} + +inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth) +{ mPriorAvailWidth = aPriorAvailWidth;} + +inline nsSize nsTableCellFrame::GetDesiredSize() +{ return mDesiredSize; } + +inline void nsTableCellFrame::SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize) +{ + mDesiredSize.width = aDesiredSize.Width(); + mDesiredSize.height = aDesiredSize.Height(); +} + +inline bool nsTableCellFrame::GetContentEmpty() +{ + return (mState & NS_TABLE_CELL_CONTENT_EMPTY) == + NS_TABLE_CELL_CONTENT_EMPTY; +} + +inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty) +{ + if (aContentEmpty) { + mState |= NS_TABLE_CELL_CONTENT_EMPTY; + } else { + mState &= ~NS_TABLE_CELL_CONTENT_EMPTY; + } +} + +inline bool nsTableCellFrame::HasPctOverHeight() +{ + return (mState & NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) == + NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; +} + +inline void nsTableCellFrame::SetHasPctOverHeight(bool aValue) +{ + if (aValue) { + mState |= NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; + } else { + mState &= ~NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; + } +} + +// nsBCTableCellFrame +class nsBCTableCellFrame : public nsTableCellFrame +{ +public: + NS_DECL_FRAMEARENA_HELPERS + + nsBCTableCellFrame(nsStyleContext* aContext); + + ~nsBCTableCellFrame(); + + virtual nsIAtom* GetType() const MOZ_OVERRIDE; + + virtual nsMargin GetUsedBorder() const MOZ_OVERRIDE; + virtual bool GetBorderRadii(nscoord aRadii[8]) const MOZ_OVERRIDE; + + // Get the *inner half of the border only*, in twips. + virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const MOZ_OVERRIDE; + + // Get the *inner half of the border only*, in pixels. + BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const; + + // Set the full (both halves) width of the border + void SetBorderWidth(mozilla::css::Side aSide, BCPixelSize aPixelValue); + + virtual nsMargin GetBorderOverflow() MOZ_OVERRIDE; + +#ifdef DEBUG_FRAME_DUMP + virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; +#endif + + virtual void PaintBackground(nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsPoint aPt, + uint32_t aFlags) MOZ_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 mTopBorder; + BCPixelSize mRightBorder; + BCPixelSize mBottomBorder; + BCPixelSize mLeftBorder; +}; + +#endif