nsTableFrame::CalcBCBorders(nsIPresContext& aPresContext)
nsTableFrame::CalcBCBorders(nsPresContext& aPresContext)
nsTableFrame::CalcBCBorders(nsIPresContext& aPresContext){  nsTableCellMap* tableCellMap = GetCellMap(); if (!tableCellMap) ABORT0();  PRInt32 numRows = GetRowCount();  PRInt32 numCols = GetColCount();  // Get the property holding the table damage area and border widths  BCPropertyData* propData =     (BCPropertyData*)nsTableFrame::GetProperty(&aPresContext, this, nsLayoutAtoms::tableBCProperty, PR_FALSE);  if (!propData) ABORT0();  CheckFixDamageArea(numRows, numCols, propData->mDamageArea);  // calculate an expanded damage area   nsRect damageArea(propData->mDamageArea);  ExpandBCDamageArea(damageArea);  // segments that are on the table border edges need to be initialized only once  PRBool tableBorderReset[4];  for (PRUint32 sideX = NS_SIDE_TOP; sideX <= NS_SIDE_LEFT; sideX++) {    tableBorderReset[sideX] = PR_FALSE;  }  GET_TWIPS_TO_PIXELS(&aPresContext, t2p);  // vertical borders indexed in x-direction (cols)  BCCellBorders lastVerBorders(damageArea.width + 1, damageArea.x); if (!lastVerBorders.borders) ABORT0();  BCCellBorder  lastTopBorder, lastBottomBorder;  // horizontal borders indexed in x-direction (cols)  BCCellBorders lastBottomBorders(damageArea.width + 1, damageArea.x); if (!lastBottomBorders.borders) ABORT0();  PRBool startSeg;  PRBool gotRowBorder = PR_FALSE;  BCMapCellInfo  info, ajaInfo;  BCBorderOwner  owner, ajaOwner;  nscolor   ownerColor, ajaColor;  PRUint8   ownerBStyle, ajaBStyle;  PRUint16  ownerWidth, ajaWidth;  PRInt32   cellEndRowIndex = -1;  PRInt32   cellEndColIndex = -1;  nscoord   smallHalf, largeHalf;  BCCorners topCorners(damageArea.width + 1, damageArea.x); if (!topCorners.corners) ABORT0();  BCCorners bottomCorners(damageArea.width + 1, damageArea.x); if (!bottomCorners.corners) ABORT0();  BCMapCellIterator iter(*this, damageArea);  for (iter.First(info); !iter.mAtEnd; iter.Next(info)) {    cellEndRowIndex = info.rowIndex + info.rowSpan - 1;    cellEndColIndex = info.colIndex + info.colSpan - 1;        PRBool bottomRowSpan = PR_FALSE;    // see if lastTopBorder, lastBottomBorder need to be reset    if (iter.IsNewRow()) {       gotRowBorder = PR_FALSE;      lastTopBorder.Reset(info.rowIndex, info.rowSpan);      lastBottomBorder.Reset(cellEndRowIndex + 1, info.rowSpan);    }    else if (info.colIndex > damageArea.x) {      lastBottomBorder = lastBottomBorders[info.colIndex - 1];      if (info.rowIndex > lastBottomBorder.index - lastBottomBorder.span) {         // the top border's left edge butts against the middle of a rowspan        lastTopBorder.Reset(info.rowIndex, info.rowSpan);      }      if (lastBottomBorder.index > (cellEndRowIndex + 1)) {         // the bottom border's left edge butts against the middle of a rowspan        lastBottomBorder.Reset(cellEndRowIndex + 1, info.rowSpan);        bottomRowSpan = PR_TRUE;      }    }    // find the dominate border considernig the cell's top border and the table, row group, row       // if the border is at the top of the table, otherwise it was processed in a previous row    if (0 == info.rowIndex) {      if (!tableBorderReset[NS_SIDE_TOP]) {        propData->mTopBorderWidth = 0;        tableBorderReset[NS_SIDE_TOP] = PR_TRUE;      }      for (PRInt32 colX = info.colIndex; colX <= cellEndColIndex; colX++) {        nsIFrame* colFrame = GetColFrame(colX); if (!colFrame) ABORT0();        nsIFrame* cgFrame = colFrame->GetParent(); if (!cgFrame) ABORT0();        CalcDominantBorder(this, cgFrame, colFrame, info.rg, info.topRow, info.cell, PR_TRUE, NS_SIDE_TOP,                            PR_FALSE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);        // update/store the top left & top right corners of the seg         BCCornerInfo& tlCorner = topCorners[colX]; // top left        if (0 == colX) {          tlCorner.Set(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);            }        else {          tlCorner.Update(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);           tableCellMap->SetBCBorderCorner(eTopLeft, *info.cellMap, 0, 0, colX,                                           tlCorner.ownerSide, tlCorner.subWidth, tlCorner.bevel);        }        topCorners[colX + 1].Set(NS_SIDE_LEFT, owner, ownerBStyle, ownerWidth, ownerColor); // top right        // update lastTopBorder and see if a new segment starts        startSeg = SetHorBorder(ownerBStyle, ownerWidth, ownerColor, tlCorner, lastTopBorder);        // store the border segment in the cell map         tableCellMap->SetBCBorderEdge(NS_SIDE_TOP, *info.cellMap, 0, 0, colX,                                      1, owner, ownerWidth, startSeg);        // update the affected borders of the cell, row, and table        DivideBCBorderSize(ownerWidth, smallHalf, largeHalf);        if (info.cell) {          info.cell->SetBorderWidth(NS_SIDE_TOP, PR_MAX(smallHalf, info.cell->GetBorderWidth(NS_SIDE_TOP)));        }        if (info.topRow) {          info.topRow->SetTopBCBorderWidth(PR_MAX(smallHalf, info.topRow->GetTopBCBorderWidth()));        }        propData->mTopBorderWidth = LimitBorderWidth(PR_MAX(propData->mTopBorderWidth, (PRUint8)ownerWidth));        //calculate column continuous borders        //we only need to do this once, so we'll do it only on the first row        if (colFrame) {          CalcDominantBorder(this, cgFrame, colFrame, info.rg, info.topRow,                             nsnull, PR_TRUE, NS_SIDE_TOP, PR_FALSE, t2p,                             owner, ownerBStyle, ownerWidth, ownerColor);          ((nsTableColFrame*)colFrame)->SetContinuousBCBorderWidth(NS_SIDE_TOP,                                                                   ownerWidth);          if (numCols == cellEndColIndex + 1) {            CalcDominantBorder(this, cgFrame, colFrame, nsnull, nsnull,                               nsnull, PR_TRUE, NS_SIDE_RIGHT, PR_FALSE, t2p,                               owner, ownerBStyle, ownerWidth, ownerColor);          }          else {            CalcDominantBorder(nsnull, cgFrame, colFrame, nsnull, nsnull,                               nsnull, PR_FALSE, NS_SIDE_RIGHT, PR_FALSE, t2p,                               owner, ownerBStyle, ownerWidth, ownerColor);          }          ((nsTableColFrame*)colFrame)->SetContinuousBCBorderWidth(NS_SIDE_RIGHT,                                                                   ownerWidth);        }      }      //calculate continuous top first row & rowgroup border: special case      //because it must include the table in the collapse      if (info.topRow) {        CalcDominantBorder(this, nsnull, nsnull, info.rg, info.topRow,                           nsnull, PR_TRUE, NS_SIDE_TOP, PR_FALSE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        info.topRow->SetContinuousBCBorderWidth(NS_SIDE_TOP, ownerWidth);      }      if (info.cgRight && info.cg) {        //calculate continuous top colgroup border once per colgroup        CalcDominantBorder(this, info.cg, nsnull, info.rg, info.topRow,                           nsnull, PR_TRUE, NS_SIDE_TOP, PR_FALSE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        info.cg->SetContinuousBCBorderWidth(NS_SIDE_TOP, ownerWidth);      }      if (0 == info.colIndex) {        CalcDominantBorder(this, info.cg, info.leftCol, nsnull, nsnull,                           nsnull, PR_TRUE, NS_SIDE_LEFT, PR_FALSE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        mBits.mLeftContBCBorder = ownerWidth;      }    }    else {      // see if the top border needs to be the start of a segment due to a vertical border owning the corner      if (info.colIndex > 0) {        BCData& data = ((BCCellData*)info.cellData)->mData;        if (!data.IsTopStart()) {          PRUint8 cornerSide;          PRPackedBool bevel;          data.GetCorner(cornerSide, bevel);          if ((NS_SIDE_TOP == cornerSide) || (NS_SIDE_BOTTOM == cornerSide)) {            data.SetTopStart(PR_TRUE);          }        }      }      }    // find the dominate border considernig the cell's left border and the table, col group, col      // if the border is at the left of the table, otherwise it was processed in a previous col    if (0 == info.colIndex) {      if (!tableBorderReset[NS_SIDE_LEFT]) {        propData->mLeftBorderWidth = 0;        tableBorderReset[NS_SIDE_LEFT] = PR_TRUE;      }      nsTableRowFrame* rowFrame = nsnull;      for (PRInt32 rowX = info.rowIndex; rowX <= cellEndRowIndex; rowX++) {        rowFrame = (rowX == info.rowIndex) ? info.topRow : rowFrame->GetNextRow();        CalcDominantBorder(this, info.cg, info.leftCol, info.rg, rowFrame, info.cell, PR_TRUE, NS_SIDE_LEFT,                           PR_FALSE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);        BCCornerInfo& tlCorner = (0 == rowX) ? topCorners[0] : bottomCorners[0]; // top left        tlCorner.Update(NS_SIDE_BOTTOM, owner, ownerBStyle, ownerWidth, ownerColor);        tableCellMap->SetBCBorderCorner(eTopLeft, *info.cellMap, iter.mRowGroupStart, rowX,                                         0, tlCorner.ownerSide, tlCorner.subWidth, tlCorner.bevel);        bottomCorners[0].Set(NS_SIDE_TOP, owner, ownerBStyle, ownerWidth, ownerColor); // bottom left                     // update lastVerBordersBorder and see if a new segment starts        startSeg = SetBorder(ownerBStyle, ownerWidth, ownerColor, lastVerBorders[0]);        // store the border segment in the cell map         tableCellMap->SetBCBorderEdge(NS_SIDE_LEFT, *info.cellMap, iter.mRowGroupStart, rowX,                                       info.colIndex, 1, owner, ownerWidth, startSeg);        // update the left border of the cell, col and table        DivideBCBorderSize(ownerWidth, smallHalf, largeHalf);        if (info.cell) {          info.cell->SetBorderWidth(NS_SIDE_LEFT, PR_MAX(smallHalf, info.cell->GetBorderWidth(NS_SIDE_LEFT)));        }        if (info.leftCol) {          info.leftCol->SetLeftBorderWidth(PR_MAX(smallHalf, info.leftCol->GetLeftBorderWidth()));        }        propData->mLeftBorderWidth = LimitBorderWidth(PR_MAX(propData->mLeftBorderWidth, ownerWidth));        //get row continuous borders        if (rowFrame) {          CalcDominantBorder(this, info.cg, info.leftCol, info.rg, rowFrame, nsnull, PR_TRUE, NS_SIDE_LEFT,                             PR_FALSE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);          rowFrame->SetContinuousBCBorderWidth(NS_SIDE_LEFT, ownerWidth);        }      }      //get row group continuous borders      if (info.rgBottom && info.rg) { //once per row group, so check for bottom        CalcDominantBorder(this, info.cg, info.leftCol, info.rg, nsnull,                           nsnull, PR_TRUE, NS_SIDE_LEFT, PR_FALSE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        info.rg->SetContinuousBCBorderWidth(NS_SIDE_LEFT, ownerWidth);      }    }    // find the dominate border considernig the cell's right border, adjacent cells and the table, row group, row    if (numCols == cellEndColIndex + 1) { // touches right edge of table      if (!tableBorderReset[NS_SIDE_RIGHT]) {        propData->mRightBorderWidth = 0;        tableBorderReset[NS_SIDE_RIGHT] = PR_TRUE;      }      nsTableRowFrame* rowFrame = nsnull;      for (PRInt32 rowX = info.rowIndex; rowX <= cellEndRowIndex; rowX++) {        rowFrame = (rowX == info.rowIndex) ? info.topRow : rowFrame->GetNextRow();        CalcDominantBorder(this, info.cg, info.rightCol, info.rg, rowFrame, info.cell, PR_TRUE, NS_SIDE_RIGHT,                            PR_TRUE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);        // update/store the top right & bottom right corners         BCCornerInfo& trCorner = (0 == rowX) ? topCorners[cellEndColIndex + 1] : bottomCorners[cellEndColIndex + 1];         trCorner.Update(NS_SIDE_BOTTOM, owner, ownerBStyle, ownerWidth, ownerColor);   // top right        tableCellMap->SetBCBorderCorner(eTopRight, *info.cellMap, iter.mRowGroupStart, rowX,                                         cellEndColIndex, trCorner.ownerSide, trCorner.subWidth, trCorner.bevel);        BCCornerInfo& brCorner = bottomCorners[cellEndColIndex + 1];         brCorner.Set(NS_SIDE_TOP, owner, ownerBStyle, ownerWidth, ownerColor); // bottom right        tableCellMap->SetBCBorderCorner(eBottomRight, *info.cellMap, iter.mRowGroupStart, rowX,                                         cellEndColIndex, brCorner.ownerSide, brCorner.subWidth, brCorner.bevel);        // update lastVerBorders and see if a new segment starts        startSeg = SetBorder(ownerBStyle, ownerWidth, ownerColor, lastVerBorders[cellEndColIndex + 1]);        // store the border segment in the cell map and update cellBorders        tableCellMap->SetBCBorderEdge(NS_SIDE_RIGHT, *info.cellMap, iter.mRowGroupStart, rowX,                                       cellEndColIndex, 1, owner, ownerWidth, startSeg);        // update the affected borders of the cell, col, and table        DivideBCBorderSize(ownerWidth, smallHalf, largeHalf);        if (info.cell) {          info.cell->SetBorderWidth(NS_SIDE_RIGHT, PR_MAX(largeHalf, info.cell->GetBorderWidth(NS_SIDE_RIGHT)));        }        if (info.rightCol) {          info.rightCol->SetRightBorderWidth(PR_MAX(largeHalf, info.rightCol->GetRightBorderWidth()));        }        propData->mRightBorderWidth = LimitBorderWidth(PR_MAX(propData->mRightBorderWidth, ownerWidth));        //get row continuous borders        if (rowFrame) {          CalcDominantBorder(this, info.cg, info.rightCol, info.rg, rowFrame,                             nsnull, PR_TRUE, NS_SIDE_RIGHT, PR_TRUE, t2p,                             owner, ownerBStyle, ownerWidth, ownerColor);          rowFrame->SetContinuousBCBorderWidth(NS_SIDE_RIGHT, ownerWidth);        }      }      //get row group continuous borders      if (info.rgBottom && info.rg) { //once per rg, so check for bottom        CalcDominantBorder(this, info.cg, info.rightCol, info.rg, nsnull,                           nsnull, PR_TRUE, NS_SIDE_RIGHT, PR_TRUE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        info.rg->SetContinuousBCBorderWidth(NS_SIDE_RIGHT, ownerWidth);      }    }    else {      PRInt32 segLength = 0;      BCMapCellInfo priorAjaInfo;      for (PRInt32 rowX = info.rowIndex; rowX <= cellEndRowIndex; rowX += segLength) {        iter.PeekRight(info, rowX, ajaInfo);        const nsIFrame* cg = (info.cgRight) ? info.cg : nsnull;        CalcDominantBorder(nsnull, cg, info.rightCol, nsnull, nsnull, info.cell, PR_FALSE, NS_SIDE_RIGHT,                            PR_TRUE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);        cg = (ajaInfo.cgLeft) ? ajaInfo.cg : nsnull;        CalcDominantBorder(nsnull, cg, ajaInfo.leftCol, nsnull, nsnull, ajaInfo.cell, PR_FALSE, NS_SIDE_LEFT,                            PR_FALSE, t2p, ajaOwner, ajaBStyle, ajaWidth, ajaColor);        CalcDominantBorder(PR_FALSE, owner, ownerBStyle, ownerWidth, ownerColor, ajaOwner, ajaBStyle,                            ajaWidth, ajaColor, owner, ownerBStyle, ownerWidth, ownerColor, PR_FALSE);        segLength = PR_MAX(1, ajaInfo.rowIndex + ajaInfo.rowSpan - rowX);        segLength = PR_MIN(segLength, info.rowIndex + info.rowSpan - rowX);        // update lastVerBorders and see if a new segment starts        startSeg = SetBorder(ownerBStyle, ownerWidth, ownerColor, lastVerBorders[cellEndColIndex + 1]);        // store the border segment in the cell map and update cellBorders        if (RIGHT_DAMAGED(cellEndColIndex) && TOP_DAMAGED(rowX) && BOTTOM_DAMAGED(rowX)) {          tableCellMap->SetBCBorderEdge(NS_SIDE_RIGHT, *info.cellMap, iter.mRowGroupStart, rowX,                                         cellEndColIndex, segLength, owner, ownerWidth, startSeg);          // update the borders of the cells and cols affected           DivideBCBorderSize(ownerWidth, smallHalf, largeHalf);          if (info.cell) {            info.cell->SetBorderWidth(NS_SIDE_RIGHT, PR_MAX(largeHalf, info.cell->GetBorderWidth(NS_SIDE_RIGHT)));          }          if (info.rightCol) {            info.rightCol->SetRightBorderWidth(PR_MAX(largeHalf, info.rightCol->GetRightBorderWidth()));          }          if (ajaInfo.cell) {            ajaInfo.cell->SetBorderWidth(NS_SIDE_LEFT, PR_MAX(smallHalf, ajaInfo.cell->GetBorderWidth(NS_SIDE_LEFT)));          }          if (ajaInfo.leftCol) {            ajaInfo.leftCol->SetLeftBorderWidth(PR_MAX(smallHalf, ajaInfo.leftCol->GetLeftBorderWidth()));          }        }        // update the top right corner        PRBool hitsSpanOnRight = (rowX > ajaInfo.rowIndex) && (rowX < ajaInfo.rowIndex + ajaInfo.rowSpan);        BCCornerInfo* trCorner = ((0 == rowX) || hitsSpanOnRight)                                  ? &topCorners[cellEndColIndex + 1] : &bottomCorners[cellEndColIndex + 1];         trCorner->Update(NS_SIDE_BOTTOM, owner, ownerBStyle, ownerWidth, ownerColor);           // if this is not the first time through, consider the segment to the right        if (rowX != info.rowIndex) {          const nsIFrame* rg = (priorAjaInfo.rgBottom) ? priorAjaInfo.rg : nsnull;          CalcDominantBorder(nsnull, nsnull, nsnull, rg, priorAjaInfo.bottomRow, priorAjaInfo.cell, PR_FALSE,                              NS_SIDE_BOTTOM, PR_TRUE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);          rg = (ajaInfo.rgTop) ? ajaInfo.rg : nsnull;          CalcDominantBorder(nsnull, nsnull, nsnull, rg, ajaInfo.topRow, ajaInfo.cell, PR_FALSE, NS_SIDE_TOP,                              PR_FALSE, t2p, ajaOwner, ajaBStyle, ajaWidth, ajaColor);          CalcDominantBorder(PR_FALSE, owner, ownerBStyle, ownerWidth, ownerColor, ajaOwner, ajaBStyle,                              ajaWidth, ajaColor, owner, ownerBStyle, ownerWidth, ownerColor, PR_TRUE);          trCorner->Update(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);           }        // store the top right corner in the cell map         if (RIGHT_DAMAGED(cellEndColIndex) && TOP_DAMAGED(rowX)) {          if (0 != rowX) {            tableCellMap->SetBCBorderCorner(eTopRight, *info.cellMap, iter.mRowGroupStart, rowX, cellEndColIndex,                                             trCorner->ownerSide, trCorner->subWidth, trCorner->bevel);          }          // store any corners this cell spans together with the aja cell          for (PRInt32 rX = rowX + 1; rX < rowX + segLength; rX++) {            tableCellMap->SetBCBorderCorner(eBottomRight, *info.cellMap, iter.mRowGroupStart, rX,                                             cellEndColIndex, trCorner->ownerSide, trCorner->subWidth, PR_FALSE);          }        }        // update bottom right corner, topCorners, bottomCorners        hitsSpanOnRight = (rowX + segLength < ajaInfo.rowIndex + ajaInfo.rowSpan);        BCCornerInfo& brCorner = (hitsSpanOnRight) ? topCorners[cellEndColIndex + 1]                                                    : bottomCorners[cellEndColIndex + 1];        brCorner.Set(NS_SIDE_TOP, owner, ownerBStyle, ownerWidth, ownerColor);        priorAjaInfo = ajaInfo;      }    }    for (PRInt32 colX = info.colIndex + 1; colX <= cellEndColIndex; colX++) {      lastVerBorders[colX].Reset();    }    // find the dominate border considernig the cell's bottom border, adjacent cells and the table, row group, row    if (numRows == cellEndRowIndex + 1) { // touches botom edge of table      if (!tableBorderReset[NS_SIDE_BOTTOM]) {        propData->mBottomBorderWidth = 0;        tableBorderReset[NS_SIDE_BOTTOM] = PR_TRUE;      }      for (PRInt32 colX = info.colIndex; colX <= cellEndColIndex; colX++) {        nsIFrame* colFrame = GetColFrame(colX); if (!colFrame) ABORT0();        nsIFrame* cgFrame = colFrame->GetParent(); if (!cgFrame) ABORT0();        CalcDominantBorder(this, cgFrame, colFrame, info.rg, info.bottomRow, info.cell, PR_TRUE, NS_SIDE_BOTTOM,                            PR_TRUE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);        // update/store the bottom left & bottom right corners         BCCornerInfo& blCorner = bottomCorners[colX]; // bottom left        blCorner.Update(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);             tableCellMap->SetBCBorderCorner(eBottomLeft, *info.cellMap, iter.mRowGroupStart, cellEndRowIndex,                                                        colX, blCorner.ownerSide, blCorner.subWidth, blCorner.bevel);         BCCornerInfo& brCorner = bottomCorners[colX + 1]; // bottom right        brCorner.Update(NS_SIDE_LEFT, owner, ownerBStyle, ownerWidth, ownerColor);         if (numCols == colX + 1) { // lower right corner of the table          tableCellMap->SetBCBorderCorner(eBottomRight, *info.cellMap, iter.mRowGroupStart, cellEndRowIndex,                                                         colX, brCorner.ownerSide, brCorner.subWidth, brCorner.bevel, PR_TRUE);          }        // update lastBottomBorder and see if a new segment starts        startSeg = SetHorBorder(ownerBStyle, ownerWidth, ownerColor, blCorner, lastBottomBorder);        if (!startSeg) {            // make sure that we did not compare apples to oranges i.e. the current border            // should be a continuation of the lastBottomBorder, as it is a bottom border            // add 1 to the cellEndRowIndex           startSeg = (lastBottomBorder.index != cellEndRowIndex + 1);         }        // store the border segment in the cell map and update cellBorders        tableCellMap->SetBCBorderEdge(NS_SIDE_BOTTOM, *info.cellMap, iter.mRowGroupStart, cellEndRowIndex,                                       colX, 1, owner, ownerWidth, startSeg);        // update the bottom borders of the cell, the bottom row, and the table         DivideBCBorderSize(ownerWidth, smallHalf, largeHalf);        if (info.cell) {          info.cell->SetBorderWidth(NS_SIDE_BOTTOM, PR_MAX(largeHalf, info.cell->GetBorderWidth(NS_SIDE_BOTTOM)));        }        if (info.bottomRow) {          info.bottomRow->SetBottomBCBorderWidth(PR_MAX(largeHalf, info.bottomRow->GetBottomBCBorderWidth()));        }        propData->mBottomBorderWidth = LimitBorderWidth(PR_MAX(propData->mBottomBorderWidth, ownerWidth));        // update lastBottomBorders        lastBottomBorder.index = cellEndRowIndex + 1;        lastBottomBorder.span = info.rowSpan;        lastBottomBorders[colX] = lastBottomBorder;        //get col continuous border        if (colFrame) {          CalcDominantBorder(this, cgFrame, colFrame, info.rg, info.bottomRow,                             nsnull, PR_TRUE, NS_SIDE_BOTTOM, PR_TRUE, t2p,                             owner, ownerBStyle, ownerWidth, ownerColor);          ((nsTableColFrame*)colFrame)->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM,                                                                   ownerWidth);        }      }      //get row group/col group continuous border      if (info.rg) {        CalcDominantBorder(this, nsnull, nsnull, info.rg, info.bottomRow,                           nsnull, PR_TRUE, NS_SIDE_BOTTOM, PR_TRUE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        info.rg->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM, ownerWidth);      }      if (info.cg) {        CalcDominantBorder(this, info.cg, nsnull, info.rg, info.bottomRow,                           nsnull, PR_TRUE, NS_SIDE_BOTTOM, PR_TRUE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        info.cg->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM, ownerWidth);      }    }    else {      PRInt32 segLength = 0;      for (PRInt32 colX = info.colIndex; colX <= cellEndColIndex; colX += segLength) {        iter.PeekBottom(info, colX, ajaInfo);        const nsIFrame* rg = (info.rgBottom) ? info.rg : nsnull;        CalcDominantBorder(nsnull, nsnull, nsnull, rg, info.bottomRow, info.cell, PR_FALSE, NS_SIDE_BOTTOM,                           PR_TRUE, t2p, owner, ownerBStyle, ownerWidth, ownerColor);        rg = (ajaInfo.rgTop) ? ajaInfo.rg : nsnull;        CalcDominantBorder(nsnull, nsnull, nsnull, rg, ajaInfo.topRow, ajaInfo.cell, PR_FALSE, NS_SIDE_TOP,                           PR_FALSE, t2p, ajaOwner, ajaBStyle, ajaWidth, ajaColor);        CalcDominantBorder(PR_FALSE, owner, ownerBStyle, ownerWidth, ownerColor, ajaOwner, ajaBStyle, ajaWidth,                           ajaColor, owner, ownerBStyle, ownerWidth, ownerColor, PR_TRUE);        segLength = PR_MAX(1, ajaInfo.colIndex + ajaInfo.colSpan - colX);        segLength = PR_MIN(segLength, info.colIndex + info.colSpan - colX);        // update, store the bottom left corner        BCCornerInfo& blCorner = bottomCorners[colX]; // bottom left        PRBool hitsSpanBelow = (colX > ajaInfo.colIndex) && (colX < ajaInfo.colIndex + ajaInfo.colSpan);        PRBool update = PR_TRUE;        if ((colX == info.colIndex) && (colX > damageArea.x)) {          PRInt32 prevRowIndex = lastBottomBorders[colX - 1].index;          if (prevRowIndex > cellEndRowIndex + 1) { // hits a rowspan on the right            update = PR_FALSE; // the corner was taken care of during the cell on the left          }          else if (prevRowIndex < cellEndRowIndex + 1) { // spans below the cell to the left            topCorners[colX] = blCorner;            blCorner.Set(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);            update = PR_FALSE;          }        }        if (update) {          blCorner.Update(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);        }        if (BOTTOM_DAMAGED(cellEndRowIndex) && LEFT_DAMAGED(colX)) {          if (hitsSpanBelow) {            tableCellMap->SetBCBorderCorner(eBottomLeft, *info.cellMap, iter.mRowGroupStart, cellEndRowIndex, colX,                                            blCorner.ownerSide, blCorner.subWidth, blCorner.bevel);          }          // store any corners this cell spans together with the aja cell          for (PRInt32 cX = colX + 1; cX < colX + segLength; cX++) {            BCCornerInfo& corner = bottomCorners[cX];            corner.Set(NS_SIDE_RIGHT, owner, ownerBStyle, ownerWidth, ownerColor);            tableCellMap->SetBCBorderCorner(eBottomLeft, *info.cellMap, iter.mRowGroupStart, cellEndRowIndex,                                            cX, corner.ownerSide, corner.subWidth, PR_FALSE);          }        }        // update lastBottomBorders and see if a new segment starts        startSeg = SetHorBorder(ownerBStyle, ownerWidth, ownerColor, blCorner, lastBottomBorder);        if (!startSeg) {            // make sure that we did not compare apples to oranges i.e. the current border            // should be a continuation of the lastBottomBorder, as it is a bottom border            // add 1 to the cellEndRowIndex           startSeg = (lastBottomBorder.index != cellEndRowIndex + 1);         }        lastBottomBorder.index = cellEndRowIndex + 1;        lastBottomBorder.span = info.rowSpan;        for (PRInt32 cX = colX; cX < colX + segLength; cX++) {          lastBottomBorders[cX] = lastBottomBorder;        }        // store the border segment the cell map and update cellBorders        if (BOTTOM_DAMAGED(cellEndRowIndex) && LEFT_DAMAGED(colX) && RIGHT_DAMAGED(colX)) {          tableCellMap->SetBCBorderEdge(NS_SIDE_BOTTOM, *info.cellMap, iter.mRowGroupStart, cellEndRowIndex,                                        colX, segLength, owner, ownerWidth, startSeg);          // update the borders of the affected cells and rows          DivideBCBorderSize(ownerWidth, smallHalf, largeHalf);          if (info.cell) {            info.cell->SetBorderWidth(NS_SIDE_BOTTOM, PR_MAX(largeHalf, info.cell->GetBorderWidth(NS_SIDE_BOTTOM)));          }          if (info.bottomRow) {            info.bottomRow->SetBottomBCBorderWidth(PR_MAX(largeHalf, info.bottomRow->GetBottomBCBorderWidth()));          }          if (ajaInfo.cell) {            ajaInfo.cell->SetBorderWidth(NS_SIDE_TOP, PR_MAX(smallHalf, ajaInfo.cell->GetBorderWidth(NS_SIDE_TOP)));          }          if (ajaInfo.topRow) {            ajaInfo.topRow->SetTopBCBorderWidth(PR_MAX(smallHalf, ajaInfo.topRow->GetTopBCBorderWidth()));          }        }        // update bottom right corner        BCCornerInfo& brCorner = bottomCorners[colX + segLength];        brCorner.Update(NS_SIDE_LEFT, owner, ownerBStyle, ownerWidth, ownerColor);      }      if (!gotRowBorder && 1 == info.rowSpan && (ajaInfo.topRow || info.rgBottom)) {        //get continuous row/row group border        //we need to check the row group's bottom border if this is        //the last row in the row group, but only a cell with rowspan=1        //will know whether *this* row is at the bottom        const nsIFrame* rg = (info.rgBottom) ? info.rg : nsnull;        CalcDominantBorder(nsnull, nsnull, nsnull, rg, info.bottomRow,                           nsnull, PR_FALSE, NS_SIDE_BOTTOM, PR_TRUE, t2p,                           owner, ownerBStyle, ownerWidth, ownerColor);        rg = (ajaInfo.rgTop) ? ajaInfo.rg : nsnull;        CalcDominantBorder(nsnull, nsnull, nsnull, rg, ajaInfo.topRow,                           nsnull, PR_FALSE, NS_SIDE_TOP, PR_FALSE, t2p,                           ajaOwner, ajaBStyle, ajaWidth, ajaColor);        CalcDominantBorder(PR_FALSE, owner, ownerBStyle, ownerWidth,                           ownerColor, ajaOwner, ajaBStyle, ajaWidth,                           ajaColor, owner, ownerBStyle, ownerWidth,                           ownerColor, PR_TRUE);        if (ajaInfo.topRow) {          ajaInfo.topRow->SetContinuousBCBorderWidth(NS_SIDE_TOP, ownerWidth);        }        if (info.rgBottom && info.rg) {          info.rg->SetContinuousBCBorderWidth(NS_SIDE_BOTTOM, ownerWidth);        }        gotRowBorder = PR_TRUE;      }    }    // see if the cell to the right had a rowspan and its lower left border needs be joined with this one's bottom    if ((numCols != cellEndColIndex + 1) &&                  // there is a cell to the right        (lastBottomBorders[cellEndColIndex + 1].span > 1)) { // cell to right was a rowspan      BCCornerInfo& corner = bottomCorners[cellEndColIndex + 1];      if ((NS_SIDE_TOP != corner.ownerSide) && (NS_SIDE_BOTTOM != corner.ownerSide)) { // not a vertical owner        BCCellBorder& thisBorder = lastBottomBorder;        BCCellBorder& nextBorder = lastBottomBorders[info.colIndex + 1];        if ((thisBorder.color == nextBorder.color) && (thisBorder.width == nextBorder.width) &&            (thisBorder.style == nextBorder.style)) {          // set the flag on the next border indicating it is not the start of a new segment          if (iter.mCellMap) {            BCData* bcData = tableCellMap->GetBCData(NS_SIDE_BOTTOM, *iter.mCellMap, cellEndRowIndex,                                                      cellEndColIndex + 1);            if (bcData) {              bcData->SetTopStart(PR_FALSE);            }          }        }      }    }  } // for (iter.First(info); info.cell; iter.Next(info)) {  // reset the bc flag and damage area  SetNeedToCalcBCBorders(PR_FALSE);  propData->mDamageArea.x = propData->mDamageArea.y = propData->mDamageArea.width = propData->mDamageArea.height = 0;#ifdef DEBUG_TABLE_CELLMAP  mCellMap->Dump();#endif}