From bb9c01d77bbbda4042bf8424ddb7944becfbd2b3 Mon Sep 17 00:00:00 2001 From: "buster%netscape.com" Date: Thu, 17 Dec 1998 22:59:40 +0000 Subject: [PATCH] WIP on border collapsing git-svn-id: svn://10.0.0.236/trunk@16619 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/html/table/src/nsBorder.h | 53 ------- .../layout/html/table/src/nsTableFrame.cpp | 132 +++++++++++++----- mozilla/layout/html/table/src/nsTableFrame.h | 9 +- mozilla/layout/tables/nsTableFrame.cpp | 132 +++++++++++++----- mozilla/layout/tables/nsTableFrame.h | 9 +- 5 files changed, 200 insertions(+), 135 deletions(-) delete mode 100644 mozilla/layout/html/table/src/nsBorder.h diff --git a/mozilla/layout/html/table/src/nsBorder.h b/mozilla/layout/html/table/src/nsBorder.h deleted file mode 100644 index 0fdb22a445c..00000000000 --- a/mozilla/layout/html/table/src/nsBorder.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ -#ifndef nsBorder_h__ -#define nsBorder_h__ - -#include "nsColor.h" -#include "nsCoord.h" -#include "nsStyleConsts.h" - - -#define BORDER_PRECEDENT_EQUAL 0 -#define BORDER_PRECEDENT_LOWER 1 -#define BORDER_PRECEDENT_HIGHER 2 - - -/** an encapsulation of border edge info - * - */ -struct nsBorderEdge -{ - nscoord mWidth; - PRUint8 mStyle; - nscolor mColor; - PRUint8 mSide; - - nsBorderEdge(); -}; - -inline nsBorderEdge::nsBorderEdge() -{ - mWidth=0; - mStyle=NS_STYLE_BORDER_STYLE_NONE; - mColor=0; - mSide=NS_SIDE_LEFT; -}; - - -#endif diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 44b684d87f5..ece78154fee 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -1223,15 +1223,15 @@ void nsTableFrame::ComputeCollapsingBorders(PRInt32 aStartRowIndex, void nsTableFrame::ComputeLeftBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex) { // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull - PRInt32 numSegments = mBorderEdges[NS_SIDE_LEFT].Count(); + PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_LEFT].Count(); while (numSegments<=aRowIndex) { nsBorderEdge *borderToAdd = new nsBorderEdge(); - mBorderEdges[NS_SIDE_LEFT].AppendElement(borderToAdd); + mBorderEdges.mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd); numSegments++; } // "border" is the border segment we are going to set - nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); + nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); // collect all the incident frames and compute the dominant border nsVoidArray styles; @@ -1267,42 +1267,39 @@ void nsTableFrame::ComputeLeftBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColInd cellFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); styles.AppendElement((void*)spacing); } - ComputeCollapsedBorderSegment(NS_SIDE_LEFT, &styles, *border); - - + ComputeCollapsedBorderSegment(NS_SIDE_LEFT, &styles, *border, PR_FALSE); + // now give half the computed border to the table segment, and half to the cell + // XXX give half to the cell + border->mWidth = (border->mWidth)/2; + mBorderEdges.mMaxBorderWidth.left = PR_MAX(border->mWidth, mBorderEdges.mMaxBorderWidth.left); } void nsTableFrame::ComputeRightBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex) { -#if 0 // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull PRInt32 colCount = mCellMap->GetColCount(); - PRInt32 numSegments = mBorderEdges[NS_SIDE_RIGHT].Count(); + PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_RIGHT].Count(); while (numSegments<=aRowIndex) { nsBorderEdge *borderToAdd = new nsBorderEdge(); - mBorderEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd); + mBorderEdges.mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd); numSegments++; } // "border" is the border segment we are going to set - nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); + nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); // collect all the incident frames and compute the dominant border nsVoidArray styles; // styles are added to the array in the order least dominant -> most dominant // 1. table, only if this cell is in the right-most column and no rowspanning cell is - // to it's right. - PRBool useTable=PR_FALSE; - nsTableCellFrame *rightNeighborFrame=nsnull; - if ((colCount-1)==aColIndex) - useTable=PR_TRUE; - else + // to it's right. Otherwise, we remember what cell is the right neighbor + nsTableCellFrame *rightNeighborFrame=nsnull; + if ((colCount-1)!=aColIndex) { PRInt32 colIndex = aColIndex+1; for ( ; colIndexGetCellAt(aRowIndex, colIndex); if (cd != nsnull) { // there's really a cell at (aRowIndex, colIndex) if (nsnull==cd->mCell) @@ -1312,19 +1309,24 @@ void nsTableFrame::ComputeRightBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIn const PRInt32 realRowIndex = cell->GetRowIndex (); if (realRowIndex!=aRowIndex) { // the span is caused by a rowspan - result = PR_TRUE; + rightNeighborFrame = cd->mRealCell->mCell; break; } } + else + { + rightNeighborFrame = cd->mCell; + break; + } } - - - rightNeighborFrame = mCellMap->GetCellFrameAt(aRowIndex, colIndex); } } const nsStyleSpacing *spacing; - GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); - styles.AppendElement((void*)spacing); + if (nsnull==rightNeighborFrame) + { // if rightNeighborFrame is null, our right neighbor is the table + GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); + styles.AppendElement((void*)spacing); + } // 2. colgroup nsTableColFrame *colFrame = mCellMap->GetColumnFrame(aColIndex); nsIFrame *colGroupFrame; @@ -1352,8 +1354,17 @@ void nsTableFrame::ComputeRightBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIn cellFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); styles.AppendElement((void*)spacing); } - ComputeCollapsedBorderSegment(NS_SIDE_RIGHT, &styles, *border); -#endif + // 7. left edge of rightNeighborCell, if there is one + if (nsnull!=rightNeighborFrame) + { + rightNeighborFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); + styles.AppendElement((void*)spacing); + } + ComputeCollapsedBorderSegment(NS_SIDE_RIGHT, &styles, *border, PRBool(nsnull!=rightNeighborFrame)); + // now give half the computed border to the table segment, and half to the cell + // XXX give half to the cell + border->mWidth = (border->mWidth)/2; //XXX: rounding + } void nsTableFrame::ComputeTopBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex) @@ -1382,6 +1393,26 @@ nscoord nsTableFrame::GetWidthForSide(const nsMargin &aBorder, PRUint8 aSide) else return aBorder.bottom; } +/* Given an Edge, find the opposing edge (top<-->bottom, left<-->right) */ +PRUint8 nsTableFrame::GetOpposingEdge(PRUint8 aEdge) +{ + PRUint8 result; + switch (aEdge) + { + case NS_SIDE_LEFT: + result = NS_SIDE_RIGHT; break; + case NS_SIDE_RIGHT: + result = NS_SIDE_LEFT; break; + case NS_SIDE_TOP: + result = NS_SIDE_BOTTOM; break; + case NS_SIDE_BOTTOM: + result = NS_SIDE_TOP; break; + default: + result = NS_SIDE_TOP; + } + return result; +} + /* returns BORDER_PRECEDENT_LOWER if aStyle1 is lower precedent that aStyle2 * BORDER_PRECEDENT_HIGHER if aStyle1 is higher precedent that aStyle2 * BORDER_PRECEDENT_EQUAL if aStyle1 and aStyle2 have the same precedence @@ -1490,9 +1521,10 @@ PRUint8 nsTableFrame::CompareBorderStyles(PRUint8 aStyle1, PRUint8 aStyle2) earlier in the list if the tie-breaker gets down to #4. This method sets the out-param aBorder with the resolved border attributes */ -void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, - nsVoidArray *aStyles, - nsBorderEdge &aBorder) +void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, + nsVoidArray *aStyles, + nsBorderEdge &aBorder, + PRBool aFlipLastSide) { if (nsnull!=aStyles) { @@ -1501,22 +1533,29 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, { nsVoidArray sameWidthBorders; nsStyleSpacing * spacing; + nsStyleSpacing * lastSpacing=nsnull; nsMargin border; PRInt32 maxWidth=0; PRInt32 i; + PRUint8 side = aSide; for (i=0; iElementAt(i)); - if (spacing->GetBorderStyle(aSide)==NS_STYLE_BORDER_STYLE_HIDDEN) + if ((PR_TRUE==aFlipLastSide) && (i==styleCount-1)) + { + side = GetOpposingEdge(aSide); + lastSpacing = spacing; + } + if (spacing->GetBorderStyle(side)==NS_STYLE_BORDER_STYLE_HIDDEN) { aBorder.mStyle=NS_STYLE_BORDER_STYLE_HIDDEN; aBorder.mWidth=0; return; } - else if (spacing->GetBorderStyle(aSide)!=NS_STYLE_BORDER_STYLE_NONE) + else if (spacing->GetBorderStyle(side)!=NS_STYLE_BORDER_STYLE_NONE) { spacing->GetBorder(border); - nscoord borderWidth = GetWidthForSide(border, aSide); + nscoord borderWidth = GetWidthForSide(border, side); if (borderWidth==maxWidth) sameWidthBorders.AppendElement(spacing); else if (borderWidth>maxWidth) @@ -1541,8 +1580,11 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, else if (1==styleCount) { // there was just one border of the largest width spacing = (nsStyleSpacing *)(sameWidthBorders.ElementAt(0)); - aBorder.mColor=spacing->GetBorderColor(aSide); - aBorder.mStyle=spacing->GetBorderStyle(aSide); + side=aSide; + if (spacing==lastSpacing) + side=GetOpposingEdge(aSide); + aBorder.mColor=spacing->GetBorderColor(side); + aBorder.mStyle=spacing->GetBorderStyle(side); return; } else @@ -1552,7 +1594,10 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, for (i=0; iElementAt(i)); - PRUint8 thisStyle = spacing->GetBorderStyle(aSide); + side=aSide; + if (spacing==lastSpacing) + side=GetOpposingEdge(aSide); + PRUint8 thisStyle = spacing->GetBorderStyle(side); PRUint8 borderCompare = CompareBorderStyles(thisStyle, winningStyle); if (BORDER_PRECEDENT_HIGHER==borderCompare) { @@ -1565,7 +1610,10 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, } } aBorder.mStyle = winningStyle; - aBorder.mColor = winningStyleBorder->GetBorderColor(aSide); + side=aSide; + if (winningStyleBorder==lastSpacing) + side=GetOpposingEdge(aSide); + aBorder.mColor = winningStyleBorder->GetBorderColor(side); } } } @@ -1810,13 +1858,21 @@ NS_METHOD nsTableFrame::Paint(nsIPresContext& aPresContext, (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + const nsStyleTable* tableStyle = + (const nsStyleTable*)mStyleContext->GetStyleData(eStyleStruct_Table); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *color, 0, 0); PRIntn skipSides = GetSkipSides(); - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *spacing, skipSides); + if (NS_STYLE_BORDER_SEPARATE==tableStyle->mBorderCollapse) + { + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, skipSides); + } + else + { + } } // for debug... diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index 09b009c8b86..839db62cb7c 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -20,10 +20,10 @@ #include "nscore.h" #include "nsVoidArray.h" -#include "nsBorder.h" #include "nsHTMLContainerFrame.h" #include "nsStyleCoord.h" #include "nsStyleConsts.h" +#include "nsIStyleContext.h" #include "nsIFrameReflow.h" // for nsReflowReason enum @@ -216,13 +216,16 @@ public: void ComputeTopBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex); void ComputeBottomBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex); + PRUint8 GetOpposingEdge(PRUint8 aEdge); + nscoord GetWidthForSide(const nsMargin &aBorder, PRUint8 aSide); PRUint8 CompareBorderStyles(PRUint8 aStyle1, PRUint8 aStyle2); void ComputeCollapsedBorderSegment(PRUint8 aSide, nsVoidArray * aStyles, - nsBorderEdge& aBorder); + nsBorderEdge& aBorder, + PRBool aFlipLastSide); void RecalcLayoutData(); @@ -655,7 +658,7 @@ private: nscoord mDefaultCellSpacingY;// the default cell spacing X for this table nscoord mDefaultCellPadding; // the default cell padding for this table - nsVoidArray mBorderEdges[4]; // one list of border segments for each side of the table frame + nsBorderEdges mBorderEdges; // one list of border segments for each side of the table frame // used only for the collapsing border model }; diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 44b684d87f5..ece78154fee 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -1223,15 +1223,15 @@ void nsTableFrame::ComputeCollapsingBorders(PRInt32 aStartRowIndex, void nsTableFrame::ComputeLeftBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex) { // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull - PRInt32 numSegments = mBorderEdges[NS_SIDE_LEFT].Count(); + PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_LEFT].Count(); while (numSegments<=aRowIndex) { nsBorderEdge *borderToAdd = new nsBorderEdge(); - mBorderEdges[NS_SIDE_LEFT].AppendElement(borderToAdd); + mBorderEdges.mEdges[NS_SIDE_LEFT].AppendElement(borderToAdd); numSegments++; } // "border" is the border segment we are going to set - nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); + nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_LEFT].ElementAt(aRowIndex)); // collect all the incident frames and compute the dominant border nsVoidArray styles; @@ -1267,42 +1267,39 @@ void nsTableFrame::ComputeLeftBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColInd cellFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); styles.AppendElement((void*)spacing); } - ComputeCollapsedBorderSegment(NS_SIDE_LEFT, &styles, *border); - - + ComputeCollapsedBorderSegment(NS_SIDE_LEFT, &styles, *border, PR_FALSE); + // now give half the computed border to the table segment, and half to the cell + // XXX give half to the cell + border->mWidth = (border->mWidth)/2; + mBorderEdges.mMaxBorderWidth.left = PR_MAX(border->mWidth, mBorderEdges.mMaxBorderWidth.left); } void nsTableFrame::ComputeRightBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex) { -#if 0 // this method just uses mCellMap, because it can't get called unless nCellMap!=nsnull PRInt32 colCount = mCellMap->GetColCount(); - PRInt32 numSegments = mBorderEdges[NS_SIDE_RIGHT].Count(); + PRInt32 numSegments = mBorderEdges.mEdges[NS_SIDE_RIGHT].Count(); while (numSegments<=aRowIndex) { nsBorderEdge *borderToAdd = new nsBorderEdge(); - mBorderEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd); + mBorderEdges.mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd); numSegments++; } // "border" is the border segment we are going to set - nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); + nsBorderEdge *border = (nsBorderEdge *)(mBorderEdges.mEdges[NS_SIDE_RIGHT].ElementAt(aRowIndex)); // collect all the incident frames and compute the dominant border nsVoidArray styles; // styles are added to the array in the order least dominant -> most dominant // 1. table, only if this cell is in the right-most column and no rowspanning cell is - // to it's right. - PRBool useTable=PR_FALSE; - nsTableCellFrame *rightNeighborFrame=nsnull; - if ((colCount-1)==aColIndex) - useTable=PR_TRUE; - else + // to it's right. Otherwise, we remember what cell is the right neighbor + nsTableCellFrame *rightNeighborFrame=nsnull; + if ((colCount-1)!=aColIndex) { PRInt32 colIndex = aColIndex+1; for ( ; colIndexGetCellAt(aRowIndex, colIndex); if (cd != nsnull) { // there's really a cell at (aRowIndex, colIndex) if (nsnull==cd->mCell) @@ -1312,19 +1309,24 @@ void nsTableFrame::ComputeRightBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIn const PRInt32 realRowIndex = cell->GetRowIndex (); if (realRowIndex!=aRowIndex) { // the span is caused by a rowspan - result = PR_TRUE; + rightNeighborFrame = cd->mRealCell->mCell; break; } } + else + { + rightNeighborFrame = cd->mCell; + break; + } } - - - rightNeighborFrame = mCellMap->GetCellFrameAt(aRowIndex, colIndex); } } const nsStyleSpacing *spacing; - GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); - styles.AppendElement((void*)spacing); + if (nsnull==rightNeighborFrame) + { // if rightNeighborFrame is null, our right neighbor is the table + GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); + styles.AppendElement((void*)spacing); + } // 2. colgroup nsTableColFrame *colFrame = mCellMap->GetColumnFrame(aColIndex); nsIFrame *colGroupFrame; @@ -1352,8 +1354,17 @@ void nsTableFrame::ComputeRightBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIn cellFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); styles.AppendElement((void*)spacing); } - ComputeCollapsedBorderSegment(NS_SIDE_RIGHT, &styles, *border); -#endif + // 7. left edge of rightNeighborCell, if there is one + if (nsnull!=rightNeighborFrame) + { + rightNeighborFrame->GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)spacing)); + styles.AppendElement((void*)spacing); + } + ComputeCollapsedBorderSegment(NS_SIDE_RIGHT, &styles, *border, PRBool(nsnull!=rightNeighborFrame)); + // now give half the computed border to the table segment, and half to the cell + // XXX give half to the cell + border->mWidth = (border->mWidth)/2; //XXX: rounding + } void nsTableFrame::ComputeTopBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex) @@ -1382,6 +1393,26 @@ nscoord nsTableFrame::GetWidthForSide(const nsMargin &aBorder, PRUint8 aSide) else return aBorder.bottom; } +/* Given an Edge, find the opposing edge (top<-->bottom, left<-->right) */ +PRUint8 nsTableFrame::GetOpposingEdge(PRUint8 aEdge) +{ + PRUint8 result; + switch (aEdge) + { + case NS_SIDE_LEFT: + result = NS_SIDE_RIGHT; break; + case NS_SIDE_RIGHT: + result = NS_SIDE_LEFT; break; + case NS_SIDE_TOP: + result = NS_SIDE_BOTTOM; break; + case NS_SIDE_BOTTOM: + result = NS_SIDE_TOP; break; + default: + result = NS_SIDE_TOP; + } + return result; +} + /* returns BORDER_PRECEDENT_LOWER if aStyle1 is lower precedent that aStyle2 * BORDER_PRECEDENT_HIGHER if aStyle1 is higher precedent that aStyle2 * BORDER_PRECEDENT_EQUAL if aStyle1 and aStyle2 have the same precedence @@ -1490,9 +1521,10 @@ PRUint8 nsTableFrame::CompareBorderStyles(PRUint8 aStyle1, PRUint8 aStyle2) earlier in the list if the tie-breaker gets down to #4. This method sets the out-param aBorder with the resolved border attributes */ -void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, - nsVoidArray *aStyles, - nsBorderEdge &aBorder) +void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, + nsVoidArray *aStyles, + nsBorderEdge &aBorder, + PRBool aFlipLastSide) { if (nsnull!=aStyles) { @@ -1501,22 +1533,29 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, { nsVoidArray sameWidthBorders; nsStyleSpacing * spacing; + nsStyleSpacing * lastSpacing=nsnull; nsMargin border; PRInt32 maxWidth=0; PRInt32 i; + PRUint8 side = aSide; for (i=0; iElementAt(i)); - if (spacing->GetBorderStyle(aSide)==NS_STYLE_BORDER_STYLE_HIDDEN) + if ((PR_TRUE==aFlipLastSide) && (i==styleCount-1)) + { + side = GetOpposingEdge(aSide); + lastSpacing = spacing; + } + if (spacing->GetBorderStyle(side)==NS_STYLE_BORDER_STYLE_HIDDEN) { aBorder.mStyle=NS_STYLE_BORDER_STYLE_HIDDEN; aBorder.mWidth=0; return; } - else if (spacing->GetBorderStyle(aSide)!=NS_STYLE_BORDER_STYLE_NONE) + else if (spacing->GetBorderStyle(side)!=NS_STYLE_BORDER_STYLE_NONE) { spacing->GetBorder(border); - nscoord borderWidth = GetWidthForSide(border, aSide); + nscoord borderWidth = GetWidthForSide(border, side); if (borderWidth==maxWidth) sameWidthBorders.AppendElement(spacing); else if (borderWidth>maxWidth) @@ -1541,8 +1580,11 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, else if (1==styleCount) { // there was just one border of the largest width spacing = (nsStyleSpacing *)(sameWidthBorders.ElementAt(0)); - aBorder.mColor=spacing->GetBorderColor(aSide); - aBorder.mStyle=spacing->GetBorderStyle(aSide); + side=aSide; + if (spacing==lastSpacing) + side=GetOpposingEdge(aSide); + aBorder.mColor=spacing->GetBorderColor(side); + aBorder.mStyle=spacing->GetBorderStyle(side); return; } else @@ -1552,7 +1594,10 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, for (i=0; iElementAt(i)); - PRUint8 thisStyle = spacing->GetBorderStyle(aSide); + side=aSide; + if (spacing==lastSpacing) + side=GetOpposingEdge(aSide); + PRUint8 thisStyle = spacing->GetBorderStyle(side); PRUint8 borderCompare = CompareBorderStyles(thisStyle, winningStyle); if (BORDER_PRECEDENT_HIGHER==borderCompare) { @@ -1565,7 +1610,10 @@ void nsTableFrame::ComputeCollapsedBorderSegment(PRUint8 aSide, } } aBorder.mStyle = winningStyle; - aBorder.mColor = winningStyleBorder->GetBorderColor(aSide); + side=aSide; + if (winningStyleBorder==lastSpacing) + side=GetOpposingEdge(aSide); + aBorder.mColor = winningStyleBorder->GetBorderColor(side); } } } @@ -1810,13 +1858,21 @@ NS_METHOD nsTableFrame::Paint(nsIPresContext& aPresContext, (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + const nsStyleTable* tableStyle = + (const nsStyleTable*)mStyleContext->GetStyleData(eStyleStruct_Table); nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *color, 0, 0); PRIntn skipSides = GetSkipSides(); - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *spacing, skipSides); + if (NS_STYLE_BORDER_SEPARATE==tableStyle->mBorderCollapse) + { + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, skipSides); + } + else + { + } } // for debug... diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index 09b009c8b86..839db62cb7c 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -20,10 +20,10 @@ #include "nscore.h" #include "nsVoidArray.h" -#include "nsBorder.h" #include "nsHTMLContainerFrame.h" #include "nsStyleCoord.h" #include "nsStyleConsts.h" +#include "nsIStyleContext.h" #include "nsIFrameReflow.h" // for nsReflowReason enum @@ -216,13 +216,16 @@ public: void ComputeTopBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex); void ComputeBottomBorderForEdgeAt(PRInt32 aRowIndex, PRInt32 aColIndex); + PRUint8 GetOpposingEdge(PRUint8 aEdge); + nscoord GetWidthForSide(const nsMargin &aBorder, PRUint8 aSide); PRUint8 CompareBorderStyles(PRUint8 aStyle1, PRUint8 aStyle2); void ComputeCollapsedBorderSegment(PRUint8 aSide, nsVoidArray * aStyles, - nsBorderEdge& aBorder); + nsBorderEdge& aBorder, + PRBool aFlipLastSide); void RecalcLayoutData(); @@ -655,7 +658,7 @@ private: nscoord mDefaultCellSpacingY;// the default cell spacing X for this table nscoord mDefaultCellPadding; // the default cell padding for this table - nsVoidArray mBorderEdges[4]; // one list of border segments for each side of the table frame + nsBorderEdges mBorderEdges; // one list of border segments for each side of the table frame // used only for the collapsing border model };