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: #include "nsCOMPtr.h" michael@0: #include "nsTableColFrame.h" michael@0: #include "nsTableFrame.h" michael@0: #include "nsContainerFrame.h" michael@0: #include "nsStyleContext.h" michael@0: #include "nsStyleConsts.h" michael@0: #include "nsPresContext.h" michael@0: #include "nsGkAtoms.h" michael@0: #include "nsCSSRendering.h" michael@0: #include "nsIContent.h" michael@0: michael@0: #define COL_TYPE_BITS (NS_FRAME_STATE_BIT(28) | \ michael@0: NS_FRAME_STATE_BIT(29) | \ michael@0: NS_FRAME_STATE_BIT(30) | \ michael@0: NS_FRAME_STATE_BIT(31)) michael@0: #define COL_TYPE_OFFSET 28 michael@0: michael@0: nsTableColFrame::nsTableColFrame(nsStyleContext* aContext) : michael@0: nsSplittableFrame(aContext) michael@0: { michael@0: SetColType(eColContent); michael@0: ResetIntrinsics(); michael@0: ResetSpanIntrinsics(); michael@0: ResetFinalWidth(); michael@0: } michael@0: michael@0: nsTableColFrame::~nsTableColFrame() michael@0: { michael@0: } michael@0: michael@0: nsTableColType michael@0: nsTableColFrame::GetColType() const michael@0: { michael@0: return (nsTableColType)((mState & COL_TYPE_BITS) >> COL_TYPE_OFFSET); michael@0: } michael@0: michael@0: void michael@0: nsTableColFrame::SetColType(nsTableColType aType) michael@0: { michael@0: NS_ASSERTION(aType != eColAnonymousCol || michael@0: (GetPrevContinuation() && michael@0: GetPrevContinuation()->GetNextContinuation() == this && michael@0: GetPrevContinuation()->GetNextSibling() == this), michael@0: "spanned content cols must be continuations"); michael@0: uint32_t type = aType - eColContent; michael@0: RemoveStateBits(COL_TYPE_BITS); michael@0: AddStateBits(nsFrameState(type << COL_TYPE_OFFSET)); michael@0: } michael@0: michael@0: /* virtual */ void michael@0: nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext) michael@0: { michael@0: nsSplittableFrame::DidSetStyleContext(aOldStyleContext); michael@0: michael@0: if (!aOldStyleContext) //avoid this on init michael@0: return; michael@0: michael@0: nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); michael@0: if (tableFrame->IsBorderCollapse() && michael@0: tableFrame->BCRecalcNeeded(aOldStyleContext, StyleContext())) { michael@0: nsIntRect damageArea(GetColIndex(), 0, 1, tableFrame->GetRowCount()); michael@0: tableFrame->AddBCDamageArea(damageArea); michael@0: } michael@0: } michael@0: michael@0: void nsTableColFrame::SetContinuousBCBorderWidth(uint8_t aForSide, michael@0: BCPixelSize aPixelValue) michael@0: { michael@0: switch (aForSide) { michael@0: case NS_SIDE_TOP: michael@0: mTopContBorderWidth = aPixelValue; michael@0: return; michael@0: case NS_SIDE_RIGHT: michael@0: mRightContBorderWidth = aPixelValue; michael@0: return; michael@0: case NS_SIDE_BOTTOM: michael@0: mBottomContBorderWidth = aPixelValue; michael@0: return; michael@0: default: michael@0: NS_ERROR("invalid side arg"); michael@0: } michael@0: } michael@0: michael@0: nsresult nsTableColFrame::Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) michael@0: { michael@0: DO_GLOBAL_REFLOW_COUNT("nsTableColFrame"); michael@0: DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus); michael@0: aDesiredSize.Width() = 0; michael@0: aDesiredSize.Height() = 0; michael@0: const nsStyleVisibility* colVis = StyleVisibility(); michael@0: bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible); michael@0: if (collapseCol) { michael@0: nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); michael@0: tableFrame->SetNeedToCollapse(true); michael@0: } michael@0: aStatus = NS_FRAME_COMPLETE; michael@0: NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); michael@0: return NS_OK; michael@0: } michael@0: michael@0: int32_t nsTableColFrame::GetSpan() michael@0: { michael@0: return StyleTable()->mSpan; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: void nsTableColFrame::Dump(int32_t aIndent) michael@0: { michael@0: char* indent = new char[aIndent + 1]; michael@0: if (!indent) return; michael@0: for (int32_t i = 0; i < aIndent + 1; i++) { michael@0: indent[i] = ' '; michael@0: } michael@0: indent[aIndent] = 0; michael@0: michael@0: printf("%s**START COL DUMP**\n%s colIndex=%d coltype=", michael@0: indent, indent, mColIndex); michael@0: nsTableColType colType = GetColType(); michael@0: switch (colType) { michael@0: case eColContent: michael@0: printf(" content "); michael@0: break; michael@0: case eColAnonymousCol: michael@0: printf(" anonymous-column "); michael@0: break; michael@0: case eColAnonymousColGroup: michael@0: printf(" anonymous-colgroup "); michael@0: break; michael@0: case eColAnonymousCell: michael@0: printf(" anonymous-cell "); michael@0: break; michael@0: } michael@0: printf("\nm:%d c:%d(%c) p:%f sm:%d sc:%d sp:%f f:%d", michael@0: int32_t(mMinCoord), int32_t(mPrefCoord), michael@0: mHasSpecifiedCoord ? 's' : 'u', mPrefPercent, michael@0: int32_t(mSpanMinCoord), int32_t(mSpanPrefCoord), michael@0: mSpanPrefPercent, michael@0: int32_t(GetFinalWidth())); michael@0: printf("\n%s**END COL DUMP** ", indent); michael@0: delete [] indent; michael@0: } michael@0: #endif michael@0: /* ----- global methods ----- */ michael@0: michael@0: nsTableColFrame* michael@0: NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) michael@0: { michael@0: return new (aPresShell) nsTableColFrame(aContext); michael@0: } michael@0: michael@0: NS_IMPL_FRAMEARENA_HELPERS(nsTableColFrame) michael@0: michael@0: nsTableColFrame* michael@0: nsTableColFrame::GetNextCol() const michael@0: { michael@0: nsIFrame* childFrame = GetNextSibling(); michael@0: while (childFrame) { michael@0: if (nsGkAtoms::tableColFrame == childFrame->GetType()) { michael@0: return (nsTableColFrame*)childFrame; michael@0: } michael@0: childFrame = childFrame->GetNextSibling(); michael@0: } michael@0: return nullptr; michael@0: } michael@0: michael@0: nsIAtom* michael@0: nsTableColFrame::GetType() const michael@0: { michael@0: return nsGkAtoms::tableColFrame; michael@0: } michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: nsresult michael@0: nsTableColFrame::GetFrameName(nsAString& aResult) const michael@0: { michael@0: return MakeFrameName(NS_LITERAL_STRING("TableCol"), aResult); michael@0: } michael@0: #endif michael@0: michael@0: nsSplittableType michael@0: nsTableColFrame::GetSplittableType() const michael@0: { michael@0: return NS_FRAME_NOT_SPLITTABLE; michael@0: } michael@0: michael@0: void michael@0: nsTableColFrame::InvalidateFrame(uint32_t aDisplayItemKey) michael@0: { michael@0: nsIFrame::InvalidateFrame(aDisplayItemKey); michael@0: GetParent()->InvalidateFrameWithRect(GetVisualOverflowRect() + GetPosition(), aDisplayItemKey); michael@0: } michael@0: michael@0: void michael@0: nsTableColFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey) michael@0: { michael@0: nsIFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey); michael@0: michael@0: // If we have filters applied that would affects our bounds, then michael@0: // we get an inactive layer created and this is computed michael@0: // within FrameLayerBuilder michael@0: GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey); michael@0: } michael@0: