зеркало из https://github.com/mozilla/gecko-dev.git
bug 41262 - new table border collapsing code. sr=attinasi, r=alexsavulov.
This commit is contained in:
Родитель
b3d4a89ff5
Коммит
679c575202
|
@ -1412,39 +1412,44 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes,
|
|||
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
|
||||
}
|
||||
else if (aData->mSID == eStyleStruct_Border && aData->mMarginData) {
|
||||
const nsStyleDisplay* readDisplay = (nsStyleDisplay*)
|
||||
aData->mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
|
||||
if (!aData->mStyleContext) return;
|
||||
const nsStyleTableBorder* tableStyle =
|
||||
(const nsStyleTableBorder*)aData->mStyleContext->GetStyleData(eStyleStruct_TableBorder);
|
||||
const nsStyleDisplay* readDisplay =
|
||||
(nsStyleDisplay*) aData->mStyleContext->GetStyleData(eStyleStruct_Display);
|
||||
if (readDisplay &&
|
||||
(readDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CELL)) {
|
||||
// set the cell's border from the table
|
||||
nsHTMLValue value;
|
||||
aAttributes->GetAttribute(nsHTMLAtoms::border, value);
|
||||
if (((value.GetUnit() == eHTMLUnit_Pixel) &&
|
||||
(value.GetPixelValue() > 0)) ||
|
||||
(value.GetUnit() == eHTMLUnit_Empty)) {
|
||||
if (aData->mMarginData->mBorderWidth->mLeft.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mLeft.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (aData->mMarginData->mBorderWidth->mRight.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mRight.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (aData->mMarginData->mBorderWidth->mTop.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mTop.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (aData->mMarginData->mBorderWidth->mBottom.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mBottom.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (NS_STYLE_BORDER_SEPARATE == tableStyle->mBorderCollapse) {
|
||||
// Set the cell's border from the table in the separate border model. If there is a border
|
||||
// on the table, then the mapping to rules=all will take care of borders in the collapsing model.
|
||||
nsHTMLValue value;
|
||||
aAttributes->GetAttribute(nsHTMLAtoms::border, value);
|
||||
if (((value.GetUnit() == eHTMLUnit_Pixel) &&
|
||||
(value.GetPixelValue() > 0)) ||
|
||||
(value.GetUnit() == eHTMLUnit_Empty)) {
|
||||
if (aData->mMarginData->mBorderWidth->mLeft.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mLeft.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (aData->mMarginData->mBorderWidth->mRight.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mRight.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (aData->mMarginData->mBorderWidth->mTop.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mTop.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
if (aData->mMarginData->mBorderWidth->mBottom.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderWidth->mBottom.SetFloatValue(1.0f, eCSSUnit_Pixel);
|
||||
|
||||
PRUint8 borderStyle = (eCompatibility_NavQuirks == mode)
|
||||
? NS_STYLE_BORDER_STYLE_BG_INSET : NS_STYLE_BORDER_STYLE_INSET;
|
||||
PRUint8 borderStyle = (eCompatibility_NavQuirks == mode)
|
||||
? NS_STYLE_BORDER_STYLE_BG_INSET : NS_STYLE_BORDER_STYLE_INSET;
|
||||
// BG_INSET results in a border color based on background colors
|
||||
// used for NavQuirks only...
|
||||
|
||||
if (aData->mMarginData->mBorderStyle->mLeft.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mLeft.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mRight.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mRight.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mTop.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mTop.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mBottom.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mBottom.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mLeft.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mLeft.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mRight.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mRight.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mTop.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mTop.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
if (aData->mMarginData->mBorderStyle->mBottom.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderStyle->mBottom.SetIntValue(borderStyle, eCSSUnit_Enumerated);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1458,7 +1463,6 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes,
|
|||
PRUint8 borderStyle = (eCompatibility_NavQuirks == mode)
|
||||
? NS_STYLE_BORDER_STYLE_BG_OUTSET :
|
||||
NS_STYLE_BORDER_STYLE_OUTSET;
|
||||
|
||||
// bordercolor
|
||||
nsHTMLValue value;
|
||||
aAttributes->GetAttribute(nsHTMLAtoms::bordercolor, value);
|
||||
|
@ -1476,6 +1480,18 @@ MapAttributesIntoRule(const nsIHTMLMappedAttributes* aAttributes,
|
|||
|
||||
borderStyle = NS_STYLE_BORDER_STYLE_OUTSET; // use css outset
|
||||
}
|
||||
else if (NS_STYLE_BORDER_COLLAPSE == tableStyle->mBorderCollapse) {
|
||||
// make the color grey
|
||||
nscolor color = NS_RGB(80, 80, 80);
|
||||
if (aData->mMarginData->mBorderColor->mLeft.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderColor->mLeft.SetColorValue(color);
|
||||
if (aData->mMarginData->mBorderColor->mRight.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderColor->mRight.SetColorValue(color);
|
||||
if (aData->mMarginData->mBorderColor->mTop.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderColor->mTop.SetColorValue(color);
|
||||
if (aData->mMarginData->mBorderColor->mBottom.GetUnit() == eCSSUnit_Null)
|
||||
aData->mMarginData->mBorderColor->mBottom.SetColorValue(color);
|
||||
}
|
||||
|
||||
// border and frame
|
||||
MapTableBorderInto(aAttributes, aData, borderStyle);
|
||||
|
@ -1500,7 +1516,6 @@ nsHTMLTableElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32
|
|||
(aAttribute == nsHTMLAtoms::cellpadding) ||
|
||||
(aAttribute == nsHTMLAtoms::cellspacing) ||
|
||||
(aAttribute == nsHTMLAtoms::cols) ||
|
||||
(aAttribute == nsHTMLAtoms::rules) ||
|
||||
(aAttribute == nsHTMLAtoms::border) ||
|
||||
(aAttribute == nsHTMLAtoms::frame) ||
|
||||
(aAttribute == nsHTMLAtoms::width) ||
|
||||
|
@ -1512,7 +1527,10 @@ nsHTMLTableElement::GetMappedAttributeImpact(const nsIAtom* aAttribute, PRInt32
|
|||
else if (aAttribute == nsHTMLAtoms::bordercolor) {
|
||||
aHint = NS_STYLE_HINT_VISUAL;
|
||||
}
|
||||
else if (aAttribute == nsHTMLAtoms::align) {
|
||||
else if ((aAttribute == nsHTMLAtoms::align) ||
|
||||
(aAttribute == nsHTMLAtoms::rules)) {
|
||||
// Changing to rules will force border-collapse. Unfortunately, if border-collapse was
|
||||
// already in effect, then a frame change is not necessary.
|
||||
aHint = NS_STYLE_HINT_FRAMECHANGE;
|
||||
}
|
||||
else if (!GetCommonMappedAttributesImpact(aAttribute, aHint)) {
|
||||
|
|
|
@ -475,6 +475,254 @@ TableTHRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessTableRulesAttribute(nsStyleStruct* aStyleStruct,
|
||||
nsRuleData* aRuleData,
|
||||
PRUint8 aSide,
|
||||
PRBool aGroup,
|
||||
PRUint8 aRulesArg1,
|
||||
PRUint8 aRulesArg2,
|
||||
PRUint8 aRulesArg3)
|
||||
{
|
||||
if (!aStyleStruct || !aRuleData || !aRuleData->mPresContext) return;
|
||||
|
||||
nsCOMPtr<nsIStyleContext> tableContext = getter_AddRefs(aRuleData->mStyleContext->GetParent()); if (!tableContext) return;
|
||||
if (!aGroup) {
|
||||
tableContext = getter_AddRefs(tableContext->GetParent()); if (!tableContext) return;
|
||||
}
|
||||
|
||||
const nsStyleTable* tableData =
|
||||
(const nsStyleTable*)tableContext->GetStyleData(eStyleStruct_Table);
|
||||
if (tableData && ((aRulesArg1 == tableData->mRules) ||
|
||||
(aRulesArg2 == tableData->mRules) ||
|
||||
(aRulesArg3 == tableData->mRules))) {
|
||||
const nsStyleBorder* tableBorderData =
|
||||
(const nsStyleBorder*)tableContext->GetStyleData(eStyleStruct_Border); if (!tableBorderData) return;
|
||||
PRUint8 tableBorderStyle = tableBorderData->GetBorderStyle(aSide);
|
||||
|
||||
nsStyleBorder* borderData = (nsStyleBorder*)aStyleStruct; if (!borderData) return;
|
||||
PRUint8 borderStyle = borderData->GetBorderStyle(aSide);
|
||||
// XXX It appears that the style system erronously applies the custom style rule after css style,
|
||||
// consequently it does not properly fit into the casade. For now, assume that a border style of none
|
||||
// implies that the style has not been set.
|
||||
if (NS_STYLE_BORDER_STYLE_NONE == borderStyle) {
|
||||
// use the table's border style if it is dashed or dotted, otherwise use solid
|
||||
PRUint8 bStyle = ((NS_STYLE_BORDER_STYLE_NONE != tableBorderStyle) &&
|
||||
(NS_STYLE_BORDER_STYLE_HIDDEN != tableBorderStyle))
|
||||
? tableBorderStyle : NS_STYLE_BORDER_STYLE_SOLID;
|
||||
if ((NS_STYLE_BORDER_STYLE_DASHED != bStyle) &&
|
||||
(NS_STYLE_BORDER_STYLE_DOTTED != bStyle) &&
|
||||
(NS_STYLE_BORDER_STYLE_SOLID != bStyle)) {
|
||||
bStyle = NS_STYLE_BORDER_STYLE_SOLID;
|
||||
}
|
||||
bStyle |= NS_STYLE_BORDER_STYLE_RULES_MASK;
|
||||
borderData->SetBorderStyle(aSide, bStyle);
|
||||
|
||||
nscolor borderColor;
|
||||
PRBool transparent, foreground;
|
||||
borderData->GetBorderColor(aSide, borderColor, transparent, foreground);
|
||||
if (transparent || foreground) {
|
||||
// use the table's border color if it is set, otherwise use black
|
||||
nscolor tableBorderColor;
|
||||
tableBorderData->GetBorderColor(aSide, tableBorderColor, transparent, foreground);
|
||||
borderColor = (transparent || foreground) ? NS_RGB(0,0,0) : tableBorderColor;
|
||||
borderData->SetBorderColor(aSide, borderColor);
|
||||
}
|
||||
// set the border width to be 1 pixel
|
||||
float p2t;
|
||||
aRuleData->mPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
nscoord onePixel = NSToCoordRound(p2t);
|
||||
nsStyleCoord coord(onePixel);
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
borderData->mBorder.SetTop(coord);
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
borderData->mBorder.SetRight(coord);
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
borderData->mBorder.SetBottom(coord);
|
||||
break;
|
||||
default: // NS_SIDE_LEFT
|
||||
borderData->mBorder.SetLeft(coord);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <thead>, <tbody>, <tfoot> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableTbodyRule: public GenericTableRule {
|
||||
public:
|
||||
TableTbodyRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableTbodyRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableTbodyRule::TableTbodyRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableTbodyRule::~TableTbodyRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void TbodyPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_TOP, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_BOTTOM, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableTbodyRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &TbodyPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <row> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableRowRule: public GenericTableRule {
|
||||
public:
|
||||
TableRowRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableRowRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableRowRule::TableRowRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableRowRule::~TableRowRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void RowPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_TOP, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_ROWS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_BOTTOM, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_ROWS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableRowRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &RowPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <colgroup> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableColgroupRule: public GenericTableRule {
|
||||
public:
|
||||
TableColgroupRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableColgroupRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableColgroupRule::TableColgroupRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableColgroupRule::~TableColgroupRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void ColgroupPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_LEFT, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_COLS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_RIGHT, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_COLS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableColgroupRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &ColgroupPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <col> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableColRule: public GenericTableRule {
|
||||
public:
|
||||
TableColRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableColRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableColRule::TableColRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableColRule::~TableColRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void ColPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_LEFT, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_COLS, NS_STYLE_TABLE_RULES_COLS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_RIGHT, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_COLS, NS_STYLE_TABLE_RULES_COLS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableColRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &ColPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
|
||||
class AttributeKey: public nsHashKey
|
||||
|
@ -653,6 +901,10 @@ protected:
|
|||
HTMLColorRule* mVisitedRule;
|
||||
HTMLColorRule* mActiveRule;
|
||||
HTMLDocumentColorRule* mDocumentColorRule;
|
||||
TableTbodyRule* mTableTbodyRule;
|
||||
TableRowRule* mTableRowRule;
|
||||
TableColgroupRule* mTableColgroupRule;
|
||||
TableColRule* mTableColRule;
|
||||
TableTHRule* mTableTHRule;
|
||||
// NOTE: if adding more rules, be sure to update
|
||||
// the SizeOf method to include them
|
||||
|
@ -710,6 +962,26 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(void)
|
|||
nsresult
|
||||
HTMLStyleSheetImpl::Init()
|
||||
{
|
||||
mTableTbodyRule = new TableTbodyRule(this);
|
||||
if (!mTableTbodyRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableTbodyRule);
|
||||
|
||||
mTableRowRule = new TableRowRule(this);
|
||||
if (!mTableRowRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableRowRule);
|
||||
|
||||
mTableColgroupRule = new TableColgroupRule(this);
|
||||
if (!mTableColgroupRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableColgroupRule);
|
||||
|
||||
mTableColRule = new TableColRule(this);
|
||||
if (!mTableColRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableColRule);
|
||||
|
||||
mTableTHRule = new TableTHRule(this);
|
||||
if (!mTableTHRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -750,6 +1022,22 @@ HTMLStyleSheetImpl::~HTMLStyleSheetImpl()
|
|||
mDocumentColorRule->mSheet = nsnull;
|
||||
NS_RELEASE(mDocumentColorRule);
|
||||
}
|
||||
if (nsnull != mTableTbodyRule) {
|
||||
mTableTbodyRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableTbodyRule);
|
||||
}
|
||||
if (nsnull != mTableRowRule) {
|
||||
mTableRowRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableRowRule);
|
||||
}
|
||||
if (nsnull != mTableColgroupRule) {
|
||||
mTableColgroupRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableColgroupRule);
|
||||
}
|
||||
if (nsnull != mTableColRule) {
|
||||
mTableColRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableColRule);
|
||||
}
|
||||
if (nsnull != mTableTHRule) {
|
||||
mTableTHRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableTHRule);
|
||||
|
@ -848,6 +1136,18 @@ HTMLStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
|
|||
else if (tag == nsHTMLAtoms::th) {
|
||||
ruleWalker->Forward(mTableTHRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::tr) {
|
||||
ruleWalker->Forward(mTableRowRule);
|
||||
}
|
||||
else if ((tag == nsHTMLAtoms::thead) || (tag == nsHTMLAtoms::tbody) || (tag == nsHTMLAtoms::tfoot)) {
|
||||
ruleWalker->Forward(mTableTbodyRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::col) {
|
||||
ruleWalker->Forward(mTableColRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::colgroup) {
|
||||
ruleWalker->Forward(mTableColgroupRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::table) {
|
||||
if (aData->mIsQuirkMode)
|
||||
ruleWalker->Forward(mDocumentColorRule);
|
||||
|
@ -888,7 +1188,13 @@ NS_IMETHODIMP
|
|||
HTMLStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
{
|
||||
// no pseudo frame style
|
||||
nsIAtom* pseudoTag = aData->mPseudoTag;
|
||||
if (pseudoTag == nsHTMLAtoms::tableColPseudo) {
|
||||
nsRuleWalker *ruleWalker = aData->mRuleWalker;
|
||||
if (ruleWalker) {
|
||||
ruleWalker->Forward(mTableColRule);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1008,6 +1314,11 @@ HTMLStyleSheetImpl::Reset(nsIURI* aURL)
|
|||
NS_RELEASE(mActiveRule);
|
||||
}
|
||||
mDocumentColorRule->Reset();
|
||||
|
||||
mTableTbodyRule->Reset();
|
||||
mTableRowRule->Reset();
|
||||
mTableColgroupRule->Reset();
|
||||
mTableColRule->Reset();
|
||||
mTableTHRule->Reset();
|
||||
|
||||
mMappedAttrTable.Enumerate(MappedDropSheet);
|
||||
|
@ -1264,6 +1575,10 @@ MappedSizeAttributes(nsHashKey *aKey, void *aData, void* closure)
|
|||
* - mVisitedRule
|
||||
* - mActiveRule
|
||||
* - mDocumentColorRule
|
||||
* - mTableTbodyRule
|
||||
* - mTableRowRule
|
||||
* - mTableColgroupRule
|
||||
* - mTableColRule
|
||||
* - mTableTHRule
|
||||
* - mMappedAttrTable
|
||||
* 2) Delegates (really) to the MappedAttributes in the mMappedAttrTable
|
||||
|
@ -1298,6 +1613,10 @@ HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
|
|||
// - mVisitedRule : sizeof object
|
||||
// - mActiveRule : sizeof object
|
||||
// - mDocumentColorRule : sizeof object
|
||||
// - mTableTbodyRule : sizeof object
|
||||
// - mTableRowRule : sizeof object
|
||||
// - mTableColgroupRule : sizeof object
|
||||
// - mTableColRule : sizeof object
|
||||
// - mTableTHRule : sizeof object
|
||||
// - mMappedAttrTable
|
||||
|
||||
|
@ -1321,6 +1640,26 @@ HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
|
|||
tag = getter_AddRefs(NS_NewAtom("DocumentColorRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableTbodyRule)){
|
||||
localSize = sizeof(*mTableTbodyRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableTbodyRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableRowRule)){
|
||||
localSize = sizeof(*mTableRowRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableRowRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableColgroupRule)){
|
||||
localSize = sizeof(*mTableColgroupRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableColgroupRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableColRule)){
|
||||
localSize = sizeof(*mTableColRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableColRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableTHRule)){
|
||||
localSize = sizeof(*mTableTHRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableTHRule"));
|
||||
|
|
|
@ -103,7 +103,7 @@ CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
|||
CSS_PROP(-moz-border-bottom-colors, border_bottom_colors, VISUAL)
|
||||
CSS_PROP(border-bottom-style, border_bottom_style, REFLOW) // on/off will need reflow
|
||||
CSS_PROP(border-bottom-width, border_bottom_width, REFLOW)
|
||||
CSS_PROP(border-collapse, border_collapse, REFLOW)
|
||||
CSS_PROP(border-collapse, border_collapse, FRAMECHANGE)
|
||||
CSS_PROP(border-color, border_color, VISUAL)
|
||||
CSS_PROP(border-left, border_left, REFLOW)
|
||||
CSS_PROP(border-left-color, border_left_color, VISUAL)
|
||||
|
|
|
@ -100,6 +100,7 @@ LAYOUT_ATOM(selectScrolledContentPseudo, ":-moz-select-scrolled-content")
|
|||
|
||||
// Alphabetical list of frame types
|
||||
LAYOUT_ATOM(areaFrame, "AreaFrame")
|
||||
LAYOUT_ATOM(bcTableCellFrame, "BCTableCellFrame") // table cell in border collapsing model
|
||||
LAYOUT_ATOM(blockFrame, "BlockFrame")
|
||||
LAYOUT_ATOM(boxFrame, "BoxFrame")
|
||||
LAYOUT_ATOM(brFrame, "BRFrame")
|
||||
|
@ -143,7 +144,8 @@ LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFra
|
|||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
|
||||
LAYOUT_ATOM(tableBCProperty, "TableBCProperty") // table border collapsing info (e.g. damage area, table border widths)
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty")
|
||||
|
||||
// Alphabetical list of event handler names
|
||||
LAYOUT_ATOM(onabort, "onabort")
|
||||
|
|
|
@ -465,7 +465,8 @@ struct nsStyleBorder: public nsStyleStruct {
|
|||
|
||||
// XXX these are deprecated methods
|
||||
void CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const;
|
||||
|
||||
void CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide, nscoord& aWidth) const;
|
||||
|
||||
protected:
|
||||
PRPackedBool mHasCachedBorder;
|
||||
nsMargin mCachedBorder;
|
||||
|
|
|
@ -605,6 +605,28 @@ nsStyleBorder::CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsStyleBorder::CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide, nscoord& aWidth) const
|
||||
{
|
||||
aWidth = 0;
|
||||
// using mCachedBorder as above, doesn't work properly
|
||||
nsStyleCoord coord;
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
coord = mBorder.GetTop(coord);
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
coord = mBorder.GetRight(coord);
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
coord = mBorder.GetBottom(coord);
|
||||
break;
|
||||
default: // NS_SIDE_LEFT
|
||||
coord = mBorder.GetLeft(coord);
|
||||
}
|
||||
aWidth = CalcSideFor(aFrame, coord, NS_SPACING_BORDER, aSide, mBorderWidths, 3);
|
||||
}
|
||||
|
||||
nsStyleOutline::nsStyleOutline(nsIPresContext* aPresContext)
|
||||
{
|
||||
// XXX support mBorderWidths until deprecated methods are removed
|
||||
|
@ -862,7 +884,7 @@ nsStyleTable::nsStyleTable()
|
|||
mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
|
||||
mCols = NS_STYLE_TABLE_COLS_NONE;
|
||||
mFrame = NS_STYLE_TABLE_FRAME_NONE;
|
||||
mRules = NS_STYLE_TABLE_RULES_ALL;
|
||||
mRules = NS_STYLE_TABLE_RULES_NONE;
|
||||
mSpan = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,11 @@
|
|||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
#include "nsTableCellFrame.h" // to get IS_CELL_FRAME
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleFrameConstruction.h"
|
||||
#include "nsHTMLParts.h"
|
||||
|
@ -859,6 +862,23 @@ nsFrameConstructorSaveState::~nsFrameConstructorSaveState()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
PRBool IsBorderCollapse(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* frame = aFrame;
|
||||
while (frame) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableFrame == fType.get()) {
|
||||
return ((nsTableFrame*)frame)->IsBorderCollapse();
|
||||
}
|
||||
frame->GetParent(&frame);
|
||||
}
|
||||
NS_ASSERTION(PR_FALSE, "program error");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// Structure used when creating table frames.
|
||||
|
@ -870,7 +890,7 @@ struct nsTableCreator {
|
|||
virtual nsresult CreateTableColFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableColGroupFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableRowFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableCellFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableCellFrame(nsIFrame* aParentFrame, nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableCellInnerFrame(nsIFrame** aNewFrame);
|
||||
|
||||
nsTableCreator(nsIPresShell* aPresShell)
|
||||
|
@ -919,8 +939,9 @@ nsTableCreator::CreateTableRowFrame(nsIFrame** aNewFrame) {
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTableCreator::CreateTableCellFrame(nsIFrame** aNewFrame) {
|
||||
return NS_NewTableCellFrame(mPresShell, aNewFrame);
|
||||
nsTableCreator::CreateTableCellFrame(nsIFrame* aParentFrame,
|
||||
nsIFrame** aNewFrame) {
|
||||
return NS_NewTableCellFrame(mPresShell, IsBorderCollapse(aParentFrame), aNewFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1527,7 +1548,7 @@ IsTableRelated(nsIAtom* aParentType,
|
|||
((nsLayoutAtoms::tableCaptionFrame == aParentType) ||
|
||||
(nsLayoutAtoms::tableColGroupFrame == aParentType) ||
|
||||
(nsLayoutAtoms::tableColFrame == aParentType) ||
|
||||
(nsLayoutAtoms::tableCellFrame == aParentType))) {
|
||||
IS_TABLE_CELL(aParentType))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else return PR_FALSE;
|
||||
|
@ -1629,7 +1650,7 @@ ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|||
|
||||
if (aPseudoFrames.mCellOuter.mFrame) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
}
|
||||
if (aPseudoFrames.mRow.mFrame) {
|
||||
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
||||
|
@ -1650,7 +1671,7 @@ ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|||
}
|
||||
if (aPseudoFrames.mCellOuter.mFrame) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
}
|
||||
if (aPseudoFrames.mRow.mFrame) {
|
||||
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
||||
|
@ -1671,12 +1692,12 @@ ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|||
}
|
||||
if (aPseudoFrames.mCellOuter.mFrame) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
}
|
||||
}
|
||||
else if (nsLayoutAtoms::tableCellFrame == aPseudoFrames.mLowestType) {
|
||||
else if (IS_TABLE_CELL(aPseudoFrames.mLowestType)) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
|
||||
if (aPseudoFrames.mRow.mFrame) {
|
||||
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
||||
|
@ -1942,6 +1963,7 @@ nsCSSFrameConstructor::CreatePseudoCellFrame(nsIPresShell* aPresShell
|
|||
|
||||
// set pseudo data for the newly created frames
|
||||
pseudoOuter.mChildList.AddChild(pseudoInner.mFrame);
|
||||
// give it nsLayoutAtoms::tableCellFrame, if it is really nsLayoutAtoms::bcTableCellFrame, it will match later
|
||||
aState.mPseudoFrames.mLowestType = nsLayoutAtoms::tableCellFrame;
|
||||
|
||||
// set pseudo data for the parent
|
||||
|
@ -2021,7 +2043,7 @@ nsCSSFrameConstructor::GetPseudoColGroupFrame(nsIPresShell* aPresShel
|
|||
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
created = PR_TRUE;
|
||||
}
|
||||
if (created || (nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
||||
if (created || IS_TABLE_CELL(parentFrameType.get()) || // cell parent
|
||||
!IsTableRelated(parentFrameType.get(), PR_TRUE)) { // block parent
|
||||
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
}
|
||||
|
@ -2065,7 +2087,7 @@ nsCSSFrameConstructor::GetPseudoRowGroupFrame(nsIPresShell* aPresShel
|
|||
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
created = PR_TRUE;
|
||||
}
|
||||
if (created || (nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
||||
if (created || IS_TABLE_CELL(parentFrameType.get()) || // cell parent
|
||||
!IsTableRelated(parentFrameType.get(), PR_TRUE)) { // block parent
|
||||
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
}
|
||||
|
@ -2102,7 +2124,7 @@ nsCSSFrameConstructor::GetPseudoRowFrame(nsIPresShell* aPresShell,
|
|||
|
||||
if (pseudoFrames.IsEmpty()) {
|
||||
PRBool created = PR_FALSE;
|
||||
if ((nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
||||
if (IS_TABLE_CELL(parentFrameType.get()) || // cell parent
|
||||
!IsTableRelated(parentFrameType.get(), PR_TRUE)) { // block parent
|
||||
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
created = PR_TRUE;
|
||||
|
@ -2230,7 +2252,7 @@ nsCSSFrameConstructor::GetParentFrame(nsIPresShell* aPresShell,
|
|||
pseudoParentFrame = pseudoFrames.mRowGroup.mFrame;
|
||||
}
|
||||
}
|
||||
else if (nsLayoutAtoms::tableCellFrame == aChildFrameType) { // cell child
|
||||
else if (IS_TABLE_CELL(aChildFrameType)) { // cell child
|
||||
if (nsLayoutAtoms::tableRowFrame != parentFrameType.get()) { // need pseudo row parent
|
||||
rv = GetPseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -2572,7 +2594,7 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShel
|
|||
PRBool& aIsPseudoParent)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
||||
if (!aPresShell || !aPresContext || !aParentFrameIn || !aStyleContext) return rv;
|
||||
|
||||
nsIFrame* parentFrame = aParentFrameIn;
|
||||
aIsPseudoParent = PR_FALSE;
|
||||
|
@ -2585,16 +2607,42 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShel
|
|||
}
|
||||
}
|
||||
|
||||
rv = aTableCreator.CreateTableColFrame(&aNewFrame);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
parentFrame, aStyleContext, nsnull, aNewFrame);
|
||||
rv = aTableCreator.CreateTableColFrame(&aNewFrame); if (NS_FAILED(rv)) return rv;
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, parentFrame, aStyleContext, nsnull, aNewFrame);
|
||||
// if the parent frame was anonymous then reparent the style context
|
||||
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
||||
parentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
||||
if (aIsPseudoParent) {
|
||||
aPresContext->ReParentStyleContext(aNewFrame, parentStyleContext);
|
||||
}
|
||||
|
||||
// construct additional col frames if the col frame has a span > 1
|
||||
PRInt32 span = 1;
|
||||
nsCOMPtr<nsIDOMHTMLTableColElement> cgContent(do_QueryInterface(aContent));
|
||||
if (cgContent) {
|
||||
cgContent->GetSpan(&span);
|
||||
nsIFrame* lastCol = aNewFrame;
|
||||
for (PRInt32 spanX = 1; spanX < span; spanX++) {
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::tableColPseudo, aStyleContext,
|
||||
PR_FALSE, getter_AddRefs(styleContext));
|
||||
nsIFrame* newCol;
|
||||
rv = aTableCreator.CreateTableColFrame(&newCol); if (NS_FAILED(rv)) return rv;
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, parentFrame, styleContext, nsnull, newCol);
|
||||
if (aIsPseudoParent) {
|
||||
aPresContext->ReParentStyleContext(newCol, aStyleContext);
|
||||
}
|
||||
((nsTableColFrame*)newCol)->SetType(eColAnonymousCol);
|
||||
lastCol->SetNextSibling(newCol);
|
||||
lastCol = newCol;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aIsPseudo) {
|
||||
nsFrameItems childItems;
|
||||
nsIFrame* captionFrame;
|
||||
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
||||
aTableCreator, childItems, captionFrame);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
aTableCreator, childItems, captionFrame); if (NS_FAILED(rv)) return rv;
|
||||
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
if (aIsPseudoParent) {
|
||||
aState.mPseudoFrames.mColGroup.mChildList.AddChild(aNewFrame);
|
||||
|
@ -2625,6 +2673,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShe
|
|||
aIsPseudoParent = PR_FALSE;
|
||||
if (!aIsPseudo) {
|
||||
// this frame may have a pseudo parent
|
||||
// use nsLayoutAtoms::tableCellFrame which will match if it is really nsLayoutAtoms::bcTableCellFrame
|
||||
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
||||
nsLayoutAtoms::tableCellFrame, aState, parentFrame, aIsPseudoParent);
|
||||
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
|
@ -2635,7 +2684,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShe
|
|||
}
|
||||
}
|
||||
|
||||
rv = aTableCreator.CreateTableCellFrame(&aNewCellOuterFrame);
|
||||
rv = aTableCreator.CreateTableCellFrame(parentFrame, &aNewCellOuterFrame);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Initialize the table cell frame
|
||||
|
@ -11328,7 +11377,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell,
|
|||
|
||||
// See if it's a table cell frame
|
||||
cellFrame->GetFrameType(&tableType);
|
||||
if (nsLayoutAtoms::tableCellFrame == tableType) {
|
||||
if (IS_TABLE_CELL(tableType)) {
|
||||
nsIFrame* continuingCellFrame;
|
||||
|
||||
CreateContinuingFrame(aPresShell, aPresContext, cellFrame, newFrame, &continuingCellFrame);
|
||||
|
@ -11343,8 +11392,8 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell,
|
|||
newFrame->SetInitialChildList(aPresContext, nsnull, newChildList.childList);
|
||||
}
|
||||
|
||||
} else if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
rv = NS_NewTableCellFrame(aPresShell, &newFrame);
|
||||
} else if (IS_TABLE_CELL(frameType)) {
|
||||
rv = NS_NewTableCellFrame(aPresShell, IsBorderCollapse(aParentFrame), &newFrame);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
||||
|
|
|
@ -514,6 +514,7 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw a dotted/dashed sides of a box
|
||||
*/
|
||||
|
@ -3821,3 +3822,356 @@ void FillOrInvertRect(nsIRenderingContext& aRC, const nsRect& aRect, PRBool aInv
|
|||
}
|
||||
}
|
||||
|
||||
// Begin table border-collapsing section
|
||||
// These functions were written to not disrupt the normal ones and yet satisfy some additional requirements
|
||||
// At some point, all functions should be unified to include the additional functionality that these provide
|
||||
|
||||
static nscoord
|
||||
RoundIntToPixel(nscoord aValue,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRBool aRoundDown = PR_FALSE)
|
||||
{
|
||||
nscoord halfPixel = NSToCoordRound(aTwipsPerPixel / 2.0f);
|
||||
nscoord extra = aValue % aTwipsPerPixel;
|
||||
nscoord finalValue = (!aRoundDown && (extra >= halfPixel)) ? aValue + (aTwipsPerPixel - extra) : aValue - extra;
|
||||
|
||||
return finalValue;
|
||||
}
|
||||
|
||||
static nscoord
|
||||
RoundFloatToPixel(float aValue,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRBool aRoundDown = PR_FALSE)
|
||||
{
|
||||
return RoundIntToPixel(NSToCoordRound(aValue), aTwipsPerPixel, aRoundDown);
|
||||
}
|
||||
|
||||
static void
|
||||
SetPoly(const nsRect& aRect,
|
||||
nsPoint* poly)
|
||||
{
|
||||
poly[0].x = aRect.x;
|
||||
poly[0].y = aRect.y;
|
||||
poly[1].x = aRect.x + aRect.width;
|
||||
poly[1].y = aRect.y;
|
||||
poly[2].x = aRect.x + aRect.width;
|
||||
poly[2].y = aRect.y + aRect.height;
|
||||
poly[3].x = aRect.x;
|
||||
poly[3].y = aRect.y + aRect.height;
|
||||
poly[4].x = aRect.x;
|
||||
poly[4].y = aRect.y;
|
||||
}
|
||||
|
||||
static void
|
||||
DrawSolidBorderSegment(nsIRenderingContext& aContext,
|
||||
nsRect aRect,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRUint8 aStartBevelSide = 0,
|
||||
nscoord aStartBevelOffset = 0,
|
||||
PRUint8 aEndBevelSide = 0,
|
||||
nscoord aEndBevelOffset = 0)
|
||||
{
|
||||
|
||||
if ((aRect.width == aTwipsPerPixel) || (aRect.height == aTwipsPerPixel) ||
|
||||
((0 == aStartBevelOffset) && (0 == aEndBevelOffset))) {
|
||||
// simple line or rectangle
|
||||
if ((NS_SIDE_TOP == aStartBevelSide) || (NS_SIDE_BOTTOM == aStartBevelSide)) {
|
||||
if (1 == aRect.height)
|
||||
aContext.DrawLine(aRect.x, aRect.y, aRect.x, aRect.y + aRect.height);
|
||||
else
|
||||
aContext.FillRect(aRect);
|
||||
}
|
||||
else {
|
||||
if (1 == aRect.width)
|
||||
aContext.DrawLine(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y);
|
||||
else
|
||||
aContext.FillRect(aRect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// polygon with beveling
|
||||
nsPoint poly[5];
|
||||
SetPoly(aRect, poly);
|
||||
switch(aStartBevelSide) {
|
||||
case NS_SIDE_TOP:
|
||||
poly[0].x += aStartBevelOffset;
|
||||
poly[4].x = poly[0].x;
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
poly[3].x += aStartBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
poly[1].y += aStartBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_LEFT:
|
||||
poly[0].y += aStartBevelOffset;
|
||||
poly[4].y = poly[0].y;
|
||||
}
|
||||
|
||||
switch(aEndBevelSide) {
|
||||
case NS_SIDE_TOP:
|
||||
poly[1].x -= aEndBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
poly[2].x -= aEndBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
poly[2].y -= aEndBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_LEFT:
|
||||
poly[3].y -= aEndBevelOffset;
|
||||
}
|
||||
|
||||
aContext.FillPolygon(poly, 5);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
GetDashInfo(nscoord aBorderLength,
|
||||
nscoord aDashLength,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRInt32& aNumDashSpaces,
|
||||
nscoord& aStartDashLength,
|
||||
nscoord& aEndDashLength)
|
||||
{
|
||||
aNumDashSpaces = 0;
|
||||
if (aStartDashLength + aDashLength + aEndDashLength >= aBorderLength) {
|
||||
aStartDashLength = aBorderLength;
|
||||
aEndDashLength = 0;
|
||||
}
|
||||
else {
|
||||
aNumDashSpaces = aBorderLength / (2 * aDashLength); // round down
|
||||
nscoord foo = ((2 * aNumDashSpaces) - 1) * aDashLength;
|
||||
nscoord extra = aBorderLength - aStartDashLength - aEndDashLength - (((2 * aNumDashSpaces) - 1) * aDashLength);
|
||||
if (extra > 0) {
|
||||
nscoord half = RoundIntToPixel(extra / 2, aTwipsPerPixel);
|
||||
aStartDashLength += half;
|
||||
aEndDashLength += (extra - half);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRendering::DrawTableBorderSegment(nsIRenderingContext& aContext,
|
||||
PRUint8 aBorderStyle,
|
||||
nscolor aBorderColor,
|
||||
const nsStyleBackground* aBGColor,
|
||||
const nsRect& aBorder,
|
||||
float aPixelsToTwips,
|
||||
PRUint8 aStartBevelSide,
|
||||
nscoord aStartBevelOffset,
|
||||
PRUint8 aEndBevelSide,
|
||||
nscoord aEndBevelOffset)
|
||||
{
|
||||
aContext.SetColor (aBorderColor);
|
||||
|
||||
PRBool horizontal = ((NS_SIDE_TOP == aStartBevelSide) || (NS_SIDE_BOTTOM == aStartBevelSide));
|
||||
nscoord twipsPerPixel = NSIntPixelsToTwips(1, aPixelsToTwips);
|
||||
PRBool ridgeGroove = NS_STYLE_BORDER_STYLE_RIDGE;
|
||||
|
||||
if ((twipsPerPixel >= aBorder.width) || (twipsPerPixel >= aBorder.height) ||
|
||||
(NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) || (NS_STYLE_BORDER_STYLE_DOTTED == aBorderStyle)) {
|
||||
// no beveling for 1 pixel border, dash or dot
|
||||
aStartBevelOffset = 0;
|
||||
aEndBevelOffset = 0;
|
||||
}
|
||||
|
||||
switch (aBorderStyle) {
|
||||
case NS_STYLE_BORDER_STYLE_NONE:
|
||||
case NS_STYLE_BORDER_STYLE_HIDDEN:
|
||||
case NS_STYLE_BORDER_STYLE_BLANK:
|
||||
//NS_ASSERTION(PR_FALSE, "style of none, hidden, or blank");
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_DOTTED:
|
||||
case NS_STYLE_BORDER_STYLE_DASHED:
|
||||
{
|
||||
nscoord dashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) ? DASH_LENGTH : DOT_LENGTH;
|
||||
// make the dash length proportional to the border thickness
|
||||
dashLength *= (horizontal) ? aBorder.height : aBorder.width;
|
||||
// make the min dash length for the ends 1/2 the dash length
|
||||
nscoord minDashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle)
|
||||
? RoundFloatToPixel(((float)dashLength) / 2.0f, twipsPerPixel) : dashLength;
|
||||
minDashLength = PR_MAX(minDashLength, twipsPerPixel);
|
||||
nscoord numDashSpaces = 0;
|
||||
nscoord startDashLength = minDashLength;
|
||||
nscoord endDashLength = minDashLength;
|
||||
if (horizontal) {
|
||||
GetDashInfo(aBorder.width, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
|
||||
nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height);
|
||||
DrawSolidBorderSegment(aContext, rect, PR_TRUE);
|
||||
for (PRInt32 spaceX = 0; spaceX < numDashSpaces; spaceX++) {
|
||||
rect.x += rect.width + dashLength;
|
||||
rect.width = (spaceX == (numDashSpaces - 1)) ? endDashLength : dashLength;
|
||||
DrawSolidBorderSegment(aContext, rect, PR_TRUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
GetDashInfo(aBorder.height, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
|
||||
nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength);
|
||||
DrawSolidBorderSegment(aContext, rect, PR_FALSE);
|
||||
for (PRInt32 spaceY = 0; spaceY < numDashSpaces; spaceY++) {
|
||||
rect.y += rect.height + dashLength;
|
||||
rect.height = (spaceY == (numDashSpaces - 1)) ? endDashLength : dashLength;
|
||||
DrawSolidBorderSegment(aContext, rect, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_GROOVE:
|
||||
ridgeGroove = NS_STYLE_BORDER_STYLE_GROOVE; // and fall through to ridge
|
||||
case NS_STYLE_BORDER_STYLE_RIDGE:
|
||||
if ((horizontal && (twipsPerPixel >= aBorder.height)) ||
|
||||
(!horizontal && (twipsPerPixel >= aBorder.width))) {
|
||||
// a one pixel border
|
||||
DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide, aStartBevelOffset,
|
||||
aEndBevelSide, aEndBevelOffset);
|
||||
}
|
||||
else {
|
||||
nscoord startBevel = (aStartBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.5f * (float)aStartBevelOffset, twipsPerPixel, PR_TRUE) : 0;
|
||||
nscoord endBevel = (aEndBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.5f * (float)aEndBevelOffset, twipsPerPixel, PR_TRUE) : 0;
|
||||
PRUint8 ridgeGrooveSide = (horizontal) ? NS_SIDE_TOP : NS_SIDE_LEFT;
|
||||
aContext.SetColor (
|
||||
MakeBevelColor (ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor, PR_TRUE));
|
||||
nsRect rect(aBorder);
|
||||
nscoord half;
|
||||
if (horizontal) { // top, bottom
|
||||
half = RoundFloatToPixel(0.5f * (float)aBorder.height, twipsPerPixel);
|
||||
rect.height = half;
|
||||
if (NS_SIDE_TOP == aStartBevelSide) {
|
||||
rect.x += startBevel;
|
||||
rect.width -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_TOP == aEndBevelSide) {
|
||||
rect.width -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
else { // left, right
|
||||
half = RoundFloatToPixel(0.5f * (float)aBorder.width, twipsPerPixel);
|
||||
rect.width = half;
|
||||
if (NS_SIDE_LEFT == aStartBevelSide) {
|
||||
rect.y += startBevel;
|
||||
rect.height -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_LEFT == aEndBevelSide) {
|
||||
rect.height -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
|
||||
rect = aBorder;
|
||||
ridgeGrooveSide = (NS_SIDE_TOP == ridgeGrooveSide) ? NS_SIDE_BOTTOM : NS_SIDE_RIGHT;
|
||||
aContext.SetColor (
|
||||
MakeBevelColor (ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor, PR_TRUE));
|
||||
if (horizontal) {
|
||||
rect.y = rect.y + half;
|
||||
rect.height = aBorder.height - half;
|
||||
if (NS_SIDE_BOTTOM == aStartBevelSide) {
|
||||
rect.x += startBevel;
|
||||
rect.width -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_BOTTOM == aEndBevelSide) {
|
||||
rect.width -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
else {
|
||||
rect.x = rect.x + half;
|
||||
rect.width = aBorder.width - half;
|
||||
if (NS_SIDE_RIGHT == aStartBevelSide) {
|
||||
rect.y += aStartBevelOffset - startBevel;
|
||||
rect.height -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_RIGHT == aEndBevelSide) {
|
||||
rect.height -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_DOUBLE:
|
||||
if ((aBorder.width > 2) && (aBorder.height > 2)) {
|
||||
nscoord startBevel = (aStartBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.333333f * (float)aStartBevelOffset, twipsPerPixel) : 0;
|
||||
nscoord endBevel = (aEndBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.333333f * (float)aEndBevelOffset, twipsPerPixel) : 0;
|
||||
if (horizontal) { // top, bottom
|
||||
nscoord thirdHeight = RoundFloatToPixel(0.333333f * (float)aBorder.height, twipsPerPixel);
|
||||
|
||||
// draw the top line or rect
|
||||
nsRect topRect(aBorder.x, aBorder.y, aBorder.width, thirdHeight);
|
||||
if (NS_SIDE_TOP == aStartBevelSide) {
|
||||
topRect.x += aStartBevelOffset - startBevel;
|
||||
topRect.width -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_TOP == aEndBevelSide) {
|
||||
topRect.width -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, topRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
|
||||
// draw the botom line or rect
|
||||
nscoord heightOffset = aBorder.height - thirdHeight;
|
||||
nsRect bottomRect(aBorder.x, aBorder.y + heightOffset, aBorder.width, aBorder.height - heightOffset);
|
||||
if (NS_SIDE_BOTTOM == aStartBevelSide) {
|
||||
bottomRect.x += aStartBevelOffset - startBevel;
|
||||
bottomRect.width -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_BOTTOM == aEndBevelSide) {
|
||||
bottomRect.width -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, bottomRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
else { // left, right
|
||||
nscoord thirdWidth = RoundFloatToPixel(0.333333f * (float)aBorder.width, twipsPerPixel);
|
||||
|
||||
nsRect leftRect(aBorder.x, aBorder.y, thirdWidth, aBorder.height);
|
||||
if (NS_SIDE_LEFT == aStartBevelSide) {
|
||||
leftRect.y += aStartBevelOffset - startBevel;
|
||||
leftRect.height -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_LEFT == aEndBevelSide) {
|
||||
leftRect.height -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, leftRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
|
||||
nscoord widthOffset = aBorder.width - thirdWidth;
|
||||
nsRect rightRect(aBorder.x + widthOffset, aBorder.y, aBorder.width - widthOffset, aBorder.height);
|
||||
if (NS_SIDE_RIGHT == aStartBevelSide) {
|
||||
rightRect.y += aStartBevelOffset - startBevel;
|
||||
rightRect.height -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_RIGHT == aEndBevelSide) {
|
||||
rightRect.height -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rightRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// else fall through to solid
|
||||
case NS_STYLE_BORDER_STYLE_SOLID:
|
||||
DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide,
|
||||
aStartBevelOffset, aEndBevelSide, aEndBevelOffset);
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_BG_OUTSET:
|
||||
case NS_STYLE_BORDER_STYLE_BG_INSET:
|
||||
case NS_STYLE_BORDER_STYLE_OUTSET:
|
||||
case NS_STYLE_BORDER_STYLE_INSET:
|
||||
NS_ASSERTION(PR_FALSE, "inset, outset should have been converted to groove, ridge");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// End table border-collapsing section
|
||||
|
||||
|
|
|
@ -180,6 +180,17 @@ public:
|
|||
PRIntn aSkipSides,
|
||||
nsRect* aGap);
|
||||
|
||||
// Draw a border segment in the table collapsing border model without beveling corners
|
||||
static void DrawTableBorderSegment(nsIRenderingContext& aContext,
|
||||
PRUint8 aBorderStyle,
|
||||
nscolor aBorderColor,
|
||||
const nsStyleBackground* aBGColor,
|
||||
const nsRect& aBorderRect,
|
||||
float aPixelsToTwips,
|
||||
PRUint8 aStartBevelSide = 0,
|
||||
nscoord aStartBevelOffset = 0,
|
||||
PRUint8 aEndBevelSide = 0,
|
||||
nscoord aEndBevelOffset = 0);
|
||||
/**
|
||||
* transform a color to a color that will show up on a printer if needed
|
||||
* aMapColor - color to evaluate
|
||||
|
|
|
@ -100,6 +100,7 @@ LAYOUT_ATOM(selectScrolledContentPseudo, ":-moz-select-scrolled-content")
|
|||
|
||||
// Alphabetical list of frame types
|
||||
LAYOUT_ATOM(areaFrame, "AreaFrame")
|
||||
LAYOUT_ATOM(bcTableCellFrame, "BCTableCellFrame") // table cell in border collapsing model
|
||||
LAYOUT_ATOM(blockFrame, "BlockFrame")
|
||||
LAYOUT_ATOM(boxFrame, "BoxFrame")
|
||||
LAYOUT_ATOM(brFrame, "BRFrame")
|
||||
|
@ -143,7 +144,8 @@ LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFra
|
|||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
|
||||
LAYOUT_ATOM(tableBCProperty, "TableBCProperty") // table border collapsing info (e.g. damage area, table border widths)
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty")
|
||||
|
||||
// Alphabetical list of event handler names
|
||||
LAYOUT_ATOM(onabort, "onabort")
|
||||
|
|
|
@ -249,6 +249,9 @@
|
|||
#define NS_STYLE_BORDER_STYLE_HIDDEN 10
|
||||
#define NS_STYLE_BORDER_STYLE_BG_INSET 11
|
||||
#define NS_STYLE_BORDER_STYLE_BG_OUTSET 12
|
||||
// a bit ORed onto the style for table border collapsing indicating that the style was
|
||||
// derived from a table with its rules attribute set
|
||||
#define NS_STYLE_BORDER_STYLE_RULES_MASK 0x10
|
||||
|
||||
// See nsStyleDisplay
|
||||
#define NS_STYLE_CLEAR_NONE 0
|
||||
|
|
|
@ -270,12 +270,13 @@ struct nsHTMLReflowState {
|
|||
|
||||
// Initialize a reflow state for a child frames reflow. Some state
|
||||
// is copied from the parent reflow state; the remaining state is
|
||||
// computed.
|
||||
// computed.
|
||||
nsHTMLReflowState(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailableSpace,
|
||||
nsReflowReason aReason);
|
||||
nsReflowReason aReason,
|
||||
PRBool aInit = PR_TRUE);
|
||||
|
||||
// Same as the previous except that the reason is taken from the
|
||||
// parent's reflow state.
|
||||
|
@ -293,6 +294,13 @@ struct nsHTMLReflowState {
|
|||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight);
|
||||
|
||||
// This method initializes various data members. It is automatically
|
||||
// called by the various constructors
|
||||
void Init(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth = -1,
|
||||
nscoord aContainingBlockHeight = -1,
|
||||
nsMargin* aBorder = nsnull,
|
||||
nsMargin* aPadding = nsnull);
|
||||
/**
|
||||
* Get the containing block reflow state, starting from a frames
|
||||
* <B>parent</B> reflow state (the parent reflow state may or may not end
|
||||
|
@ -352,15 +360,12 @@ struct nsHTMLReflowState {
|
|||
|
||||
|
||||
protected:
|
||||
// This method initializes various data members. It is automatically
|
||||
// called by the various constructors
|
||||
void Init(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth = -1,
|
||||
nscoord aContainingBlockHeight = -1);
|
||||
|
||||
void InitConstraints(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight);
|
||||
nscoord aContainingBlockHeight,
|
||||
nsMargin* aBorder,
|
||||
nsMargin* aPadding);
|
||||
|
||||
void CalculateHypotheticalBox(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPlaceholderFrame,
|
||||
|
|
|
@ -249,6 +249,9 @@
|
|||
#define NS_STYLE_BORDER_STYLE_HIDDEN 10
|
||||
#define NS_STYLE_BORDER_STYLE_BG_INSET 11
|
||||
#define NS_STYLE_BORDER_STYLE_BG_OUTSET 12
|
||||
// a bit ORed onto the style for table border collapsing indicating that the style was
|
||||
// derived from a table with its rules attribute set
|
||||
#define NS_STYLE_BORDER_STYLE_RULES_MASK 0x10
|
||||
|
||||
// See nsStyleDisplay
|
||||
#define NS_STYLE_CLEAR_NONE 0
|
||||
|
|
|
@ -4646,6 +4646,7 @@ void DR_State::InitFrameTypeTable()
|
|||
AddFrameTypeInfo(nsLayoutAtoms::scrollFrame, "scroll", "scroll");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableCaptionFrame, "caption", "tableCaption");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableCellFrame, "cell", "tableCell");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::bcTableCellFrame, "bcCell", "bcTableCell");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableColFrame, "col", "tableCol");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableColGroupFrame, "colG", "tableColGroup");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableFrame, "tbl", "table");
|
||||
|
|
|
@ -204,7 +204,7 @@ extern nsresult NS_NewTableColFrame(nsIPresShell* aPresShell, nsIFrame** aResult
|
|||
extern nsresult NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableRowFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableCellFrame(nsIPresShell* aPresShell, PRBool aIsBorderCollapse, nsIFrame** aResult);
|
||||
|
||||
// XXX passing aWebShell into this is wrong
|
||||
extern nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#define IS_TABLE_CELL(frameType)\
|
||||
((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType))
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#undef NOISY_VERTICAL_ALIGN
|
||||
#else
|
||||
|
@ -140,7 +143,8 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
|
|||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailableSpace,
|
||||
nsReflowReason aReason)
|
||||
nsReflowReason aReason,
|
||||
PRBool aInit)
|
||||
: mReflowDepth(aParentReflowState.mReflowDepth + 1),
|
||||
mFlags(aParentReflowState.mFlags)
|
||||
{
|
||||
|
@ -159,7 +163,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
|
|||
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
|
||||
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver;
|
||||
|
||||
Init(aPresContext);
|
||||
if (aInit) {
|
||||
Init(aPresContext);
|
||||
}
|
||||
|
||||
#ifdef IBMBIDI
|
||||
mRightEdge = aParentReflowState.mRightEdge;
|
||||
|
@ -228,7 +234,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
|
|||
void
|
||||
nsHTMLReflowState::Init(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight)
|
||||
nscoord aContainingBlockHeight,
|
||||
nsMargin* aBorder,
|
||||
nsMargin* aPadding)
|
||||
{
|
||||
mCompactMarginWidth = 0;
|
||||
#ifdef DEBUG
|
||||
|
@ -244,7 +252,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext,
|
|||
GetStyleData(frame, &mStyleText);
|
||||
|
||||
mFrameType = DetermineFrameType(frame, mStyleDisplay);
|
||||
InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight);
|
||||
InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight, aBorder, aPadding);
|
||||
}
|
||||
|
||||
const nsHTMLReflowState*
|
||||
|
@ -261,7 +269,7 @@ nsHTMLReflowState::GetContainingBlockReflowState(const nsHTMLReflowState* aParen
|
|||
if (aParentRS->parentReflowState) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aParentRS->parentReflowState->frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType.get()) {
|
||||
if (IS_TABLE_CELL(fType.get())) {
|
||||
aParentRS = aParentRS->parentReflowState;
|
||||
}
|
||||
}
|
||||
|
@ -1575,7 +1583,9 @@ static PRBool BlinkIsAllowed(void)
|
|||
void
|
||||
nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight)
|
||||
nscoord aContainingBlockHeight,
|
||||
nsMargin* aBorder,
|
||||
nsMargin* aPadding)
|
||||
{
|
||||
// If this is the root frame, then set the computed width and
|
||||
// height equal to the available space
|
||||
|
@ -1633,7 +1643,7 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
|
|||
}
|
||||
else {
|
||||
cbrs->frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType.get()) {
|
||||
if (IS_TABLE_CELL(fType.get())) {
|
||||
// use the cell's computed height
|
||||
aContainingBlockHeight =
|
||||
((nsHTMLReflowState*)cbrs)->mComputedHeight;
|
||||
|
@ -1647,10 +1657,26 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
|
|||
// XXX fix to provide 0,0 for the top&bottom margins for
|
||||
// inline-non-replaced elements
|
||||
ComputeMargin(aContainingBlockWidth, cbrs);
|
||||
ComputePadding(aContainingBlockWidth, cbrs);
|
||||
if (!mStyleBorder->GetBorder(mComputedBorderPadding)) {
|
||||
// CSS2 has no percentage borders
|
||||
mComputedBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
if (aPadding) { // padding is an input arg
|
||||
mComputedPadding.top = aPadding->top;
|
||||
mComputedPadding.right = aPadding->right;
|
||||
mComputedPadding.bottom = aPadding->bottom;
|
||||
mComputedPadding.left = aPadding->left;
|
||||
}
|
||||
else {
|
||||
ComputePadding(aContainingBlockWidth, cbrs);
|
||||
}
|
||||
if (aBorder) { // border is an input arg
|
||||
mComputedBorderPadding.top = aBorder->top;
|
||||
mComputedBorderPadding.right = aBorder->right;
|
||||
mComputedBorderPadding.bottom = aBorder->bottom;
|
||||
mComputedBorderPadding.left = aBorder->left;
|
||||
}
|
||||
else {
|
||||
if (!mStyleBorder->GetBorder(mComputedBorderPadding)) {
|
||||
// CSS2 has no percentage borders
|
||||
mComputedBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
mComputedBorderPadding += mComputedPadding;
|
||||
|
||||
|
|
|
@ -270,12 +270,13 @@ struct nsHTMLReflowState {
|
|||
|
||||
// Initialize a reflow state for a child frames reflow. Some state
|
||||
// is copied from the parent reflow state; the remaining state is
|
||||
// computed.
|
||||
// computed.
|
||||
nsHTMLReflowState(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailableSpace,
|
||||
nsReflowReason aReason);
|
||||
nsReflowReason aReason,
|
||||
PRBool aInit = PR_TRUE);
|
||||
|
||||
// Same as the previous except that the reason is taken from the
|
||||
// parent's reflow state.
|
||||
|
@ -293,6 +294,13 @@ struct nsHTMLReflowState {
|
|||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight);
|
||||
|
||||
// This method initializes various data members. It is automatically
|
||||
// called by the various constructors
|
||||
void Init(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth = -1,
|
||||
nscoord aContainingBlockHeight = -1,
|
||||
nsMargin* aBorder = nsnull,
|
||||
nsMargin* aPadding = nsnull);
|
||||
/**
|
||||
* Get the containing block reflow state, starting from a frames
|
||||
* <B>parent</B> reflow state (the parent reflow state may or may not end
|
||||
|
@ -352,15 +360,12 @@ struct nsHTMLReflowState {
|
|||
|
||||
|
||||
protected:
|
||||
// This method initializes various data members. It is automatically
|
||||
// called by the various constructors
|
||||
void Init(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth = -1,
|
||||
nscoord aContainingBlockHeight = -1);
|
||||
|
||||
void InitConstraints(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight);
|
||||
nscoord aContainingBlockHeight,
|
||||
nsMargin* aBorder,
|
||||
nsMargin* aPadding);
|
||||
|
||||
void CalculateHypotheticalBox(nsIPresContext* aPresContext,
|
||||
nsIFrame* aPlaceholderFrame,
|
||||
|
|
|
@ -4646,6 +4646,7 @@ void DR_State::InitFrameTypeTable()
|
|||
AddFrameTypeInfo(nsLayoutAtoms::scrollFrame, "scroll", "scroll");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableCaptionFrame, "caption", "tableCaption");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableCellFrame, "cell", "tableCell");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::bcTableCellFrame, "bcCell", "bcTableCell");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableColFrame, "col", "tableCol");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableColGroupFrame, "colG", "tableColGroup");
|
||||
AddFrameTypeInfo(nsLayoutAtoms::tableFrame, "tbl", "table");
|
||||
|
|
|
@ -204,7 +204,7 @@ extern nsresult NS_NewTableColFrame(nsIPresShell* aPresShell, nsIFrame** aResult
|
|||
extern nsresult NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableRowFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
|
||||
extern nsresult NS_NewTableCellFrame(nsIPresShell* aPresShell, PRBool aIsBorderCollapse, nsIFrame** aResult);
|
||||
|
||||
// XXX passing aWebShell into this is wrong
|
||||
extern nsresult NS_NewHTMLContentSink(nsIHTMLContentSink** aInstancePtrResult,
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#define IS_TABLE_CELL(frameType)\
|
||||
((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType))
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
#undef NOISY_VERTICAL_ALIGN
|
||||
#else
|
||||
|
@ -140,7 +143,8 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
|
|||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailableSpace,
|
||||
nsReflowReason aReason)
|
||||
nsReflowReason aReason,
|
||||
PRBool aInit)
|
||||
: mReflowDepth(aParentReflowState.mReflowDepth + 1),
|
||||
mFlags(aParentReflowState.mFlags)
|
||||
{
|
||||
|
@ -159,7 +163,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
|
|||
mFlags.mIsTopOfPage = aParentReflowState.mFlags.mIsTopOfPage;
|
||||
mPercentHeightObserver = aParentReflowState.mPercentHeightObserver;
|
||||
|
||||
Init(aPresContext);
|
||||
if (aInit) {
|
||||
Init(aPresContext);
|
||||
}
|
||||
|
||||
#ifdef IBMBIDI
|
||||
mRightEdge = aParentReflowState.mRightEdge;
|
||||
|
@ -228,7 +234,9 @@ nsHTMLReflowState::nsHTMLReflowState(nsIPresContext* aPresContext,
|
|||
void
|
||||
nsHTMLReflowState::Init(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight)
|
||||
nscoord aContainingBlockHeight,
|
||||
nsMargin* aBorder,
|
||||
nsMargin* aPadding)
|
||||
{
|
||||
mCompactMarginWidth = 0;
|
||||
#ifdef DEBUG
|
||||
|
@ -244,7 +252,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext,
|
|||
GetStyleData(frame, &mStyleText);
|
||||
|
||||
mFrameType = DetermineFrameType(frame, mStyleDisplay);
|
||||
InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight);
|
||||
InitConstraints(aPresContext, aContainingBlockWidth, aContainingBlockHeight, aBorder, aPadding);
|
||||
}
|
||||
|
||||
const nsHTMLReflowState*
|
||||
|
@ -261,7 +269,7 @@ nsHTMLReflowState::GetContainingBlockReflowState(const nsHTMLReflowState* aParen
|
|||
if (aParentRS->parentReflowState) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aParentRS->parentReflowState->frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType.get()) {
|
||||
if (IS_TABLE_CELL(fType.get())) {
|
||||
aParentRS = aParentRS->parentReflowState;
|
||||
}
|
||||
}
|
||||
|
@ -1575,7 +1583,9 @@ static PRBool BlinkIsAllowed(void)
|
|||
void
|
||||
nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight)
|
||||
nscoord aContainingBlockHeight,
|
||||
nsMargin* aBorder,
|
||||
nsMargin* aPadding)
|
||||
{
|
||||
// If this is the root frame, then set the computed width and
|
||||
// height equal to the available space
|
||||
|
@ -1633,7 +1643,7 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
|
|||
}
|
||||
else {
|
||||
cbrs->frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableCellFrame == fType.get()) {
|
||||
if (IS_TABLE_CELL(fType.get())) {
|
||||
// use the cell's computed height
|
||||
aContainingBlockHeight =
|
||||
((nsHTMLReflowState*)cbrs)->mComputedHeight;
|
||||
|
@ -1647,10 +1657,26 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext,
|
|||
// XXX fix to provide 0,0 for the top&bottom margins for
|
||||
// inline-non-replaced elements
|
||||
ComputeMargin(aContainingBlockWidth, cbrs);
|
||||
ComputePadding(aContainingBlockWidth, cbrs);
|
||||
if (!mStyleBorder->GetBorder(mComputedBorderPadding)) {
|
||||
// CSS2 has no percentage borders
|
||||
mComputedBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
if (aPadding) { // padding is an input arg
|
||||
mComputedPadding.top = aPadding->top;
|
||||
mComputedPadding.right = aPadding->right;
|
||||
mComputedPadding.bottom = aPadding->bottom;
|
||||
mComputedPadding.left = aPadding->left;
|
||||
}
|
||||
else {
|
||||
ComputePadding(aContainingBlockWidth, cbrs);
|
||||
}
|
||||
if (aBorder) { // border is an input arg
|
||||
mComputedBorderPadding.top = aBorder->top;
|
||||
mComputedBorderPadding.right = aBorder->right;
|
||||
mComputedBorderPadding.bottom = aBorder->bottom;
|
||||
mComputedBorderPadding.left = aBorder->left;
|
||||
}
|
||||
else {
|
||||
if (!mStyleBorder->GetBorder(mComputedBorderPadding)) {
|
||||
// CSS2 has no percentage borders
|
||||
mComputedBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
mComputedBorderPadding += mComputedPadding;
|
||||
|
||||
|
|
|
@ -168,6 +168,10 @@ table[align="right"] {
|
|||
text-align: start;
|
||||
}
|
||||
|
||||
table[rules] {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
*|*:table-outer {
|
||||
display: table;
|
||||
margin: 0;
|
||||
|
@ -219,6 +223,11 @@ tr {
|
|||
|
||||
col, *|*:table-column {
|
||||
display: table-column;
|
||||
border: inherit;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
background: inherit;
|
||||
border: inherit;
|
||||
}
|
||||
|
||||
colgroup, *|*:table-column-group {
|
||||
|
|
|
@ -52,8 +52,11 @@
|
|||
#include "nsIPresContext.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTableFrame.h"
|
||||
#include "nsTableColGroupFrame.h"
|
||||
#include "nsTableColFrame.h"
|
||||
#include "nsIDOMHTMLTableColElement.h"
|
||||
#include "nsTableCellFrame.h" // to get IS_CELL_FRAME
|
||||
#include "nsHTMLIIDs.h"
|
||||
#include "nsIStyleFrameConstruction.h"
|
||||
#include "nsHTMLParts.h"
|
||||
|
@ -859,6 +862,23 @@ nsFrameConstructorSaveState::~nsFrameConstructorSaveState()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
PRBool IsBorderCollapse(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* frame = aFrame;
|
||||
while (frame) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableFrame == fType.get()) {
|
||||
return ((nsTableFrame*)frame)->IsBorderCollapse();
|
||||
}
|
||||
frame->GetParent(&frame);
|
||||
}
|
||||
NS_ASSERTION(PR_FALSE, "program error");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// Structure used when creating table frames.
|
||||
|
@ -870,7 +890,7 @@ struct nsTableCreator {
|
|||
virtual nsresult CreateTableColFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableColGroupFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableRowFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableCellFrame(nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableCellFrame(nsIFrame* aParentFrame, nsIFrame** aNewFrame);
|
||||
virtual nsresult CreateTableCellInnerFrame(nsIFrame** aNewFrame);
|
||||
|
||||
nsTableCreator(nsIPresShell* aPresShell)
|
||||
|
@ -919,8 +939,9 @@ nsTableCreator::CreateTableRowFrame(nsIFrame** aNewFrame) {
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsTableCreator::CreateTableCellFrame(nsIFrame** aNewFrame) {
|
||||
return NS_NewTableCellFrame(mPresShell, aNewFrame);
|
||||
nsTableCreator::CreateTableCellFrame(nsIFrame* aParentFrame,
|
||||
nsIFrame** aNewFrame) {
|
||||
return NS_NewTableCellFrame(mPresShell, IsBorderCollapse(aParentFrame), aNewFrame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1527,7 +1548,7 @@ IsTableRelated(nsIAtom* aParentType,
|
|||
((nsLayoutAtoms::tableCaptionFrame == aParentType) ||
|
||||
(nsLayoutAtoms::tableColGroupFrame == aParentType) ||
|
||||
(nsLayoutAtoms::tableColFrame == aParentType) ||
|
||||
(nsLayoutAtoms::tableCellFrame == aParentType))) {
|
||||
IS_TABLE_CELL(aParentType))) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else return PR_FALSE;
|
||||
|
@ -1629,7 +1650,7 @@ ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|||
|
||||
if (aPseudoFrames.mCellOuter.mFrame) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
}
|
||||
if (aPseudoFrames.mRow.mFrame) {
|
||||
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
||||
|
@ -1650,7 +1671,7 @@ ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|||
}
|
||||
if (aPseudoFrames.mCellOuter.mFrame) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
}
|
||||
if (aPseudoFrames.mRow.mFrame) {
|
||||
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
||||
|
@ -1671,12 +1692,12 @@ ProcessPseudoFrames(nsIPresContext* aPresContext,
|
|||
}
|
||||
if (aPseudoFrames.mCellOuter.mFrame) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
}
|
||||
}
|
||||
else if (nsLayoutAtoms::tableCellFrame == aPseudoFrames.mLowestType) {
|
||||
else if (IS_TABLE_CELL(aPseudoFrames.mLowestType)) {
|
||||
rv = ProcessPseudoCellFrame(aPresContext, aPseudoFrames, aHighestFrame);
|
||||
if (nsLayoutAtoms::tableCellFrame == aHighestType) return rv;
|
||||
if (IS_TABLE_CELL(aHighestType)) return rv;
|
||||
|
||||
if (aPseudoFrames.mRow.mFrame) {
|
||||
rv = ProcessPseudoFrame(aPresContext, aPseudoFrames.mRow, aHighestFrame);
|
||||
|
@ -1942,6 +1963,7 @@ nsCSSFrameConstructor::CreatePseudoCellFrame(nsIPresShell* aPresShell
|
|||
|
||||
// set pseudo data for the newly created frames
|
||||
pseudoOuter.mChildList.AddChild(pseudoInner.mFrame);
|
||||
// give it nsLayoutAtoms::tableCellFrame, if it is really nsLayoutAtoms::bcTableCellFrame, it will match later
|
||||
aState.mPseudoFrames.mLowestType = nsLayoutAtoms::tableCellFrame;
|
||||
|
||||
// set pseudo data for the parent
|
||||
|
@ -2021,7 +2043,7 @@ nsCSSFrameConstructor::GetPseudoColGroupFrame(nsIPresShell* aPresShel
|
|||
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
created = PR_TRUE;
|
||||
}
|
||||
if (created || (nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
||||
if (created || IS_TABLE_CELL(parentFrameType.get()) || // cell parent
|
||||
!IsTableRelated(parentFrameType.get(), PR_TRUE)) { // block parent
|
||||
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
}
|
||||
|
@ -2065,7 +2087,7 @@ nsCSSFrameConstructor::GetPseudoRowGroupFrame(nsIPresShell* aPresShel
|
|||
rv = CreatePseudoCellFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
created = PR_TRUE;
|
||||
}
|
||||
if (created || (nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
||||
if (created || IS_TABLE_CELL(parentFrameType.get()) || // cell parent
|
||||
!IsTableRelated(parentFrameType.get(), PR_TRUE)) { // block parent
|
||||
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
}
|
||||
|
@ -2102,7 +2124,7 @@ nsCSSFrameConstructor::GetPseudoRowFrame(nsIPresShell* aPresShell,
|
|||
|
||||
if (pseudoFrames.IsEmpty()) {
|
||||
PRBool created = PR_FALSE;
|
||||
if ((nsLayoutAtoms::tableCellFrame == parentFrameType.get()) || // cell parent
|
||||
if (IS_TABLE_CELL(parentFrameType.get()) || // cell parent
|
||||
!IsTableRelated(parentFrameType.get(), PR_TRUE)) { // block parent
|
||||
rv = CreatePseudoTableFrame(aPresShell, aPresContext, aTableCreator, aState, &aParentFrameIn);
|
||||
created = PR_TRUE;
|
||||
|
@ -2230,7 +2252,7 @@ nsCSSFrameConstructor::GetParentFrame(nsIPresShell* aPresShell,
|
|||
pseudoParentFrame = pseudoFrames.mRowGroup.mFrame;
|
||||
}
|
||||
}
|
||||
else if (nsLayoutAtoms::tableCellFrame == aChildFrameType) { // cell child
|
||||
else if (IS_TABLE_CELL(aChildFrameType)) { // cell child
|
||||
if (nsLayoutAtoms::tableRowFrame != parentFrameType.get()) { // need pseudo row parent
|
||||
rv = GetPseudoRowFrame(aPresShell, aPresContext, aTableCreator, aState, aParentFrameIn);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -2572,7 +2594,7 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShel
|
|||
PRBool& aIsPseudoParent)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!aPresShell || !aPresContext || !aParentFrameIn) return rv;
|
||||
if (!aPresShell || !aPresContext || !aParentFrameIn || !aStyleContext) return rv;
|
||||
|
||||
nsIFrame* parentFrame = aParentFrameIn;
|
||||
aIsPseudoParent = PR_FALSE;
|
||||
|
@ -2585,16 +2607,42 @@ nsCSSFrameConstructor::ConstructTableColFrame(nsIPresShell* aPresShel
|
|||
}
|
||||
}
|
||||
|
||||
rv = aTableCreator.CreateTableColFrame(&aNewFrame);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent,
|
||||
parentFrame, aStyleContext, nsnull, aNewFrame);
|
||||
rv = aTableCreator.CreateTableColFrame(&aNewFrame); if (NS_FAILED(rv)) return rv;
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, parentFrame, aStyleContext, nsnull, aNewFrame);
|
||||
// if the parent frame was anonymous then reparent the style context
|
||||
nsCOMPtr<nsIStyleContext> parentStyleContext;
|
||||
parentFrame->GetStyleContext(getter_AddRefs(parentStyleContext));
|
||||
if (aIsPseudoParent) {
|
||||
aPresContext->ReParentStyleContext(aNewFrame, parentStyleContext);
|
||||
}
|
||||
|
||||
// construct additional col frames if the col frame has a span > 1
|
||||
PRInt32 span = 1;
|
||||
nsCOMPtr<nsIDOMHTMLTableColElement> cgContent(do_QueryInterface(aContent));
|
||||
if (cgContent) {
|
||||
cgContent->GetSpan(&span);
|
||||
nsIFrame* lastCol = aNewFrame;
|
||||
for (PRInt32 spanX = 1; spanX < span; spanX++) {
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
aPresContext->ResolvePseudoStyleContextFor(aContent, nsHTMLAtoms::tableColPseudo, aStyleContext,
|
||||
PR_FALSE, getter_AddRefs(styleContext));
|
||||
nsIFrame* newCol;
|
||||
rv = aTableCreator.CreateTableColFrame(&newCol); if (NS_FAILED(rv)) return rv;
|
||||
InitAndRestoreFrame(aPresContext, aState, aContent, parentFrame, styleContext, nsnull, newCol);
|
||||
if (aIsPseudoParent) {
|
||||
aPresContext->ReParentStyleContext(newCol, aStyleContext);
|
||||
}
|
||||
((nsTableColFrame*)newCol)->SetType(eColAnonymousCol);
|
||||
lastCol->SetNextSibling(newCol);
|
||||
lastCol = newCol;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aIsPseudo) {
|
||||
nsFrameItems childItems;
|
||||
nsIFrame* captionFrame;
|
||||
rv = TableProcessChildren(aPresShell, aPresContext, aState, aContent, aNewFrame,
|
||||
aTableCreator, childItems, captionFrame);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
aTableCreator, childItems, captionFrame); if (NS_FAILED(rv)) return rv;
|
||||
aNewFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
if (aIsPseudoParent) {
|
||||
aState.mPseudoFrames.mColGroup.mChildList.AddChild(aNewFrame);
|
||||
|
@ -2625,6 +2673,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShe
|
|||
aIsPseudoParent = PR_FALSE;
|
||||
if (!aIsPseudo) {
|
||||
// this frame may have a pseudo parent
|
||||
// use nsLayoutAtoms::tableCellFrame which will match if it is really nsLayoutAtoms::bcTableCellFrame
|
||||
GetParentFrame(aPresShell, aPresContext, aTableCreator, *aParentFrameIn,
|
||||
nsLayoutAtoms::tableCellFrame, aState, parentFrame, aIsPseudoParent);
|
||||
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
|
||||
|
@ -2635,7 +2684,7 @@ nsCSSFrameConstructor::ConstructTableCellFrame(nsIPresShell* aPresShe
|
|||
}
|
||||
}
|
||||
|
||||
rv = aTableCreator.CreateTableCellFrame(&aNewCellOuterFrame);
|
||||
rv = aTableCreator.CreateTableCellFrame(parentFrame, &aNewCellOuterFrame);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Initialize the table cell frame
|
||||
|
@ -11328,7 +11377,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell,
|
|||
|
||||
// See if it's a table cell frame
|
||||
cellFrame->GetFrameType(&tableType);
|
||||
if (nsLayoutAtoms::tableCellFrame == tableType) {
|
||||
if (IS_TABLE_CELL(tableType)) {
|
||||
nsIFrame* continuingCellFrame;
|
||||
|
||||
CreateContinuingFrame(aPresShell, aPresContext, cellFrame, newFrame, &continuingCellFrame);
|
||||
|
@ -11343,8 +11392,8 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsIPresShell* aPresShell,
|
|||
newFrame->SetInitialChildList(aPresContext, nsnull, newChildList.childList);
|
||||
}
|
||||
|
||||
} else if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
rv = NS_NewTableCellFrame(aPresShell, &newFrame);
|
||||
} else if (IS_TABLE_CELL(frameType)) {
|
||||
rv = NS_NewTableCellFrame(aPresShell, IsBorderCollapse(aParentFrame), &newFrame);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
newFrame->Init(aPresContext, content, aParentFrame, styleContext, aFrame);
|
||||
nsHTMLContainerFrame::CreateViewForFrame(aPresContext, newFrame,
|
||||
|
|
|
@ -514,6 +514,7 @@ void nsCSSRendering::DrawSide(nsIRenderingContext& aContext,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw a dotted/dashed sides of a box
|
||||
*/
|
||||
|
@ -3821,3 +3822,356 @@ void FillOrInvertRect(nsIRenderingContext& aRC, const nsRect& aRect, PRBool aInv
|
|||
}
|
||||
}
|
||||
|
||||
// Begin table border-collapsing section
|
||||
// These functions were written to not disrupt the normal ones and yet satisfy some additional requirements
|
||||
// At some point, all functions should be unified to include the additional functionality that these provide
|
||||
|
||||
static nscoord
|
||||
RoundIntToPixel(nscoord aValue,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRBool aRoundDown = PR_FALSE)
|
||||
{
|
||||
nscoord halfPixel = NSToCoordRound(aTwipsPerPixel / 2.0f);
|
||||
nscoord extra = aValue % aTwipsPerPixel;
|
||||
nscoord finalValue = (!aRoundDown && (extra >= halfPixel)) ? aValue + (aTwipsPerPixel - extra) : aValue - extra;
|
||||
|
||||
return finalValue;
|
||||
}
|
||||
|
||||
static nscoord
|
||||
RoundFloatToPixel(float aValue,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRBool aRoundDown = PR_FALSE)
|
||||
{
|
||||
return RoundIntToPixel(NSToCoordRound(aValue), aTwipsPerPixel, aRoundDown);
|
||||
}
|
||||
|
||||
static void
|
||||
SetPoly(const nsRect& aRect,
|
||||
nsPoint* poly)
|
||||
{
|
||||
poly[0].x = aRect.x;
|
||||
poly[0].y = aRect.y;
|
||||
poly[1].x = aRect.x + aRect.width;
|
||||
poly[1].y = aRect.y;
|
||||
poly[2].x = aRect.x + aRect.width;
|
||||
poly[2].y = aRect.y + aRect.height;
|
||||
poly[3].x = aRect.x;
|
||||
poly[3].y = aRect.y + aRect.height;
|
||||
poly[4].x = aRect.x;
|
||||
poly[4].y = aRect.y;
|
||||
}
|
||||
|
||||
static void
|
||||
DrawSolidBorderSegment(nsIRenderingContext& aContext,
|
||||
nsRect aRect,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRUint8 aStartBevelSide = 0,
|
||||
nscoord aStartBevelOffset = 0,
|
||||
PRUint8 aEndBevelSide = 0,
|
||||
nscoord aEndBevelOffset = 0)
|
||||
{
|
||||
|
||||
if ((aRect.width == aTwipsPerPixel) || (aRect.height == aTwipsPerPixel) ||
|
||||
((0 == aStartBevelOffset) && (0 == aEndBevelOffset))) {
|
||||
// simple line or rectangle
|
||||
if ((NS_SIDE_TOP == aStartBevelSide) || (NS_SIDE_BOTTOM == aStartBevelSide)) {
|
||||
if (1 == aRect.height)
|
||||
aContext.DrawLine(aRect.x, aRect.y, aRect.x, aRect.y + aRect.height);
|
||||
else
|
||||
aContext.FillRect(aRect);
|
||||
}
|
||||
else {
|
||||
if (1 == aRect.width)
|
||||
aContext.DrawLine(aRect.x, aRect.y, aRect.x + aRect.width, aRect.y);
|
||||
else
|
||||
aContext.FillRect(aRect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// polygon with beveling
|
||||
nsPoint poly[5];
|
||||
SetPoly(aRect, poly);
|
||||
switch(aStartBevelSide) {
|
||||
case NS_SIDE_TOP:
|
||||
poly[0].x += aStartBevelOffset;
|
||||
poly[4].x = poly[0].x;
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
poly[3].x += aStartBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
poly[1].y += aStartBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_LEFT:
|
||||
poly[0].y += aStartBevelOffset;
|
||||
poly[4].y = poly[0].y;
|
||||
}
|
||||
|
||||
switch(aEndBevelSide) {
|
||||
case NS_SIDE_TOP:
|
||||
poly[1].x -= aEndBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
poly[2].x -= aEndBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
poly[2].y -= aEndBevelOffset;
|
||||
break;
|
||||
case NS_SIDE_LEFT:
|
||||
poly[3].y -= aEndBevelOffset;
|
||||
}
|
||||
|
||||
aContext.FillPolygon(poly, 5);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
GetDashInfo(nscoord aBorderLength,
|
||||
nscoord aDashLength,
|
||||
nscoord aTwipsPerPixel,
|
||||
PRInt32& aNumDashSpaces,
|
||||
nscoord& aStartDashLength,
|
||||
nscoord& aEndDashLength)
|
||||
{
|
||||
aNumDashSpaces = 0;
|
||||
if (aStartDashLength + aDashLength + aEndDashLength >= aBorderLength) {
|
||||
aStartDashLength = aBorderLength;
|
||||
aEndDashLength = 0;
|
||||
}
|
||||
else {
|
||||
aNumDashSpaces = aBorderLength / (2 * aDashLength); // round down
|
||||
nscoord foo = ((2 * aNumDashSpaces) - 1) * aDashLength;
|
||||
nscoord extra = aBorderLength - aStartDashLength - aEndDashLength - (((2 * aNumDashSpaces) - 1) * aDashLength);
|
||||
if (extra > 0) {
|
||||
nscoord half = RoundIntToPixel(extra / 2, aTwipsPerPixel);
|
||||
aStartDashLength += half;
|
||||
aEndDashLength += (extra - half);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRendering::DrawTableBorderSegment(nsIRenderingContext& aContext,
|
||||
PRUint8 aBorderStyle,
|
||||
nscolor aBorderColor,
|
||||
const nsStyleBackground* aBGColor,
|
||||
const nsRect& aBorder,
|
||||
float aPixelsToTwips,
|
||||
PRUint8 aStartBevelSide,
|
||||
nscoord aStartBevelOffset,
|
||||
PRUint8 aEndBevelSide,
|
||||
nscoord aEndBevelOffset)
|
||||
{
|
||||
aContext.SetColor (aBorderColor);
|
||||
|
||||
PRBool horizontal = ((NS_SIDE_TOP == aStartBevelSide) || (NS_SIDE_BOTTOM == aStartBevelSide));
|
||||
nscoord twipsPerPixel = NSIntPixelsToTwips(1, aPixelsToTwips);
|
||||
PRBool ridgeGroove = NS_STYLE_BORDER_STYLE_RIDGE;
|
||||
|
||||
if ((twipsPerPixel >= aBorder.width) || (twipsPerPixel >= aBorder.height) ||
|
||||
(NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) || (NS_STYLE_BORDER_STYLE_DOTTED == aBorderStyle)) {
|
||||
// no beveling for 1 pixel border, dash or dot
|
||||
aStartBevelOffset = 0;
|
||||
aEndBevelOffset = 0;
|
||||
}
|
||||
|
||||
switch (aBorderStyle) {
|
||||
case NS_STYLE_BORDER_STYLE_NONE:
|
||||
case NS_STYLE_BORDER_STYLE_HIDDEN:
|
||||
case NS_STYLE_BORDER_STYLE_BLANK:
|
||||
//NS_ASSERTION(PR_FALSE, "style of none, hidden, or blank");
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_DOTTED:
|
||||
case NS_STYLE_BORDER_STYLE_DASHED:
|
||||
{
|
||||
nscoord dashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle) ? DASH_LENGTH : DOT_LENGTH;
|
||||
// make the dash length proportional to the border thickness
|
||||
dashLength *= (horizontal) ? aBorder.height : aBorder.width;
|
||||
// make the min dash length for the ends 1/2 the dash length
|
||||
nscoord minDashLength = (NS_STYLE_BORDER_STYLE_DASHED == aBorderStyle)
|
||||
? RoundFloatToPixel(((float)dashLength) / 2.0f, twipsPerPixel) : dashLength;
|
||||
minDashLength = PR_MAX(minDashLength, twipsPerPixel);
|
||||
nscoord numDashSpaces = 0;
|
||||
nscoord startDashLength = minDashLength;
|
||||
nscoord endDashLength = minDashLength;
|
||||
if (horizontal) {
|
||||
GetDashInfo(aBorder.width, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
|
||||
nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height);
|
||||
DrawSolidBorderSegment(aContext, rect, PR_TRUE);
|
||||
for (PRInt32 spaceX = 0; spaceX < numDashSpaces; spaceX++) {
|
||||
rect.x += rect.width + dashLength;
|
||||
rect.width = (spaceX == (numDashSpaces - 1)) ? endDashLength : dashLength;
|
||||
DrawSolidBorderSegment(aContext, rect, PR_TRUE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
GetDashInfo(aBorder.height, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
|
||||
nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength);
|
||||
DrawSolidBorderSegment(aContext, rect, PR_FALSE);
|
||||
for (PRInt32 spaceY = 0; spaceY < numDashSpaces; spaceY++) {
|
||||
rect.y += rect.height + dashLength;
|
||||
rect.height = (spaceY == (numDashSpaces - 1)) ? endDashLength : dashLength;
|
||||
DrawSolidBorderSegment(aContext, rect, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_GROOVE:
|
||||
ridgeGroove = NS_STYLE_BORDER_STYLE_GROOVE; // and fall through to ridge
|
||||
case NS_STYLE_BORDER_STYLE_RIDGE:
|
||||
if ((horizontal && (twipsPerPixel >= aBorder.height)) ||
|
||||
(!horizontal && (twipsPerPixel >= aBorder.width))) {
|
||||
// a one pixel border
|
||||
DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide, aStartBevelOffset,
|
||||
aEndBevelSide, aEndBevelOffset);
|
||||
}
|
||||
else {
|
||||
nscoord startBevel = (aStartBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.5f * (float)aStartBevelOffset, twipsPerPixel, PR_TRUE) : 0;
|
||||
nscoord endBevel = (aEndBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.5f * (float)aEndBevelOffset, twipsPerPixel, PR_TRUE) : 0;
|
||||
PRUint8 ridgeGrooveSide = (horizontal) ? NS_SIDE_TOP : NS_SIDE_LEFT;
|
||||
aContext.SetColor (
|
||||
MakeBevelColor (ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor, PR_TRUE));
|
||||
nsRect rect(aBorder);
|
||||
nscoord half;
|
||||
if (horizontal) { // top, bottom
|
||||
half = RoundFloatToPixel(0.5f * (float)aBorder.height, twipsPerPixel);
|
||||
rect.height = half;
|
||||
if (NS_SIDE_TOP == aStartBevelSide) {
|
||||
rect.x += startBevel;
|
||||
rect.width -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_TOP == aEndBevelSide) {
|
||||
rect.width -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
else { // left, right
|
||||
half = RoundFloatToPixel(0.5f * (float)aBorder.width, twipsPerPixel);
|
||||
rect.width = half;
|
||||
if (NS_SIDE_LEFT == aStartBevelSide) {
|
||||
rect.y += startBevel;
|
||||
rect.height -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_LEFT == aEndBevelSide) {
|
||||
rect.height -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
|
||||
rect = aBorder;
|
||||
ridgeGrooveSide = (NS_SIDE_TOP == ridgeGrooveSide) ? NS_SIDE_BOTTOM : NS_SIDE_RIGHT;
|
||||
aContext.SetColor (
|
||||
MakeBevelColor (ridgeGrooveSide, ridgeGroove, aBGColor->mBackgroundColor, aBorderColor, PR_TRUE));
|
||||
if (horizontal) {
|
||||
rect.y = rect.y + half;
|
||||
rect.height = aBorder.height - half;
|
||||
if (NS_SIDE_BOTTOM == aStartBevelSide) {
|
||||
rect.x += startBevel;
|
||||
rect.width -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_BOTTOM == aEndBevelSide) {
|
||||
rect.width -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
else {
|
||||
rect.x = rect.x + half;
|
||||
rect.width = aBorder.width - half;
|
||||
if (NS_SIDE_RIGHT == aStartBevelSide) {
|
||||
rect.y += aStartBevelOffset - startBevel;
|
||||
rect.height -= startBevel;
|
||||
}
|
||||
if (NS_SIDE_RIGHT == aEndBevelSide) {
|
||||
rect.height -= endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_DOUBLE:
|
||||
if ((aBorder.width > 2) && (aBorder.height > 2)) {
|
||||
nscoord startBevel = (aStartBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.333333f * (float)aStartBevelOffset, twipsPerPixel) : 0;
|
||||
nscoord endBevel = (aEndBevelOffset > 0)
|
||||
? RoundFloatToPixel(0.333333f * (float)aEndBevelOffset, twipsPerPixel) : 0;
|
||||
if (horizontal) { // top, bottom
|
||||
nscoord thirdHeight = RoundFloatToPixel(0.333333f * (float)aBorder.height, twipsPerPixel);
|
||||
|
||||
// draw the top line or rect
|
||||
nsRect topRect(aBorder.x, aBorder.y, aBorder.width, thirdHeight);
|
||||
if (NS_SIDE_TOP == aStartBevelSide) {
|
||||
topRect.x += aStartBevelOffset - startBevel;
|
||||
topRect.width -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_TOP == aEndBevelSide) {
|
||||
topRect.width -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, topRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
|
||||
// draw the botom line or rect
|
||||
nscoord heightOffset = aBorder.height - thirdHeight;
|
||||
nsRect bottomRect(aBorder.x, aBorder.y + heightOffset, aBorder.width, aBorder.height - heightOffset);
|
||||
if (NS_SIDE_BOTTOM == aStartBevelSide) {
|
||||
bottomRect.x += aStartBevelOffset - startBevel;
|
||||
bottomRect.width -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_BOTTOM == aEndBevelSide) {
|
||||
bottomRect.width -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, bottomRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
else { // left, right
|
||||
nscoord thirdWidth = RoundFloatToPixel(0.333333f * (float)aBorder.width, twipsPerPixel);
|
||||
|
||||
nsRect leftRect(aBorder.x, aBorder.y, thirdWidth, aBorder.height);
|
||||
if (NS_SIDE_LEFT == aStartBevelSide) {
|
||||
leftRect.y += aStartBevelOffset - startBevel;
|
||||
leftRect.height -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_LEFT == aEndBevelSide) {
|
||||
leftRect.height -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, leftRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
|
||||
nscoord widthOffset = aBorder.width - thirdWidth;
|
||||
nsRect rightRect(aBorder.x + widthOffset, aBorder.y, aBorder.width - widthOffset, aBorder.height);
|
||||
if (NS_SIDE_RIGHT == aStartBevelSide) {
|
||||
rightRect.y += aStartBevelOffset - startBevel;
|
||||
rightRect.height -= aStartBevelOffset - startBevel;
|
||||
}
|
||||
if (NS_SIDE_RIGHT == aEndBevelSide) {
|
||||
rightRect.height -= aEndBevelOffset - endBevel;
|
||||
}
|
||||
DrawSolidBorderSegment(aContext, rightRect, twipsPerPixel, aStartBevelSide,
|
||||
startBevel, aEndBevelSide, endBevel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// else fall through to solid
|
||||
case NS_STYLE_BORDER_STYLE_SOLID:
|
||||
DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide,
|
||||
aStartBevelOffset, aEndBevelSide, aEndBevelOffset);
|
||||
break;
|
||||
case NS_STYLE_BORDER_STYLE_BG_OUTSET:
|
||||
case NS_STYLE_BORDER_STYLE_BG_INSET:
|
||||
case NS_STYLE_BORDER_STYLE_OUTSET:
|
||||
case NS_STYLE_BORDER_STYLE_INSET:
|
||||
NS_ASSERTION(PR_FALSE, "inset, outset should have been converted to groove, ridge");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// End table border-collapsing section
|
||||
|
||||
|
|
|
@ -180,6 +180,17 @@ public:
|
|||
PRIntn aSkipSides,
|
||||
nsRect* aGap);
|
||||
|
||||
// Draw a border segment in the table collapsing border model without beveling corners
|
||||
static void DrawTableBorderSegment(nsIRenderingContext& aContext,
|
||||
PRUint8 aBorderStyle,
|
||||
nscolor aBorderColor,
|
||||
const nsStyleBackground* aBGColor,
|
||||
const nsRect& aBorderRect,
|
||||
float aPixelsToTwips,
|
||||
PRUint8 aStartBevelSide = 0,
|
||||
nscoord aStartBevelOffset = 0,
|
||||
PRUint8 aEndBevelSide = 0,
|
||||
nscoord aEndBevelOffset = 0);
|
||||
/**
|
||||
* transform a color to a color that will show up on a printer if needed
|
||||
* aMapColor - color to evaluate
|
||||
|
|
|
@ -139,7 +139,7 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContex
|
|||
nscoord minWidth, prefWidth;
|
||||
mTableFrame->CalcMinAndPreferredWidths(aPresContext, aReflowState, PR_FALSE, minWidth, prefWidth);
|
||||
if (hasPctCol && mTableFrame->IsAutoWidth()) {
|
||||
prefWidth = CalcPctAdjTableWidth(aReflowState, boxWidth, p2t);
|
||||
prefWidth = CalcPctAdjTableWidth(*aPresContext, aReflowState, boxWidth, p2t);
|
||||
}
|
||||
// calc the desired width, considering if there is a specified width.
|
||||
// don't use nsTableFrame::CalcDesiredWidth because it is based on table column widths.
|
||||
|
@ -195,7 +195,7 @@ ResetPctValues(nsTableFrame* aTableFrame,
|
|||
// initialize the col percent and cell percent values to 0.
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < aNumCols; colX++) {
|
||||
nsTableColFrame* colFrame = aTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = aTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (colFrame) {
|
||||
colFrame->SetWidth(PCT, WIDTH_NOT_SET);
|
||||
colFrame->SetWidth(PCT_ADJ, WIDTH_NOT_SET);
|
||||
|
@ -207,6 +207,7 @@ PRBool
|
|||
BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
if (!aPresContext) ABORT1(PR_FALSE);
|
||||
#ifdef DEBUG_TABLE_STRATEGY
|
||||
printf("BalanceColumnWidths en count=%d \n", gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);
|
||||
#endif
|
||||
|
@ -220,8 +221,16 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
|
|||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRBool tableIsAutoWidth = mTableFrame->IsAutoWidth();
|
||||
nscoord horBorderPadding = aReflowState.mComputedBorderPadding.left +
|
||||
aReflowState.mComputedBorderPadding.right;
|
||||
|
||||
nscoord horOffset;
|
||||
// get the reduction in available horizontal space due to borders and padding
|
||||
if (mTableFrame->IsBorderCollapse()) {
|
||||
nsMargin offset = mTableFrame->GetChildAreaOffset(*aPresContext, &aReflowState);
|
||||
horOffset = offset.left + offset.right;
|
||||
}
|
||||
else {
|
||||
horOffset = aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
|
||||
}
|
||||
|
||||
// determine if the table is auto/fixed and get the fixed width if available
|
||||
nscoord maxWidth = mTableFrame->CalcBorderBoxWidth(aPresContext, aReflowState);
|
||||
|
@ -238,19 +247,19 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
|
|||
// An auto table returns a new table width based on percent cells/cols if they exist
|
||||
nscoord perAdjTableWidth = 0;
|
||||
if (mTableFrame->HasPctCol()) {
|
||||
perAdjTableWidth = AssignPctColumnWidths(aReflowState, maxWidth, tableIsAutoWidth, p2t);
|
||||
perAdjTableWidth = AssignPctColumnWidths(*aPresContext, aReflowState, maxWidth, tableIsAutoWidth, p2t);
|
||||
if (perAdjTableWidth > 0) {
|
||||
// if an auto table has a pct col or cell, set the preferred table width
|
||||
// here so that CalcPctAdjTableWidth wont't need to be called by the table
|
||||
mTableFrame->SetPreferredWidth(perAdjTableWidth);
|
||||
}
|
||||
perAdjTableWidth = PR_MIN(perAdjTableWidth, maxWidth);
|
||||
perAdjTableWidth -= horBorderPadding;
|
||||
perAdjTableWidth -= horOffset;
|
||||
perAdjTableWidth = PR_MAX(perAdjTableWidth, 0);
|
||||
}
|
||||
|
||||
// reduce the maxWidth by border and padding, since we will be dealing with content width
|
||||
maxWidth -= horBorderPadding;
|
||||
maxWidth -= horOffset;
|
||||
maxWidth = PR_MAX(0, maxWidth);
|
||||
|
||||
PRInt32 numNonZeroWidthCols = 0;
|
||||
|
@ -258,7 +267,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
|
|||
nscoord minTableWidth = 0;
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord colMinWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, colMinWidth);
|
||||
|
@ -400,7 +409,7 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated,
|
|||
{
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame)) {
|
||||
continue;
|
||||
|
@ -454,7 +463,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
|||
}
|
||||
else {
|
||||
if (aExclude0Pro) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (colFrame->GetConstraint() == e0ProportionConstraint) {
|
||||
aAllocTypes[colX] = FINISHED;
|
||||
}
|
||||
|
@ -467,7 +476,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
|||
PRInt32 numColsAllocated = 0;
|
||||
PRInt32 totalAllocated = 0;
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
PRBool skipColumn = aExclude0Pro && (e0ProportionConstraint == colFrame->GetConstraint());
|
||||
if (FINISHED != aAllocTypes[colX] && !skipColumn ) {
|
||||
divisor += mTableFrame->GetColumnWidth(colX);
|
||||
|
@ -477,7 +486,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
|||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (FINISHED != aAllocTypes[colX]) {
|
||||
if (aExclude0Pro) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (colFrame && (e0ProportionConstraint == colFrame->GetConstraint())) {
|
||||
continue;
|
||||
}
|
||||
|
@ -533,7 +542,7 @@ BasicTableLayoutStrategy::ComputeNonPctColspanWidths(const nsHTMLReflowState& aR
|
|||
|
||||
PRInt32 colX;
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
colFrame->SetWidth(MIN_ADJ, WIDTH_NOT_SET);
|
||||
colFrame->SetWidth(FIX_ADJ, WIDTH_NOT_SET);
|
||||
|
@ -698,7 +707,7 @@ BasicTableLayoutStrategy::ComputeNonPctColspanWidths(PRInt32 aWidthInd
|
|||
PRInt32 spanX;
|
||||
// accumulate the various divisors to be used later
|
||||
for (spanX = 0; spanX < aColSpan; spanX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord minWidth = PR_MAX(colFrame->GetMinWidth(), 0);
|
||||
nscoord pctWidth = PR_MAX(colFrame->GetPctWidth(), 0);
|
||||
|
@ -802,7 +811,7 @@ BasicTableLayoutStrategy::ComputeNonPctColspanWidths(PRInt32 aWidthInd
|
|||
// get the correct numerator in a similar fashion to getting the divisor
|
||||
for (spanX = 0; spanX < aColSpan; spanX++) {
|
||||
if (usedWidth >= availWidth) break;
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord minWidth = colFrame->GetMinWidth();
|
||||
nscoord pctWidth = PR_MAX(colFrame->GetPctWidth(), 0);
|
||||
|
@ -974,7 +983,7 @@ BasicTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
|
|||
nscoord fixWidth = WIDTH_NOT_SET;
|
||||
|
||||
// Get column frame and reset it
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
NS_ASSERTION(nsnull != colFrame, "bad col frame");
|
||||
colFrame->ResetSizingInfo();
|
||||
|
@ -1079,7 +1088,7 @@ BasicTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
|
|||
}
|
||||
//set the table col fixed width if present
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord fixColWidth = colFrame->GetWidth(FIX);
|
||||
// use the style width of a col only if the col hasn't gotten a fixed width from any cell
|
||||
|
@ -1140,7 +1149,7 @@ BasicTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
|
|||
|
||||
// Set the table col width for each col to the content min.
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
nscoord minWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, minWidth);
|
||||
}
|
||||
|
@ -1159,7 +1168,7 @@ BasicTableLayoutStrategy::ReduceOverSpecifiedPctCols(nscoord aExcess)
|
|||
{
|
||||
nscoord numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = numCols - 1; (colX >= 0) && (aExcess > 0); colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
nscoord pctWidth = colFrame->GetWidth(PCT);
|
||||
nscoord reduction = 0;
|
||||
|
@ -1198,7 +1207,8 @@ inline nscoord WrapupAssignPctColumnWidths(nsTableFrame* aTableFrame,
|
|||
#endif
|
||||
|
||||
nscoord
|
||||
BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowState,
|
||||
BasicTableLayoutStrategy::CalcPctAdjTableWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidthIn,
|
||||
float aPixelToTwips)
|
||||
{
|
||||
|
@ -1219,7 +1229,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
rawPctValues[colX] = 0.0f;
|
||||
}
|
||||
|
||||
nsMargin borderPadding = mTableFrame->GetBorderPadding(aReflowState);
|
||||
nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState);
|
||||
nscoord availWidth = aAvailWidthIn;
|
||||
if (NS_UNCONSTRAINEDSIZE != availWidth) {
|
||||
// adjust the avail width to exclude table border, padding and cell spacing
|
||||
|
@ -1227,7 +1237,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
}
|
||||
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
nscoord maxColBasis = -1;
|
||||
// Scan the cells in the col
|
||||
|
@ -1282,7 +1292,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
nscoord fixDesTotalNoPct = 0; // total of fix or des widths of cols without pct
|
||||
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(0);
|
||||
nscoord fixWidth = colFrame->GetFixWidth();
|
||||
nscoord fixDesWidth = (fixWidth > 0) ? fixWidth : colFrame->GetDesWidth();
|
||||
fixDesTotal += fixDesWidth;
|
||||
|
@ -1329,7 +1339,8 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
|
||||
// Determine percentage col widths for each col frame
|
||||
nscoord
|
||||
BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflowState,
|
||||
BasicTableLayoutStrategy::AssignPctColumnWidths(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
PRBool aTableIsAutoWidth,
|
||||
float aPixelToTwips)
|
||||
|
@ -1349,11 +1360,11 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// on percent cells/cols. This probably should only be a NavQuirks thing, since
|
||||
// a percentage based cell or column on an auto table should force the column to auto
|
||||
nscoord basis = (aTableIsAutoWidth)
|
||||
? CalcPctAdjTableWidth(aReflowState, aAvailWidth, aPixelToTwips)
|
||||
? CalcPctAdjTableWidth(aPresContext, aReflowState, aAvailWidth, aPixelToTwips)
|
||||
: aAvailWidth;
|
||||
|
||||
// adjust the basis to exclude table border, padding and cell spacing
|
||||
nsMargin borderPadding = mTableFrame->GetBorderPadding(aReflowState);
|
||||
nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState);
|
||||
basis -= borderPadding.left + borderPadding.right + mCellSpacingTotal;
|
||||
|
||||
nscoord colPctTotal = 0;
|
||||
|
@ -1361,7 +1372,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// Determine the percentage contribution for cols and for cells with colspan = 1
|
||||
// Iterate backwards, similarly to the reasoning in AssignNonPctColumnWidths
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
nscoord maxColPctWidth = WIDTH_NOT_SET;
|
||||
float maxColPct = 0.0f;
|
||||
|
@ -1431,7 +1442,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
}
|
||||
// determine if the cell spans cols which have a pct value
|
||||
for (PRInt32 spanX = 0; (spanX < colSpan) && !done; spanX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
if (colFrame->GetWidth(PCT) > 0) {
|
||||
mTableFrame->SetHasCellSpanningPctCol(PR_TRUE);
|
||||
|
@ -1511,7 +1522,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// accumulate the spanTotal as the max of MIN, DES, FIX, PCT
|
||||
PRInt32 spanX;
|
||||
for (spanX = 0; spanX < colSpan; spanX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
nscoord colPctWidth = colFrame->GetWidth(PCT);
|
||||
if (colPctWidth > 0) { // skip pct cols
|
||||
|
@ -1546,7 +1557,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// record the percent contributions for the spanned cols
|
||||
PRInt32 usedColumns = colSpan;
|
||||
for (spanX = colSpan-1; spanX >= 0; spanX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
if ((colFrame->GetWidth(PCT) > 0) || (canSkipPctAdj && (colFrame->GetWidth(PCT_ADJ) > 0))) {
|
||||
// dont use pct cols or if we can skip the pct adj event do not take the PCT_ADJ cols
|
||||
|
@ -1621,7 +1632,7 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32* aTotalCounts,
|
|||
PRInt32 colX;
|
||||
|
||||
for (colX = 0; colX < numEffCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
nscoord minCol = colFrame->GetMinWidth();
|
||||
aTotalCounts[MIN_CON]++;
|
||||
|
@ -1820,7 +1831,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
|||
PRInt32 colX;
|
||||
// find out how many constrained cols there are
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame)) {
|
||||
continue;
|
||||
|
@ -1837,7 +1848,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
|||
PRInt32 constrColX = 0;
|
||||
// set the col info entries for each constrained col
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame)) {
|
||||
continue;
|
||||
|
|
|
@ -93,7 +93,8 @@ public:
|
|||
* @param aPixelToTwips - the number of twips in a pixel.
|
||||
* @return - the basis for percent calculations
|
||||
*/
|
||||
virtual nscoord CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowState,
|
||||
virtual nscoord CalcPctAdjTableWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
float aPixelToTwips);
|
||||
void Dump(PRInt32 aIndent);
|
||||
|
@ -159,7 +160,8 @@ protected:
|
|||
* @param aPixelToTwips - the number of twips in a pixel.
|
||||
* @return - the adjusted basis including table border, padding and cell spacing
|
||||
*/
|
||||
nscoord AssignPctColumnWidths(const nsHTMLReflowState& aReflowState,
|
||||
nscoord AssignPctColumnWidths(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aBasis,
|
||||
PRBool aTableIsAutoWidth,
|
||||
float aPixelToTwips);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define CellData_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsCoord.h"
|
||||
|
||||
class nsTableCellFrame;
|
||||
|
||||
|
@ -51,8 +52,9 @@ public:
|
|||
|
||||
~CellData();
|
||||
|
||||
void Init(nsTableCellFrame* aCellFrame);
|
||||
PRBool IsOrig() const;
|
||||
|
||||
PRBool IsDead() const;
|
||||
PRBool IsSpan() const;
|
||||
|
||||
PRBool IsRowSpan() const;
|
||||
|
@ -84,6 +86,93 @@ protected:
|
|||
};
|
||||
};
|
||||
|
||||
// Border Collapsing Cell Data
|
||||
enum BCBorderOwner
|
||||
{
|
||||
eTableOwner = 0,
|
||||
eColGroupOwner = 1,
|
||||
eAjaColGroupOwner = 2, // col group to the left
|
||||
eColOwner = 3,
|
||||
eAjaColOwner = 4, // col to the left
|
||||
eRowGroupOwner = 5,
|
||||
eAjaRowGroupOwner = 6, // row group above
|
||||
eRowOwner = 7,
|
||||
eAjaRowOwner = 8, // row above
|
||||
eCellOwner = 9,
|
||||
eAjaCellOwner = 10, // cell to the top or to the left
|
||||
};
|
||||
|
||||
// These are the max sizes that are stored. If they are exceeded, then the max is stored and
|
||||
// the actual value is computed when needed.
|
||||
#define MAX_BORDER_WIDTH 64
|
||||
#define MAX_CORNER_SUB_WIDTH 128
|
||||
|
||||
// BCData stores the top and left border info and the corner connecting the two.
|
||||
class BCData
|
||||
{
|
||||
public:
|
||||
BCData();
|
||||
|
||||
~BCData();
|
||||
|
||||
nscoord GetLeftEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const;
|
||||
|
||||
void SetLeftEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart);
|
||||
|
||||
nscoord GetTopEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const;
|
||||
|
||||
void SetTopEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart);
|
||||
|
||||
PRUint8 GetCorner(PRUint8& aCornerOwner,
|
||||
PRPackedBool& aBevel) const;
|
||||
|
||||
void SetCorner(PRUint8 aOwner,
|
||||
PRUint8 aSubSize,
|
||||
PRBool aBevel);
|
||||
|
||||
PRBool IsLeftStart() const;
|
||||
|
||||
void SetLeftStart(PRBool aValue);
|
||||
|
||||
PRBool IsTopStart() const;
|
||||
|
||||
void SetTopStart(PRBool aValue);
|
||||
|
||||
|
||||
protected:
|
||||
unsigned mLeftOwner: 4; // owner of left border
|
||||
unsigned mLeftSize: 6; // size in pixels of left border
|
||||
unsigned mLeftStart: 1; // set if this is the start of a vertical border segment
|
||||
unsigned mCornerSide: 2; // side of the owner of the upper left corner relative to the corner
|
||||
unsigned mCornerSubSize: 7; // size of the largest border not in the dominate plane (for example, if
|
||||
// corner is owned by the segment to its top or bottom, then the size is the
|
||||
// max of the border sizes of the segments to its left or right.
|
||||
unsigned mCornerBevel: 1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
|
||||
unsigned mTopOwner: 4; // owner of top border
|
||||
unsigned mTopSize: 6; // size in pixels of top border
|
||||
unsigned mTopStart: 1; // set if this is the start of a horizontal border segment
|
||||
};
|
||||
|
||||
// BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
|
||||
// effect. BCData for a row and col entry contains the left and top borders of cell at that row and
|
||||
// col and the corner connecting the two. The right borders of the cells in the last col and the bottom
|
||||
// borders of the last row are stored in separate BCData entries in the cell map.
|
||||
class BCCellData : public CellData
|
||||
{
|
||||
public:
|
||||
BCCellData(nsTableCellFrame* aOrigCell);
|
||||
~BCCellData();
|
||||
|
||||
BCData mData;
|
||||
};
|
||||
|
||||
|
||||
#define SPAN 0x00000001 // there a row or col span
|
||||
#define ROW_SPAN 0x00000002 // there is a row span
|
||||
#define ROW_SPAN_0 0x00000004 // the row span is 0
|
||||
|
@ -103,9 +192,19 @@ inline nsTableCellFrame* CellData::GetCellFrame() const
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
inline void CellData::Init(nsTableCellFrame* aCellFrame)
|
||||
{
|
||||
mOrigCell = aCellFrame;
|
||||
}
|
||||
|
||||
inline PRBool CellData::IsOrig() const
|
||||
{
|
||||
return (SPAN != (SPAN & mBits));
|
||||
return ((nsnull != mOrigCell) && (SPAN != (SPAN & mBits)));
|
||||
}
|
||||
|
||||
inline PRBool CellData::IsDead() const
|
||||
{
|
||||
return (0 == mBits);
|
||||
}
|
||||
|
||||
inline PRBool CellData::IsSpan() const
|
||||
|
@ -213,4 +312,88 @@ inline void CellData::SetOverlap(PRBool aOverlap)
|
|||
}
|
||||
}
|
||||
|
||||
inline BCData::BCData()
|
||||
{
|
||||
mLeftOwner = mTopOwner = eCellOwner;
|
||||
mLeftStart = mTopStart = 1;
|
||||
mLeftSize = mCornerSide = mCornerSubSize = mTopSize = 0;
|
||||
}
|
||||
|
||||
inline BCData::~BCData()
|
||||
{
|
||||
}
|
||||
|
||||
inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const
|
||||
{
|
||||
aOwner = (BCBorderOwner)mLeftOwner;
|
||||
aStart = (PRBool)mLeftStart;
|
||||
|
||||
return (nscoord)mLeftSize;
|
||||
}
|
||||
|
||||
inline void BCData::SetLeftEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart)
|
||||
{
|
||||
mLeftOwner = aOwner;
|
||||
mLeftSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
|
||||
mLeftStart = aStart;
|
||||
}
|
||||
|
||||
inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const
|
||||
{
|
||||
aOwner = (BCBorderOwner)mTopOwner;
|
||||
aStart = (PRBool)mTopStart;
|
||||
|
||||
return (nscoord)mTopSize;
|
||||
}
|
||||
|
||||
inline void BCData::SetTopEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart)
|
||||
{
|
||||
mTopOwner = aOwner;
|
||||
mTopSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
|
||||
mTopStart = aStart;
|
||||
}
|
||||
|
||||
inline PRUint8 BCData::GetCorner(PRUint8& aOwnerSide,
|
||||
PRPackedBool& aBevel) const
|
||||
{
|
||||
aOwnerSide = mCornerSide;
|
||||
aBevel = (PRBool)mCornerBevel;
|
||||
return (PRUint8)mCornerSubSize;
|
||||
}
|
||||
|
||||
inline void BCData::SetCorner(PRUint8 aSubSize,
|
||||
PRUint8 aOwnerSide,
|
||||
PRBool aBevel)
|
||||
{
|
||||
mCornerSubSize = (aSubSize > MAX_CORNER_SUB_WIDTH) ? MAX_CORNER_SUB_WIDTH : aSubSize;
|
||||
mCornerSide = aOwnerSide;
|
||||
mCornerBevel = aBevel;
|
||||
}
|
||||
|
||||
inline PRBool BCData::IsLeftStart() const
|
||||
{
|
||||
return (PRBool)mLeftStart;
|
||||
}
|
||||
|
||||
inline void BCData::SetLeftStart(PRBool aValue)
|
||||
{
|
||||
mLeftStart = aValue;
|
||||
}
|
||||
|
||||
inline PRBool BCData::IsTopStart() const
|
||||
{
|
||||
return (PRBool)mTopStart;
|
||||
}
|
||||
|
||||
inline void BCData::SetTopStart(PRBool aValue)
|
||||
{
|
||||
mTopStart = aValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -40,6 +40,8 @@
|
|||
#include "nscore.h"
|
||||
#include "celldata.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsTableColFrame;
|
||||
class nsTableCellFrame;
|
||||
class nsIPresContext;
|
||||
|
@ -58,10 +60,27 @@ struct nsColInfo
|
|||
PRInt32 aNumCellsSpan);
|
||||
};
|
||||
|
||||
enum Corner
|
||||
{
|
||||
eTopLeft = 0,
|
||||
eTopRight = 1,
|
||||
eBottomRight = 2,
|
||||
eBottomLeft = 3
|
||||
};
|
||||
|
||||
struct BCInfo
|
||||
{
|
||||
nsVoidArray mRightBorders;
|
||||
nsVoidArray mBottomBorders;
|
||||
BCData mLowerRightCorner;
|
||||
};
|
||||
|
||||
class nsTableCellMap
|
||||
{
|
||||
public:
|
||||
nsTableCellMap(nsIPresContext* aPresContext, nsTableFrame& aTableFrame);
|
||||
nsTableCellMap(nsIPresContext* aPresContext,
|
||||
nsTableFrame& aTableFrame,
|
||||
PRBool aBorderCollapse);
|
||||
|
||||
/** destructor
|
||||
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
|
||||
|
@ -69,43 +88,52 @@ public:
|
|||
~nsTableCellMap();
|
||||
|
||||
void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
|
||||
|
||||
void InsertGroupCellMap(nsTableRowGroupFrame& aNewRowGroup,
|
||||
nsTableRowGroupFrame*& aPrevRowGroup);
|
||||
|
||||
nsCellMap* GetMapFor(nsTableRowGroupFrame& aRowGroup);
|
||||
|
||||
nsTableCellFrame* GetCellFrame(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
CellData& aData,
|
||||
PRBool aUseRowIfOverlap) const;
|
||||
|
||||
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
|
||||
CellData* GetCellAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
CellData* GetDataAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aUpdateZeroSpan = PR_TRUE);
|
||||
|
||||
nsColInfo* GetColInfoAt(PRInt32 aColIndex);
|
||||
|
||||
/** append the cellFrame at the end of the row at aRowIndex and return the col index
|
||||
*/
|
||||
PRInt32 AppendCell(nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary);
|
||||
CellData* AppendCell(nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertCells(nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
PRInt32 aColIndexBefore,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
PRInt32 aRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertRows(nsIPresContext* aPresContext,
|
||||
nsTableRowGroupFrame& aRowGroup,
|
||||
nsVoidArray& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveRows(nsIPresContext* aPresContext,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex);
|
||||
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
|
||||
|
@ -134,6 +162,32 @@ public:
|
|||
PRBool ColIsSpannedInto(PRInt32 aColIndex);
|
||||
PRBool ColHasSpanningCells(PRInt32 aColIndex);
|
||||
|
||||
BCData* GetBCData(PRUint8 aSide,
|
||||
nsCellMap& aCellMap,
|
||||
PRUint32 aYPos,
|
||||
PRUint32 aXPos,
|
||||
PRBool aIsLowerRight = PR_FALSE);
|
||||
|
||||
void SetBCBorderEdge(PRUint8 aEdge,
|
||||
nsCellMap& aCellMap,
|
||||
PRUint32 aCellMapStart,
|
||||
PRUint32 aYPos,
|
||||
PRUint32 aXPos,
|
||||
PRUint32 aLength,
|
||||
BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aChanged);
|
||||
|
||||
void SetBCBorderCorner(Corner aCorner,
|
||||
nsCellMap& aCellMap,
|
||||
PRUint32 aCellMapStart,
|
||||
PRUint32 aYPos,
|
||||
PRUint32 aXPos,
|
||||
PRUint8 aOwner,
|
||||
nscoord aSubSize,
|
||||
PRBool aBevel,
|
||||
PRBool aIsBottomRight = PR_FALSE);
|
||||
|
||||
/** dump a representation of the cell map to stdout for debugging */
|
||||
#ifdef NS_DEBUG
|
||||
void Dump(char* aString = nsnull) const;
|
||||
|
@ -144,13 +198,21 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
BCData* GetRightMostBorder(PRInt32 aRowIndex);
|
||||
BCData* GetBottomMostBorder(PRInt32 aColIndex);
|
||||
|
||||
friend class nsCellMap;
|
||||
friend class BCMapCellIterator;
|
||||
friend class BCMapBorderIterator;
|
||||
void InsertGroupCellMap(nsCellMap* aPrevMap,
|
||||
nsCellMap& aNewMap);
|
||||
void DeleteRightBottomBorders();
|
||||
|
||||
nsTableFrame& mTableFrame;
|
||||
nsTableFrame& mTableFrame;
|
||||
nsAutoVoidArray mCols;
|
||||
nsCellMap* mFirstMap;
|
||||
nsCellMap* mFirstMap;
|
||||
// border collapsing info
|
||||
BCInfo* mBCInfo;
|
||||
};
|
||||
|
||||
/** nsCellMap is a support class for nsTablePart.
|
||||
|
@ -190,40 +252,38 @@ public:
|
|||
CellData& aData,
|
||||
PRBool aUseRowSpanIfOverlap) const;
|
||||
|
||||
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
|
||||
CellData* GetCellAt(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
/** append the cellFrame at the end of the row at aRowIndex and return the col index
|
||||
*/
|
||||
PRInt32 AppendCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary);
|
||||
CellData* AppendCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertCells(nsTableCellMap& aMap,
|
||||
nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
PRInt32 aColIndexBefore,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void RemoveCol(PRInt32 aColIndex);
|
||||
PRInt32 aRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
nsVoidArray& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
|
||||
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
|
||||
|
@ -246,9 +306,20 @@ public:
|
|||
PRBool ColHasSpanningCells(nsTableCellMap& aMap,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
PRInt32 GetRowSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aGetEffective,
|
||||
PRBool& aIsZeroRowSpan);
|
||||
|
||||
PRInt32 GetEffectiveColSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool& aIsZeroColSpan);
|
||||
|
||||
/** dump a representation of the cell map to stdout for debugging */
|
||||
#ifdef NS_DEBUG
|
||||
void Dump() const;
|
||||
void Dump(PRBool aIsBorderCollapse) const;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -257,6 +328,9 @@ public:
|
|||
|
||||
protected:
|
||||
friend class nsTableCellMap;
|
||||
friend class BCMapCellIterator;
|
||||
friend class BCMapBorderIterator;
|
||||
friend class nsTableFrame;
|
||||
|
||||
PRBool Grow(nsTableCellMap& aMap,
|
||||
PRInt32 aNumRows,
|
||||
|
@ -266,51 +340,57 @@ protected:
|
|||
PRInt32 aNumCols);
|
||||
|
||||
/** assign aCellData to the cell at (aRow,aColumn) */
|
||||
void SetMapCellAt(nsTableCellMap& aMap,
|
||||
CellData& aCellData,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aCountZeroSpanAsSpan);
|
||||
void SetDataAt(nsTableCellMap& aMap,
|
||||
CellData& aCellData,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aCountZeroSpanAsSpan);
|
||||
|
||||
CellData* GetMapCellAt(nsTableCellMap& aMap,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aUpdateZeroSpan);
|
||||
CellData* GetDataAt(nsTableCellMap& aMap,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aUpdateZeroSpan);
|
||||
|
||||
PRInt32 GetNumCellsIn(PRInt32 aColIndex) const;
|
||||
|
||||
void ExpandWithRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
nsVoidArray& aRowFrames,
|
||||
PRInt32 aStartRowIndex);
|
||||
PRInt32 aStartRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ExpandWithCells(nsTableCellMap& aMap,
|
||||
nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aRowSpan,
|
||||
PRBool aRowSpanIsZero);
|
||||
PRBool aRowSpanIsZero,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ShrinkWithoutRows(nsTableCellMap& aMap,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove);
|
||||
PRInt32 aNumRowsToRemove,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ShrinkWithoutCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
PRInt32 aColIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RebuildConsideringRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
PRInt32 aStartRowIndex,
|
||||
nsVoidArray* aRowsToInsert,
|
||||
PRInt32 aNumRowsToRemove = 0);
|
||||
PRInt32 aNumRowsToRemove,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RebuildConsideringCells(nsTableCellMap& aMap,
|
||||
nsVoidArray* aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aInsert);
|
||||
PRBool aInsert,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRBool CellsSpanOut(nsIPresContext* aPresContext,
|
||||
nsVoidArray& aNewRows);
|
||||
|
@ -327,21 +407,10 @@ protected:
|
|||
PRBool CreateEmptyRow(PRInt32 aRowIndex,
|
||||
PRInt32 aNumCols);
|
||||
|
||||
PRInt32 GetRowSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aGetEffective,
|
||||
PRBool& aIsZeroRowSpan);
|
||||
|
||||
PRInt32 GetRowSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool& aIsZeroRowSpan);
|
||||
|
||||
PRInt32 GetEffectiveColSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool& aIsZeroColSpan);
|
||||
|
||||
PRInt32 GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aNumColsInTable,
|
||||
|
|
|
@ -76,7 +76,8 @@ public:
|
|||
* @param aPixelToTwips - the number of twips in a pixel.
|
||||
* @return - the basis for percent calculations
|
||||
*/
|
||||
virtual nscoord CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowState,
|
||||
virtual nscoord CalcPctAdjTableWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
float aPixelToTwips)=0;
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ nsTableCellFrame::GetNextCell() const
|
|||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
return (nsTableCellFrame*)childFrame;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
|
@ -439,7 +439,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext,
|
|||
if ((NS_SUCCEEDED(rv)) && tableFrame) {
|
||||
const nsStyleTableBorder* tableStyle;
|
||||
tableFrame->GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)tableStyle));
|
||||
if (NS_STYLE_BORDER_SEPARATE == tableFrame->GetBorderCollapseStyle()) {
|
||||
if (!tableFrame->IsBorderCollapse()) {
|
||||
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
|
||||
aDirtyRect, rect, *myBorder, mStyleContext, skipSides);
|
||||
}
|
||||
|
@ -582,10 +582,9 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex
|
|||
const nsStyleTextReset* textStyle =
|
||||
(const nsStyleTextReset*)mStyleContext->GetStyleData(eStyleStruct_TextReset);
|
||||
/* XXX: remove tableFrame when border-collapse inherits */
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
(void) nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
nsMargin borderPadding;
|
||||
GetCellBorder (borderPadding, tableFrame);
|
||||
GetBorderWidth (p2t, borderPadding);
|
||||
nsMargin padding = nsTableFrame::GetPadding(aReflowState, this);
|
||||
borderPadding += padding;
|
||||
|
||||
|
@ -822,13 +821,13 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
PRBool contentEmptyBeforeReflow = GetContentEmpty();
|
||||
/* XXX: remove tableFrame when border-collapse inherits */
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(NS_ERROR_NULL_POINTER);
|
||||
nsTableFrame* tableFrameFirstInFlow = (nsTableFrame*)tableFrame->GetFirstInFlow();
|
||||
|
||||
nsMargin borderPadding = aReflowState.mComputedPadding;
|
||||
nsMargin border;
|
||||
GetCellBorder(border, tableFrame);
|
||||
GetBorderWidth(p2t, border);
|
||||
if ((NS_UNCONSTRAINEDSIZE == availSize.width) || !contentEmptyBeforeReflow) {
|
||||
borderPadding += border;
|
||||
}
|
||||
|
@ -1130,51 +1129,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Update the border style to map to the HTML border style
|
||||
*
|
||||
*/
|
||||
void nsTableCellFrame::MapHTMLBorderStyle(nsIPresContext* aPresContext,
|
||||
nsStyleBorder& aBorderStyle,
|
||||
nsTableFrame* aTableFrame)
|
||||
{
|
||||
//adjust the border style based on the table rules attribute
|
||||
|
||||
/* The RULES code below has been disabled because collapsing borders have been disabled
|
||||
and RULES depend on collapsing borders
|
||||
|
||||
const nsStyleTable* tableStyle;
|
||||
aTableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
|
||||
switch (tableStyle->mRules)
|
||||
{
|
||||
case NS_STYLE_TABLE_RULES_NONE:
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
break;
|
||||
|
||||
case NS_STYLE_TABLE_RULES_COLS:
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE);
|
||||
break;
|
||||
|
||||
case NS_STYLE_TABLE_RULES_ROWS:
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing for "GROUPS" or "ALL" or for any illegal value
|
||||
// "GROUPS" will be handled in nsTableFrame::ProcessGroupRules
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
PRBool nsTableCellFrame::ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult)
|
||||
{
|
||||
if (aValue.GetUnit() == eHTMLUnit_Pixel)
|
||||
|
@ -1401,13 +1355,16 @@ nsTableCellFrame::GetNextCellInColumn(nsITableCellLayout **aCellLayout)
|
|||
}
|
||||
|
||||
nsresult
|
||||
NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
NS_NewTableCellFrame(nsIPresShell* aPresShell,
|
||||
PRBool aIsBorderCollapse,
|
||||
nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsTableCellFrame* it = new (aPresShell) nsTableCellFrame;
|
||||
nsTableCellFrame* it = (aIsBorderCollapse) ? new (aPresShell) nsBCTableCellFrame
|
||||
: new (aPresShell) nsTableCellFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -1415,27 +1372,16 @@ NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----- methods from CellLayoutData ----- */
|
||||
|
||||
void
|
||||
nsTableCellFrame::GetCellBorder(nsMargin& aBorder,
|
||||
nsTableFrame* aTableFrame)
|
||||
nsMargin*
|
||||
nsTableCellFrame::GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const
|
||||
{
|
||||
aBorder.left = aBorder.right = aBorder.top = aBorder.bottom = 0;
|
||||
if (nsnull==aTableFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_STYLE_BORDER_SEPARATE == aTableFrame->GetBorderCollapseStyle()) {
|
||||
const nsStyleBorder* borderData;
|
||||
GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData);
|
||||
borderData->GetBorder(aBorder);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "not implemented");
|
||||
}
|
||||
const nsStyleBorder* borderData;
|
||||
GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData);
|
||||
borderData->GetBorder(aBorder);
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1502,3 +1448,100 @@ nsTableCellFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
|||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsBCTableCellFrame
|
||||
|
||||
nsBCTableCellFrame::nsBCTableCellFrame()
|
||||
:nsTableCellFrame()
|
||||
{
|
||||
mTopBorder = mRightBorder = mBottomBorder = mLeftBorder = 0;
|
||||
}
|
||||
|
||||
nsBCTableCellFrame::~nsBCTableCellFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBCTableCellFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
|
||||
*aType = nsLayoutAtoms::bcTableCellFrame;
|
||||
NS_ADDREF(*aType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsBCTableCellFrame::GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("BCTableCell"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBCTableCellFrame::SetBorderWidth(const nsMargin& aBorder)
|
||||
{
|
||||
mTopBorder = aBorder.top;
|
||||
mRightBorder = aBorder.right;
|
||||
mBottomBorder = aBorder.bottom;
|
||||
mLeftBorder = aBorder.left;
|
||||
}
|
||||
|
||||
nsMargin*
|
||||
nsBCTableCellFrame::GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const
|
||||
{
|
||||
aBorder.top = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mTopBorder) : mTopBorder;
|
||||
aBorder.right = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mRightBorder) : mRightBorder;
|
||||
aBorder.bottom = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mBottomBorder): mBottomBorder;
|
||||
aBorder.left = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mLeftBorder): mLeftBorder;
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsBCTableCellFrame::GetBorderWidth(PRUint8 aSide) const
|
||||
{
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
return (PRUint8)mTopBorder;
|
||||
case NS_SIDE_RIGHT:
|
||||
return (PRUint8)mRightBorder;
|
||||
case NS_SIDE_BOTTOM:
|
||||
return (PRUint8)mBottomBorder;
|
||||
default:
|
||||
return (PRUint8)mLeftBorder;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsBCTableCellFrame::SetBorderWidth(PRUint8 aSide,
|
||||
nscoord aValue)
|
||||
{
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
mTopBorder = aValue;
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
mRightBorder = aValue;
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
mBottomBorder = aValue;
|
||||
break;
|
||||
default:
|
||||
mLeftBorder = aValue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsBCTableCellFrame::SizeOf(nsISizeOfHandler* aHandler,
|
||||
PRUint32* aResult) const
|
||||
{
|
||||
if (!aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
PRUint32 sum = sizeof(*this);
|
||||
*aResult = sum;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsTableRowFrame.h" // need to actually include this here to inline GetRowIndex
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIPercentHeightObserver.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
class nsTableFrame;
|
||||
class nsHTMLValue;
|
||||
|
@ -266,6 +267,9 @@ public:
|
|||
|
||||
nsTableCellFrame* GetNextCell() const;
|
||||
|
||||
virtual nsMargin* GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const;
|
||||
|
||||
protected:
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
@ -277,18 +281,11 @@ private:
|
|||
// All these methods are support methods for RecalcLayoutData
|
||||
nsIFrame* GetFrameAt(nsVoidArray* aList, PRInt32 aIndex);
|
||||
|
||||
//XXX: aTableFrame can be removed as soon as border-collapse inherits correctly
|
||||
void GetCellBorder(nsMargin &aBorder, nsTableFrame *aTableFrame);
|
||||
|
||||
protected:
|
||||
|
||||
friend class nsTableRowFrame;
|
||||
void MapBorderPadding(nsIPresContext* aPresContext);
|
||||
|
||||
void MapHTMLBorderStyle(nsIPresContext* aPresContext,
|
||||
nsStyleBorder& aBorderStyle,
|
||||
nsTableFrame* aTableFrame);
|
||||
|
||||
void MapVAlignAttribute(nsIPresContext* aPresContext, nsTableFrame *aTableFrame);
|
||||
void MapHAlignAttribute(nsIPresContext* aPresContext, nsTableFrame *aTableFrame);
|
||||
|
||||
|
@ -421,6 +418,41 @@ inline void nsTableCellFrame::SetLastBlockHeight(nscoord aValue)
|
|||
{
|
||||
mBits.mLastBlockHeight = aValue;
|
||||
}
|
||||
|
||||
// nsBCTableCellFrame
|
||||
class nsBCTableCellFrame : public nsTableCellFrame
|
||||
{
|
||||
public:
|
||||
|
||||
nsBCTableCellFrame();
|
||||
|
||||
~nsBCTableCellFrame();
|
||||
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
|
||||
virtual nsMargin* GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const;
|
||||
nscoord GetBorderWidth(PRUint8 aSide) const;
|
||||
|
||||
void SetBorderWidth(const nsMargin& aBorder);
|
||||
void SetBorderWidth(PRUint8 aSide, nscoord aPixelValue);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
PRUint32 mTopBorder: 8;
|
||||
PRUint32 mRightBorder: 8;
|
||||
PRUint32 mBottomBorder: 8;
|
||||
PRUint32 mLeftBorder: 8;
|
||||
};
|
||||
|
||||
#define IS_TABLE_CELL(frameType)\
|
||||
((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -113,7 +113,8 @@ nsStyleCoord nsTableColFrame::GetStyleWidth() const
|
|||
nsStyleCoord styleWidth = position->mWidth;
|
||||
// the following should not be necessary since html.css defines table-col and
|
||||
// :table-col to inherit. However, :table-col is not inheriting properly
|
||||
if (eStyleUnit_Auto == styleWidth.GetUnit()) {
|
||||
if (eStyleUnit_Auto == styleWidth.GetUnit() ||
|
||||
eStyleUnit_Inherit == styleWidth.GetUnit()) {
|
||||
nsIFrame* parent;
|
||||
GetParent(&parent);
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
|
@ -305,6 +306,22 @@ nsTableColFrame::Init(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsTableColFrame*
|
||||
nsTableColFrame::GetNextCol() const
|
||||
{
|
||||
nsIFrame* childFrame;
|
||||
GetNextSibling(&childFrame);
|
||||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableColFrame == frameType.get()) {
|
||||
return (nsTableColFrame*)childFrame;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
|
||||
void SetColIndex (PRInt32 aColIndex);
|
||||
|
||||
nsTableColFrame* GetNextCol() const;
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
|
@ -164,6 +166,11 @@ public:
|
|||
|
||||
void ResetSizingInfo();
|
||||
|
||||
nscoord GetLeftBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetLeftBorderWidth(nscoord aWidth);
|
||||
nscoord GetRightBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetRightBorderWidth(nscoord aWidth);
|
||||
|
||||
void Dump(PRInt32 aIndent);
|
||||
|
||||
protected:
|
||||
|
@ -172,17 +179,46 @@ protected:
|
|||
~nsTableColFrame();
|
||||
|
||||
// the starting index of the column (starting at 0) that this col object represents //
|
||||
PRInt32 mColIndex;
|
||||
PRUint32 mColIndex: 16;
|
||||
PRUint32 mLeftBorderWidth: 8; // stored as pixels
|
||||
PRUint32 mRightBorderWidth: 8; // stored as pixels
|
||||
// Widths including MIN_CON, DES_CON, FIX_CON, MIN_ADJ, DES_ADJ, FIX_ADJ, PCT, PCT_ADJ, MIN_PRO, FINAL
|
||||
// Widths including MIN_CON, DES_CON, FIX_CON, MIN_ADJ, DES_ADJ, FIX_ADJ, PCT, PCT_ADJ, MIN_PRO, FINAL
|
||||
// XXX these could be stored as pixels and converted to twips for a savings of 10 x 2 bytes.
|
||||
nscoord mWidths[NUM_WIDTHS];
|
||||
};
|
||||
|
||||
inline PRInt32 nsTableColFrame::GetColIndex() const
|
||||
{ return mColIndex; }
|
||||
{
|
||||
return mColIndex;
|
||||
}
|
||||
|
||||
inline void nsTableColFrame::SetColIndex (PRInt32 aColIndex)
|
||||
{ mColIndex = aColIndex; }
|
||||
{
|
||||
mColIndex = aColIndex;
|
||||
}
|
||||
|
||||
inline nscoord nsTableColFrame::GetLeftBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mLeftBorderWidth) : mLeftBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableColFrame::SetLeftBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mLeftBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
inline nscoord nsTableColFrame::GetRightBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mRightBorderWidth) : mRightBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableColFrame::SetRightBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mRightBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -250,29 +250,6 @@ nsTableColGroupFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame* kidFrame = aChildList;
|
||||
while (kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
// Set the preliminary values for the column frame
|
||||
PRInt32 span = ((nsTableColFrame*)kidFrame)->GetSpan();
|
||||
if (span > 1) {
|
||||
nsTableColFrame* firstSpannedCol;
|
||||
tableFrame->CreateAnonymousColFrames(*aPresContext, *this, span - 1, eColAnonymousCol,
|
||||
PR_FALSE, (nsTableColFrame*)kidFrame, (nsIFrame **)&firstSpannedCol);
|
||||
nsIFrame* spanner = kidFrame;
|
||||
kidFrame->GetNextSibling(&kidFrame); // need to do this before we insert the new frames
|
||||
nsFrameList newChildren(aChildList); // used as a convience to hook up siblings
|
||||
newChildren.InsertFrames(this, (nsTableColFrame*)spanner, (nsIFrame *)firstSpannedCol);
|
||||
NS_RELEASE(kidType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
|
||||
mFrames.AppendFrames(this, aChildList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -53,7 +53,6 @@ class nsTableColFrame;
|
|||
class nsTableRowGroupFrame;
|
||||
class nsTableRowFrame;
|
||||
class nsTableColGroupFrame;
|
||||
class nsTableBorderCollapser;
|
||||
class nsITableLayoutStrategy;
|
||||
class nsHTMLValue;
|
||||
|
||||
|
@ -208,6 +207,8 @@ public:
|
|||
nsIAtom* aPropertyName,
|
||||
PRBool aCreateIfNecessary = PR_FALSE);
|
||||
|
||||
static float GetTwipsToPixels(nsIPresContext* aPresContext);
|
||||
|
||||
static nscoord RoundToPixel(nscoord aValue,
|
||||
float aPixelToTwips,
|
||||
nsPixelRound aRound= eAlwaysRoundUp);
|
||||
|
@ -249,7 +250,13 @@ public:
|
|||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
nsMargin GetBorderPadding(const nsHTMLReflowState& aReflowState) const;
|
||||
// Get the offset from the border box to the area where the row groups fit
|
||||
nsMargin GetChildAreaOffset(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState* aReflowState) const;
|
||||
|
||||
// Get the offset from the border box to the area where the content fits
|
||||
nsMargin GetContentAreaOffset(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState* aReflowState) const;
|
||||
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
// TODO: today, this depends on display types. This should be changed to rely
|
||||
|
@ -297,6 +304,17 @@ public:
|
|||
nsFramePaintLayer aWhichLayer,
|
||||
PRUint32 aFlags = 0);
|
||||
|
||||
nsMargin* GetBCBorder(nsIPresContext& aPresContext,
|
||||
PRBool aInnerBorderOnly,
|
||||
nsMargin& aBorder) const;
|
||||
|
||||
void SetBCDamageArea(nsIPresContext& aPresContext,
|
||||
const nsRect& aValue);
|
||||
|
||||
void PaintBCBorders(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
|
||||
const nsPoint& aPoint,
|
||||
nsFramePaintLayer aWhichLayer,
|
||||
|
@ -371,15 +389,12 @@ public:
|
|||
/** set the width of the column at aColIndex to aWidth */
|
||||
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
|
||||
|
||||
/** helper to get the border collapse style value */
|
||||
virtual PRUint8 GetBorderCollapseStyle();
|
||||
|
||||
/** helper to get the cell spacing X style value */
|
||||
virtual nscoord GetCellSpacingX();
|
||||
|
||||
/** helper to get the cell spacing Y style value */
|
||||
virtual nscoord GetCellSpacingY();
|
||||
|
||||
|
||||
/** return the row span of a cell, taking into account row span magic at the bottom
|
||||
* of a table. The row span equals the number of rows spanned by aCell starting at
|
||||
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
|
||||
|
@ -440,9 +455,9 @@ public:
|
|||
/** empty the column frame cache */
|
||||
void ClearColCache();
|
||||
|
||||
virtual PRInt32 AppendCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
virtual void AppendCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
virtual void InsertCells(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aCellFrames,
|
||||
|
@ -522,6 +537,9 @@ protected:
|
|||
/** destructor, responsible for mColumnLayoutData */
|
||||
virtual ~nsTableFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
|
@ -619,7 +637,8 @@ protected:
|
|||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY);
|
||||
|
||||
nsresult RecoverState(nsTableReflowState& aReflowState,
|
||||
nsresult RecoverState(nsIPresContext& aPresContext,
|
||||
nsTableReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame);
|
||||
|
||||
NS_METHOD CollapseRowGroupIfNecessary(nsIPresContext* aPresContext,
|
||||
|
@ -646,10 +665,11 @@ public:
|
|||
|
||||
// calculate the computed height of aFrame including its border and padding given
|
||||
// its reflow state.
|
||||
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
|
||||
nscoord CalcBorderBoxHeight(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState);
|
||||
// calculate the minimum width to layout aFrame and its desired width
|
||||
// including border and padding given its reflow state and column width information
|
||||
void CalcMinAndPreferredWidths(nsIPresContext* aPresContextconst,
|
||||
void CalcMinAndPreferredWidths(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
PRBool aCalcPrefWidthIfAutoWithPctCol,
|
||||
nscoord& aMinWidth,
|
||||
|
@ -657,7 +677,8 @@ public:
|
|||
protected:
|
||||
|
||||
// calcs the width of the table according to the computed widths of each column.
|
||||
virtual PRInt32 CalcDesiredWidth(const nsHTMLReflowState& aReflowState);
|
||||
virtual PRInt32 CalcDesiredWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState);
|
||||
|
||||
// return the desired height of this table accounting for the current
|
||||
// reflow state, and for the table attributes and parent
|
||||
|
@ -699,7 +720,7 @@ public:
|
|||
PRUint32& aNumRowGroups,
|
||||
nsIFrame** aFirstBody = nsnull,
|
||||
nsTableRowGroupFrame** aHead = nsnull,
|
||||
nsTableRowGroupFrame** aFoot = nsnull);
|
||||
nsTableRowGroupFrame** aFoot = nsnull) const;
|
||||
|
||||
// Returns PR_TRUE if there are any cells above the row at
|
||||
// aRowIndex and spanning into the row at aRowIndex
|
||||
|
@ -735,9 +756,6 @@ protected:
|
|||
PRBool DidResizeReflow() const;
|
||||
void SetResizeReflow(PRBool aValue);
|
||||
|
||||
/** Support methods for DidSetStyleContext */
|
||||
void MapBorderMarginPadding(nsIPresContext* aPresContext);
|
||||
void MapHTMLBorderStyle(nsStyleBorder& aBorderStyle, nscoord aBorderWidth);
|
||||
PRBool ConvertToPixelValue(nsHTMLValue& aValue,
|
||||
PRInt32 aDefault,
|
||||
PRInt32& aResult);
|
||||
|
@ -749,6 +767,11 @@ public:
|
|||
PRBool NeedStrategyBalance() const;
|
||||
void SetNeedStrategyBalance(PRBool aValue);
|
||||
|
||||
PRBool IsBorderCollapse() const;
|
||||
|
||||
PRBool NeedToCalcBCBorders() const;
|
||||
void SetNeedToCalcBCBorders(PRBool aValue);
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
|
@ -763,9 +786,6 @@ public:
|
|||
PRInt32 aRowIndex,
|
||||
PRInt32 anAdjustment);
|
||||
|
||||
// Return PR_TRUE if rules=groups is set for the table content
|
||||
PRBool HasGroupRules() const;
|
||||
|
||||
// Remove cell borders which aren't bordering row and/or col groups
|
||||
void ProcessGroupRules(nsIPresContext* aPresContext);
|
||||
|
||||
|
@ -775,10 +795,16 @@ public:
|
|||
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
|
||||
*/
|
||||
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
|
||||
nsIAtom* aFrameTypeIn = nsnull);
|
||||
nsIAtom* aFrameTypeIn = nsnull) const;
|
||||
|
||||
protected:
|
||||
|
||||
void SetBorderCollapse(PRBool aValue);
|
||||
|
||||
void CalcBCBorders(nsIPresContext& aPresContext);
|
||||
|
||||
void ExpandBCDamageArea(nsRect& aRect) const;
|
||||
|
||||
PRBool HadInitialReflow() const;
|
||||
void SetHadInitialReflow(PRBool aValue);
|
||||
|
||||
|
@ -809,8 +835,8 @@ public: /* ----- Cell Map public methods ----- */
|
|||
|
||||
/** returns the number of columns in this table after redundant columns have been removed
|
||||
*/
|
||||
virtual PRInt32 GetEffectiveColCount();
|
||||
virtual PRInt32 GetColCount();
|
||||
virtual PRInt32 GetEffectiveColCount() const;
|
||||
virtual PRInt32 GetColCount() const;
|
||||
|
||||
/** return the column frame at colIndex.
|
||||
* returns nsnull if the col frame has not yet been allocated, or if aColIndex is out of range
|
||||
|
@ -886,6 +912,7 @@ protected:
|
|||
unsigned mHasPctCol:1; // does any cell or col have a pct width
|
||||
unsigned mCellSpansPctCol:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
|
||||
unsigned mDidResizeReflow:1; // did a resize reflow happen (indicating pass 2)
|
||||
unsigned mIsBorderCollapse:1; // border collapsing model vs. separate model
|
||||
// true if a descendant was reflowed normally since the last time we reflowed.
|
||||
// We will likely need a timeout reflow (targeted either at us or below)
|
||||
unsigned mDescendantReflowedNotTimeout:1;
|
||||
|
@ -896,7 +923,8 @@ protected:
|
|||
unsigned mRowInserted:1;
|
||||
unsigned mNeedSpecialReflow:1;
|
||||
unsigned mNeedToInitiateSpecialReflow:1;
|
||||
unsigned : 20; // unused
|
||||
unsigned mNeedToCalcBCBorders:1;
|
||||
unsigned : 18; // unused
|
||||
} mBits;
|
||||
|
||||
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
|
||||
|
@ -1054,8 +1082,26 @@ inline void nsTableFrame::SetPreferredWidth(nscoord aWidth)
|
|||
mPreferredWidth = aWidth;
|
||||
}
|
||||
|
||||
inline PRBool nsTableFrame::IsBorderCollapse() const
|
||||
{
|
||||
return (PRBool)mBits.mIsBorderCollapse;
|
||||
}
|
||||
|
||||
inline void nsTableFrame::SetBorderCollapse(PRBool aValue)
|
||||
{
|
||||
mBits.mIsBorderCollapse = aValue;
|
||||
}
|
||||
|
||||
inline PRBool nsTableFrame::NeedToCalcBCBorders() const
|
||||
{
|
||||
return (PRBool)mBits.mNeedToCalcBCBorders;
|
||||
}
|
||||
|
||||
inline void nsTableFrame::SetNeedToCalcBCBorders(PRBool aValue)
|
||||
{
|
||||
mBits.mNeedToCalcBCBorders = (unsigned)aValue;
|
||||
}
|
||||
|
||||
|
||||
enum nsTableIteration {
|
||||
eTableLTR = 0,
|
||||
eTableRTL = 1,
|
||||
|
@ -1085,6 +1131,23 @@ protected:
|
|||
PRInt32 mCount;
|
||||
};
|
||||
|
||||
#define ABORT0() \
|
||||
{NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
|
||||
return;}
|
||||
|
||||
#define ABORT1(aReturn) \
|
||||
{NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
|
||||
return aReturn;}
|
||||
|
||||
#define GET_PIXELS_TO_TWIPS(presContext,var) \
|
||||
float var; \
|
||||
(presContext)->GetScaledPixelsToTwips(&var);
|
||||
|
||||
#define GET_TWIPS_TO_PIXELS(presContext,var) \
|
||||
float var; \
|
||||
(presContext)->GetScaledPixelsToTwips(&var); \
|
||||
var = 1.0f / var;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -232,7 +232,14 @@ nsTableOuterFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
}
|
||||
else {
|
||||
mFrames.SetFrames(aChildList);
|
||||
mInnerTableFrame = aChildList;
|
||||
mInnerTableFrame = nsnull;
|
||||
if (aChildList) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aChildList->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableFrame == fType.get()) {
|
||||
mInnerTableFrame = (nsTableFrame*)aChildList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -466,21 +473,46 @@ FixAutoMargins(nscoord aAvailWidth,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableOuterFrame::InitChildReflowState(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState& aReflowState)
|
||||
|
||||
{
|
||||
nsMargin collapseBorder;
|
||||
nsMargin collapsePadding(0,0,0,0);
|
||||
nsMargin* pCollapseBorder = nsnull;
|
||||
nsMargin* pCollapsePadding = nsnull;
|
||||
if ((aReflowState.frame == mInnerTableFrame) && (mInnerTableFrame->IsBorderCollapse())) {
|
||||
if (mInnerTableFrame->NeedToCalcBCBorders()) {
|
||||
mInnerTableFrame->CalcBCBorders(aPresContext);
|
||||
}
|
||||
pCollapseBorder = mInnerTableFrame->GetBCBorder(aPresContext, PR_FALSE, collapseBorder);
|
||||
pCollapsePadding = &collapsePadding;
|
||||
}
|
||||
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, pCollapsePadding);
|
||||
}
|
||||
|
||||
// get the margin and padding data. nsHTMLReflowState doesn't handle the
|
||||
// case of auto margins
|
||||
void
|
||||
GetMarginPadding(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aOuterRS,
|
||||
nsIFrame* aChildFrame,
|
||||
nsMargin& aMargin,
|
||||
nsMargin& aMarginNoAuto,
|
||||
nsMargin& aPadding)
|
||||
nsTableOuterFrame::GetMarginPadding(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aOuterRS,
|
||||
nsIFrame* aChildFrame,
|
||||
nsMargin& aMargin,
|
||||
nsMargin& aMarginNoAuto,
|
||||
nsMargin& aPadding)
|
||||
{
|
||||
if (!aPresContext) ABORT0();
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
// construct a reflow state to compute margin and padding. Auto margins
|
||||
// will not be computed at this time.
|
||||
|
||||
// create an init the child reflow state
|
||||
nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame,
|
||||
nsSize(aOuterRS.availableWidth, aOuterRS.availableHeight),
|
||||
eReflowReason_Resize);
|
||||
eReflowReason_Resize, PR_FALSE);
|
||||
InitChildReflowState(*aPresContext, childRS);
|
||||
|
||||
nsRect childRect;
|
||||
aChildFrame->GetRect(childRect);
|
||||
FixAutoMargins(aOuterRS.availableWidth, childRect.width, childRS);
|
||||
|
@ -931,6 +963,7 @@ nsTableOuterFrame::OuterReflowChild(nsIPresContext* aPresContext,
|
|||
nsReflowReason aReflowReason,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (!aPresContext) ABORT1(NS_ERROR_NULL_POINTER);
|
||||
aMargin = aPadding = nsMargin(0,0,0,0);
|
||||
|
||||
nscoord availWidth = GetChildAvailWidth(aPresContext, aChildFrame, aOuterRS,
|
||||
|
@ -946,9 +979,10 @@ nsTableOuterFrame::OuterReflowChild(nsIPresContext* aPresContext,
|
|||
availHeight = nsTableFrame::RoundToPixel(availHeight, p2t, eAlwaysRoundDown);
|
||||
}
|
||||
|
||||
nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame,
|
||||
nsSize(availWidth, availHeight));
|
||||
childRS.reason = aReflowReason;
|
||||
// create and init the child reflow state
|
||||
nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame, nsSize(availWidth, availHeight),
|
||||
aReflowReason);
|
||||
InitChildReflowState(*aPresContext, childRS);
|
||||
childRS.mPercentHeightObserver = nsnull; // the observer is for non table related frames inside cells
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ class nsReflowTimer;
|
|||
#endif
|
||||
|
||||
struct nsStyleTable;
|
||||
class nsTableFrame;
|
||||
|
||||
class nsTableCaptionFrame : public nsBlockFrame
|
||||
{
|
||||
|
@ -201,6 +202,9 @@ protected:
|
|||
nsTableOuterFrame();
|
||||
virtual ~nsTableOuterFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
/** Always returns 0, since the outer table frame has no border of its own
|
||||
* The inner table frame can answer this question in a meaningful way.
|
||||
* @see nsHTMLContainerFrame::GetSkipSides */
|
||||
|
@ -362,11 +366,17 @@ protected:
|
|||
PRBool aInnerChanged,
|
||||
PRBool aCaptionChanged);
|
||||
|
||||
void GetMarginPadding(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aOuterRS,
|
||||
nsIFrame* aChildFrame,
|
||||
nsMargin& aMargin,
|
||||
nsMargin& aMarginNoAuto,
|
||||
nsMargin& aPadding);
|
||||
|
||||
private:
|
||||
// used to keep track of this frame's children. They are redundant with mFrames, but more convient
|
||||
nsIFrame* mInnerTableFrame;
|
||||
nsIFrame* mCaptionFrame;
|
||||
nsTableFrame* mInnerTableFrame;
|
||||
nsIFrame* mCaptionFrame;
|
||||
|
||||
// used to track caption max element size
|
||||
PRInt32 mMinCaptionWidth;
|
||||
|
|
|
@ -68,11 +68,6 @@ struct nsTableCellReflowState : public nsHTMLReflowState
|
|||
const nsSize& aAvailableSpace,
|
||||
nsReflowReason aReason);
|
||||
|
||||
nsTableCellReflowState(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailableSpace);
|
||||
|
||||
void FixUp(const nsSize& aAvailSpace);
|
||||
};
|
||||
|
||||
|
@ -83,16 +78,43 @@ nsTableCellReflowState::nsTableCellReflowState(nsIPresContext* aPresCon
|
|||
nsReflowReason aReason)
|
||||
:nsHTMLReflowState(aPresContext, aParentRS, aFrame, aAvailSpace, aReason)
|
||||
{
|
||||
FixUp(aAvailSpace);
|
||||
}
|
||||
|
||||
nsTableCellReflowState::nsTableCellReflowState(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aParentRS,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailSpace)
|
||||
:nsHTMLReflowState(aPresContext, aParentRS, aFrame, aAvailSpace)
|
||||
void nsTableCellReflowState::FixUp(const nsSize& aAvailSpace)
|
||||
{
|
||||
FixUp(aAvailSpace);
|
||||
// fix the mComputed values during a pass 2 reflow since the cell can be a percentage base
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.width) {
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedWidth) {
|
||||
mComputedWidth = aAvailSpace.width - mComputedBorderPadding.left - mComputedBorderPadding.right;
|
||||
mComputedWidth = PR_MAX(0, mComputedWidth);
|
||||
}
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedHeight) {
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.height) {
|
||||
mComputedHeight = aAvailSpace.height - mComputedBorderPadding.top - mComputedBorderPadding.bottom;
|
||||
mComputedHeight = PR_MAX(0, mComputedHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableRowFrame::InitChildReflowState(nsIPresContext& aPresContext,
|
||||
const nsSize& aAvailSize,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsTableCellReflowState& aReflowState)
|
||||
{
|
||||
nsMargin collapseBorder;
|
||||
nsMargin* pCollapseBorder = nsnull;
|
||||
if (aBorderCollapse) {
|
||||
// we only reflow cells, so don't need to check frame type
|
||||
nsBCTableCellFrame* bcCellFrame = (nsBCTableCellFrame*)aReflowState.frame;
|
||||
if (bcCellFrame) {
|
||||
pCollapseBorder = bcCellFrame->GetBorderWidth(aPixelsToTwips, collapseBorder);
|
||||
}
|
||||
}
|
||||
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder);
|
||||
aReflowState.FixUp(aAvailSize);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -132,23 +154,6 @@ nsTableRowFrame::SetPctHeight(float aPctValue,
|
|||
}
|
||||
}
|
||||
|
||||
void nsTableCellReflowState::FixUp(const nsSize& aAvailSpace)
|
||||
{
|
||||
// fix the mComputed values during a pass 2 reflow since the cell can be a percentage base
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.width) {
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedWidth) {
|
||||
mComputedWidth = aAvailSpace.width - mComputedBorderPadding.left - mComputedBorderPadding.right;
|
||||
mComputedWidth = PR_MAX(0, mComputedWidth);
|
||||
}
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedHeight) {
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.height) {
|
||||
mComputedHeight = aAvailSpace.height - mComputedBorderPadding.top - mComputedBorderPadding.bottom;
|
||||
mComputedHeight = PR_MAX(0, mComputedHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 'old' is old cached cell's desired size
|
||||
// 'new' is new cell's size including style constraints
|
||||
static PRBool
|
||||
|
@ -217,7 +222,7 @@ nsTableRowFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
kidFrame->GetNextSibling(&kidFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
kidFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
if (((nsTableCellFrame*)kidFrame)->GetRowSpan() > 1) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
|
@ -241,7 +246,7 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext,
|
|||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
// Add the cell to the cell map
|
||||
tableFrame->AppendCell(*aPresContext, (nsTableCellFrame&)*childFrame, GetRowIndex());
|
||||
// XXX this could be optimized with some effort
|
||||
|
@ -272,12 +277,13 @@ nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext,
|
|||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// gather the new frames (only those which are cells) into an array
|
||||
nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(aPresContext, this, aPrevFrame, nsLayoutAtoms::tableCellFrame);
|
||||
nsIAtom* cellFrameType = (tableFrame->IsBorderCollapse()) ? nsLayoutAtoms::bcTableCellFrame : nsLayoutAtoms::tableCellFrame;
|
||||
nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(aPresContext, this, aPrevFrame, cellFrameType);
|
||||
nsVoidArray cellChildren;
|
||||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
cellChildren.AppendElement(childFrame);
|
||||
// XXX this could be optimized with some effort
|
||||
tableFrame->SetNeedStrategyInit(PR_TRUE);
|
||||
|
@ -315,7 +321,7 @@ nsTableRowFrame::RemoveFrame(nsIPresContext* aPresContext,
|
|||
if (tableFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aOldFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aOldFrame;
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
|
@ -372,7 +378,7 @@ nsTableRowFrame::GetFirstCell()
|
|||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
return (nsTableCellFrame*)childFrame;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
|
@ -398,7 +404,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
|
|||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)childFrame;
|
||||
nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
|
||||
|
||||
|
@ -534,7 +540,7 @@ nsTableRowFrame::CalcHeight(const nsHTMLReflowState& aReflowState)
|
|||
for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
kidFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nscoord availWidth = ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth();
|
||||
nsSize desSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
|
||||
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) && !mPrevInFlow) {
|
||||
|
@ -888,28 +894,29 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (!mFrames.FirstChild()) return NS_OK;
|
||||
|
||||
nsTableFrame* tableFrame = &aTableFrame;
|
||||
if (!tableFrame) return NS_ERROR_NULL_POINTER;
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
PRBool borderCollapse = (((nsTableFrame*)aTableFrame.GetFirstInFlow())->IsBorderCollapse());
|
||||
|
||||
nsIFrame* tablePrevInFlow;
|
||||
tableFrame->GetPrevInFlow(&tablePrevInFlow);
|
||||
aTableFrame.GetPrevInFlow(&tablePrevInFlow);
|
||||
PRBool isPaginated;
|
||||
aPresContext->IsPaginated(&isPaginated);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nscoord cellSpacingX = tableFrame->GetCellSpacingX();
|
||||
nscoord cellSpacingX = aTableFrame.GetCellSpacingX();
|
||||
PRInt32 cellColSpan = 1; // must be defined here so it's set properly for non-cell kids
|
||||
|
||||
nsTableIteration dir = (aReflowState.availableWidth == NS_UNCONSTRAINEDSIZE)
|
||||
? eTableLTR : eTableDIR;
|
||||
nsTableIterator iter(aPresContext, *this, dir);
|
||||
// remember the col index of the previous cell to handle rowspans into this row
|
||||
PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : tableFrame->GetColCount();
|
||||
PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : aTableFrame.GetColCount();
|
||||
PRInt32 prevColIndex = firstPrevColIndex;
|
||||
nscoord x = 0; // running total of children x offset
|
||||
|
||||
nsTableFrame* tableFirstInFlow = (nsTableFrame*)tableFrame->GetFirstInFlow();
|
||||
PRBool isAutoLayout = tableFrame->IsAutoLayout();
|
||||
nsTableFrame* tableFirstInFlow = (nsTableFrame*)aTableFrame.GetFirstInFlow();
|
||||
PRBool isAutoLayout = aTableFrame.IsAutoLayout();
|
||||
PRBool needToNotifyTable = PR_TRUE;
|
||||
nscoord paginatedHeight = 0;
|
||||
// If the incremental reflow command is a StyleChanged reflow and
|
||||
|
@ -945,7 +952,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
doReflowChild = PR_FALSE;
|
||||
}
|
||||
if (aReflowState.mFlags.mSpecialHeightReflow) {
|
||||
if (!isPaginated && (nsLayoutAtoms::tableCellFrame == frameType.get() &&
|
||||
if (!isPaginated && (IS_TABLE_CELL(frameType.get()) &&
|
||||
!((nsTableCellFrame*)kidFrame)->NeedSpecialReflow())) {
|
||||
kidFrame = iter.Next();
|
||||
continue;
|
||||
|
@ -954,22 +961,22 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
|
||||
// Reflow the child frame
|
||||
if (doReflowChild) {
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)kidFrame;
|
||||
PRInt32 cellColIndex;
|
||||
cellFrame->GetColIndex(cellColIndex);
|
||||
cellColSpan = tableFrame->GetEffectiveColSpan(*cellFrame);
|
||||
cellColSpan = aTableFrame.GetEffectiveColSpan(*cellFrame);
|
||||
|
||||
x += cellSpacingX;
|
||||
// If the adjacent cell is in a prior row (because of a rowspan) add in the space
|
||||
if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) ||
|
||||
(!iter.IsLeftToRight() && (prevColIndex != cellColIndex + cellColSpan))) {
|
||||
x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, *tableFrame,
|
||||
x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, aTableFrame,
|
||||
cellSpacingX, iter.IsLeftToRight());
|
||||
}
|
||||
// Calculate the available width for the table cell using the known column widths
|
||||
nscoord availColWidth, availCellWidth;
|
||||
CalcAvailWidth(*tableFrame, GetComputedWidth(aReflowState, *tableFrame),
|
||||
CalcAvailWidth(aTableFrame, GetComputedWidth(aReflowState, aTableFrame),
|
||||
*cellFrame, cellSpacingX, availColWidth, availCellWidth);
|
||||
if (0 == availColWidth) availColWidth = NS_UNCONSTRAINEDSIZE;
|
||||
if (0 == availCellWidth) availCellWidth = NS_UNCONSTRAINEDSIZE;
|
||||
|
@ -1032,6 +1039,8 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
// Reflow the child
|
||||
nsTableCellReflowState kidReflowState(aPresContext, aReflowState,
|
||||
kidFrame, kidAvailSize, reason);
|
||||
InitChildReflowState(*aPresContext, kidAvailSize, borderCollapse, p2t, kidReflowState);
|
||||
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||
x, 0, 0, status);
|
||||
|
@ -1052,7 +1061,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
|
||||
// allow the table to determine if/how the table needs to be rebalanced
|
||||
if (cellToWatch && needToNotifyTable) {
|
||||
needToNotifyTable = !tableFrame->CellChangedWidth(*cellFrame, oldMaxWidth, oldMaxElemWidth);
|
||||
needToNotifyTable = !aTableFrame.CellChangedWidth(*cellFrame, oldMaxWidth, oldMaxElemWidth);
|
||||
}
|
||||
|
||||
// If any of the cells are not complete, then we're not complete
|
||||
|
@ -1081,10 +1090,10 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
// height may have changed, adjust descent to absorb any excess difference
|
||||
nscoord ascent = cellFrame->GetDesiredAscent();
|
||||
nscoord descent = desiredSize.height - ascent;
|
||||
UpdateHeight(desiredSize.height, ascent, descent, tableFrame, cellFrame);
|
||||
UpdateHeight(desiredSize.height, ascent, descent, &aTableFrame, cellFrame);
|
||||
}
|
||||
else {
|
||||
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
|
||||
PRInt32 rowSpan = aTableFrame.GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
|
||||
if ((1 == rowSpan) && (desiredSize.height > paginatedHeight)) {
|
||||
paginatedHeight = desiredSize.height;
|
||||
SetContentHeight(paginatedHeight);
|
||||
|
@ -1102,13 +1111,14 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
else {// it's an unknown frame type, give it a generic reflow and ignore the results
|
||||
nsTableCellReflowState kidReflowState(aPresContext, aReflowState,
|
||||
kidFrame, nsSize(0,0), eReflowReason_Resize);
|
||||
InitChildReflowState(*aPresContext, nsSize(0,0), PR_FALSE, p2t, kidReflowState);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
nsReflowStatus status;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
|
||||
kidFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
||||
}
|
||||
}
|
||||
else if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
else if (IS_TABLE_CELL(frameType.get())) {
|
||||
// we need to account for the cell's width even if it isn't reflowed
|
||||
nsRect rect;
|
||||
kidFrame->GetRect(rect);
|
||||
|
@ -1244,7 +1254,10 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// update its maximum width.
|
||||
nsHTMLReflowMetrics cellMet(&kidMaxElementSize, isAutoLayout ?
|
||||
NS_REFLOW_CALC_MAX_WIDTH : 0);
|
||||
nsTableCellReflowState kidRS(aPresContext, aReflowState, aNextFrame, cellAvailSize);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
nsTableCellReflowState kidRS(aPresContext, aReflowState, aNextFrame, cellAvailSize,
|
||||
aReflowState.reason);
|
||||
InitChildReflowState(*aPresContext, cellAvailSize, aTableFrame.IsBorderCollapse(), p2t, kidRS);
|
||||
|
||||
// Remember the current desired size, we'll need it later
|
||||
nscoord oldCellMinWidth = cellFrame->GetPass1MaxElementWidth();
|
||||
|
@ -1492,13 +1505,20 @@ nsTableRowFrame::ReflowCellFrame(nsIPresContext* aPresContext,
|
|||
nscoord aAvailableHeight,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(0);
|
||||
|
||||
// Reflow the cell frame with the specified height. Use the existing width
|
||||
nsSize cellSize;
|
||||
aCellFrame->GetSize(cellSize);
|
||||
|
||||
nsSize availSize(cellSize.width, aAvailableHeight);
|
||||
PRBool borderCollapse = ((nsTableFrame*)tableFrame->GetFirstInFlow())->IsBorderCollapse();
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
nsTableCellReflowState cellReflowState(aPresContext, aReflowState, aCellFrame, availSize,
|
||||
eReflowReason_Resize);
|
||||
InitChildReflowState(*aPresContext, availSize, borderCollapse, p2t, cellReflowState);
|
||||
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
|
||||
|
@ -1534,7 +1554,7 @@ nsTableRowFrame::InsertCellFrame(nsTableCellFrame* aFrame,
|
|||
for (nsIFrame* child = mFrames.FirstChild(); child; child->GetNextSibling(&child)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
child->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame != frameType.get()) {
|
||||
if (!IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)child;
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
class nsTableFrame;
|
||||
class nsTableCellFrame;
|
||||
struct nsTableCellReflowState;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
|
@ -240,6 +241,12 @@ public:
|
|||
nscoord GetUnpaginatedHeight(nsIPresContext* aPresContext);
|
||||
void SetUnpaginatedHeight(nsIPresContext* aPresContext, nscoord aValue);
|
||||
|
||||
nscoord GetTopBCBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetTopBCBorderWidth(nscoord aWidth);
|
||||
nscoord GetBottomBCBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetBottomBCBorderWidth(nscoord aWidth);
|
||||
nsMargin* GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder);
|
||||
protected:
|
||||
|
||||
/** protected constructor.
|
||||
|
@ -247,6 +254,12 @@ protected:
|
|||
*/
|
||||
nsTableRowFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
const nsSize& aAvailSize,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsTableCellReflowState& aReflowState);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
|
@ -315,6 +328,10 @@ private:
|
|||
nscoord mMaxCellAscent; // does include cells with rowspan > 1
|
||||
nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
|
||||
|
||||
// border widths in pixels in the collapsing border model
|
||||
unsigned mTopBorderWidth:8;
|
||||
unsigned mBottomBorderWidth:8;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
|
@ -421,4 +438,37 @@ inline void nsTableRowFrame::SetHasUnpaginatedHeight(PRBool aValue)
|
|||
}
|
||||
}
|
||||
|
||||
inline nscoord nsTableRowFrame::GetTopBCBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mTopBorderWidth) : mTopBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::SetTopBCBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mTopBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
inline nscoord nsTableRowFrame::GetBottomBCBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mBottomBorderWidth) : mBottomBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::SetBottomBCBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mBottomBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
inline nsMargin* nsTableRowFrame::GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder)
|
||||
{
|
||||
aBorder.left = aBorder.right = 0;
|
||||
|
||||
aBorder.top = NSToCoordRound(aPixelsToTwips * mTopBorderWidth);
|
||||
aBorder.bottom = NSToCoordRound(aPixelsToTwips * mBottomBorderWidth);
|
||||
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -180,7 +180,7 @@ nsTableRowGroupFrame::InitRepeatedFrame(nsIPresContext* aPresContext,
|
|||
nsIAtom* frameType;
|
||||
copyCellFrame->GetFrameType(&frameType);
|
||||
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
if (IS_TABLE_CELL(frameType)) {
|
||||
#ifdef NS_DEBUG
|
||||
nsIContent* content1;
|
||||
nsIContent* content2;
|
||||
|
@ -360,6 +360,28 @@ nsTableRowGroupFrame::PlaceChild(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableRowGroupFrame::InitChildReflowState(nsIPresContext& aPresContext,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
nsMargin collapseBorder;
|
||||
nsMargin padding(0,0,0,0);
|
||||
nsMargin* pCollapseBorder = nsnull;
|
||||
if (aBorderCollapse) {
|
||||
if (aReflowState.frame) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aReflowState.frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableRowFrame == fType.get()) {
|
||||
nsTableRowFrame* rowFrame = (nsTableRowFrame*)aReflowState.frame;
|
||||
pCollapseBorder = rowFrame->GetBCBorderWidth(aPixelsToTwips, collapseBorder);
|
||||
}
|
||||
}
|
||||
}
|
||||
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, &padding);
|
||||
}
|
||||
|
||||
// Reflow the frames we've already created. If aDirtyOnly is set then only
|
||||
// reflow dirty frames. This assumes that all of the dirty frames are contiguous.
|
||||
NS_METHOD
|
||||
|
@ -372,8 +394,10 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
nsTableRowFrame** aFirstRowReflowed)
|
||||
{
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || !tableFrame) return rv;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(rv);
|
||||
|
||||
PRBool borderCollapse = tableFrame->IsBorderCollapse();
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
|
||||
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
|
||||
|
||||
|
@ -439,6 +463,7 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize, reason);
|
||||
InitChildReflowState(*aPresContext, borderCollapse, p2t, kidReflowState);
|
||||
|
||||
// If this isn't the first row frame, then we can't be at the top of
|
||||
// the page anymore...
|
||||
|
@ -555,7 +580,7 @@ HasMoreThanOneCell(nsTableCellMap* aCellMap,
|
|||
PRInt32 colIndex = 0;
|
||||
PRInt32 count = 0;
|
||||
do {
|
||||
cellData = aCellMap->GetCellAt(aRowIndex, colIndex);
|
||||
cellData = aCellMap->GetDataAt(aRowIndex, colIndex);
|
||||
if (cellData && (cellData->GetCellFrame() || cellData->IsRowSpan()))
|
||||
count++;
|
||||
if (count > 1)
|
||||
|
@ -998,8 +1023,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext* aPresContext,
|
|||
presShell->GetStyleSet(getter_AddRefs(styleSet));
|
||||
if (!styleSet) {NS_ASSERTION(PR_FALSE, "no style set"); return NS_ERROR_NULL_POINTER;}
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
PRBool borderCollapse = ((nsTableFrame*)aTableFrame->GetFirstInFlow())->IsBorderCollapse();
|
||||
|
||||
nscoord availWidth = nsTableFrame::RoundToPixel(aReflowState.availableWidth, p2t);
|
||||
nscoord availHeight = nsTableFrame::RoundToPixel(aReflowState.availableHeight, p2t);
|
||||
|
@ -1022,9 +1047,11 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext* aPresContext,
|
|||
// row or there is at least 5% of the current page available
|
||||
if (!prevRowFrame || (availHeight - aDesiredSize.height > pageHeight / 20)) {
|
||||
// Reflow the row in the available space and have it split
|
||||
nsSize availSize(availWidth, availHeight - bounds.y);
|
||||
nsHTMLReflowState rowReflowState(aPresContext, aReflowState, rowFrame,
|
||||
availSize, eReflowReason_Resize);
|
||||
nsSize availSize(availWidth, availHeight - bounds.y);
|
||||
nsHTMLReflowState rowReflowState(aPresContext, aReflowState, rowFrame, availSize,
|
||||
eReflowReason_Resize);
|
||||
InitChildReflowState(*aPresContext, borderCollapse, p2t, rowReflowState);
|
||||
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
rv = ReflowChild(rowFrame, aPresContext, desiredSize, rowReflowState,
|
||||
|
@ -1530,6 +1557,10 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(NS_ERROR_NULL_POINTER);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
|
||||
// Recover the state as if aNextFrame is about to be reflowed
|
||||
RecoverState(aReflowState, aNextFrame);
|
||||
|
||||
|
@ -1540,9 +1571,11 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// Reflow the child giving it as much room as it wants. We'll deal with
|
||||
// splitting later after final determination of rows heights taking into
|
||||
// account cells with row spans...
|
||||
nsSize kidAvailSize(aReflowState.availSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
|
||||
aNextFrame, kidAvailSize);
|
||||
nsSize kidAvailSize(aReflowState.availSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, aNextFrame,
|
||||
kidAvailSize, aReflowState.reason);
|
||||
InitChildReflowState(*aPresContext, tableFrame->IsBorderCollapse(), p2t, kidReflowState);
|
||||
|
||||
nsSize kidMaxElementSize;
|
||||
nsHTMLReflowMetrics desiredSize(aDesiredSize.maxElementSize ? &kidMaxElementSize : nsnull,
|
||||
aDesiredSize.mFlags);
|
||||
|
@ -1715,6 +1748,28 @@ nsTableRowGroupFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) cons
|
|||
}
|
||||
#endif
|
||||
|
||||
nsMargin*
|
||||
nsTableRowGroupFrame::GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder)
|
||||
{
|
||||
aBorder.left = aBorder.right = 0;
|
||||
|
||||
nsTableRowFrame* firstRowFrame = nsnull;
|
||||
nsTableRowFrame* lastRowFrame = nsnull;
|
||||
for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
|
||||
if(!firstRowFrame) {
|
||||
firstRowFrame = rowFrame;
|
||||
}
|
||||
lastRowFrame = rowFrame;
|
||||
}
|
||||
if (firstRowFrame) {
|
||||
aBorder.top = firstRowFrame->GetTopBCBorderWidth(&aPixelsToTwips);
|
||||
aBorder.bottom = lastRowFrame->GetBottomBCBorderWidth(&aPixelsToTwips);
|
||||
}
|
||||
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
//nsILineIterator methods for nsTableFrame
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::GetNumLines(PRInt32* aResult)
|
||||
|
@ -1757,7 +1812,7 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber,
|
|||
*aLineFlags = 0;/// should we fill these in later?
|
||||
// not gonna touch aLineBounds right now
|
||||
|
||||
CellData* firstCellData = cellMap->GetCellAt(aLineNumber, 0);
|
||||
CellData* firstCellData = cellMap->GetDataAt(aLineNumber, 0);
|
||||
if(!firstCellData)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1767,7 +1822,7 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber,
|
|||
while((aLineNumber > 0)&&(!(*aFirstFrameOnLine)))
|
||||
{
|
||||
aLineNumber--;
|
||||
firstCellData = cellMap->GetCellAt(aLineNumber, 0);
|
||||
firstCellData = cellMap->GetDataAt(aLineNumber, 0);
|
||||
*aFirstFrameOnLine = (nsIFrame*)firstCellData->GetCellFrame();
|
||||
}
|
||||
}
|
||||
|
@ -1847,7 +1902,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber,
|
|||
PRBool gotParentRect = PR_FALSE;
|
||||
for(int i =0;i < cellCount; i++)
|
||||
{
|
||||
cellData = cellMap->GetCellAt(aLineNumber, i);
|
||||
cellData = cellMap->GetDataAt(aLineNumber, i);
|
||||
tempFrame = (nsIFrame*)cellData->GetCellFrame();
|
||||
|
||||
if(!tempFrame)
|
||||
|
@ -1919,11 +1974,11 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame,
|
|||
PRInt32& colIndexRef = colIndex;
|
||||
cellFrame->GetColIndex(colIndexRef);
|
||||
|
||||
CellData* cellData = cellMap->GetCellAt(aLineNumber, colIndex + 1);
|
||||
CellData* cellData = cellMap->GetDataAt(aLineNumber, colIndex + 1);
|
||||
|
||||
if(!cellData)// if this isnt a valid cell, drop down and check the next line
|
||||
{
|
||||
cellData = cellMap->GetCellAt(aLineNumber + 1, 0);
|
||||
cellData = cellMap->GetDataAt(aLineNumber + 1, 0);
|
||||
if(!cellData)
|
||||
{
|
||||
//*aFrame = nsnull;
|
||||
|
@ -1940,14 +1995,14 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame,
|
|||
while((tempCol > 0) && (!aFrame))
|
||||
{
|
||||
tempCol--;
|
||||
cellData = cellMap->GetCellAt(aLineNumber, tempCol);
|
||||
cellData = cellMap->GetDataAt(aLineNumber, tempCol);
|
||||
aFrame = (nsIFrame*)cellData->GetCellFrame();
|
||||
if(!aFrame && (tempCol==0))
|
||||
{
|
||||
while((tempRow > 0) && (!aFrame))
|
||||
{
|
||||
tempRow--;
|
||||
cellData = cellMap->GetCellAt(tempRow, 0);
|
||||
cellData = cellMap->GetDataAt(tempRow, 0);
|
||||
aFrame = (nsIFrame*)cellData->GetCellFrame();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,6 +216,8 @@ public:
|
|||
nscoord GetHeightOfRows(nsIPresContext* aPresContext);
|
||||
nscoord GetHeightBasis(const nsHTMLReflowState& aReflowState);
|
||||
|
||||
nsMargin* GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder);
|
||||
// nsILineIterator methods
|
||||
public:
|
||||
NS_IMETHOD GetNumLines(PRInt32* aResult);
|
||||
|
@ -251,6 +253,11 @@ public:
|
|||
protected:
|
||||
nsTableRowGroupFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
|
|
|
@ -168,6 +168,10 @@ table[align="right"] {
|
|||
text-align: start;
|
||||
}
|
||||
|
||||
table[rules] {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
*|*:table-outer {
|
||||
display: table;
|
||||
margin: 0;
|
||||
|
@ -219,6 +223,11 @@ tr {
|
|||
|
||||
col, *|*:table-column {
|
||||
display: table-column;
|
||||
border: inherit;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
background: inherit;
|
||||
border: inherit;
|
||||
}
|
||||
|
||||
colgroup, *|*:table-column-group {
|
||||
|
|
|
@ -103,7 +103,7 @@ CSS_PROP(border-bottom-color, border_bottom_color, VISUAL)
|
|||
CSS_PROP(-moz-border-bottom-colors, border_bottom_colors, VISUAL)
|
||||
CSS_PROP(border-bottom-style, border_bottom_style, REFLOW) // on/off will need reflow
|
||||
CSS_PROP(border-bottom-width, border_bottom_width, REFLOW)
|
||||
CSS_PROP(border-collapse, border_collapse, REFLOW)
|
||||
CSS_PROP(border-collapse, border_collapse, FRAMECHANGE)
|
||||
CSS_PROP(border-color, border_color, VISUAL)
|
||||
CSS_PROP(border-left, border_left, REFLOW)
|
||||
CSS_PROP(border-left-color, border_left_color, VISUAL)
|
||||
|
|
|
@ -475,6 +475,254 @@ TableTHRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessTableRulesAttribute(nsStyleStruct* aStyleStruct,
|
||||
nsRuleData* aRuleData,
|
||||
PRUint8 aSide,
|
||||
PRBool aGroup,
|
||||
PRUint8 aRulesArg1,
|
||||
PRUint8 aRulesArg2,
|
||||
PRUint8 aRulesArg3)
|
||||
{
|
||||
if (!aStyleStruct || !aRuleData || !aRuleData->mPresContext) return;
|
||||
|
||||
nsCOMPtr<nsIStyleContext> tableContext = getter_AddRefs(aRuleData->mStyleContext->GetParent()); if (!tableContext) return;
|
||||
if (!aGroup) {
|
||||
tableContext = getter_AddRefs(tableContext->GetParent()); if (!tableContext) return;
|
||||
}
|
||||
|
||||
const nsStyleTable* tableData =
|
||||
(const nsStyleTable*)tableContext->GetStyleData(eStyleStruct_Table);
|
||||
if (tableData && ((aRulesArg1 == tableData->mRules) ||
|
||||
(aRulesArg2 == tableData->mRules) ||
|
||||
(aRulesArg3 == tableData->mRules))) {
|
||||
const nsStyleBorder* tableBorderData =
|
||||
(const nsStyleBorder*)tableContext->GetStyleData(eStyleStruct_Border); if (!tableBorderData) return;
|
||||
PRUint8 tableBorderStyle = tableBorderData->GetBorderStyle(aSide);
|
||||
|
||||
nsStyleBorder* borderData = (nsStyleBorder*)aStyleStruct; if (!borderData) return;
|
||||
PRUint8 borderStyle = borderData->GetBorderStyle(aSide);
|
||||
// XXX It appears that the style system erronously applies the custom style rule after css style,
|
||||
// consequently it does not properly fit into the casade. For now, assume that a border style of none
|
||||
// implies that the style has not been set.
|
||||
if (NS_STYLE_BORDER_STYLE_NONE == borderStyle) {
|
||||
// use the table's border style if it is dashed or dotted, otherwise use solid
|
||||
PRUint8 bStyle = ((NS_STYLE_BORDER_STYLE_NONE != tableBorderStyle) &&
|
||||
(NS_STYLE_BORDER_STYLE_HIDDEN != tableBorderStyle))
|
||||
? tableBorderStyle : NS_STYLE_BORDER_STYLE_SOLID;
|
||||
if ((NS_STYLE_BORDER_STYLE_DASHED != bStyle) &&
|
||||
(NS_STYLE_BORDER_STYLE_DOTTED != bStyle) &&
|
||||
(NS_STYLE_BORDER_STYLE_SOLID != bStyle)) {
|
||||
bStyle = NS_STYLE_BORDER_STYLE_SOLID;
|
||||
}
|
||||
bStyle |= NS_STYLE_BORDER_STYLE_RULES_MASK;
|
||||
borderData->SetBorderStyle(aSide, bStyle);
|
||||
|
||||
nscolor borderColor;
|
||||
PRBool transparent, foreground;
|
||||
borderData->GetBorderColor(aSide, borderColor, transparent, foreground);
|
||||
if (transparent || foreground) {
|
||||
// use the table's border color if it is set, otherwise use black
|
||||
nscolor tableBorderColor;
|
||||
tableBorderData->GetBorderColor(aSide, tableBorderColor, transparent, foreground);
|
||||
borderColor = (transparent || foreground) ? NS_RGB(0,0,0) : tableBorderColor;
|
||||
borderData->SetBorderColor(aSide, borderColor);
|
||||
}
|
||||
// set the border width to be 1 pixel
|
||||
float p2t;
|
||||
aRuleData->mPresContext->GetScaledPixelsToTwips(&p2t);
|
||||
nscoord onePixel = NSToCoordRound(p2t);
|
||||
nsStyleCoord coord(onePixel);
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
borderData->mBorder.SetTop(coord);
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
borderData->mBorder.SetRight(coord);
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
borderData->mBorder.SetBottom(coord);
|
||||
break;
|
||||
default: // NS_SIDE_LEFT
|
||||
borderData->mBorder.SetLeft(coord);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <thead>, <tbody>, <tfoot> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableTbodyRule: public GenericTableRule {
|
||||
public:
|
||||
TableTbodyRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableTbodyRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableTbodyRule::TableTbodyRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableTbodyRule::~TableTbodyRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void TbodyPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_TOP, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_BOTTOM, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableTbodyRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &TbodyPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <row> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableRowRule: public GenericTableRule {
|
||||
public:
|
||||
TableRowRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableRowRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableRowRule::TableRowRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableRowRule::~TableRowRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void RowPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_TOP, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_ROWS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_BOTTOM, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_ROWS, NS_STYLE_TABLE_RULES_ROWS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableRowRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &RowPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <colgroup> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableColgroupRule: public GenericTableRule {
|
||||
public:
|
||||
TableColgroupRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableColgroupRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableColgroupRule::TableColgroupRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableColgroupRule::~TableColgroupRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void ColgroupPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_LEFT, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_COLS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_RIGHT, PR_TRUE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_GROUPS, NS_STYLE_TABLE_RULES_COLS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableColgroupRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &ColgroupPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// this rule handles borders on a <col> when rules is set on its <table>
|
||||
// -----------------------------------------------------------
|
||||
class TableColRule: public GenericTableRule {
|
||||
public:
|
||||
TableColRule(nsIHTMLStyleSheet* aSheet);
|
||||
virtual ~TableColRule();
|
||||
|
||||
void Reset()
|
||||
{
|
||||
GenericTableRule::Reset();
|
||||
}
|
||||
|
||||
NS_IMETHOD MapRuleInfoInto(nsRuleData* aRuleData);
|
||||
};
|
||||
|
||||
TableColRule::TableColRule(nsIHTMLStyleSheet* aSheet)
|
||||
: GenericTableRule(aSheet)
|
||||
{
|
||||
}
|
||||
|
||||
TableColRule::~TableColRule()
|
||||
{
|
||||
}
|
||||
|
||||
static void ColPostResolveCallback(nsStyleStruct* aStyleStruct, nsRuleData* aRuleData)
|
||||
{
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_LEFT, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_COLS, NS_STYLE_TABLE_RULES_COLS);
|
||||
::ProcessTableRulesAttribute(aStyleStruct, aRuleData, NS_SIDE_RIGHT, PR_FALSE, NS_STYLE_TABLE_RULES_ALL,
|
||||
NS_STYLE_TABLE_RULES_COLS, NS_STYLE_TABLE_RULES_COLS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TableColRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
{
|
||||
if (aRuleData && aRuleData->mSID == eStyleStruct_Border) {
|
||||
aRuleData->mCanStoreInRuleTree = PR_FALSE;
|
||||
aRuleData->mPostResolveCallback = &ColPostResolveCallback;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
|
||||
class AttributeKey: public nsHashKey
|
||||
|
@ -653,6 +901,10 @@ protected:
|
|||
HTMLColorRule* mVisitedRule;
|
||||
HTMLColorRule* mActiveRule;
|
||||
HTMLDocumentColorRule* mDocumentColorRule;
|
||||
TableTbodyRule* mTableTbodyRule;
|
||||
TableRowRule* mTableRowRule;
|
||||
TableColgroupRule* mTableColgroupRule;
|
||||
TableColRule* mTableColRule;
|
||||
TableTHRule* mTableTHRule;
|
||||
// NOTE: if adding more rules, be sure to update
|
||||
// the SizeOf method to include them
|
||||
|
@ -710,6 +962,26 @@ HTMLStyleSheetImpl::HTMLStyleSheetImpl(void)
|
|||
nsresult
|
||||
HTMLStyleSheetImpl::Init()
|
||||
{
|
||||
mTableTbodyRule = new TableTbodyRule(this);
|
||||
if (!mTableTbodyRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableTbodyRule);
|
||||
|
||||
mTableRowRule = new TableRowRule(this);
|
||||
if (!mTableRowRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableRowRule);
|
||||
|
||||
mTableColgroupRule = new TableColgroupRule(this);
|
||||
if (!mTableColgroupRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableColgroupRule);
|
||||
|
||||
mTableColRule = new TableColRule(this);
|
||||
if (!mTableColRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mTableColRule);
|
||||
|
||||
mTableTHRule = new TableTHRule(this);
|
||||
if (!mTableTHRule)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -750,6 +1022,22 @@ HTMLStyleSheetImpl::~HTMLStyleSheetImpl()
|
|||
mDocumentColorRule->mSheet = nsnull;
|
||||
NS_RELEASE(mDocumentColorRule);
|
||||
}
|
||||
if (nsnull != mTableTbodyRule) {
|
||||
mTableTbodyRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableTbodyRule);
|
||||
}
|
||||
if (nsnull != mTableRowRule) {
|
||||
mTableRowRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableRowRule);
|
||||
}
|
||||
if (nsnull != mTableColgroupRule) {
|
||||
mTableColgroupRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableColgroupRule);
|
||||
}
|
||||
if (nsnull != mTableColRule) {
|
||||
mTableColRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableColRule);
|
||||
}
|
||||
if (nsnull != mTableTHRule) {
|
||||
mTableTHRule->mSheet = nsnull;
|
||||
NS_RELEASE(mTableTHRule);
|
||||
|
@ -848,6 +1136,18 @@ HTMLStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData,
|
|||
else if (tag == nsHTMLAtoms::th) {
|
||||
ruleWalker->Forward(mTableTHRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::tr) {
|
||||
ruleWalker->Forward(mTableRowRule);
|
||||
}
|
||||
else if ((tag == nsHTMLAtoms::thead) || (tag == nsHTMLAtoms::tbody) || (tag == nsHTMLAtoms::tfoot)) {
|
||||
ruleWalker->Forward(mTableTbodyRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::col) {
|
||||
ruleWalker->Forward(mTableColRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::colgroup) {
|
||||
ruleWalker->Forward(mTableColgroupRule);
|
||||
}
|
||||
else if (tag == nsHTMLAtoms::table) {
|
||||
if (aData->mIsQuirkMode)
|
||||
ruleWalker->Forward(mDocumentColorRule);
|
||||
|
@ -888,7 +1188,13 @@ NS_IMETHODIMP
|
|||
HTMLStyleSheetImpl::RulesMatching(PseudoRuleProcessorData* aData,
|
||||
nsIAtom* aMedium)
|
||||
{
|
||||
// no pseudo frame style
|
||||
nsIAtom* pseudoTag = aData->mPseudoTag;
|
||||
if (pseudoTag == nsHTMLAtoms::tableColPseudo) {
|
||||
nsRuleWalker *ruleWalker = aData->mRuleWalker;
|
||||
if (ruleWalker) {
|
||||
ruleWalker->Forward(mTableColRule);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1008,6 +1314,11 @@ HTMLStyleSheetImpl::Reset(nsIURI* aURL)
|
|||
NS_RELEASE(mActiveRule);
|
||||
}
|
||||
mDocumentColorRule->Reset();
|
||||
|
||||
mTableTbodyRule->Reset();
|
||||
mTableRowRule->Reset();
|
||||
mTableColgroupRule->Reset();
|
||||
mTableColRule->Reset();
|
||||
mTableTHRule->Reset();
|
||||
|
||||
mMappedAttrTable.Enumerate(MappedDropSheet);
|
||||
|
@ -1264,6 +1575,10 @@ MappedSizeAttributes(nsHashKey *aKey, void *aData, void* closure)
|
|||
* - mVisitedRule
|
||||
* - mActiveRule
|
||||
* - mDocumentColorRule
|
||||
* - mTableTbodyRule
|
||||
* - mTableRowRule
|
||||
* - mTableColgroupRule
|
||||
* - mTableColRule
|
||||
* - mTableTHRule
|
||||
* - mMappedAttrTable
|
||||
* 2) Delegates (really) to the MappedAttributes in the mMappedAttrTable
|
||||
|
@ -1298,6 +1613,10 @@ HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
|
|||
// - mVisitedRule : sizeof object
|
||||
// - mActiveRule : sizeof object
|
||||
// - mDocumentColorRule : sizeof object
|
||||
// - mTableTbodyRule : sizeof object
|
||||
// - mTableRowRule : sizeof object
|
||||
// - mTableColgroupRule : sizeof object
|
||||
// - mTableColRule : sizeof object
|
||||
// - mTableTHRule : sizeof object
|
||||
// - mMappedAttrTable
|
||||
|
||||
|
@ -1321,6 +1640,26 @@ HTMLStyleSheetImpl::SizeOf(nsISizeOfHandler *aSizeOfHandler, PRUint32 &aSize)
|
|||
tag = getter_AddRefs(NS_NewAtom("DocumentColorRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableTbodyRule)){
|
||||
localSize = sizeof(*mTableTbodyRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableTbodyRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableRowRule)){
|
||||
localSize = sizeof(*mTableRowRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableRowRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableColgroupRule)){
|
||||
localSize = sizeof(*mTableColgroupRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableColgroupRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableColRule)){
|
||||
localSize = sizeof(*mTableColRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableColRule"));
|
||||
aSizeOfHandler->AddSize(tag,localSize);
|
||||
}
|
||||
if(uniqueItems->AddItem((void*)mTableTHRule)){
|
||||
localSize = sizeof(*mTableTHRule);
|
||||
tag = getter_AddRefs(NS_NewAtom("TableTHRule"));
|
||||
|
|
|
@ -605,6 +605,28 @@ nsStyleBorder::CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsStyleBorder::CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide, nscoord& aWidth) const
|
||||
{
|
||||
aWidth = 0;
|
||||
// using mCachedBorder as above, doesn't work properly
|
||||
nsStyleCoord coord;
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
coord = mBorder.GetTop(coord);
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
coord = mBorder.GetRight(coord);
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
coord = mBorder.GetBottom(coord);
|
||||
break;
|
||||
default: // NS_SIDE_LEFT
|
||||
coord = mBorder.GetLeft(coord);
|
||||
}
|
||||
aWidth = CalcSideFor(aFrame, coord, NS_SPACING_BORDER, aSide, mBorderWidths, 3);
|
||||
}
|
||||
|
||||
nsStyleOutline::nsStyleOutline(nsIPresContext* aPresContext)
|
||||
{
|
||||
// XXX support mBorderWidths until deprecated methods are removed
|
||||
|
@ -862,7 +884,7 @@ nsStyleTable::nsStyleTable()
|
|||
mLayoutStrategy = NS_STYLE_TABLE_LAYOUT_AUTO;
|
||||
mCols = NS_STYLE_TABLE_COLS_NONE;
|
||||
mFrame = NS_STYLE_TABLE_FRAME_NONE;
|
||||
mRules = NS_STYLE_TABLE_RULES_ALL;
|
||||
mRules = NS_STYLE_TABLE_RULES_NONE;
|
||||
mSpan = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -465,7 +465,8 @@ struct nsStyleBorder: public nsStyleStruct {
|
|||
|
||||
// XXX these are deprecated methods
|
||||
void CalcBorderFor(const nsIFrame* aFrame, nsMargin& aBorder) const;
|
||||
|
||||
void CalcBorderFor(const nsIFrame* aFrame, PRUint8 aSide, nscoord& aWidth) const;
|
||||
|
||||
protected:
|
||||
PRPackedBool mHasCachedBorder;
|
||||
nsMargin mCachedBorder;
|
||||
|
|
|
@ -139,7 +139,7 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContex
|
|||
nscoord minWidth, prefWidth;
|
||||
mTableFrame->CalcMinAndPreferredWidths(aPresContext, aReflowState, PR_FALSE, minWidth, prefWidth);
|
||||
if (hasPctCol && mTableFrame->IsAutoWidth()) {
|
||||
prefWidth = CalcPctAdjTableWidth(aReflowState, boxWidth, p2t);
|
||||
prefWidth = CalcPctAdjTableWidth(*aPresContext, aReflowState, boxWidth, p2t);
|
||||
}
|
||||
// calc the desired width, considering if there is a specified width.
|
||||
// don't use nsTableFrame::CalcDesiredWidth because it is based on table column widths.
|
||||
|
@ -195,7 +195,7 @@ ResetPctValues(nsTableFrame* aTableFrame,
|
|||
// initialize the col percent and cell percent values to 0.
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < aNumCols; colX++) {
|
||||
nsTableColFrame* colFrame = aTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = aTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (colFrame) {
|
||||
colFrame->SetWidth(PCT, WIDTH_NOT_SET);
|
||||
colFrame->SetWidth(PCT_ADJ, WIDTH_NOT_SET);
|
||||
|
@ -207,6 +207,7 @@ PRBool
|
|||
BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
if (!aPresContext) ABORT1(PR_FALSE);
|
||||
#ifdef DEBUG_TABLE_STRATEGY
|
||||
printf("BalanceColumnWidths en count=%d \n", gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);
|
||||
#endif
|
||||
|
@ -220,8 +221,16 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
|
|||
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
PRBool tableIsAutoWidth = mTableFrame->IsAutoWidth();
|
||||
nscoord horBorderPadding = aReflowState.mComputedBorderPadding.left +
|
||||
aReflowState.mComputedBorderPadding.right;
|
||||
|
||||
nscoord horOffset;
|
||||
// get the reduction in available horizontal space due to borders and padding
|
||||
if (mTableFrame->IsBorderCollapse()) {
|
||||
nsMargin offset = mTableFrame->GetChildAreaOffset(*aPresContext, &aReflowState);
|
||||
horOffset = offset.left + offset.right;
|
||||
}
|
||||
else {
|
||||
horOffset = aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
|
||||
}
|
||||
|
||||
// determine if the table is auto/fixed and get the fixed width if available
|
||||
nscoord maxWidth = mTableFrame->CalcBorderBoxWidth(aPresContext, aReflowState);
|
||||
|
@ -238,19 +247,19 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
|
|||
// An auto table returns a new table width based on percent cells/cols if they exist
|
||||
nscoord perAdjTableWidth = 0;
|
||||
if (mTableFrame->HasPctCol()) {
|
||||
perAdjTableWidth = AssignPctColumnWidths(aReflowState, maxWidth, tableIsAutoWidth, p2t);
|
||||
perAdjTableWidth = AssignPctColumnWidths(*aPresContext, aReflowState, maxWidth, tableIsAutoWidth, p2t);
|
||||
if (perAdjTableWidth > 0) {
|
||||
// if an auto table has a pct col or cell, set the preferred table width
|
||||
// here so that CalcPctAdjTableWidth wont't need to be called by the table
|
||||
mTableFrame->SetPreferredWidth(perAdjTableWidth);
|
||||
}
|
||||
perAdjTableWidth = PR_MIN(perAdjTableWidth, maxWidth);
|
||||
perAdjTableWidth -= horBorderPadding;
|
||||
perAdjTableWidth -= horOffset;
|
||||
perAdjTableWidth = PR_MAX(perAdjTableWidth, 0);
|
||||
}
|
||||
|
||||
// reduce the maxWidth by border and padding, since we will be dealing with content width
|
||||
maxWidth -= horBorderPadding;
|
||||
maxWidth -= horOffset;
|
||||
maxWidth = PR_MAX(0, maxWidth);
|
||||
|
||||
PRInt32 numNonZeroWidthCols = 0;
|
||||
|
@ -258,7 +267,7 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
|
|||
nscoord minTableWidth = 0;
|
||||
PRInt32 colX;
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord colMinWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, colMinWidth);
|
||||
|
@ -400,7 +409,7 @@ void BasicTableLayoutStrategy::AllocateFully(nscoord& aTotalAllocated,
|
|||
{
|
||||
PRInt32 numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame)) {
|
||||
continue;
|
||||
|
@ -454,7 +463,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
|||
}
|
||||
else {
|
||||
if (aExclude0Pro) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (colFrame->GetConstraint() == e0ProportionConstraint) {
|
||||
aAllocTypes[colX] = FINISHED;
|
||||
}
|
||||
|
@ -467,7 +476,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
|||
PRInt32 numColsAllocated = 0;
|
||||
PRInt32 totalAllocated = 0;
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
PRBool skipColumn = aExclude0Pro && (e0ProportionConstraint == colFrame->GetConstraint());
|
||||
if (FINISHED != aAllocTypes[colX] && !skipColumn ) {
|
||||
divisor += mTableFrame->GetColumnWidth(colX);
|
||||
|
@ -477,7 +486,7 @@ void BasicTableLayoutStrategy::AllocateUnconstrained(PRInt32 aAllocAmount,
|
|||
for (colX = 0; colX < numCols; colX++) {
|
||||
if (FINISHED != aAllocTypes[colX]) {
|
||||
if (aExclude0Pro) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (colFrame && (e0ProportionConstraint == colFrame->GetConstraint())) {
|
||||
continue;
|
||||
}
|
||||
|
@ -533,7 +542,7 @@ BasicTableLayoutStrategy::ComputeNonPctColspanWidths(const nsHTMLReflowState& aR
|
|||
|
||||
PRInt32 colX;
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
colFrame->SetWidth(MIN_ADJ, WIDTH_NOT_SET);
|
||||
colFrame->SetWidth(FIX_ADJ, WIDTH_NOT_SET);
|
||||
|
@ -698,7 +707,7 @@ BasicTableLayoutStrategy::ComputeNonPctColspanWidths(PRInt32 aWidthInd
|
|||
PRInt32 spanX;
|
||||
// accumulate the various divisors to be used later
|
||||
for (spanX = 0; spanX < aColSpan; spanX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord minWidth = PR_MAX(colFrame->GetMinWidth(), 0);
|
||||
nscoord pctWidth = PR_MAX(colFrame->GetPctWidth(), 0);
|
||||
|
@ -802,7 +811,7 @@ BasicTableLayoutStrategy::ComputeNonPctColspanWidths(PRInt32 aWidthInd
|
|||
// get the correct numerator in a similar fashion to getting the divisor
|
||||
for (spanX = 0; spanX < aColSpan; spanX++) {
|
||||
if (usedWidth >= availWidth) break;
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(aColIndex + spanX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord minWidth = colFrame->GetMinWidth();
|
||||
nscoord pctWidth = PR_MAX(colFrame->GetPctWidth(), 0);
|
||||
|
@ -974,7 +983,7 @@ BasicTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
|
|||
nscoord fixWidth = WIDTH_NOT_SET;
|
||||
|
||||
// Get column frame and reset it
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
NS_ASSERTION(nsnull != colFrame, "bad col frame");
|
||||
colFrame->ResetSizingInfo();
|
||||
|
@ -1079,7 +1088,7 @@ BasicTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
|
|||
}
|
||||
//set the table col fixed width if present
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
if (!colFrame) continue;
|
||||
nscoord fixColWidth = colFrame->GetWidth(FIX);
|
||||
// use the style width of a col only if the col hasn't gotten a fixed width from any cell
|
||||
|
@ -1140,7 +1149,7 @@ BasicTableLayoutStrategy::AssignNonPctColumnWidths(nsIPresContext* aPre
|
|||
|
||||
// Set the table col width for each col to the content min.
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(PR_FALSE);
|
||||
nscoord minWidth = colFrame->GetMinWidth();
|
||||
mTableFrame->SetColumnWidth(colX, minWidth);
|
||||
}
|
||||
|
@ -1159,7 +1168,7 @@ BasicTableLayoutStrategy::ReduceOverSpecifiedPctCols(nscoord aExcess)
|
|||
{
|
||||
nscoord numCols = mTableFrame->GetColCount();
|
||||
for (PRInt32 colX = numCols - 1; (colX >= 0) && (aExcess > 0); colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
nscoord pctWidth = colFrame->GetWidth(PCT);
|
||||
nscoord reduction = 0;
|
||||
|
@ -1198,7 +1207,8 @@ inline nscoord WrapupAssignPctColumnWidths(nsTableFrame* aTableFrame,
|
|||
#endif
|
||||
|
||||
nscoord
|
||||
BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowState,
|
||||
BasicTableLayoutStrategy::CalcPctAdjTableWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidthIn,
|
||||
float aPixelToTwips)
|
||||
{
|
||||
|
@ -1219,7 +1229,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
rawPctValues[colX] = 0.0f;
|
||||
}
|
||||
|
||||
nsMargin borderPadding = mTableFrame->GetBorderPadding(aReflowState);
|
||||
nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState);
|
||||
nscoord availWidth = aAvailWidthIn;
|
||||
if (NS_UNCONSTRAINEDSIZE != availWidth) {
|
||||
// adjust the avail width to exclude table border, padding and cell spacing
|
||||
|
@ -1227,7 +1237,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
}
|
||||
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
nscoord maxColBasis = -1;
|
||||
// Scan the cells in the col
|
||||
|
@ -1282,7 +1292,7 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
nscoord fixDesTotalNoPct = 0; // total of fix or des widths of cols without pct
|
||||
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(0);
|
||||
nscoord fixWidth = colFrame->GetFixWidth();
|
||||
nscoord fixDesWidth = (fixWidth > 0) ? fixWidth : colFrame->GetDesWidth();
|
||||
fixDesTotal += fixDesWidth;
|
||||
|
@ -1329,7 +1339,8 @@ BasicTableLayoutStrategy::CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowS
|
|||
|
||||
// Determine percentage col widths for each col frame
|
||||
nscoord
|
||||
BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflowState,
|
||||
BasicTableLayoutStrategy::AssignPctColumnWidths(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
PRBool aTableIsAutoWidth,
|
||||
float aPixelToTwips)
|
||||
|
@ -1349,11 +1360,11 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// on percent cells/cols. This probably should only be a NavQuirks thing, since
|
||||
// a percentage based cell or column on an auto table should force the column to auto
|
||||
nscoord basis = (aTableIsAutoWidth)
|
||||
? CalcPctAdjTableWidth(aReflowState, aAvailWidth, aPixelToTwips)
|
||||
? CalcPctAdjTableWidth(aPresContext, aReflowState, aAvailWidth, aPixelToTwips)
|
||||
: aAvailWidth;
|
||||
|
||||
// adjust the basis to exclude table border, padding and cell spacing
|
||||
nsMargin borderPadding = mTableFrame->GetBorderPadding(aReflowState);
|
||||
nsMargin borderPadding = mTableFrame->GetContentAreaOffset(aPresContext, &aReflowState);
|
||||
basis -= borderPadding.left + borderPadding.right + mCellSpacingTotal;
|
||||
|
||||
nscoord colPctTotal = 0;
|
||||
|
@ -1361,7 +1372,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// Determine the percentage contribution for cols and for cells with colspan = 1
|
||||
// Iterate backwards, similarly to the reasoning in AssignNonPctColumnWidths
|
||||
for (colX = numCols - 1; colX >= 0; colX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
nscoord maxColPctWidth = WIDTH_NOT_SET;
|
||||
float maxColPct = 0.0f;
|
||||
|
@ -1431,7 +1442,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
}
|
||||
// determine if the cell spans cols which have a pct value
|
||||
for (PRInt32 spanX = 0; (spanX < colSpan) && !done; spanX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
if (colFrame->GetWidth(PCT) > 0) {
|
||||
mTableFrame->SetHasCellSpanningPctCol(PR_TRUE);
|
||||
|
@ -1511,7 +1522,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// accumulate the spanTotal as the max of MIN, DES, FIX, PCT
|
||||
PRInt32 spanX;
|
||||
for (spanX = 0; spanX < colSpan; spanX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
nscoord colPctWidth = colFrame->GetWidth(PCT);
|
||||
if (colPctWidth > 0) { // skip pct cols
|
||||
|
@ -1546,7 +1557,7 @@ BasicTableLayoutStrategy::AssignPctColumnWidths(const nsHTMLReflowState& aReflow
|
|||
// record the percent contributions for the spanned cols
|
||||
PRInt32 usedColumns = colSpan;
|
||||
for (spanX = colSpan-1; spanX >= 0; spanX--) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX + spanX); if (!colFrame) ABORT1(0);
|
||||
if (!colFrame) continue;
|
||||
if ((colFrame->GetWidth(PCT) > 0) || (canSkipPctAdj && (colFrame->GetWidth(PCT_ADJ) > 0))) {
|
||||
// dont use pct cols or if we can skip the pct adj event do not take the PCT_ADJ cols
|
||||
|
@ -1621,7 +1632,7 @@ void BasicTableLayoutStrategy::CalculateTotals(PRInt32* aTotalCounts,
|
|||
PRInt32 colX;
|
||||
|
||||
for (colX = 0; colX < numEffCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
nscoord minCol = colFrame->GetMinWidth();
|
||||
aTotalCounts[MIN_CON]++;
|
||||
|
@ -1820,7 +1831,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
|||
PRInt32 colX;
|
||||
// find out how many constrained cols there are
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame)) {
|
||||
continue;
|
||||
|
@ -1837,7 +1848,7 @@ void BasicTableLayoutStrategy::AllocateConstrained(PRInt32 aAvailWidth,
|
|||
PRInt32 constrColX = 0;
|
||||
// set the col info entries for each constrained col
|
||||
for (colX = 0; colX < numCols; colX++) {
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); if (!colFrame) ABORT0();
|
||||
if (!colFrame) continue;
|
||||
if (!CanAllocate(aWidthType, aAllocTypes[colX], colFrame)) {
|
||||
continue;
|
||||
|
|
|
@ -93,7 +93,8 @@ public:
|
|||
* @param aPixelToTwips - the number of twips in a pixel.
|
||||
* @return - the basis for percent calculations
|
||||
*/
|
||||
virtual nscoord CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowState,
|
||||
virtual nscoord CalcPctAdjTableWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
float aPixelToTwips);
|
||||
void Dump(PRInt32 aIndent);
|
||||
|
@ -159,7 +160,8 @@ protected:
|
|||
* @param aPixelToTwips - the number of twips in a pixel.
|
||||
* @return - the adjusted basis including table border, padding and cell spacing
|
||||
*/
|
||||
nscoord AssignPctColumnWidths(const nsHTMLReflowState& aReflowState,
|
||||
nscoord AssignPctColumnWidths(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aBasis,
|
||||
PRBool aTableIsAutoWidth,
|
||||
float aPixelToTwips);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#define CellData_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsCoord.h"
|
||||
|
||||
class nsTableCellFrame;
|
||||
|
||||
|
@ -51,8 +52,9 @@ public:
|
|||
|
||||
~CellData();
|
||||
|
||||
void Init(nsTableCellFrame* aCellFrame);
|
||||
PRBool IsOrig() const;
|
||||
|
||||
PRBool IsDead() const;
|
||||
PRBool IsSpan() const;
|
||||
|
||||
PRBool IsRowSpan() const;
|
||||
|
@ -84,6 +86,93 @@ protected:
|
|||
};
|
||||
};
|
||||
|
||||
// Border Collapsing Cell Data
|
||||
enum BCBorderOwner
|
||||
{
|
||||
eTableOwner = 0,
|
||||
eColGroupOwner = 1,
|
||||
eAjaColGroupOwner = 2, // col group to the left
|
||||
eColOwner = 3,
|
||||
eAjaColOwner = 4, // col to the left
|
||||
eRowGroupOwner = 5,
|
||||
eAjaRowGroupOwner = 6, // row group above
|
||||
eRowOwner = 7,
|
||||
eAjaRowOwner = 8, // row above
|
||||
eCellOwner = 9,
|
||||
eAjaCellOwner = 10, // cell to the top or to the left
|
||||
};
|
||||
|
||||
// These are the max sizes that are stored. If they are exceeded, then the max is stored and
|
||||
// the actual value is computed when needed.
|
||||
#define MAX_BORDER_WIDTH 64
|
||||
#define MAX_CORNER_SUB_WIDTH 128
|
||||
|
||||
// BCData stores the top and left border info and the corner connecting the two.
|
||||
class BCData
|
||||
{
|
||||
public:
|
||||
BCData();
|
||||
|
||||
~BCData();
|
||||
|
||||
nscoord GetLeftEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const;
|
||||
|
||||
void SetLeftEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart);
|
||||
|
||||
nscoord GetTopEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const;
|
||||
|
||||
void SetTopEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart);
|
||||
|
||||
PRUint8 GetCorner(PRUint8& aCornerOwner,
|
||||
PRPackedBool& aBevel) const;
|
||||
|
||||
void SetCorner(PRUint8 aOwner,
|
||||
PRUint8 aSubSize,
|
||||
PRBool aBevel);
|
||||
|
||||
PRBool IsLeftStart() const;
|
||||
|
||||
void SetLeftStart(PRBool aValue);
|
||||
|
||||
PRBool IsTopStart() const;
|
||||
|
||||
void SetTopStart(PRBool aValue);
|
||||
|
||||
|
||||
protected:
|
||||
unsigned mLeftOwner: 4; // owner of left border
|
||||
unsigned mLeftSize: 6; // size in pixels of left border
|
||||
unsigned mLeftStart: 1; // set if this is the start of a vertical border segment
|
||||
unsigned mCornerSide: 2; // side of the owner of the upper left corner relative to the corner
|
||||
unsigned mCornerSubSize: 7; // size of the largest border not in the dominate plane (for example, if
|
||||
// corner is owned by the segment to its top or bottom, then the size is the
|
||||
// max of the border sizes of the segments to its left or right.
|
||||
unsigned mCornerBevel: 1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
|
||||
unsigned mTopOwner: 4; // owner of top border
|
||||
unsigned mTopSize: 6; // size in pixels of top border
|
||||
unsigned mTopStart: 1; // set if this is the start of a horizontal border segment
|
||||
};
|
||||
|
||||
// BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
|
||||
// effect. BCData for a row and col entry contains the left and top borders of cell at that row and
|
||||
// col and the corner connecting the two. The right borders of the cells in the last col and the bottom
|
||||
// borders of the last row are stored in separate BCData entries in the cell map.
|
||||
class BCCellData : public CellData
|
||||
{
|
||||
public:
|
||||
BCCellData(nsTableCellFrame* aOrigCell);
|
||||
~BCCellData();
|
||||
|
||||
BCData mData;
|
||||
};
|
||||
|
||||
|
||||
#define SPAN 0x00000001 // there a row or col span
|
||||
#define ROW_SPAN 0x00000002 // there is a row span
|
||||
#define ROW_SPAN_0 0x00000004 // the row span is 0
|
||||
|
@ -103,9 +192,19 @@ inline nsTableCellFrame* CellData::GetCellFrame() const
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
inline void CellData::Init(nsTableCellFrame* aCellFrame)
|
||||
{
|
||||
mOrigCell = aCellFrame;
|
||||
}
|
||||
|
||||
inline PRBool CellData::IsOrig() const
|
||||
{
|
||||
return (SPAN != (SPAN & mBits));
|
||||
return ((nsnull != mOrigCell) && (SPAN != (SPAN & mBits)));
|
||||
}
|
||||
|
||||
inline PRBool CellData::IsDead() const
|
||||
{
|
||||
return (0 == mBits);
|
||||
}
|
||||
|
||||
inline PRBool CellData::IsSpan() const
|
||||
|
@ -213,4 +312,88 @@ inline void CellData::SetOverlap(PRBool aOverlap)
|
|||
}
|
||||
}
|
||||
|
||||
inline BCData::BCData()
|
||||
{
|
||||
mLeftOwner = mTopOwner = eCellOwner;
|
||||
mLeftStart = mTopStart = 1;
|
||||
mLeftSize = mCornerSide = mCornerSubSize = mTopSize = 0;
|
||||
}
|
||||
|
||||
inline BCData::~BCData()
|
||||
{
|
||||
}
|
||||
|
||||
inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const
|
||||
{
|
||||
aOwner = (BCBorderOwner)mLeftOwner;
|
||||
aStart = (PRBool)mLeftStart;
|
||||
|
||||
return (nscoord)mLeftSize;
|
||||
}
|
||||
|
||||
inline void BCData::SetLeftEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart)
|
||||
{
|
||||
mLeftOwner = aOwner;
|
||||
mLeftSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
|
||||
mLeftStart = aStart;
|
||||
}
|
||||
|
||||
inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner,
|
||||
PRBool& aStart) const
|
||||
{
|
||||
aOwner = (BCBorderOwner)mTopOwner;
|
||||
aStart = (PRBool)mTopStart;
|
||||
|
||||
return (nscoord)mTopSize;
|
||||
}
|
||||
|
||||
inline void BCData::SetTopEdge(BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aStart)
|
||||
{
|
||||
mTopOwner = aOwner;
|
||||
mTopSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
|
||||
mTopStart = aStart;
|
||||
}
|
||||
|
||||
inline PRUint8 BCData::GetCorner(PRUint8& aOwnerSide,
|
||||
PRPackedBool& aBevel) const
|
||||
{
|
||||
aOwnerSide = mCornerSide;
|
||||
aBevel = (PRBool)mCornerBevel;
|
||||
return (PRUint8)mCornerSubSize;
|
||||
}
|
||||
|
||||
inline void BCData::SetCorner(PRUint8 aSubSize,
|
||||
PRUint8 aOwnerSide,
|
||||
PRBool aBevel)
|
||||
{
|
||||
mCornerSubSize = (aSubSize > MAX_CORNER_SUB_WIDTH) ? MAX_CORNER_SUB_WIDTH : aSubSize;
|
||||
mCornerSide = aOwnerSide;
|
||||
mCornerBevel = aBevel;
|
||||
}
|
||||
|
||||
inline PRBool BCData::IsLeftStart() const
|
||||
{
|
||||
return (PRBool)mLeftStart;
|
||||
}
|
||||
|
||||
inline void BCData::SetLeftStart(PRBool aValue)
|
||||
{
|
||||
mLeftStart = aValue;
|
||||
}
|
||||
|
||||
inline PRBool BCData::IsTopStart() const
|
||||
{
|
||||
return (PRBool)mTopStart;
|
||||
}
|
||||
|
||||
inline void BCData::SetTopStart(PRBool aValue)
|
||||
{
|
||||
mTopStart = aValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -40,6 +40,8 @@
|
|||
#include "nscore.h"
|
||||
#include "celldata.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsTableColFrame;
|
||||
class nsTableCellFrame;
|
||||
class nsIPresContext;
|
||||
|
@ -58,10 +60,27 @@ struct nsColInfo
|
|||
PRInt32 aNumCellsSpan);
|
||||
};
|
||||
|
||||
enum Corner
|
||||
{
|
||||
eTopLeft = 0,
|
||||
eTopRight = 1,
|
||||
eBottomRight = 2,
|
||||
eBottomLeft = 3
|
||||
};
|
||||
|
||||
struct BCInfo
|
||||
{
|
||||
nsVoidArray mRightBorders;
|
||||
nsVoidArray mBottomBorders;
|
||||
BCData mLowerRightCorner;
|
||||
};
|
||||
|
||||
class nsTableCellMap
|
||||
{
|
||||
public:
|
||||
nsTableCellMap(nsIPresContext* aPresContext, nsTableFrame& aTableFrame);
|
||||
nsTableCellMap(nsIPresContext* aPresContext,
|
||||
nsTableFrame& aTableFrame,
|
||||
PRBool aBorderCollapse);
|
||||
|
||||
/** destructor
|
||||
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
|
||||
|
@ -69,43 +88,52 @@ public:
|
|||
~nsTableCellMap();
|
||||
|
||||
void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
|
||||
|
||||
void InsertGroupCellMap(nsTableRowGroupFrame& aNewRowGroup,
|
||||
nsTableRowGroupFrame*& aPrevRowGroup);
|
||||
|
||||
nsCellMap* GetMapFor(nsTableRowGroupFrame& aRowGroup);
|
||||
|
||||
nsTableCellFrame* GetCellFrame(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
CellData& aData,
|
||||
PRBool aUseRowIfOverlap) const;
|
||||
|
||||
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
|
||||
CellData* GetCellAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
CellData* GetDataAt(PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aUpdateZeroSpan = PR_TRUE);
|
||||
|
||||
nsColInfo* GetColInfoAt(PRInt32 aColIndex);
|
||||
|
||||
/** append the cellFrame at the end of the row at aRowIndex and return the col index
|
||||
*/
|
||||
PRInt32 AppendCell(nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary);
|
||||
CellData* AppendCell(nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertCells(nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
PRInt32 aColIndexBefore,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveCell(nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
PRInt32 aRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertRows(nsIPresContext* aPresContext,
|
||||
nsTableRowGroupFrame& aRowGroup,
|
||||
nsVoidArray& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveRows(nsIPresContext* aPresContext,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex);
|
||||
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
|
||||
|
@ -134,6 +162,32 @@ public:
|
|||
PRBool ColIsSpannedInto(PRInt32 aColIndex);
|
||||
PRBool ColHasSpanningCells(PRInt32 aColIndex);
|
||||
|
||||
BCData* GetBCData(PRUint8 aSide,
|
||||
nsCellMap& aCellMap,
|
||||
PRUint32 aYPos,
|
||||
PRUint32 aXPos,
|
||||
PRBool aIsLowerRight = PR_FALSE);
|
||||
|
||||
void SetBCBorderEdge(PRUint8 aEdge,
|
||||
nsCellMap& aCellMap,
|
||||
PRUint32 aCellMapStart,
|
||||
PRUint32 aYPos,
|
||||
PRUint32 aXPos,
|
||||
PRUint32 aLength,
|
||||
BCBorderOwner aOwner,
|
||||
nscoord aSize,
|
||||
PRBool aChanged);
|
||||
|
||||
void SetBCBorderCorner(Corner aCorner,
|
||||
nsCellMap& aCellMap,
|
||||
PRUint32 aCellMapStart,
|
||||
PRUint32 aYPos,
|
||||
PRUint32 aXPos,
|
||||
PRUint8 aOwner,
|
||||
nscoord aSubSize,
|
||||
PRBool aBevel,
|
||||
PRBool aIsBottomRight = PR_FALSE);
|
||||
|
||||
/** dump a representation of the cell map to stdout for debugging */
|
||||
#ifdef NS_DEBUG
|
||||
void Dump(char* aString = nsnull) const;
|
||||
|
@ -144,13 +198,21 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
BCData* GetRightMostBorder(PRInt32 aRowIndex);
|
||||
BCData* GetBottomMostBorder(PRInt32 aColIndex);
|
||||
|
||||
friend class nsCellMap;
|
||||
friend class BCMapCellIterator;
|
||||
friend class BCMapBorderIterator;
|
||||
void InsertGroupCellMap(nsCellMap* aPrevMap,
|
||||
nsCellMap& aNewMap);
|
||||
void DeleteRightBottomBorders();
|
||||
|
||||
nsTableFrame& mTableFrame;
|
||||
nsTableFrame& mTableFrame;
|
||||
nsAutoVoidArray mCols;
|
||||
nsCellMap* mFirstMap;
|
||||
nsCellMap* mFirstMap;
|
||||
// border collapsing info
|
||||
BCInfo* mBCInfo;
|
||||
};
|
||||
|
||||
/** nsCellMap is a support class for nsTablePart.
|
||||
|
@ -190,40 +252,38 @@ public:
|
|||
CellData& aData,
|
||||
PRBool aUseRowSpanIfOverlap) const;
|
||||
|
||||
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
|
||||
CellData* GetCellAt(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
/** append the cellFrame at the end of the row at aRowIndex and return the col index
|
||||
*/
|
||||
PRInt32 AppendCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary);
|
||||
CellData* AppendCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool aRebuildIfNecessary,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertCells(nsTableCellMap& aMap,
|
||||
nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore);
|
||||
PRInt32 aColIndexBefore,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
void RemoveCol(PRInt32 aColIndex);
|
||||
PRInt32 aRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
nsVoidArray& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRBool aConsiderSpans);
|
||||
PRBool aConsiderSpans,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
|
||||
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
|
||||
|
@ -246,9 +306,20 @@ public:
|
|||
PRBool ColHasSpanningCells(nsTableCellMap& aMap,
|
||||
PRInt32 aColIndex);
|
||||
|
||||
PRInt32 GetRowSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aGetEffective,
|
||||
PRBool& aIsZeroRowSpan);
|
||||
|
||||
PRInt32 GetEffectiveColSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool& aIsZeroColSpan);
|
||||
|
||||
/** dump a representation of the cell map to stdout for debugging */
|
||||
#ifdef NS_DEBUG
|
||||
void Dump() const;
|
||||
void Dump(PRBool aIsBorderCollapse) const;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -257,6 +328,9 @@ public:
|
|||
|
||||
protected:
|
||||
friend class nsTableCellMap;
|
||||
friend class BCMapCellIterator;
|
||||
friend class BCMapBorderIterator;
|
||||
friend class nsTableFrame;
|
||||
|
||||
PRBool Grow(nsTableCellMap& aMap,
|
||||
PRInt32 aNumRows,
|
||||
|
@ -266,51 +340,57 @@ protected:
|
|||
PRInt32 aNumCols);
|
||||
|
||||
/** assign aCellData to the cell at (aRow,aColumn) */
|
||||
void SetMapCellAt(nsTableCellMap& aMap,
|
||||
CellData& aCellData,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aCountZeroSpanAsSpan);
|
||||
void SetDataAt(nsTableCellMap& aMap,
|
||||
CellData& aCellData,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aCountZeroSpanAsSpan);
|
||||
|
||||
CellData* GetMapCellAt(nsTableCellMap& aMap,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aUpdateZeroSpan);
|
||||
CellData* GetDataAt(nsTableCellMap& aMap,
|
||||
PRInt32 aMapRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aUpdateZeroSpan);
|
||||
|
||||
PRInt32 GetNumCellsIn(PRInt32 aColIndex) const;
|
||||
|
||||
void ExpandWithRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
nsVoidArray& aRowFrames,
|
||||
PRInt32 aStartRowIndex);
|
||||
PRInt32 aStartRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ExpandWithCells(nsTableCellMap& aMap,
|
||||
nsVoidArray& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aRowSpan,
|
||||
PRBool aRowSpanIsZero);
|
||||
PRBool aRowSpanIsZero,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ShrinkWithoutRows(nsTableCellMap& aMap,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove);
|
||||
PRInt32 aNumRowsToRemove,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ShrinkWithoutCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex);
|
||||
PRInt32 aColIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RebuildConsideringRows(nsIPresContext* aPresContext,
|
||||
nsTableCellMap& aMap,
|
||||
PRInt32 aStartRowIndex,
|
||||
nsVoidArray* aRowsToInsert,
|
||||
PRInt32 aNumRowsToRemove = 0);
|
||||
PRInt32 aNumRowsToRemove,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RebuildConsideringCells(nsTableCellMap& aMap,
|
||||
nsVoidArray* aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aInsert);
|
||||
PRBool aInsert,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRBool CellsSpanOut(nsIPresContext* aPresContext,
|
||||
nsVoidArray& aNewRows);
|
||||
|
@ -327,21 +407,10 @@ protected:
|
|||
PRBool CreateEmptyRow(PRInt32 aRowIndex,
|
||||
PRInt32 aNumCols);
|
||||
|
||||
PRInt32 GetRowSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool aGetEffective,
|
||||
PRBool& aIsZeroRowSpan);
|
||||
|
||||
PRInt32 GetRowSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
PRInt32 aRowIndex,
|
||||
PRBool& aIsZeroRowSpan);
|
||||
|
||||
PRInt32 GetEffectiveColSpan(nsTableCellMap& aMap,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRBool& aIsZeroColSpan);
|
||||
|
||||
PRInt32 GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aNumColsInTable,
|
||||
|
|
|
@ -76,7 +76,8 @@ public:
|
|||
* @param aPixelToTwips - the number of twips in a pixel.
|
||||
* @return - the basis for percent calculations
|
||||
*/
|
||||
virtual nscoord CalcPctAdjTableWidth(const nsHTMLReflowState& aReflowState,
|
||||
virtual nscoord CalcPctAdjTableWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nscoord aAvailWidth,
|
||||
float aPixelToTwips)=0;
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ nsTableCellFrame::GetNextCell() const
|
|||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
return (nsTableCellFrame*)childFrame;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
|
@ -439,7 +439,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext,
|
|||
if ((NS_SUCCEEDED(rv)) && tableFrame) {
|
||||
const nsStyleTableBorder* tableStyle;
|
||||
tableFrame->GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)tableStyle));
|
||||
if (NS_STYLE_BORDER_SEPARATE == tableFrame->GetBorderCollapseStyle()) {
|
||||
if (!tableFrame->IsBorderCollapse()) {
|
||||
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this,
|
||||
aDirtyRect, rect, *myBorder, mStyleContext, skipSides);
|
||||
}
|
||||
|
@ -582,10 +582,9 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex
|
|||
const nsStyleTextReset* textStyle =
|
||||
(const nsStyleTextReset*)mStyleContext->GetStyleData(eStyleStruct_TextReset);
|
||||
/* XXX: remove tableFrame when border-collapse inherits */
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
(void) nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
nsMargin borderPadding;
|
||||
GetCellBorder (borderPadding, tableFrame);
|
||||
GetBorderWidth (p2t, borderPadding);
|
||||
nsMargin padding = nsTableFrame::GetPadding(aReflowState, this);
|
||||
borderPadding += padding;
|
||||
|
||||
|
@ -822,13 +821,13 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
PRBool contentEmptyBeforeReflow = GetContentEmpty();
|
||||
/* XXX: remove tableFrame when border-collapse inherits */
|
||||
nsTableFrame* tableFrame=nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(NS_ERROR_NULL_POINTER);
|
||||
nsTableFrame* tableFrameFirstInFlow = (nsTableFrame*)tableFrame->GetFirstInFlow();
|
||||
|
||||
nsMargin borderPadding = aReflowState.mComputedPadding;
|
||||
nsMargin border;
|
||||
GetCellBorder(border, tableFrame);
|
||||
GetBorderWidth(p2t, border);
|
||||
if ((NS_UNCONSTRAINEDSIZE == availSize.width) || !contentEmptyBeforeReflow) {
|
||||
borderPadding += border;
|
||||
}
|
||||
|
@ -1130,51 +1129,6 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Update the border style to map to the HTML border style
|
||||
*
|
||||
*/
|
||||
void nsTableCellFrame::MapHTMLBorderStyle(nsIPresContext* aPresContext,
|
||||
nsStyleBorder& aBorderStyle,
|
||||
nsTableFrame* aTableFrame)
|
||||
{
|
||||
//adjust the border style based on the table rules attribute
|
||||
|
||||
/* The RULES code below has been disabled because collapsing borders have been disabled
|
||||
and RULES depend on collapsing borders
|
||||
|
||||
const nsStyleTable* tableStyle;
|
||||
aTableFrame->GetStyleData(eStyleStruct_Table, (const nsStyleStruct *&)tableStyle);
|
||||
|
||||
switch (tableStyle->mRules)
|
||||
{
|
||||
case NS_STYLE_TABLE_RULES_NONE:
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
break;
|
||||
|
||||
case NS_STYLE_TABLE_RULES_COLS:
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_TOP, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_BOTTOM, NS_STYLE_BORDER_STYLE_NONE);
|
||||
break;
|
||||
|
||||
case NS_STYLE_TABLE_RULES_ROWS:
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_LEFT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
aBorderStyle.SetBorderStyle(NS_SIDE_RIGHT, NS_STYLE_BORDER_STYLE_NONE);
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing for "GROUPS" or "ALL" or for any illegal value
|
||||
// "GROUPS" will be handled in nsTableFrame::ProcessGroupRules
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
PRBool nsTableCellFrame::ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult)
|
||||
{
|
||||
if (aValue.GetUnit() == eHTMLUnit_Pixel)
|
||||
|
@ -1401,13 +1355,16 @@ nsTableCellFrame::GetNextCellInColumn(nsITableCellLayout **aCellLayout)
|
|||
}
|
||||
|
||||
nsresult
|
||||
NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
||||
NS_NewTableCellFrame(nsIPresShell* aPresShell,
|
||||
PRBool aIsBorderCollapse,
|
||||
nsIFrame** aNewFrame)
|
||||
{
|
||||
NS_PRECONDITION(aNewFrame, "null OUT ptr");
|
||||
if (nsnull == aNewFrame) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
nsTableCellFrame* it = new (aPresShell) nsTableCellFrame;
|
||||
nsTableCellFrame* it = (aIsBorderCollapse) ? new (aPresShell) nsBCTableCellFrame
|
||||
: new (aPresShell) nsTableCellFrame;
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -1415,27 +1372,16 @@ NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----- methods from CellLayoutData ----- */
|
||||
|
||||
void
|
||||
nsTableCellFrame::GetCellBorder(nsMargin& aBorder,
|
||||
nsTableFrame* aTableFrame)
|
||||
nsMargin*
|
||||
nsTableCellFrame::GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const
|
||||
{
|
||||
aBorder.left = aBorder.right = aBorder.top = aBorder.bottom = 0;
|
||||
if (nsnull==aTableFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_STYLE_BORDER_SEPARATE == aTableFrame->GetBorderCollapseStyle()) {
|
||||
const nsStyleBorder* borderData;
|
||||
GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData);
|
||||
borderData->GetBorder(aBorder);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(PR_FALSE, "not implemented");
|
||||
}
|
||||
const nsStyleBorder* borderData;
|
||||
GetStyleData(eStyleStruct_Border, (const nsStyleStruct*&)borderData);
|
||||
borderData->GetBorder(aBorder);
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1502,3 +1448,100 @@ nsTableCellFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const
|
|||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsBCTableCellFrame
|
||||
|
||||
nsBCTableCellFrame::nsBCTableCellFrame()
|
||||
:nsTableCellFrame()
|
||||
{
|
||||
mTopBorder = mRightBorder = mBottomBorder = mLeftBorder = 0;
|
||||
}
|
||||
|
||||
nsBCTableCellFrame::~nsBCTableCellFrame()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBCTableCellFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aType, "null OUT parameter pointer");
|
||||
*aType = nsLayoutAtoms::bcTableCellFrame;
|
||||
NS_ADDREF(*aType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsBCTableCellFrame::GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("BCTableCell"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsBCTableCellFrame::SetBorderWidth(const nsMargin& aBorder)
|
||||
{
|
||||
mTopBorder = aBorder.top;
|
||||
mRightBorder = aBorder.right;
|
||||
mBottomBorder = aBorder.bottom;
|
||||
mLeftBorder = aBorder.left;
|
||||
}
|
||||
|
||||
nsMargin*
|
||||
nsBCTableCellFrame::GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const
|
||||
{
|
||||
aBorder.top = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mTopBorder) : mTopBorder;
|
||||
aBorder.right = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mRightBorder) : mRightBorder;
|
||||
aBorder.bottom = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mBottomBorder): mBottomBorder;
|
||||
aBorder.left = (aPixelsToTwips) ? NSToCoordRound(aPixelsToTwips * mLeftBorder): mLeftBorder;
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsBCTableCellFrame::GetBorderWidth(PRUint8 aSide) const
|
||||
{
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
return (PRUint8)mTopBorder;
|
||||
case NS_SIDE_RIGHT:
|
||||
return (PRUint8)mRightBorder;
|
||||
case NS_SIDE_BOTTOM:
|
||||
return (PRUint8)mBottomBorder;
|
||||
default:
|
||||
return (PRUint8)mLeftBorder;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsBCTableCellFrame::SetBorderWidth(PRUint8 aSide,
|
||||
nscoord aValue)
|
||||
{
|
||||
switch(aSide) {
|
||||
case NS_SIDE_TOP:
|
||||
mTopBorder = aValue;
|
||||
break;
|
||||
case NS_SIDE_RIGHT:
|
||||
mRightBorder = aValue;
|
||||
break;
|
||||
case NS_SIDE_BOTTOM:
|
||||
mBottomBorder = aValue;
|
||||
break;
|
||||
default:
|
||||
mLeftBorder = aValue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHODIMP
|
||||
nsBCTableCellFrame::SizeOf(nsISizeOfHandler* aHandler,
|
||||
PRUint32* aResult) const
|
||||
{
|
||||
if (!aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
PRUint32 sum = sizeof(*this);
|
||||
*aResult = sum;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsTableRowFrame.h" // need to actually include this here to inline GetRowIndex
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIPercentHeightObserver.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
class nsTableFrame;
|
||||
class nsHTMLValue;
|
||||
|
@ -266,6 +267,9 @@ public:
|
|||
|
||||
nsTableCellFrame* GetNextCell() const;
|
||||
|
||||
virtual nsMargin* GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const;
|
||||
|
||||
protected:
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
@ -277,18 +281,11 @@ private:
|
|||
// All these methods are support methods for RecalcLayoutData
|
||||
nsIFrame* GetFrameAt(nsVoidArray* aList, PRInt32 aIndex);
|
||||
|
||||
//XXX: aTableFrame can be removed as soon as border-collapse inherits correctly
|
||||
void GetCellBorder(nsMargin &aBorder, nsTableFrame *aTableFrame);
|
||||
|
||||
protected:
|
||||
|
||||
friend class nsTableRowFrame;
|
||||
void MapBorderPadding(nsIPresContext* aPresContext);
|
||||
|
||||
void MapHTMLBorderStyle(nsIPresContext* aPresContext,
|
||||
nsStyleBorder& aBorderStyle,
|
||||
nsTableFrame* aTableFrame);
|
||||
|
||||
void MapVAlignAttribute(nsIPresContext* aPresContext, nsTableFrame *aTableFrame);
|
||||
void MapHAlignAttribute(nsIPresContext* aPresContext, nsTableFrame *aTableFrame);
|
||||
|
||||
|
@ -421,6 +418,41 @@ inline void nsTableCellFrame::SetLastBlockHeight(nscoord aValue)
|
|||
{
|
||||
mBits.mLastBlockHeight = aValue;
|
||||
}
|
||||
|
||||
// nsBCTableCellFrame
|
||||
class nsBCTableCellFrame : public nsTableCellFrame
|
||||
{
|
||||
public:
|
||||
|
||||
nsBCTableCellFrame();
|
||||
|
||||
~nsBCTableCellFrame();
|
||||
|
||||
NS_IMETHOD GetFrameType(nsIAtom** aType) const;
|
||||
|
||||
virtual nsMargin* GetBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder) const;
|
||||
nscoord GetBorderWidth(PRUint8 aSide) const;
|
||||
|
||||
void SetBorderWidth(const nsMargin& aBorder);
|
||||
void SetBorderWidth(PRUint8 aSide, nscoord aPixelValue);
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const;
|
||||
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
PRUint32 mTopBorder: 8;
|
||||
PRUint32 mRightBorder: 8;
|
||||
PRUint32 mBottomBorder: 8;
|
||||
PRUint32 mLeftBorder: 8;
|
||||
};
|
||||
|
||||
#define IS_TABLE_CELL(frameType)\
|
||||
((nsLayoutAtoms::tableCellFrame == frameType) || (nsLayoutAtoms::bcTableCellFrame == frameType))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -113,7 +113,8 @@ nsStyleCoord nsTableColFrame::GetStyleWidth() const
|
|||
nsStyleCoord styleWidth = position->mWidth;
|
||||
// the following should not be necessary since html.css defines table-col and
|
||||
// :table-col to inherit. However, :table-col is not inheriting properly
|
||||
if (eStyleUnit_Auto == styleWidth.GetUnit()) {
|
||||
if (eStyleUnit_Auto == styleWidth.GetUnit() ||
|
||||
eStyleUnit_Inherit == styleWidth.GetUnit()) {
|
||||
nsIFrame* parent;
|
||||
GetParent(&parent);
|
||||
nsCOMPtr<nsIStyleContext> styleContext;
|
||||
|
@ -305,6 +306,22 @@ nsTableColFrame::Init(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsTableColFrame*
|
||||
nsTableColFrame::GetNextCol() const
|
||||
{
|
||||
nsIFrame* childFrame;
|
||||
GetNextSibling(&childFrame);
|
||||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableColFrame == frameType.get()) {
|
||||
return (nsTableColFrame*)childFrame;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableColFrame::GetFrameType(nsIAtom** aType) const
|
||||
{
|
||||
|
|
|
@ -102,6 +102,8 @@ public:
|
|||
|
||||
void SetColIndex (PRInt32 aColIndex);
|
||||
|
||||
nsTableColFrame* GetNextCol() const;
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
|
@ -164,6 +166,11 @@ public:
|
|||
|
||||
void ResetSizingInfo();
|
||||
|
||||
nscoord GetLeftBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetLeftBorderWidth(nscoord aWidth);
|
||||
nscoord GetRightBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetRightBorderWidth(nscoord aWidth);
|
||||
|
||||
void Dump(PRInt32 aIndent);
|
||||
|
||||
protected:
|
||||
|
@ -172,17 +179,46 @@ protected:
|
|||
~nsTableColFrame();
|
||||
|
||||
// the starting index of the column (starting at 0) that this col object represents //
|
||||
PRInt32 mColIndex;
|
||||
PRUint32 mColIndex: 16;
|
||||
PRUint32 mLeftBorderWidth: 8; // stored as pixels
|
||||
PRUint32 mRightBorderWidth: 8; // stored as pixels
|
||||
// Widths including MIN_CON, DES_CON, FIX_CON, MIN_ADJ, DES_ADJ, FIX_ADJ, PCT, PCT_ADJ, MIN_PRO, FINAL
|
||||
// Widths including MIN_CON, DES_CON, FIX_CON, MIN_ADJ, DES_ADJ, FIX_ADJ, PCT, PCT_ADJ, MIN_PRO, FINAL
|
||||
// XXX these could be stored as pixels and converted to twips for a savings of 10 x 2 bytes.
|
||||
nscoord mWidths[NUM_WIDTHS];
|
||||
};
|
||||
|
||||
inline PRInt32 nsTableColFrame::GetColIndex() const
|
||||
{ return mColIndex; }
|
||||
{
|
||||
return mColIndex;
|
||||
}
|
||||
|
||||
inline void nsTableColFrame::SetColIndex (PRInt32 aColIndex)
|
||||
{ mColIndex = aColIndex; }
|
||||
{
|
||||
mColIndex = aColIndex;
|
||||
}
|
||||
|
||||
inline nscoord nsTableColFrame::GetLeftBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mLeftBorderWidth) : mLeftBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableColFrame::SetLeftBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mLeftBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
inline nscoord nsTableColFrame::GetRightBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mRightBorderWidth) : mRightBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableColFrame::SetRightBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mRightBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -250,29 +250,6 @@ nsTableColGroupFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFrame* kidFrame = aChildList;
|
||||
while (kidFrame) {
|
||||
nsIAtom* kidType;
|
||||
kidFrame->GetFrameType(&kidType);
|
||||
if (nsLayoutAtoms::tableColFrame == kidType) {
|
||||
// Set the preliminary values for the column frame
|
||||
PRInt32 span = ((nsTableColFrame*)kidFrame)->GetSpan();
|
||||
if (span > 1) {
|
||||
nsTableColFrame* firstSpannedCol;
|
||||
tableFrame->CreateAnonymousColFrames(*aPresContext, *this, span - 1, eColAnonymousCol,
|
||||
PR_FALSE, (nsTableColFrame*)kidFrame, (nsIFrame **)&firstSpannedCol);
|
||||
nsIFrame* spanner = kidFrame;
|
||||
kidFrame->GetNextSibling(&kidFrame); // need to do this before we insert the new frames
|
||||
nsFrameList newChildren(aChildList); // used as a convience to hook up siblings
|
||||
newChildren.InsertFrames(this, (nsTableColFrame*)spanner, (nsIFrame *)firstSpannedCol);
|
||||
NS_RELEASE(kidType);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(kidType);
|
||||
kidFrame->GetNextSibling(&kidFrame);
|
||||
}
|
||||
|
||||
mFrames.AppendFrames(this, aChildList);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -53,7 +53,6 @@ class nsTableColFrame;
|
|||
class nsTableRowGroupFrame;
|
||||
class nsTableRowFrame;
|
||||
class nsTableColGroupFrame;
|
||||
class nsTableBorderCollapser;
|
||||
class nsITableLayoutStrategy;
|
||||
class nsHTMLValue;
|
||||
|
||||
|
@ -208,6 +207,8 @@ public:
|
|||
nsIAtom* aPropertyName,
|
||||
PRBool aCreateIfNecessary = PR_FALSE);
|
||||
|
||||
static float GetTwipsToPixels(nsIPresContext* aPresContext);
|
||||
|
||||
static nscoord RoundToPixel(nscoord aValue,
|
||||
float aPixelToTwips,
|
||||
nsPixelRound aRound= eAlwaysRoundUp);
|
||||
|
@ -249,7 +250,13 @@ public:
|
|||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
nsMargin GetBorderPadding(const nsHTMLReflowState& aReflowState) const;
|
||||
// Get the offset from the border box to the area where the row groups fit
|
||||
nsMargin GetChildAreaOffset(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState* aReflowState) const;
|
||||
|
||||
// Get the offset from the border box to the area where the content fits
|
||||
nsMargin GetContentAreaOffset(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState* aReflowState) const;
|
||||
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
// TODO: today, this depends on display types. This should be changed to rely
|
||||
|
@ -297,6 +304,17 @@ public:
|
|||
nsFramePaintLayer aWhichLayer,
|
||||
PRUint32 aFlags = 0);
|
||||
|
||||
nsMargin* GetBCBorder(nsIPresContext& aPresContext,
|
||||
PRBool aInnerBorderOnly,
|
||||
nsMargin& aBorder) const;
|
||||
|
||||
void SetBCDamageArea(nsIPresContext& aPresContext,
|
||||
const nsRect& aValue);
|
||||
|
||||
void PaintBCBorders(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect);
|
||||
|
||||
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
|
||||
const nsPoint& aPoint,
|
||||
nsFramePaintLayer aWhichLayer,
|
||||
|
@ -371,15 +389,12 @@ public:
|
|||
/** set the width of the column at aColIndex to aWidth */
|
||||
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
|
||||
|
||||
/** helper to get the border collapse style value */
|
||||
virtual PRUint8 GetBorderCollapseStyle();
|
||||
|
||||
/** helper to get the cell spacing X style value */
|
||||
virtual nscoord GetCellSpacingX();
|
||||
|
||||
/** helper to get the cell spacing Y style value */
|
||||
virtual nscoord GetCellSpacingY();
|
||||
|
||||
|
||||
/** return the row span of a cell, taking into account row span magic at the bottom
|
||||
* of a table. The row span equals the number of rows spanned by aCell starting at
|
||||
* aStartRowIndex, and can be smaller if aStartRowIndex is greater than the row
|
||||
|
@ -440,9 +455,9 @@ public:
|
|||
/** empty the column frame cache */
|
||||
void ClearColCache();
|
||||
|
||||
virtual PRInt32 AppendCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
virtual void AppendCell(nsIPresContext& aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex);
|
||||
|
||||
virtual void InsertCells(nsIPresContext& aPresContext,
|
||||
nsVoidArray& aCellFrames,
|
||||
|
@ -522,6 +537,9 @@ protected:
|
|||
/** destructor, responsible for mColumnLayoutData */
|
||||
virtual ~nsTableFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
|
@ -619,7 +637,8 @@ protected:
|
|||
nsIFrame* aKidFrame,
|
||||
nscoord aDeltaY);
|
||||
|
||||
nsresult RecoverState(nsTableReflowState& aReflowState,
|
||||
nsresult RecoverState(nsIPresContext& aPresContext,
|
||||
nsTableReflowState& aReflowState,
|
||||
nsIFrame* aKidFrame);
|
||||
|
||||
NS_METHOD CollapseRowGroupIfNecessary(nsIPresContext* aPresContext,
|
||||
|
@ -646,10 +665,11 @@ public:
|
|||
|
||||
// calculate the computed height of aFrame including its border and padding given
|
||||
// its reflow state.
|
||||
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
|
||||
nscoord CalcBorderBoxHeight(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState);
|
||||
// calculate the minimum width to layout aFrame and its desired width
|
||||
// including border and padding given its reflow state and column width information
|
||||
void CalcMinAndPreferredWidths(nsIPresContext* aPresContextconst,
|
||||
void CalcMinAndPreferredWidths(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
PRBool aCalcPrefWidthIfAutoWithPctCol,
|
||||
nscoord& aMinWidth,
|
||||
|
@ -657,7 +677,8 @@ public:
|
|||
protected:
|
||||
|
||||
// calcs the width of the table according to the computed widths of each column.
|
||||
virtual PRInt32 CalcDesiredWidth(const nsHTMLReflowState& aReflowState);
|
||||
virtual PRInt32 CalcDesiredWidth(nsIPresContext& aPresContext,
|
||||
const nsHTMLReflowState& aReflowState);
|
||||
|
||||
// return the desired height of this table accounting for the current
|
||||
// reflow state, and for the table attributes and parent
|
||||
|
@ -699,7 +720,7 @@ public:
|
|||
PRUint32& aNumRowGroups,
|
||||
nsIFrame** aFirstBody = nsnull,
|
||||
nsTableRowGroupFrame** aHead = nsnull,
|
||||
nsTableRowGroupFrame** aFoot = nsnull);
|
||||
nsTableRowGroupFrame** aFoot = nsnull) const;
|
||||
|
||||
// Returns PR_TRUE if there are any cells above the row at
|
||||
// aRowIndex and spanning into the row at aRowIndex
|
||||
|
@ -735,9 +756,6 @@ protected:
|
|||
PRBool DidResizeReflow() const;
|
||||
void SetResizeReflow(PRBool aValue);
|
||||
|
||||
/** Support methods for DidSetStyleContext */
|
||||
void MapBorderMarginPadding(nsIPresContext* aPresContext);
|
||||
void MapHTMLBorderStyle(nsStyleBorder& aBorderStyle, nscoord aBorderWidth);
|
||||
PRBool ConvertToPixelValue(nsHTMLValue& aValue,
|
||||
PRInt32 aDefault,
|
||||
PRInt32& aResult);
|
||||
|
@ -749,6 +767,11 @@ public:
|
|||
PRBool NeedStrategyBalance() const;
|
||||
void SetNeedStrategyBalance(PRBool aValue);
|
||||
|
||||
PRBool IsBorderCollapse() const;
|
||||
|
||||
PRBool NeedToCalcBCBorders() const;
|
||||
void SetNeedToCalcBCBorders(PRBool aValue);
|
||||
|
||||
/** Get the cell map for this table frame. It is not always mCellMap.
|
||||
* Only the firstInFlow has a legit cell map
|
||||
*/
|
||||
|
@ -763,9 +786,6 @@ public:
|
|||
PRInt32 aRowIndex,
|
||||
PRInt32 anAdjustment);
|
||||
|
||||
// Return PR_TRUE if rules=groups is set for the table content
|
||||
PRBool HasGroupRules() const;
|
||||
|
||||
// Remove cell borders which aren't bordering row and/or col groups
|
||||
void ProcessGroupRules(nsIPresContext* aPresContext);
|
||||
|
||||
|
@ -775,10 +795,16 @@ public:
|
|||
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
|
||||
*/
|
||||
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
|
||||
nsIAtom* aFrameTypeIn = nsnull);
|
||||
nsIAtom* aFrameTypeIn = nsnull) const;
|
||||
|
||||
protected:
|
||||
|
||||
void SetBorderCollapse(PRBool aValue);
|
||||
|
||||
void CalcBCBorders(nsIPresContext& aPresContext);
|
||||
|
||||
void ExpandBCDamageArea(nsRect& aRect) const;
|
||||
|
||||
PRBool HadInitialReflow() const;
|
||||
void SetHadInitialReflow(PRBool aValue);
|
||||
|
||||
|
@ -809,8 +835,8 @@ public: /* ----- Cell Map public methods ----- */
|
|||
|
||||
/** returns the number of columns in this table after redundant columns have been removed
|
||||
*/
|
||||
virtual PRInt32 GetEffectiveColCount();
|
||||
virtual PRInt32 GetColCount();
|
||||
virtual PRInt32 GetEffectiveColCount() const;
|
||||
virtual PRInt32 GetColCount() const;
|
||||
|
||||
/** return the column frame at colIndex.
|
||||
* returns nsnull if the col frame has not yet been allocated, or if aColIndex is out of range
|
||||
|
@ -886,6 +912,7 @@ protected:
|
|||
unsigned mHasPctCol:1; // does any cell or col have a pct width
|
||||
unsigned mCellSpansPctCol:1; // does any cell span a col with a pct width (or containing a cell with a pct width)
|
||||
unsigned mDidResizeReflow:1; // did a resize reflow happen (indicating pass 2)
|
||||
unsigned mIsBorderCollapse:1; // border collapsing model vs. separate model
|
||||
// true if a descendant was reflowed normally since the last time we reflowed.
|
||||
// We will likely need a timeout reflow (targeted either at us or below)
|
||||
unsigned mDescendantReflowedNotTimeout:1;
|
||||
|
@ -896,7 +923,8 @@ protected:
|
|||
unsigned mRowInserted:1;
|
||||
unsigned mNeedSpecialReflow:1;
|
||||
unsigned mNeedToInitiateSpecialReflow:1;
|
||||
unsigned : 20; // unused
|
||||
unsigned mNeedToCalcBCBorders:1;
|
||||
unsigned : 18; // unused
|
||||
} mBits;
|
||||
|
||||
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
|
||||
|
@ -1054,8 +1082,26 @@ inline void nsTableFrame::SetPreferredWidth(nscoord aWidth)
|
|||
mPreferredWidth = aWidth;
|
||||
}
|
||||
|
||||
inline PRBool nsTableFrame::IsBorderCollapse() const
|
||||
{
|
||||
return (PRBool)mBits.mIsBorderCollapse;
|
||||
}
|
||||
|
||||
inline void nsTableFrame::SetBorderCollapse(PRBool aValue)
|
||||
{
|
||||
mBits.mIsBorderCollapse = aValue;
|
||||
}
|
||||
|
||||
inline PRBool nsTableFrame::NeedToCalcBCBorders() const
|
||||
{
|
||||
return (PRBool)mBits.mNeedToCalcBCBorders;
|
||||
}
|
||||
|
||||
inline void nsTableFrame::SetNeedToCalcBCBorders(PRBool aValue)
|
||||
{
|
||||
mBits.mNeedToCalcBCBorders = (unsigned)aValue;
|
||||
}
|
||||
|
||||
|
||||
enum nsTableIteration {
|
||||
eTableLTR = 0,
|
||||
eTableRTL = 1,
|
||||
|
@ -1085,6 +1131,23 @@ protected:
|
|||
PRInt32 mCount;
|
||||
};
|
||||
|
||||
#define ABORT0() \
|
||||
{NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
|
||||
return;}
|
||||
|
||||
#define ABORT1(aReturn) \
|
||||
{NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
|
||||
return aReturn;}
|
||||
|
||||
#define GET_PIXELS_TO_TWIPS(presContext,var) \
|
||||
float var; \
|
||||
(presContext)->GetScaledPixelsToTwips(&var);
|
||||
|
||||
#define GET_TWIPS_TO_PIXELS(presContext,var) \
|
||||
float var; \
|
||||
(presContext)->GetScaledPixelsToTwips(&var); \
|
||||
var = 1.0f / var;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -232,7 +232,14 @@ nsTableOuterFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
}
|
||||
else {
|
||||
mFrames.SetFrames(aChildList);
|
||||
mInnerTableFrame = aChildList;
|
||||
mInnerTableFrame = nsnull;
|
||||
if (aChildList) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aChildList->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableFrame == fType.get()) {
|
||||
mInnerTableFrame = (nsTableFrame*)aChildList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -466,21 +473,46 @@ FixAutoMargins(nscoord aAvailWidth,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableOuterFrame::InitChildReflowState(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState& aReflowState)
|
||||
|
||||
{
|
||||
nsMargin collapseBorder;
|
||||
nsMargin collapsePadding(0,0,0,0);
|
||||
nsMargin* pCollapseBorder = nsnull;
|
||||
nsMargin* pCollapsePadding = nsnull;
|
||||
if ((aReflowState.frame == mInnerTableFrame) && (mInnerTableFrame->IsBorderCollapse())) {
|
||||
if (mInnerTableFrame->NeedToCalcBCBorders()) {
|
||||
mInnerTableFrame->CalcBCBorders(aPresContext);
|
||||
}
|
||||
pCollapseBorder = mInnerTableFrame->GetBCBorder(aPresContext, PR_FALSE, collapseBorder);
|
||||
pCollapsePadding = &collapsePadding;
|
||||
}
|
||||
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, pCollapsePadding);
|
||||
}
|
||||
|
||||
// get the margin and padding data. nsHTMLReflowState doesn't handle the
|
||||
// case of auto margins
|
||||
void
|
||||
GetMarginPadding(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aOuterRS,
|
||||
nsIFrame* aChildFrame,
|
||||
nsMargin& aMargin,
|
||||
nsMargin& aMarginNoAuto,
|
||||
nsMargin& aPadding)
|
||||
nsTableOuterFrame::GetMarginPadding(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aOuterRS,
|
||||
nsIFrame* aChildFrame,
|
||||
nsMargin& aMargin,
|
||||
nsMargin& aMarginNoAuto,
|
||||
nsMargin& aPadding)
|
||||
{
|
||||
if (!aPresContext) ABORT0();
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
// construct a reflow state to compute margin and padding. Auto margins
|
||||
// will not be computed at this time.
|
||||
|
||||
// create an init the child reflow state
|
||||
nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame,
|
||||
nsSize(aOuterRS.availableWidth, aOuterRS.availableHeight),
|
||||
eReflowReason_Resize);
|
||||
eReflowReason_Resize, PR_FALSE);
|
||||
InitChildReflowState(*aPresContext, childRS);
|
||||
|
||||
nsRect childRect;
|
||||
aChildFrame->GetRect(childRect);
|
||||
FixAutoMargins(aOuterRS.availableWidth, childRect.width, childRS);
|
||||
|
@ -931,6 +963,7 @@ nsTableOuterFrame::OuterReflowChild(nsIPresContext* aPresContext,
|
|||
nsReflowReason aReflowReason,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
if (!aPresContext) ABORT1(NS_ERROR_NULL_POINTER);
|
||||
aMargin = aPadding = nsMargin(0,0,0,0);
|
||||
|
||||
nscoord availWidth = GetChildAvailWidth(aPresContext, aChildFrame, aOuterRS,
|
||||
|
@ -946,9 +979,10 @@ nsTableOuterFrame::OuterReflowChild(nsIPresContext* aPresContext,
|
|||
availHeight = nsTableFrame::RoundToPixel(availHeight, p2t, eAlwaysRoundDown);
|
||||
}
|
||||
|
||||
nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame,
|
||||
nsSize(availWidth, availHeight));
|
||||
childRS.reason = aReflowReason;
|
||||
// create and init the child reflow state
|
||||
nsHTMLReflowState childRS(aPresContext, aOuterRS, aChildFrame, nsSize(availWidth, availHeight),
|
||||
aReflowReason);
|
||||
InitChildReflowState(*aPresContext, childRS);
|
||||
childRS.mPercentHeightObserver = nsnull; // the observer is for non table related frames inside cells
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ class nsReflowTimer;
|
|||
#endif
|
||||
|
||||
struct nsStyleTable;
|
||||
class nsTableFrame;
|
||||
|
||||
class nsTableCaptionFrame : public nsBlockFrame
|
||||
{
|
||||
|
@ -201,6 +202,9 @@ protected:
|
|||
nsTableOuterFrame();
|
||||
virtual ~nsTableOuterFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
/** Always returns 0, since the outer table frame has no border of its own
|
||||
* The inner table frame can answer this question in a meaningful way.
|
||||
* @see nsHTMLContainerFrame::GetSkipSides */
|
||||
|
@ -362,11 +366,17 @@ protected:
|
|||
PRBool aInnerChanged,
|
||||
PRBool aCaptionChanged);
|
||||
|
||||
void GetMarginPadding(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aOuterRS,
|
||||
nsIFrame* aChildFrame,
|
||||
nsMargin& aMargin,
|
||||
nsMargin& aMarginNoAuto,
|
||||
nsMargin& aPadding);
|
||||
|
||||
private:
|
||||
// used to keep track of this frame's children. They are redundant with mFrames, but more convient
|
||||
nsIFrame* mInnerTableFrame;
|
||||
nsIFrame* mCaptionFrame;
|
||||
nsTableFrame* mInnerTableFrame;
|
||||
nsIFrame* mCaptionFrame;
|
||||
|
||||
// used to track caption max element size
|
||||
PRInt32 mMinCaptionWidth;
|
||||
|
|
|
@ -68,11 +68,6 @@ struct nsTableCellReflowState : public nsHTMLReflowState
|
|||
const nsSize& aAvailableSpace,
|
||||
nsReflowReason aReason);
|
||||
|
||||
nsTableCellReflowState(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aParentReflowState,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailableSpace);
|
||||
|
||||
void FixUp(const nsSize& aAvailSpace);
|
||||
};
|
||||
|
||||
|
@ -83,16 +78,43 @@ nsTableCellReflowState::nsTableCellReflowState(nsIPresContext* aPresCon
|
|||
nsReflowReason aReason)
|
||||
:nsHTMLReflowState(aPresContext, aParentRS, aFrame, aAvailSpace, aReason)
|
||||
{
|
||||
FixUp(aAvailSpace);
|
||||
}
|
||||
|
||||
nsTableCellReflowState::nsTableCellReflowState(nsIPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aParentRS,
|
||||
nsIFrame* aFrame,
|
||||
const nsSize& aAvailSpace)
|
||||
:nsHTMLReflowState(aPresContext, aParentRS, aFrame, aAvailSpace)
|
||||
void nsTableCellReflowState::FixUp(const nsSize& aAvailSpace)
|
||||
{
|
||||
FixUp(aAvailSpace);
|
||||
// fix the mComputed values during a pass 2 reflow since the cell can be a percentage base
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.width) {
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedWidth) {
|
||||
mComputedWidth = aAvailSpace.width - mComputedBorderPadding.left - mComputedBorderPadding.right;
|
||||
mComputedWidth = PR_MAX(0, mComputedWidth);
|
||||
}
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedHeight) {
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.height) {
|
||||
mComputedHeight = aAvailSpace.height - mComputedBorderPadding.top - mComputedBorderPadding.bottom;
|
||||
mComputedHeight = PR_MAX(0, mComputedHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableRowFrame::InitChildReflowState(nsIPresContext& aPresContext,
|
||||
const nsSize& aAvailSize,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsTableCellReflowState& aReflowState)
|
||||
{
|
||||
nsMargin collapseBorder;
|
||||
nsMargin* pCollapseBorder = nsnull;
|
||||
if (aBorderCollapse) {
|
||||
// we only reflow cells, so don't need to check frame type
|
||||
nsBCTableCellFrame* bcCellFrame = (nsBCTableCellFrame*)aReflowState.frame;
|
||||
if (bcCellFrame) {
|
||||
pCollapseBorder = bcCellFrame->GetBorderWidth(aPixelsToTwips, collapseBorder);
|
||||
}
|
||||
}
|
||||
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder);
|
||||
aReflowState.FixUp(aAvailSize);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -132,23 +154,6 @@ nsTableRowFrame::SetPctHeight(float aPctValue,
|
|||
}
|
||||
}
|
||||
|
||||
void nsTableCellReflowState::FixUp(const nsSize& aAvailSpace)
|
||||
{
|
||||
// fix the mComputed values during a pass 2 reflow since the cell can be a percentage base
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.width) {
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedWidth) {
|
||||
mComputedWidth = aAvailSpace.width - mComputedBorderPadding.left - mComputedBorderPadding.right;
|
||||
mComputedWidth = PR_MAX(0, mComputedWidth);
|
||||
}
|
||||
if (NS_UNCONSTRAINEDSIZE != mComputedHeight) {
|
||||
if (NS_UNCONSTRAINEDSIZE != aAvailSpace.height) {
|
||||
mComputedHeight = aAvailSpace.height - mComputedBorderPadding.top - mComputedBorderPadding.bottom;
|
||||
mComputedHeight = PR_MAX(0, mComputedHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 'old' is old cached cell's desired size
|
||||
// 'new' is new cell's size including style constraints
|
||||
static PRBool
|
||||
|
@ -217,7 +222,7 @@ nsTableRowFrame::SetInitialChildList(nsIPresContext* aPresContext,
|
|||
kidFrame->GetNextSibling(&kidFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
kidFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
if (((nsTableCellFrame*)kidFrame)->GetRowSpan() > 1) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
|
@ -241,7 +246,7 @@ nsTableRowFrame::AppendFrames(nsIPresContext* aPresContext,
|
|||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
// Add the cell to the cell map
|
||||
tableFrame->AppendCell(*aPresContext, (nsTableCellFrame&)*childFrame, GetRowIndex());
|
||||
// XXX this could be optimized with some effort
|
||||
|
@ -272,12 +277,13 @@ nsTableRowFrame::InsertFrames(nsIPresContext* aPresContext,
|
|||
nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
|
||||
// gather the new frames (only those which are cells) into an array
|
||||
nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(aPresContext, this, aPrevFrame, nsLayoutAtoms::tableCellFrame);
|
||||
nsIAtom* cellFrameType = (tableFrame->IsBorderCollapse()) ? nsLayoutAtoms::bcTableCellFrame : nsLayoutAtoms::tableCellFrame;
|
||||
nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(aPresContext, this, aPrevFrame, cellFrameType);
|
||||
nsVoidArray cellChildren;
|
||||
for (nsIFrame* childFrame = aFrameList; childFrame; childFrame->GetNextSibling(&childFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
cellChildren.AppendElement(childFrame);
|
||||
// XXX this could be optimized with some effort
|
||||
tableFrame->SetNeedStrategyInit(PR_TRUE);
|
||||
|
@ -315,7 +321,7 @@ nsTableRowFrame::RemoveFrame(nsIPresContext* aPresContext,
|
|||
if (tableFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aOldFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aOldFrame;
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
|
@ -372,7 +378,7 @@ nsTableRowFrame::GetFirstCell()
|
|||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
return (nsTableCellFrame*)childFrame;
|
||||
}
|
||||
childFrame->GetNextSibling(&childFrame);
|
||||
|
@ -398,7 +404,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
|
|||
while (childFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
childFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)childFrame;
|
||||
nscoord cellHeight = mRect.height + GetHeightOfRowsSpannedBelowFirst(*cellFrame, *tableFrame);
|
||||
|
||||
|
@ -534,7 +540,7 @@ nsTableRowFrame::CalcHeight(const nsHTMLReflowState& aReflowState)
|
|||
for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
kidFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nscoord availWidth = ((nsTableCellFrame *)kidFrame)->GetPriorAvailWidth();
|
||||
nsSize desSize = ((nsTableCellFrame *)kidFrame)->GetDesiredSize();
|
||||
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableHeight) && !mPrevInFlow) {
|
||||
|
@ -888,28 +894,29 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
aStatus = NS_FRAME_COMPLETE;
|
||||
if (!mFrames.FirstChild()) return NS_OK;
|
||||
|
||||
nsTableFrame* tableFrame = &aTableFrame;
|
||||
if (!tableFrame) return NS_ERROR_NULL_POINTER;
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
PRBool borderCollapse = (((nsTableFrame*)aTableFrame.GetFirstInFlow())->IsBorderCollapse());
|
||||
|
||||
nsIFrame* tablePrevInFlow;
|
||||
tableFrame->GetPrevInFlow(&tablePrevInFlow);
|
||||
aTableFrame.GetPrevInFlow(&tablePrevInFlow);
|
||||
PRBool isPaginated;
|
||||
aPresContext->IsPaginated(&isPaginated);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nscoord cellSpacingX = tableFrame->GetCellSpacingX();
|
||||
nscoord cellSpacingX = aTableFrame.GetCellSpacingX();
|
||||
PRInt32 cellColSpan = 1; // must be defined here so it's set properly for non-cell kids
|
||||
|
||||
nsTableIteration dir = (aReflowState.availableWidth == NS_UNCONSTRAINEDSIZE)
|
||||
? eTableLTR : eTableDIR;
|
||||
nsTableIterator iter(aPresContext, *this, dir);
|
||||
// remember the col index of the previous cell to handle rowspans into this row
|
||||
PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : tableFrame->GetColCount();
|
||||
PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : aTableFrame.GetColCount();
|
||||
PRInt32 prevColIndex = firstPrevColIndex;
|
||||
nscoord x = 0; // running total of children x offset
|
||||
|
||||
nsTableFrame* tableFirstInFlow = (nsTableFrame*)tableFrame->GetFirstInFlow();
|
||||
PRBool isAutoLayout = tableFrame->IsAutoLayout();
|
||||
nsTableFrame* tableFirstInFlow = (nsTableFrame*)aTableFrame.GetFirstInFlow();
|
||||
PRBool isAutoLayout = aTableFrame.IsAutoLayout();
|
||||
PRBool needToNotifyTable = PR_TRUE;
|
||||
nscoord paginatedHeight = 0;
|
||||
// If the incremental reflow command is a StyleChanged reflow and
|
||||
|
@ -945,7 +952,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
doReflowChild = PR_FALSE;
|
||||
}
|
||||
if (aReflowState.mFlags.mSpecialHeightReflow) {
|
||||
if (!isPaginated && (nsLayoutAtoms::tableCellFrame == frameType.get() &&
|
||||
if (!isPaginated && (IS_TABLE_CELL(frameType.get()) &&
|
||||
!((nsTableCellFrame*)kidFrame)->NeedSpecialReflow())) {
|
||||
kidFrame = iter.Next();
|
||||
continue;
|
||||
|
@ -954,22 +961,22 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
|
||||
// Reflow the child frame
|
||||
if (doReflowChild) {
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
if (IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)kidFrame;
|
||||
PRInt32 cellColIndex;
|
||||
cellFrame->GetColIndex(cellColIndex);
|
||||
cellColSpan = tableFrame->GetEffectiveColSpan(*cellFrame);
|
||||
cellColSpan = aTableFrame.GetEffectiveColSpan(*cellFrame);
|
||||
|
||||
x += cellSpacingX;
|
||||
// If the adjacent cell is in a prior row (because of a rowspan) add in the space
|
||||
if ((iter.IsLeftToRight() && (prevColIndex != (cellColIndex - 1))) ||
|
||||
(!iter.IsLeftToRight() && (prevColIndex != cellColIndex + cellColSpan))) {
|
||||
x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, *tableFrame,
|
||||
x += GetSpaceBetween(prevColIndex, cellColIndex, cellColSpan, aTableFrame,
|
||||
cellSpacingX, iter.IsLeftToRight());
|
||||
}
|
||||
// Calculate the available width for the table cell using the known column widths
|
||||
nscoord availColWidth, availCellWidth;
|
||||
CalcAvailWidth(*tableFrame, GetComputedWidth(aReflowState, *tableFrame),
|
||||
CalcAvailWidth(aTableFrame, GetComputedWidth(aReflowState, aTableFrame),
|
||||
*cellFrame, cellSpacingX, availColWidth, availCellWidth);
|
||||
if (0 == availColWidth) availColWidth = NS_UNCONSTRAINEDSIZE;
|
||||
if (0 == availCellWidth) availCellWidth = NS_UNCONSTRAINEDSIZE;
|
||||
|
@ -1032,6 +1039,8 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
// Reflow the child
|
||||
nsTableCellReflowState kidReflowState(aPresContext, aReflowState,
|
||||
kidFrame, kidAvailSize, reason);
|
||||
InitChildReflowState(*aPresContext, kidAvailSize, borderCollapse, p2t, kidReflowState);
|
||||
|
||||
nsReflowStatus status;
|
||||
rv = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState,
|
||||
x, 0, 0, status);
|
||||
|
@ -1052,7 +1061,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
|
||||
// allow the table to determine if/how the table needs to be rebalanced
|
||||
if (cellToWatch && needToNotifyTable) {
|
||||
needToNotifyTable = !tableFrame->CellChangedWidth(*cellFrame, oldMaxWidth, oldMaxElemWidth);
|
||||
needToNotifyTable = !aTableFrame.CellChangedWidth(*cellFrame, oldMaxWidth, oldMaxElemWidth);
|
||||
}
|
||||
|
||||
// If any of the cells are not complete, then we're not complete
|
||||
|
@ -1081,10 +1090,10 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
// height may have changed, adjust descent to absorb any excess difference
|
||||
nscoord ascent = cellFrame->GetDesiredAscent();
|
||||
nscoord descent = desiredSize.height - ascent;
|
||||
UpdateHeight(desiredSize.height, ascent, descent, tableFrame, cellFrame);
|
||||
UpdateHeight(desiredSize.height, ascent, descent, &aTableFrame, cellFrame);
|
||||
}
|
||||
else {
|
||||
PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
|
||||
PRInt32 rowSpan = aTableFrame.GetEffectiveRowSpan((nsTableCellFrame&)*kidFrame);
|
||||
if ((1 == rowSpan) && (desiredSize.height > paginatedHeight)) {
|
||||
paginatedHeight = desiredSize.height;
|
||||
SetContentHeight(paginatedHeight);
|
||||
|
@ -1102,13 +1111,14 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
else {// it's an unknown frame type, give it a generic reflow and ignore the results
|
||||
nsTableCellReflowState kidReflowState(aPresContext, aReflowState,
|
||||
kidFrame, nsSize(0,0), eReflowReason_Resize);
|
||||
InitChildReflowState(*aPresContext, nsSize(0,0), PR_FALSE, p2t, kidReflowState);
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
nsReflowStatus status;
|
||||
ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState, 0, 0, 0, status);
|
||||
kidFrame->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
|
||||
}
|
||||
}
|
||||
else if (nsLayoutAtoms::tableCellFrame == frameType.get()) {
|
||||
else if (IS_TABLE_CELL(frameType.get())) {
|
||||
// we need to account for the cell's width even if it isn't reflowed
|
||||
nsRect rect;
|
||||
kidFrame->GetRect(rect);
|
||||
|
@ -1244,7 +1254,10 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// update its maximum width.
|
||||
nsHTMLReflowMetrics cellMet(&kidMaxElementSize, isAutoLayout ?
|
||||
NS_REFLOW_CALC_MAX_WIDTH : 0);
|
||||
nsTableCellReflowState kidRS(aPresContext, aReflowState, aNextFrame, cellAvailSize);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
nsTableCellReflowState kidRS(aPresContext, aReflowState, aNextFrame, cellAvailSize,
|
||||
aReflowState.reason);
|
||||
InitChildReflowState(*aPresContext, cellAvailSize, aTableFrame.IsBorderCollapse(), p2t, kidRS);
|
||||
|
||||
// Remember the current desired size, we'll need it later
|
||||
nscoord oldCellMinWidth = cellFrame->GetPass1MaxElementWidth();
|
||||
|
@ -1492,13 +1505,20 @@ nsTableRowFrame::ReflowCellFrame(nsIPresContext* aPresContext,
|
|||
nscoord aAvailableHeight,
|
||||
nsReflowStatus& aStatus)
|
||||
{
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(0);
|
||||
|
||||
// Reflow the cell frame with the specified height. Use the existing width
|
||||
nsSize cellSize;
|
||||
aCellFrame->GetSize(cellSize);
|
||||
|
||||
nsSize availSize(cellSize.width, aAvailableHeight);
|
||||
PRBool borderCollapse = ((nsTableFrame*)tableFrame->GetFirstInFlow())->IsBorderCollapse();
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
nsTableCellReflowState cellReflowState(aPresContext, aReflowState, aCellFrame, availSize,
|
||||
eReflowReason_Resize);
|
||||
InitChildReflowState(*aPresContext, availSize, borderCollapse, p2t, cellReflowState);
|
||||
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
|
||||
|
@ -1534,7 +1554,7 @@ nsTableRowFrame::InsertCellFrame(nsTableCellFrame* aFrame,
|
|||
for (nsIFrame* child = mFrames.FirstChild(); child; child->GetNextSibling(&child)) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
child->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableCellFrame != frameType.get()) {
|
||||
if (!IS_TABLE_CELL(frameType.get())) {
|
||||
nsTableCellFrame* cellFrame = (nsTableCellFrame*)child;
|
||||
PRInt32 colIndex;
|
||||
cellFrame->GetColIndex(colIndex);
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
class nsTableFrame;
|
||||
class nsTableCellFrame;
|
||||
struct nsTableCellReflowState;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
class nsReflowTimer;
|
||||
|
@ -240,6 +241,12 @@ public:
|
|||
nscoord GetUnpaginatedHeight(nsIPresContext* aPresContext);
|
||||
void SetUnpaginatedHeight(nsIPresContext* aPresContext, nscoord aValue);
|
||||
|
||||
nscoord GetTopBCBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetTopBCBorderWidth(nscoord aWidth);
|
||||
nscoord GetBottomBCBorderWidth(float* aPixelsToTwips = nsnull);
|
||||
void SetBottomBCBorderWidth(nscoord aWidth);
|
||||
nsMargin* GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder);
|
||||
protected:
|
||||
|
||||
/** protected constructor.
|
||||
|
@ -247,6 +254,12 @@ protected:
|
|||
*/
|
||||
nsTableRowFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
const nsSize& aAvailSize,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsTableCellReflowState& aReflowState);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
|
@ -315,6 +328,10 @@ private:
|
|||
nscoord mMaxCellAscent; // does include cells with rowspan > 1
|
||||
nscoord mMaxCellDescent; // does *not* include cells with rowspan > 1
|
||||
|
||||
// border widths in pixels in the collapsing border model
|
||||
unsigned mTopBorderWidth:8;
|
||||
unsigned mBottomBorderWidth:8;
|
||||
|
||||
#ifdef DEBUG_TABLE_REFLOW_TIMING
|
||||
public:
|
||||
nsReflowTimer* mTimer;
|
||||
|
@ -421,4 +438,37 @@ inline void nsTableRowFrame::SetHasUnpaginatedHeight(PRBool aValue)
|
|||
}
|
||||
}
|
||||
|
||||
inline nscoord nsTableRowFrame::GetTopBCBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mTopBorderWidth) : mTopBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::SetTopBCBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mTopBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
inline nscoord nsTableRowFrame::GetBottomBCBorderWidth(float* aPixelsToTwips)
|
||||
{
|
||||
nscoord width = (aPixelsToTwips) ? NSToCoordRound(*aPixelsToTwips * mBottomBorderWidth) : mBottomBorderWidth;
|
||||
return width;
|
||||
}
|
||||
|
||||
inline void nsTableRowFrame::SetBottomBCBorderWidth(nscoord aWidth)
|
||||
{
|
||||
mBottomBorderWidth = aWidth;
|
||||
}
|
||||
|
||||
inline nsMargin* nsTableRowFrame::GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder)
|
||||
{
|
||||
aBorder.left = aBorder.right = 0;
|
||||
|
||||
aBorder.top = NSToCoordRound(aPixelsToTwips * mTopBorderWidth);
|
||||
aBorder.bottom = NSToCoordRound(aPixelsToTwips * mBottomBorderWidth);
|
||||
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -180,7 +180,7 @@ nsTableRowGroupFrame::InitRepeatedFrame(nsIPresContext* aPresContext,
|
|||
nsIAtom* frameType;
|
||||
copyCellFrame->GetFrameType(&frameType);
|
||||
|
||||
if (nsLayoutAtoms::tableCellFrame == frameType) {
|
||||
if (IS_TABLE_CELL(frameType)) {
|
||||
#ifdef NS_DEBUG
|
||||
nsIContent* content1;
|
||||
nsIContent* content2;
|
||||
|
@ -360,6 +360,28 @@ nsTableRowGroupFrame::PlaceChild(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableRowGroupFrame::InitChildReflowState(nsIPresContext& aPresContext,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
nsMargin collapseBorder;
|
||||
nsMargin padding(0,0,0,0);
|
||||
nsMargin* pCollapseBorder = nsnull;
|
||||
if (aBorderCollapse) {
|
||||
if (aReflowState.frame) {
|
||||
nsCOMPtr<nsIAtom> fType;
|
||||
aReflowState.frame->GetFrameType(getter_AddRefs(fType));
|
||||
if (nsLayoutAtoms::tableRowFrame == fType.get()) {
|
||||
nsTableRowFrame* rowFrame = (nsTableRowFrame*)aReflowState.frame;
|
||||
pCollapseBorder = rowFrame->GetBCBorderWidth(aPixelsToTwips, collapseBorder);
|
||||
}
|
||||
}
|
||||
}
|
||||
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, &padding);
|
||||
}
|
||||
|
||||
// Reflow the frames we've already created. If aDirtyOnly is set then only
|
||||
// reflow dirty frames. This assumes that all of the dirty frames are contiguous.
|
||||
NS_METHOD
|
||||
|
@ -372,8 +394,10 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
nsTableRowFrame** aFirstRowReflowed)
|
||||
{
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
|
||||
if (NS_FAILED(rv) || !tableFrame) return rv;
|
||||
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(rv);
|
||||
|
||||
PRBool borderCollapse = tableFrame->IsBorderCollapse();
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
|
||||
nscoord cellSpacingY = tableFrame->GetCellSpacingY();
|
||||
|
||||
|
@ -439,6 +463,7 @@ nsTableRowGroupFrame::ReflowChildren(nsIPresContext* aPresContext,
|
|||
}
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, kidFrame,
|
||||
kidAvailSize, reason);
|
||||
InitChildReflowState(*aPresContext, borderCollapse, p2t, kidReflowState);
|
||||
|
||||
// If this isn't the first row frame, then we can't be at the top of
|
||||
// the page anymore...
|
||||
|
@ -555,7 +580,7 @@ HasMoreThanOneCell(nsTableCellMap* aCellMap,
|
|||
PRInt32 colIndex = 0;
|
||||
PRInt32 count = 0;
|
||||
do {
|
||||
cellData = aCellMap->GetCellAt(aRowIndex, colIndex);
|
||||
cellData = aCellMap->GetDataAt(aRowIndex, colIndex);
|
||||
if (cellData && (cellData->GetCellFrame() || cellData->IsRowSpan()))
|
||||
count++;
|
||||
if (count > 1)
|
||||
|
@ -998,8 +1023,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext* aPresContext,
|
|||
presShell->GetStyleSet(getter_AddRefs(styleSet));
|
||||
if (!styleSet) {NS_ASSERTION(PR_FALSE, "no style set"); return NS_ERROR_NULL_POINTER;}
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
PRBool borderCollapse = ((nsTableFrame*)aTableFrame->GetFirstInFlow())->IsBorderCollapse();
|
||||
|
||||
nscoord availWidth = nsTableFrame::RoundToPixel(aReflowState.availableWidth, p2t);
|
||||
nscoord availHeight = nsTableFrame::RoundToPixel(aReflowState.availableHeight, p2t);
|
||||
|
@ -1022,9 +1047,11 @@ nsTableRowGroupFrame::SplitRowGroup(nsIPresContext* aPresContext,
|
|||
// row or there is at least 5% of the current page available
|
||||
if (!prevRowFrame || (availHeight - aDesiredSize.height > pageHeight / 20)) {
|
||||
// Reflow the row in the available space and have it split
|
||||
nsSize availSize(availWidth, availHeight - bounds.y);
|
||||
nsHTMLReflowState rowReflowState(aPresContext, aReflowState, rowFrame,
|
||||
availSize, eReflowReason_Resize);
|
||||
nsSize availSize(availWidth, availHeight - bounds.y);
|
||||
nsHTMLReflowState rowReflowState(aPresContext, aReflowState, rowFrame, availSize,
|
||||
eReflowReason_Resize);
|
||||
InitChildReflowState(*aPresContext, borderCollapse, p2t, rowReflowState);
|
||||
|
||||
nsHTMLReflowMetrics desiredSize(nsnull);
|
||||
|
||||
rv = ReflowChild(rowFrame, aPresContext, desiredSize, rowReflowState,
|
||||
|
@ -1530,6 +1557,10 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
nsTableFrame* tableFrame = nsnull;
|
||||
nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(NS_ERROR_NULL_POINTER);
|
||||
GET_PIXELS_TO_TWIPS(aPresContext, p2t);
|
||||
|
||||
// Recover the state as if aNextFrame is about to be reflowed
|
||||
RecoverState(aReflowState, aNextFrame);
|
||||
|
||||
|
@ -1540,9 +1571,11 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
|
|||
// Reflow the child giving it as much room as it wants. We'll deal with
|
||||
// splitting later after final determination of rows heights taking into
|
||||
// account cells with row spans...
|
||||
nsSize kidAvailSize(aReflowState.availSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
|
||||
aNextFrame, kidAvailSize);
|
||||
nsSize kidAvailSize(aReflowState.availSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState, aNextFrame,
|
||||
kidAvailSize, aReflowState.reason);
|
||||
InitChildReflowState(*aPresContext, tableFrame->IsBorderCollapse(), p2t, kidReflowState);
|
||||
|
||||
nsSize kidMaxElementSize;
|
||||
nsHTMLReflowMetrics desiredSize(aDesiredSize.maxElementSize ? &kidMaxElementSize : nsnull,
|
||||
aDesiredSize.mFlags);
|
||||
|
@ -1715,6 +1748,28 @@ nsTableRowGroupFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) cons
|
|||
}
|
||||
#endif
|
||||
|
||||
nsMargin*
|
||||
nsTableRowGroupFrame::GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder)
|
||||
{
|
||||
aBorder.left = aBorder.right = 0;
|
||||
|
||||
nsTableRowFrame* firstRowFrame = nsnull;
|
||||
nsTableRowFrame* lastRowFrame = nsnull;
|
||||
for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
|
||||
if(!firstRowFrame) {
|
||||
firstRowFrame = rowFrame;
|
||||
}
|
||||
lastRowFrame = rowFrame;
|
||||
}
|
||||
if (firstRowFrame) {
|
||||
aBorder.top = firstRowFrame->GetTopBCBorderWidth(&aPixelsToTwips);
|
||||
aBorder.bottom = lastRowFrame->GetBottomBCBorderWidth(&aPixelsToTwips);
|
||||
}
|
||||
|
||||
return &aBorder;
|
||||
}
|
||||
|
||||
//nsILineIterator methods for nsTableFrame
|
||||
NS_IMETHODIMP
|
||||
nsTableRowGroupFrame::GetNumLines(PRInt32* aResult)
|
||||
|
@ -1757,7 +1812,7 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber,
|
|||
*aLineFlags = 0;/// should we fill these in later?
|
||||
// not gonna touch aLineBounds right now
|
||||
|
||||
CellData* firstCellData = cellMap->GetCellAt(aLineNumber, 0);
|
||||
CellData* firstCellData = cellMap->GetDataAt(aLineNumber, 0);
|
||||
if(!firstCellData)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -1767,7 +1822,7 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber,
|
|||
while((aLineNumber > 0)&&(!(*aFirstFrameOnLine)))
|
||||
{
|
||||
aLineNumber--;
|
||||
firstCellData = cellMap->GetCellAt(aLineNumber, 0);
|
||||
firstCellData = cellMap->GetDataAt(aLineNumber, 0);
|
||||
*aFirstFrameOnLine = (nsIFrame*)firstCellData->GetCellFrame();
|
||||
}
|
||||
}
|
||||
|
@ -1847,7 +1902,7 @@ nsTableRowGroupFrame::FindFrameAt(PRInt32 aLineNumber,
|
|||
PRBool gotParentRect = PR_FALSE;
|
||||
for(int i =0;i < cellCount; i++)
|
||||
{
|
||||
cellData = cellMap->GetCellAt(aLineNumber, i);
|
||||
cellData = cellMap->GetDataAt(aLineNumber, i);
|
||||
tempFrame = (nsIFrame*)cellData->GetCellFrame();
|
||||
|
||||
if(!tempFrame)
|
||||
|
@ -1919,11 +1974,11 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame,
|
|||
PRInt32& colIndexRef = colIndex;
|
||||
cellFrame->GetColIndex(colIndexRef);
|
||||
|
||||
CellData* cellData = cellMap->GetCellAt(aLineNumber, colIndex + 1);
|
||||
CellData* cellData = cellMap->GetDataAt(aLineNumber, colIndex + 1);
|
||||
|
||||
if(!cellData)// if this isnt a valid cell, drop down and check the next line
|
||||
{
|
||||
cellData = cellMap->GetCellAt(aLineNumber + 1, 0);
|
||||
cellData = cellMap->GetDataAt(aLineNumber + 1, 0);
|
||||
if(!cellData)
|
||||
{
|
||||
//*aFrame = nsnull;
|
||||
|
@ -1940,14 +1995,14 @@ nsTableRowGroupFrame::GetNextSiblingOnLine(nsIFrame*& aFrame,
|
|||
while((tempCol > 0) && (!aFrame))
|
||||
{
|
||||
tempCol--;
|
||||
cellData = cellMap->GetCellAt(aLineNumber, tempCol);
|
||||
cellData = cellMap->GetDataAt(aLineNumber, tempCol);
|
||||
aFrame = (nsIFrame*)cellData->GetCellFrame();
|
||||
if(!aFrame && (tempCol==0))
|
||||
{
|
||||
while((tempRow > 0) && (!aFrame))
|
||||
{
|
||||
tempRow--;
|
||||
cellData = cellMap->GetCellAt(tempRow, 0);
|
||||
cellData = cellMap->GetDataAt(tempRow, 0);
|
||||
aFrame = (nsIFrame*)cellData->GetCellFrame();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,6 +216,8 @@ public:
|
|||
nscoord GetHeightOfRows(nsIPresContext* aPresContext);
|
||||
nscoord GetHeightBasis(const nsHTMLReflowState& aReflowState);
|
||||
|
||||
nsMargin* GetBCBorderWidth(float aPixelsToTwips,
|
||||
nsMargin& aBorder);
|
||||
// nsILineIterator methods
|
||||
public:
|
||||
NS_IMETHOD GetNumLines(PRInt32* aResult);
|
||||
|
@ -251,6 +253,11 @@ public:
|
|||
protected:
|
||||
nsTableRowGroupFrame();
|
||||
|
||||
void InitChildReflowState(nsIPresContext& aPresContext,
|
||||
PRBool aBorderCollapse,
|
||||
float aPixelsToTwips,
|
||||
nsHTMLReflowState& aReflowState);
|
||||
|
||||
/** implement abstract method on nsHTMLContainerFrame */
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче